Move memory to cpu

This commit is contained in:
copy 2016-08-02 04:15:24 +02:00
parent 272273ebf0
commit 70ad2f9031
11 changed files with 255 additions and 267 deletions

View file

@ -18,9 +18,6 @@
* bsf, bsr
*
* popcnt
*
* Gets #included by cpu.macro.js
*
*/
"use strict";
@ -1393,42 +1390,42 @@ CPU.prototype.btc_mem = function(virt_addr, bit_offset)
{
dbg_assert(bit_offset >= 0);
var phys_addr = this.translate_address_write(virt_addr + (bit_offset >> 3) | 0);
var bit_base = this.memory.read8(phys_addr);
var bit_base = this.read8(phys_addr);
bit_offset &= 7;
this.flags = (this.flags & ~1) | (bit_base >> bit_offset & 1);
this.flags_changed &= ~1;
this.memory.write8(phys_addr, bit_base ^ 1 << bit_offset);
this.write8(phys_addr, bit_base ^ 1 << bit_offset);
}
CPU.prototype.btr_mem = function(virt_addr, bit_offset)
{
dbg_assert(bit_offset >= 0);
var phys_addr = this.translate_address_write(virt_addr + (bit_offset >> 3) | 0);
var bit_base = this.memory.read8(phys_addr);
var bit_base = this.read8(phys_addr);
bit_offset &= 7;
this.flags = (this.flags & ~1) | (bit_base >> bit_offset & 1);
this.flags_changed &= ~1;
this.memory.write8(phys_addr, bit_base & ~(1 << bit_offset));
this.write8(phys_addr, bit_base & ~(1 << bit_offset));
}
CPU.prototype.bts_mem = function(virt_addr, bit_offset)
{
dbg_assert(bit_offset >= 0);
var phys_addr = this.translate_address_write(virt_addr + (bit_offset >> 3) | 0);
var bit_base = this.memory.read8(phys_addr);
var bit_base = this.read8(phys_addr);
bit_offset &= 7;
this.flags = (this.flags & ~1) | (bit_base >> bit_offset & 1);
this.flags_changed &= ~1;
this.memory.write8(phys_addr, bit_base | 1 << bit_offset);
this.write8(phys_addr, bit_base | 1 << bit_offset);
}
CPU.prototype.bsf16 = function(old, bit_base)

View file

@ -888,7 +888,7 @@
$("memory_dump").onclick = function()
{
dump_file(emulator.v86.cpu.memory.mem8, "v86memory.bin");
dump_file(emulator.v86.cpu.mem8, "v86memory.bin");
$("memory_dump").blur();
};

View file

@ -12,6 +12,14 @@ function CPU()
/** @type {number} */
this.memory_size = 0;
// Note: Currently unused (degrades performance and not required by any OS
// that we support)
this.a20_enabled = true;
this.mem8 = new Uint8Array(0);
this.mem16 = new Uint16Array(this.mem8.buffer);
this.mem32s = new Int32Array(this.mem8.buffer);
this.segment_is_null = [];
this.segment_offsets = [];
this.segment_limits = [];
@ -205,6 +213,12 @@ function CPU()
/** @type {number} */
this.previous_ip = 0;
// managed in io.js
/** @const */ this.memory_map_read8 = [];
/** @const */ this.memory_map_write8 = [];
/** @const */ this.memory_map_read32 = [];
/** @const */ this.memory_map_write32 = [];
/**
* @const
* @type {{main: ArrayBuffer, vga: ArrayBuffer}}
@ -233,9 +247,6 @@ function CPU()
// debug registers
this.dreg = new Int32Array(8);
/** @type {Memory} */
this.memory = null;
// current state of prefixes
this.segment_prefix = SEG_PREFIX_NONE;
@ -254,6 +265,8 @@ function CPU()
this.tsc_offset = v86.microtick();
this.debug_init();
//Object.seal(this);
}
CPU.prototype.get_state = function()
@ -300,7 +313,7 @@ CPU.prototype.get_state = function()
state[39] = this.reg32s;
state[40] = this.sreg;
state[41] = this.dreg;
state[42] = this.memory;
state[42] = this.mem8;
state[43] = this.fpu;
state[45] = this.devices.virtio;
@ -320,6 +333,8 @@ CPU.prototype.get_state = function()
state[59] = this.devices.net;
state[60] = this.devices.pic;
state[61] = this.a20_enabled;
return state;
};
@ -365,7 +380,7 @@ CPU.prototype.set_state = function(state)
this.reg32s = state[39];
this.sreg = state[40];
this.dreg = state[41];
this.memory = state[42];
this.mem8 = state[42];
this.fpu = state[43];
this.devices.virtio = state[45];
@ -385,6 +400,11 @@ CPU.prototype.set_state = function(state)
this.devices.net = state[59];
this.devices.pic = state[60];
this.a20_enabled = state[61];
this.mem16 = new Uint16Array(this.mem8.buffer, this.mem8.byteOffset, this.mem8.length >> 1);
this.mem32s = new Int32Array(this.mem8.buffer, this.mem8.byteOffset, this.mem8.length >> 2);
this.full_clear_tlb();
// tsc_offset?
@ -457,6 +477,8 @@ CPU.prototype.reboot_internal = function()
CPU.prototype.reset = function()
{
this.a20_enabled = true;
this.segment_is_null = new Uint8Array(8);
this.segment_limits = new Uint32Array(8);
//this.segment_infos = new Uint32Array(8);
@ -535,10 +557,31 @@ CPU.prototype.reset = function()
};
/** @export */
CPU.prototype.create_memory = function(size, no_initial_alloc)
CPU.prototype.create_memory = function(size, no_alloc)
{
this.memory_size = size;
this.memory = new Memory(this.memory_size, no_initial_alloc);
// use by dynamic translator
//if(OP_TRANSLATION) this.mem_page_infos = new Uint8Array(1 << 20);
dbg_assert((size & MMAP_BLOCK_SIZE - 1) === 0);
if(no_alloc)
{
var buffer = new ArrayBuffer(0);
this.mem8 = new Uint8Array(buffer);
this.mem16 = new Uint16Array(buffer);
this.mem32s = new Int32Array(buffer);
}
else
{
var buffer = new ArrayBuffer(size);
this.mem8 = new Uint8Array(buffer);
this.mem16 = new Uint16Array(buffer);
this.mem32s = new Int32Array(buffer);
}
};
CPU.prototype.init = function(settings, device_bus)
@ -552,7 +595,7 @@ CPU.prototype.init = function(settings, device_bus)
this.translator = new DynamicTranslator(this);
}
var io = new IO(this.memory);
var io = new IO(this);
this.io = io;
this.bios.main = settings.bios;
@ -726,13 +769,13 @@ CPU.prototype.load_bios = function()
var data = new Uint8Array(bios),
start = 0x100000 - bios.byteLength;
this.memory.mem8.set(data, start);
this.mem8.set(data, start);
if(vga_bios)
{
// load vga bios
data = new Uint8Array(vga_bios);
this.memory.mem8.set(data, 0xC0000);
this.mem8.set(data, 0xC0000);
}
else
{
@ -744,12 +787,12 @@ CPU.prototype.load_bios = function()
function(addr)
{
addr &= 0xFFFFF;
return this.memory.mem8[addr];
return this.mem8[addr];
}.bind(this),
function(addr, value)
{
addr &= 0xFFFFF;
this.memory.mem8[addr] = value;
this.mem8[addr] = value;
}.bind(this));
};
@ -1016,7 +1059,7 @@ CPU.prototype.read_imm8 = function()
this.last_virt_eip = this.instruction_pointer & ~0xFFF;
}
var data8 = this.memory.read8(this.eip_phys ^ this.instruction_pointer);
var data8 = this.read8(this.eip_phys ^ this.instruction_pointer);
this.instruction_pointer = this.instruction_pointer + 1 | 0;
return data8;
@ -1037,7 +1080,7 @@ CPU.prototype.read_imm16 = function()
return this.read_imm8() | this.read_imm8() << 8;
}
var data16 = this.memory.read16(this.eip_phys ^ this.instruction_pointer);
var data16 = this.read16(this.eip_phys ^ this.instruction_pointer);
this.instruction_pointer = this.instruction_pointer + 2 | 0;
return data16;
@ -1056,7 +1099,7 @@ CPU.prototype.read_imm32s = function()
return this.read_imm16() | this.read_imm16() << 16;
}
var data32 = this.memory.read32s(this.eip_phys ^ this.instruction_pointer);
var data32 = this.read32s(this.eip_phys ^ this.instruction_pointer);
this.instruction_pointer = this.instruction_pointer + 4 | 0;
return data32;
@ -1069,7 +1112,7 @@ CPU.prototype.get_imm16 = function()
//{
// return this.safe_read16(this.instruction_pointer);
//}
//return this.memory.read16(this.eip_phys ^ this.instruction_pointer);
//return this.read16(this.eip_phys ^ this.instruction_pointer);
};
CPU.prototype.get_imm32s = function()
@ -1079,7 +1122,7 @@ CPU.prototype.get_imm32s = function()
return this.safe_read32s(this.instruction_pointer);
}
return this.memory.read32s(this.eip_phys ^ this.instruction_pointer);
return this.read32s(this.eip_phys ^ this.instruction_pointer);
};
@ -1089,7 +1132,7 @@ CPU.prototype.virt_boundary_read16 = function(low, high)
dbg_assert((low & 0xFFF) === 0xFFF);
dbg_assert((high & 0xFFF) === 0);
return this.memory.read8(low) | this.memory.read8(high) << 8;
return this.read8(low) | this.read8(high) << 8;
};
// read doubleword from a page boundary, given 2 addresses
@ -1105,12 +1148,12 @@ CPU.prototype.virt_boundary_read32s = function(low, high)
if(low & 2)
{
// 0xFFF
mid = this.memory.read_aligned16(high - 2 >> 1);
mid = this.read_aligned16(high - 2 >> 1);
}
else
{
// 0xFFD
mid = this.memory.read_aligned16(low + 1 >> 1);
mid = this.read_aligned16(low + 1 >> 1);
}
}
else
@ -1119,7 +1162,7 @@ CPU.prototype.virt_boundary_read32s = function(low, high)
mid = this.virt_boundary_read16(low + 1 | 0, high - 1 | 0);
}
return this.memory.read8(low) | mid << 8 | this.memory.read8(high) << 24;;
return this.read8(low) | mid << 8 | this.read8(high) << 24;;
};
CPU.prototype.virt_boundary_write16 = function(low, high, value)
@ -1127,8 +1170,8 @@ CPU.prototype.virt_boundary_write16 = function(low, high, value)
dbg_assert((low & 0xFFF) === 0xFFF);
dbg_assert((high & 0xFFF) === 0);
this.memory.write8(low, value);
this.memory.write8(high, value >> 8);
this.write8(low, value);
this.write8(high, value >> 8);
};
CPU.prototype.virt_boundary_write32 = function(low, high, value)
@ -1136,29 +1179,29 @@ CPU.prototype.virt_boundary_write32 = function(low, high, value)
dbg_assert((low & 0xFFF) >= 0xFFD);
dbg_assert((high - 3 & 0xFFF) === (low & 0xFFF));
this.memory.write8(low, value);
this.memory.write8(high, value >> 24);
this.write8(low, value);
this.write8(high, value >> 24);
if(low & 1)
{
if(low & 2)
{
// 0xFFF
this.memory.write8(high - 2, value >> 8);
this.memory.write8(high - 1, value >> 16);
this.write8(high - 2, value >> 8);
this.write8(high - 1, value >> 16);
}
else
{
// 0xFFD
this.memory.write8(low + 1 | 0, value >> 8);
this.memory.write8(low + 2 | 0, value >> 16);
this.write8(low + 1 | 0, value >> 8);
this.write8(low + 2 | 0, value >> 16);
}
}
else
{
// 0xFFE
this.memory.write8(low + 1 | 0, value >> 8);
this.memory.write8(high - 1, value >> 16);
this.write8(low + 1 | 0, value >> 8);
this.write8(high - 1, value >> 16);
}
};
@ -1169,7 +1212,7 @@ CPU.prototype.virt_boundary_write32 = function(low, high, value)
CPU.prototype.safe_read8 = function(addr)
{
dbg_assert(addr < 0x80000000);
return this.memory.read8(this.translate_address_read(addr));
return this.read8(this.translate_address_read(addr));
};
CPU.prototype.safe_read16 = function(addr)
@ -1180,7 +1223,7 @@ CPU.prototype.safe_read16 = function(addr)
}
else
{
return this.memory.read16(this.translate_address_read(addr));
return this.read16(this.translate_address_read(addr));
}
};
@ -1192,14 +1235,14 @@ CPU.prototype.safe_read32s = function(addr)
}
else
{
return this.memory.read32s(this.translate_address_read(addr));
return this.read32s(this.translate_address_read(addr));
}
};
CPU.prototype.safe_write8 = function(addr, value)
{
dbg_assert(addr < 0x80000000);
this.memory.write8(this.translate_address_write(addr), value);
this.write8(this.translate_address_write(addr), value);
};
CPU.prototype.safe_write16 = function(addr, value)
@ -1212,7 +1255,7 @@ CPU.prototype.safe_write16 = function(addr, value)
}
else
{
this.memory.write16(phys_low, value);
this.write16(phys_low, value);
}
};
@ -1226,7 +1269,7 @@ CPU.prototype.safe_write32 = function(addr, value)
}
else
{
this.memory.write32(phys_low, value);
this.write32(phys_low, value);
}
};
@ -1408,9 +1451,9 @@ CPU.prototype.call_interrupt_vector = function(interrupt_nr, is_software_int, er
addr = this.translate_address_system_read(addr);
}
var base = this.memory.read16(addr) | this.memory.read16(addr + 6 | 0) << 16;
var selector = this.memory.read16(addr + 2 | 0);
var access = this.memory.read8(addr + 5 | 0);
var base = this.read16(addr) | this.read16(addr + 6 | 0) << 16;
var selector = this.read16(addr + 2 | 0);
var access = this.read8(addr + 5 | 0);
var dpl = access >> 5 & 3;
var type = access & 31;
@ -1490,8 +1533,8 @@ CPU.prototype.call_interrupt_vector = function(interrupt_nr, is_software_int, er
//this.debug.dump_regs_short();
var tss_stack_addr = this.get_tss_stack_addr(info.dpl);
var new_esp = this.memory.read32s(tss_stack_addr);
var new_ss = this.memory.read16(tss_stack_addr + 4 | 0);
var new_esp = this.read32s(tss_stack_addr);
var new_ss = this.read16(tss_stack_addr + 4 | 0);
var ss_info = this.lookup_segment_selector(new_ss);
// Disabled: Incorrect handling of direction bit
@ -1672,8 +1715,8 @@ CPU.prototype.call_interrupt_vector = function(interrupt_nr, is_software_int, er
// call 4 byte cs:ip interrupt vector from ivt at cpu.memory 0
var index = interrupt_nr << 2;
var new_ip = this.memory.read16(index);
var new_cs = this.memory.read16(index + 2 | 0);
var new_ip = this.read16(index);
var new_cs = this.read16(index + 2 | 0);
// push flags, cs:ip
this.load_eflags();
@ -2205,8 +2248,8 @@ CPU.prototype.far_jump = function(eip, selector, is_call)
dbg_log("more privilege call gate is_16=" + is_16 + " from=" + this.cpl + " to=" + cs_info.dpl);
var tss_stack_addr = this.get_tss_stack_addr(cs_info.dpl);
var new_esp = this.memory.read32s(tss_stack_addr);
var new_ss = this.memory.read16(tss_stack_addr + 4 | 0);
var new_esp = this.read32s(tss_stack_addr);
var new_ss = this.read16(tss_stack_addr + 4 | 0);
var ss_info = this.lookup_segment_selector(new_ss);
// Disabled: Incorrect handling of direction bit
@ -2503,7 +2546,7 @@ CPU.prototype.do_task_switch = function(selector)
if(true /* is jump or call or int */)
{
// mark as busy
this.memory.write8(descriptor.table_offset + 5 | 0, this.memory.read8(descriptor.table_offset + 5 | 0) | 2);
this.write8(descriptor.table_offset + 5 | 0, this.read8(descriptor.table_offset + 5 | 0) | 2);
}
//var new_tsr_size = descriptor.effective_limit;
@ -2831,7 +2874,7 @@ CPU.prototype.read_write_e8 = function()
if(this.modrm_byte < 0xC0) {
var virt_addr = this.modrm_resolve(this.modrm_byte);
this.phys_addr = this.translate_address_write(virt_addr);
return this.memory.read8(this.phys_addr);
return this.read8(this.phys_addr);
} else {
return this.reg8[this.modrm_byte << 2 & 0xC | this.modrm_byte >> 2 & 1];
}
@ -2840,7 +2883,7 @@ CPU.prototype.read_write_e8 = function()
CPU.prototype.write_e8 = function(value)
{
if(this.modrm_byte < 0xC0) {
this.memory.write8(this.phys_addr, value);
this.write8(this.phys_addr, value);
}
else {
this.reg8[this.modrm_byte << 2 & 0xC | this.modrm_byte >> 2 & 1] = value;
@ -2858,7 +2901,7 @@ CPU.prototype.read_write_e16 = function()
return this.virt_boundary_read16(this.phys_addr, this.phys_addr_high);
} else {
this.phys_addr_high = 0;
return this.memory.read16(this.phys_addr);
return this.read16(this.phys_addr);
}
} else {
return this.reg16[this.modrm_byte << 1 & 14];
@ -2871,7 +2914,7 @@ CPU.prototype.write_e16 = function(value)
if(this.phys_addr_high) {
this.virt_boundary_write16(this.phys_addr, this.phys_addr_high, value);
} else {
this.memory.write16(this.phys_addr, value);
this.write16(this.phys_addr, value);
}
} else {
this.reg16[this.modrm_byte << 1 & 14] = value;
@ -2889,7 +2932,7 @@ CPU.prototype.read_write_e32 = function()
return this.virt_boundary_read32s(this.phys_addr, this.phys_addr_high);
} else {
this.phys_addr_high = 0;
return this.memory.read32s(this.phys_addr);
return this.read32s(this.phys_addr);
}
} else {
return this.reg32s[this.modrm_byte & 7];
@ -2902,7 +2945,7 @@ CPU.prototype.write_e32 = function(value)
if(this.phys_addr_high) {
this.virt_boundary_write32(this.phys_addr, this.phys_addr_high, value);
} else {
this.memory.write32(this.phys_addr, value);
this.write32(this.phys_addr, value);
}
} else {
this.reg32s[this.modrm_byte & 7] = value;
@ -3026,7 +3069,7 @@ CPU.prototype.test_privileges_for_io = function(port, size)
{
dbg_assert((tsr_offset + 0x64 + 2 & 0xFFF) < 0xFFF);
var iomap_base = this.memory.read16(this.translate_address_system_read(tsr_offset + 0x64 + 2 | 0)),
var iomap_base = this.read16(this.translate_address_system_read(tsr_offset + 0x64 + 2 | 0)),
high_port = port + size - 1 | 0;
if(tsr_size >= (iomap_base + (high_port >> 3) | 0))
@ -3034,7 +3077,7 @@ CPU.prototype.test_privileges_for_io = function(port, size)
var mask = ((1 << size) - 1) << (port & 7),
addr = this.translate_address_system_read(tsr_offset + iomap_base + (port >> 3) | 0),
port_info = (mask & 0xFF00) ?
this.memory.read16(addr) : this.memory.read8(addr);
this.read16(addr) : this.read8(addr);
dbg_assert((addr & 0xFFF) < 0xFFF);
@ -3282,15 +3325,15 @@ CPU.prototype.lookup_segment_selector = function(selector)
}
info.table_offset = table_offset;
info.base = this.memory.read16(table_offset + 2 | 0) | this.memory.read8(table_offset + 4 | 0) << 16 |
this.memory.read8(table_offset + 7 | 0) << 24;
info.access = this.memory.read8(table_offset + 5 | 0);
info.flags = this.memory.read8(table_offset + 6 | 0) >> 4;
info.base = this.read16(table_offset + 2 | 0) | this.read8(table_offset + 4 | 0) << 16 |
this.read8(table_offset + 7 | 0) << 24;
info.access = this.read8(table_offset + 5 | 0);
info.flags = this.read8(table_offset + 6 | 0) >> 4;
info.raw0 = this.memory.read32s(table_offset | 0);
info.raw1 = this.memory.read32s(table_offset + 4 | 0);
info.raw0 = this.read32s(table_offset | 0);
info.raw1 = this.read32s(table_offset + 4 | 0);
//this.memory.write8(table_offset + 5 | 0, info.access | 1);
//this.write8(table_offset + 5 | 0, info.access | 1);
// used if system
info.type = info.access & 0xF;
@ -3308,8 +3351,8 @@ CPU.prototype.lookup_segment_selector = function(selector)
info.size = (info.flags & 4) === 4;
var limit = this.memory.read16(table_offset) |
(this.memory.read8(table_offset + 6 | 0) & 0xF) << 16;
var limit = this.read16(table_offset) |
(this.read8(table_offset + 6 | 0) & 0xF) << 16;
if(info.flags & 8)
{
@ -3476,7 +3519,7 @@ CPU.prototype.load_tr = function(selector)
this.sreg[reg_tr] = selector;
// Mark task as busy
this.memory.write8(info.table_offset + 5 | 0, this.memory.read8(info.table_offset + 5 | 0) | 2);
this.write8(info.table_offset + 5 | 0, this.read8(info.table_offset + 5 | 0) | 2);
//dbg_log("tsr at " + h(info.base) + "; (" + info.effective_limit + " bytes)");
};
@ -3786,7 +3829,7 @@ CPU.prototype.do_page_translation = function(addr, for_writing, user)
{
var page = addr >>> 12,
page_dir_addr = (this.cr[3] >>> 2) + (page >> 10) | 0,
page_dir_entry = this.memory.mem32s[page_dir_addr],
page_dir_entry = this.mem32s[page_dir_addr],
high,
can_write = true,
global,
@ -3842,7 +3885,7 @@ CPU.prototype.do_page_translation = function(addr, for_writing, user)
// size bit is set
// set the accessed and dirty bits
this.memory.mem32s[page_dir_addr] = page_dir_entry | 0x20 | for_writing << 6;
this.mem32s[page_dir_addr] = page_dir_entry | 0x20 | for_writing << 6;
high = (page_dir_entry & 0xFFC00000) | (addr & 0x3FF000);
global = page_dir_entry & 0x100;
@ -3850,7 +3893,7 @@ CPU.prototype.do_page_translation = function(addr, for_writing, user)
else
{
var page_table_addr = ((page_dir_entry & 0xFFFFF000) >>> 2) + (page & 0x3FF) | 0,
page_table_entry = this.memory.mem32s[page_table_addr];
page_table_entry = this.mem32s[page_table_addr];
if((page_table_entry & 1) === 0)
{
@ -3887,8 +3930,8 @@ CPU.prototype.do_page_translation = function(addr, for_writing, user)
}
// set the accessed and dirty bits
this.memory.mem32s[page_dir_addr] = page_dir_entry | 0x20;
this.memory.mem32s[page_table_addr] = page_table_entry | 0x20 | for_writing << 6;
this.mem32s[page_dir_addr] = page_dir_entry | 0x20;
this.mem32s[page_table_addr] = page_table_entry | 0x20 | for_writing << 6;
high = page_table_entry & 0xFFFFF000;
global = page_table_entry & 0x100;

View file

@ -217,7 +217,7 @@ CPU.prototype.debug_init = function()
line += h(i, 2) + " | ";
dbg_log(line + h(esp + 4 * i, 8) + " | " + h(cpu.memory.read32s(esp + 4 * i) >>> 0));
dbg_log(line + h(esp + 4 * i, 8) + " | " + h(cpu.read32s(esp + 4 * i) >>> 0));
}
}
@ -230,12 +230,13 @@ CPU.prototype.debug_init = function()
var iopl = cpu.getiopl();
var cpl = cpu.cpl;
var cs_eip = h(cpu.sreg[reg_cs], 4) + ":" + h(cpu.get_real_eip() >>> 0, 8);
var ss_esp = h(cpu.sreg[reg_ss], 4) + ":" + h(cpu.get_stack_reg() >>> 0, 8);
var op_size = cpu.is_32 ? "32" : "16";
var if_ = (cpu.flags & flag_interrupt) ? 1 : 0;
dbg_log("mode=" + mode + "/" + op_size + " paging=" + (+cpu.paging) + " vm=" + vm +
" iopl=" + iopl + " cpl=" + cpl + " if=" + if_ + " cs:eip=" + cs_eip +
" cs_off=" + h(cpu.get_seg(reg_cs) >>> 0, 8) + " flgs=" + h(cpu.get_eflags() >>> 0), LOG_CPU);
" cs_off=" + h(cpu.get_seg(reg_cs) >>> 0, 8) + " flgs=" + h(cpu.get_eflags() >>> 0) + " ss:esp=" + ss_esp, LOG_CPU);
}
function dump_regs_short()
@ -382,13 +383,13 @@ CPU.prototype.debug_init = function()
{
for(var i = 0; i < size; i += 8, addr += 8)
{
var base = cpu.memory.read16(addr + 2) |
cpu.memory.read8(addr + 4) << 16 |
cpu.memory.read8(addr + 7) << 24,
var base = cpu.read16(addr + 2) |
cpu.read8(addr + 4) << 16 |
cpu.read8(addr + 7) << 24,
limit = cpu.memory.read16(addr) | (cpu.memory.read8(addr + 6) & 0xF) << 16,
access = cpu.memory.read8(addr + 5),
flags = cpu.memory.read8(addr + 6) >> 4,
limit = cpu.read16(addr) | (cpu.read8(addr + 6) & 0xF) << 16,
access = cpu.read8(addr + 5),
flags = cpu.read8(addr + 6) >> 4,
flags_str = "",
dpl = access >> 5 & 3;
@ -457,9 +458,9 @@ CPU.prototype.debug_init = function()
for(var i = 0; i < cpu.idtr_size; i += 8)
{
var addr = cpu.translate_address_system_read(cpu.idtr_offset + i),
base = cpu.memory.read16(addr) | cpu.memory.read16(addr + 6) << 16,
selector = cpu.memory.read16(addr + 2),
type = cpu.memory.read8(addr + 5),
base = cpu.read16(addr) | cpu.read16(addr + 6) << 16,
selector = cpu.read16(addr + 2),
type = cpu.read8(addr + 5),
line,
dpl = type >> 5 & 3;
@ -538,7 +539,8 @@ CPU.prototype.debug_init = function()
for(var i = 0; i < 1024; i++)
{
var dword = cpu.memory.read32s(cpu.cr[3] + 4 * i),
var addr = cpu.cr[3] + 4 * i;
var dword = cpu.read32s(addr),
entry = load_page_entry(dword, true);
if(!entry)
@ -566,7 +568,8 @@ CPU.prototype.debug_init = function()
for(var j = 0; j < 1024; j++)
{
dword = cpu.memory.read32s(entry.address + 4 * j);
var sub_addr = entry.address + 4 * j;
dword = cpu.read32s(sub_addr);
var subentry = load_page_entry(dword, false);
@ -582,7 +585,7 @@ CPU.prototype.debug_init = function()
flags += subentry.dirty ? "Di " : " ";
dbg_log("# " + h((i << 22 | j << 12) >>> 0, 8) + " -> " +
h(subentry.address, 8) + " | " + flags);
h(subentry.address, 8) + " | " + flags + " (at " + h(sub_addr, 8) + ")");
}
}
}
@ -604,7 +607,7 @@ CPU.prototype.debug_init = function()
start = 0;
}
return cpu.memory.mem8.slice(start, start + count).buffer;
return cpu.mem8.slice(start, start + count).buffer;
}
@ -621,7 +624,7 @@ CPU.prototype.debug_init = function()
for(var j = 0; j < 0x10; j++)
{
byt = cpu.memory.read8(addr + (i << 4) + j);
byt = cpu.read8(addr + (i << 4) + j);
line += h(byt, 2) + " ";
}
@ -629,7 +632,7 @@ CPU.prototype.debug_init = function()
for(j = 0; j < 0x10; j++)
{
byt = cpu.memory.read8(addr + (i << 4) + j);
byt = cpu.read8(addr + (i << 4) + j);
line += (byt < 33 || byt > 126) ? "." : String.fromCharCode(byt);
}
@ -652,7 +655,7 @@ CPU.prototype.debug_init = function()
for(var j = 0; j < width; j++)
{
var used = cpu.memory.mem32s[(i * width + j) * block_size] > 0;
var used = cpu.mem32s[(i * width + j) * block_size] > 0;
row += used ? "X" : " ";
}
@ -666,9 +669,14 @@ CPU.prototype.debug_init = function()
{
//if(interrupt_nr === 0x20)
//{
// var vxd_device = this.safe_read16(this.instruction_pointer + 2);
// var vxd_sub = this.safe_read16(this.instruction_pointer + 0);
// dbg_log("vxd: " + h(vxd_device, 4) + " " + h(vxd_sub, 4));
// //var vxd_device = cpu.safe_read16(cpu.instruction_pointer + 2);
// //var vxd_sub = cpu.safe_read16(cpu.instruction_pointer + 0);
// //var service = "";
// //if(vxd_device === 1)
// //{
// // service = vxd_table1[vxd_sub];
// //}
// //dbg_log("vxd: " + h(vxd_device, 4) + " " + h(vxd_sub, 4) + " " + service);
//}
//if(interrupt_nr >= 0x21 && interrupt_nr < 0x30)
@ -698,7 +706,7 @@ CPU.prototype.debug_init = function()
// this.instruction_pointer += 2;
// dbg_log("BUG()", LOG_CPU);
// dbg_log("line=" + this.read_imm16() + " " +
// "file=" + this.memory.read_string(this.translate_address_read(this.read_imm32s())), LOG_CPU);
// "file=" + this.read_string(this.translate_address_read(this.read_imm32s())), LOG_CPU);
// this.instruction_pointer -= 8;
// this.debug.dump_regs_short();
//}

View file

@ -2,19 +2,19 @@
/**
* @constructor
* @param {CPU} dev
* @param {CPU} cpu
*/
function DMA(dev)
function DMA(cpu)
{
/** @const @type {Memory} */
this.memory = dev.memory;
/** @const @type {CPU} */
this.cpu = cpu;
this.channel_addr = new Int32Array(4);
this.channel_count = new Int32Array(4);
this.lsb_msb_flipflop = 0;
var io = dev.io;
var io = cpu.io;
io.register_write(0x04, this, this.port_write.bind(this, 0x04));
io.register_write(0x05, this, this.port_write.bind(this, 0x05));
io.register_write(0x0A, this, this.portA_write);
@ -121,12 +121,12 @@ DMA.prototype.do_read = function(buffer, start, len, channel, fn)
}
else
{
var memory = this.memory;
var cpu = this.cpu;
this.channel_addr[channel] += read_count;
buffer.get(start, read_count, function(data)
{
memory.write_blob(data, addr);
cpu.write_blob(data, addr);
fn(false);
});
}
@ -156,7 +156,7 @@ DMA.prototype.do_write = function(buffer, start, len, channel, fn)
this.channel_addr[channel] += read_count;
buffer.set(start,
this.memory.mem8.subarray(addr, addr + read_count + 1),
this.cpu.mem8.subarray(addr, addr + read_count + 1),
function() {
fn(false);
}

View file

@ -399,9 +399,6 @@ function IDEInterface(device, cpu, buffer, is_cd, device_nr, interface_nr, bus)
/** @const @type {CPU} */
this.cpu = cpu;
/** @const @type {Memory} */
this.memory = cpu.memory;
this.buffer = buffer;
/** @type {number} */
@ -1131,9 +1128,9 @@ IDEInterface.prototype.atapi_read_dma = function(cmd)
offset = 0;
do {
var addr = this.memory.read32s(prdt_start),
count = this.memory.read16(prdt_start + 4),
end = this.memory.read8(prdt_start + 7) & 0x80;
var addr = this.cpu.read32s(prdt_start),
count = this.cpu.read16(prdt_start + 4),
end = this.cpu.read8(prdt_start + 7) & 0x80;
if(!count)
{
@ -1141,7 +1138,7 @@ IDEInterface.prototype.atapi_read_dma = function(cmd)
}
dbg_log("dma read dest=" + h(addr) + " count=" + h(count), LOG_DISK);
this.memory.write_blob(data.subarray(offset, offset + count), addr);
this.cpu.write_blob(data.subarray(offset, offset + count), addr);
offset += count;
prdt_start += 8;
@ -1387,9 +1384,9 @@ IDEInterface.prototype.ata_read_sectors_dma = function(cmd)
dbg_assert(orig_prdt_start === prdt_start);
do {
var addr = this.memory.read32s(prdt_start),
count = this.memory.read16(prdt_start + 4),
end = this.memory.read8(prdt_start + 7) & 0x80;
var addr = this.cpu.read32s(prdt_start),
count = this.cpu.read16(prdt_start + 4),
end = this.cpu.read8(prdt_start + 7) & 0x80;
if(!count)
{
@ -1397,7 +1394,7 @@ IDEInterface.prototype.ata_read_sectors_dma = function(cmd)
}
dbg_log("dma read transfer dest=" + h(addr) + " count=" + h(count), LOG_DISK);
this.memory.write_blob(data.subarray(offset, offset + count), addr);
this.cpu.write_blob(data.subarray(offset, offset + count), addr);
offset += count;
prdt_start += 8;
@ -1509,9 +1506,9 @@ IDEInterface.prototype.ata_write_dma = function(cmd)
dbg_log("prdt addr: " + h(prdt_start, 8), LOG_DISK);
do {
var prd_addr = this.memory.read32s(prdt_start),
prd_count = this.memory.read16(prdt_start + 4),
end = this.memory.read8(prdt_start + 7) & 0x80;
var prd_addr = this.cpu.read32s(prdt_start),
prd_count = this.cpu.read16(prdt_start + 4),
end = this.cpu.read8(prdt_start + 7) & 0x80;
if(!prd_count)
{
@ -1521,7 +1518,7 @@ IDEInterface.prototype.ata_write_dma = function(cmd)
dbg_log("dma write transfer dest=" + h(prd_addr) + " prd_count=" + h(prd_count), LOG_DISK);
var slice = this.memory.mem8.subarray(prd_addr, prd_addr + prd_count);
var slice = this.cpu.mem8.subarray(prd_addr, prd_addr + prd_count);
dbg_assert(slice.length === prd_count);
//if(DEBUG)

View file

@ -5,9 +5,9 @@
* Devices register their ports here
*
* @constructor
* @param {Memory} memory
* @param {CPU} cpu
*/
function IO(memory)
function IO(cpu)
{
/** @const */
this.ports = [];
@ -15,8 +15,8 @@ function IO(memory)
/* const */
this.devices = Array(0x10000);
/** @const @type {Memory} */
this.memory = memory;
/** @const @type {CPU} */
this.cpu = cpu;
for(var i = 0; i < 0x10000; i++)
@ -34,13 +34,13 @@ function IO(memory)
};
}
var memory_size = memory.size;
var memory_size = cpu.memory_size;
for(var i = 0; (i << MMAP_BLOCK_BITS) < memory_size; i++)
{
// avoid sparse arrays
memory.memory_map_read8[i] = memory.memory_map_write8[i] = undefined;
memory.memory_map_read32[i] = memory.memory_map_write32[i] = undefined;
cpu.memory_map_read8[i] = cpu.memory_map_write8[i] = undefined;
cpu.memory_map_read32[i] = cpu.memory_map_write32[i] = undefined;
}
this.mmap_register(memory_size, 0x100000000 - memory_size,
@ -253,7 +253,7 @@ IO.prototype.in_mmap_range = function(start, count)
var end = start + count;
if(end >= this.memory.size)
if(end >= this.cpu.memory_size)
{
return true;
}
@ -263,7 +263,7 @@ IO.prototype.in_mmap_range = function(start, count)
while(start < end)
{
if(this.memory.in_mapped_range(start))
if(this.cpu.in_mapped_range(start))
{
return true;
}
@ -277,7 +277,7 @@ IO.prototype.in_mmap_range = function(start, count)
IO.prototype.mmap_read32_shim = function(addr)
{
var aligned_addr = addr >>> MMAP_BLOCK_BITS;
var fn = this.memory.memory_map_read8[aligned_addr];
var fn = this.cpu.memory_map_read8[aligned_addr];
return fn(addr) | fn(addr + 1) << 8 |
fn(addr + 2) << 16 | fn(addr + 3) << 24;
@ -286,7 +286,7 @@ IO.prototype.mmap_read32_shim = function(addr)
IO.prototype.mmap_write32_shim = function(addr, value)
{
var aligned_addr = addr >>> MMAP_BLOCK_BITS;
var fn = this.memory.memory_map_write8[aligned_addr];
var fn = this.cpu.memory_map_write8[aligned_addr];
fn(addr, value & 0xFF);
fn(addr + 1, value >> 8 & 0xFF);
@ -319,10 +319,10 @@ IO.prototype.mmap_register = function(addr, size, read_func8, write_func8, read_
for(; size > 0; aligned_addr++)
{
this.memory.memory_map_read8[aligned_addr] = read_func8;
this.memory.memory_map_write8[aligned_addr] = write_func8;
this.memory.memory_map_read32[aligned_addr] = read_func32;
this.memory.memory_map_write32[aligned_addr] = write_func32;
this.cpu.memory_map_read8[aligned_addr] = read_func8;
this.cpu.memory_map_write8[aligned_addr] = write_func8;
this.cpu.memory_map_read32[aligned_addr] = read_func32;
this.cpu.memory_map_write32[aligned_addr] = write_func32;
size -= MMAP_BLOCK_SIZE;
}

View file

@ -10,64 +10,8 @@ var A20_MASK32 = ~(1 << 20 - 2);
/** @const */
var USE_A20 = false;
/**
* @constructor
* @param {number} memory_size
*/
function Memory(memory_size, no_alloc)
{
this.size = memory_size;
// managed by IO() in io.js
/** @const */ this.memory_map_read8 = [];
/** @const */ this.memory_map_write8 = [];
/** @const */ this.memory_map_read32 = [];
/** @const */ this.memory_map_write32 = [];
// use by dynamic translator
//if(OP_TRANSLATION) this.mem_page_infos = new Uint8Array(1 << 20);
dbg_assert((memory_size & MMAP_BLOCK_SIZE - 1) === 0);
if(no_alloc)
{
var buffer = new ArrayBuffer(0);
this.mem8 = new Uint8Array(buffer);
this.mem16 = new Uint16Array(buffer);
this.mem32s = new Int32Array(buffer);
}
else
{
var buffer = new ArrayBuffer(memory_size);
this.mem8 = new Uint8Array(buffer);
this.mem16 = new Uint16Array(buffer);
this.mem32s = new Int32Array(buffer);
}
this.a20_enabled = true;
};
Memory.prototype.get_state = function()
{
return [
this.size,
this.mem8,
];
}
Memory.prototype.set_state = function(state)
{
this.size = state[0];
this.mem8 = state[1];
this.mem16 = new Uint16Array(this.mem8.buffer, this.mem8.byteOffset, this.mem8.length >> 1);
this.mem32s = new Int32Array(this.mem8.buffer, this.mem8.byteOffset, this.mem8.length >> 2);
};
// called by all memory reads and writes
Memory.prototype.debug_write = function(addr, size, value)
CPU.prototype.debug_write = function(addr, size, value)
{
if(!DEBUG)
{
@ -83,7 +27,7 @@ Memory.prototype.debug_write = function(addr, size, value)
/**
* @param {boolean=} is_write
*/
Memory.prototype.debug_read = function(addr, size, is_write)
CPU.prototype.debug_read = function(addr, size, is_write)
{
if(!DEBUG)
{
@ -95,24 +39,24 @@ Memory.prototype.debug_read = function(addr, size, is_write)
};
Memory.prototype.mmap_read8 = function(addr)
CPU.prototype.mmap_read8 = function(addr)
{
return this.memory_map_read8[addr >>> MMAP_BLOCK_BITS](addr);
};
Memory.prototype.mmap_write8 = function(addr, value)
CPU.prototype.mmap_write8 = function(addr, value)
{
this.memory_map_write8[addr >>> MMAP_BLOCK_BITS](addr, value);
};
Memory.prototype.mmap_read16 = function(addr)
CPU.prototype.mmap_read16 = function(addr)
{
var fn = this.memory_map_read8[addr >>> MMAP_BLOCK_BITS];
return fn(addr) | fn(addr + 1 | 0) << 8;
};
Memory.prototype.mmap_write16 = function(addr, value)
CPU.prototype.mmap_write16 = function(addr, value)
{
var fn = this.memory_map_write8[addr >>> MMAP_BLOCK_BITS];
@ -120,29 +64,29 @@ Memory.prototype.mmap_write16 = function(addr, value)
fn(addr + 1 | 0, value >> 8 & 0xFF);
};
Memory.prototype.mmap_read32 = function(addr)
CPU.prototype.mmap_read32 = function(addr)
{
var aligned_addr = addr >>> MMAP_BLOCK_BITS;
return this.memory_map_read32[aligned_addr](addr);
}
Memory.prototype.mmap_write32 = function(addr, value)
CPU.prototype.mmap_write32 = function(addr, value)
{
var aligned_addr = addr >>> MMAP_BLOCK_BITS;
this.memory_map_write32[aligned_addr](addr, value);
}
Memory.prototype.in_mapped_range = function(addr)
CPU.prototype.in_mapped_range = function(addr)
{
return addr < 0 || addr >= 0xA0000 && addr < 0xC0000 || addr >= this.size;
return addr < 0 || addr >= 0xA0000 && addr < 0xC0000 || addr >= this.memory_size;
};
/**
* @param {number} addr
*/
Memory.prototype.read8 = function(addr)
CPU.prototype.read8 = function(addr)
{
this.debug_read(addr, 1);
if(USE_A20 && !this.a20_enabled) addr &= A20_MASK;
@ -160,7 +104,7 @@ Memory.prototype.read8 = function(addr)
/**
* @param {number} addr
*/
Memory.prototype.read16 = function(addr)
CPU.prototype.read16 = function(addr)
{
this.debug_read(addr, 2);
if(USE_A20 && !this.a20_enabled) addr &= A20_MASK;
@ -178,7 +122,7 @@ Memory.prototype.read16 = function(addr)
/**
* @param {number} addr
*/
Memory.prototype.read_aligned16 = function(addr)
CPU.prototype.read_aligned16 = function(addr)
{
dbg_assert(addr >= 0 && addr < 0x80000000);
this.debug_read(addr << 1, 2);
@ -197,7 +141,7 @@ Memory.prototype.read_aligned16 = function(addr)
/**
* @param {number} addr
*/
Memory.prototype.read32s = function(addr)
CPU.prototype.read32s = function(addr)
{
this.debug_read(addr, 4);
if(USE_A20 && !this.a20_enabled) addr &= A20_MASK;
@ -216,7 +160,7 @@ Memory.prototype.read32s = function(addr)
/**
* @param {number} addr
*/
Memory.prototype.read_aligned32 = function(addr)
CPU.prototype.read_aligned32 = function(addr)
{
dbg_assert(addr >= 0 && addr < 0x40000000);
this.debug_read(addr << 2, 4);
@ -236,7 +180,7 @@ Memory.prototype.read_aligned32 = function(addr)
* @param {number} addr
* @param {number} value
*/
Memory.prototype.write8 = function(addr, value)
CPU.prototype.write8 = function(addr, value)
{
this.debug_write(addr, 1, value);
if(USE_A20 && !this.a20_enabled) addr &= A20_MASK;
@ -259,7 +203,7 @@ Memory.prototype.write8 = function(addr, value)
* @param {number} addr
* @param {number} value
*/
Memory.prototype.write16 = function(addr, value)
CPU.prototype.write16 = function(addr, value)
{
this.debug_write(addr, 2, value);
if(USE_A20 && !this.a20_enabled) addr &= A20_MASK;
@ -287,7 +231,7 @@ Memory.prototype.write16 = function(addr, value)
* @param {number} addr
* @param {number} value
*/
Memory.prototype.write_aligned16 = function(addr, value)
CPU.prototype.write_aligned16 = function(addr, value)
{
dbg_assert(addr >= 0 && addr < 0x80000000);
this.debug_write(addr << 1, 2, value);
@ -311,7 +255,7 @@ Memory.prototype.write_aligned16 = function(addr, value)
* @param {number} addr
* @param {number} value
*/
Memory.prototype.write32 = function(addr, value)
CPU.prototype.write32 = function(addr, value)
{
this.debug_write(addr, 4, value);
if(USE_A20 && !this.a20_enabled) addr &= A20_MASK;
@ -337,7 +281,7 @@ Memory.prototype.write32 = function(addr, value)
}
};
Memory.prototype.write_aligned32 = function(addr, value)
CPU.prototype.write_aligned32 = function(addr, value)
{
dbg_assert(addr >= 0 && addr < 0x40000000);
this.debug_write(addr << 2, 4, value);
@ -361,7 +305,7 @@ Memory.prototype.write_aligned32 = function(addr, value)
* @param {number} offset
* @param {Array.<number>} blob
*/
Memory.prototype.write_blob = function(blob, offset)
CPU.prototype.write_blob = function(blob, offset)
{
dbg_assert(blob && blob.length);
@ -382,7 +326,7 @@ Memory.prototype.write_blob = function(blob, offset)
/**
* zero byte terminated string
*/
Memory.prototype.read_string = function(addr)
CPU.prototype.read_string = function(addr)
{
var str = "",
data_byte;
@ -396,7 +340,7 @@ Memory.prototype.read_string = function(addr)
return str;
};
Memory.prototype.write_string = function(str, addr)
CPU.prototype.write_string = function(str, addr)
{
for(var i = 0; i < str.length; i++)
{

View file

@ -272,7 +272,9 @@ function PIC(cpu, master)
else
{
dbg_log("Unknown eoi: " + h(data_byte), LOG_PIC);
dbg_assert(false);
// os2 v4
//dbg_assert(false);
this.isr &= this.isr - 1;
}
this.cpu.handle_irqs();

View file

@ -62,7 +62,7 @@ function movsb(cpu)
}
do
{
cpu.memory.write8(phys_dest, cpu.memory.read8(phys_src));
cpu.write8(phys_dest, cpu.read8(phys_src));
phys_dest += size;
phys_src += size;
cont = --count !== 0;
@ -110,7 +110,7 @@ function movsw(cpu)
}
do
{
cpu.memory.write_aligned16(phys_dest, cpu.memory.read_aligned16(phys_src));
cpu.write_aligned16(phys_dest, cpu.read_aligned16(phys_src));
phys_dest += single_size;
phys_src += single_size;
cont = --count !== 0;
@ -153,7 +153,7 @@ function movsd(cpu)
if(cpu.repeat_string_prefix !== REPEAT_STRING_PREFIX_NONE)
{
// often used by memcpy, well worth optimizing
// using cpu.memory.mem32s.set
// using cpu.mem32s.set
var ds = cpu.get_seg_prefix(reg_ds),
src = ds + cpu.regv[cpu.reg_vsi] | 0,
es = cpu.get_seg(reg_es),
@ -198,7 +198,7 @@ function movsd(cpu)
dest >>= 2;
src >>= 2;
cpu.memory.mem32s.set(cpu.memory.mem32s.subarray(src, src + count), dest);
cpu.mem32s.set(cpu.mem32s.subarray(src, src + count), dest);
if(cont)
{
@ -232,7 +232,7 @@ function movsd(cpu)
}
do
{
cpu.memory.write_aligned32(phys_dest, cpu.memory.read_aligned32(phys_src));
cpu.write_aligned32(phys_dest, cpu.read_aligned32(phys_src));
phys_dest += single_size;
phys_src += single_size;
cont = --count !== 0;
@ -293,8 +293,8 @@ function cmpsb(cpu)
}
do
{
data_dest = cpu.memory.read8(phys_dest);
data_src = cpu.memory.read8(phys_src);
data_dest = cpu.read8(phys_dest);
data_src = cpu.read8(phys_src);
phys_dest += size;
phys_src += size;
cont = --count !== 0 && (data_src === data_dest) === is_repz;
@ -347,8 +347,8 @@ function cmpsw(cpu)
}
do
{
data_dest = cpu.memory.read_aligned16(phys_dest);
data_src = cpu.memory.read_aligned16(phys_src);
data_dest = cpu.read_aligned16(phys_dest);
data_src = cpu.read_aligned16(phys_src);
phys_dest += single_size;
phys_src += single_size;
cont = --count !== 0 && (data_src === data_dest) === is_repz;
@ -416,8 +416,8 @@ function cmpsd(cpu)
}
do
{
data_dest = cpu.memory.read_aligned32(phys_dest);
data_src = cpu.memory.read_aligned32(phys_src);
data_dest = cpu.read_aligned32(phys_dest);
data_src = cpu.read_aligned32(phys_src);
phys_dest += single_size;
phys_src += single_size;
cont = --count !== 0 && (data_src === data_dest) === is_repz;
@ -479,7 +479,7 @@ function stosb(cpu)
}
do
{
cpu.memory.write8(phys_dest, data);
cpu.write8(phys_dest, data);
phys_dest += size;
cont = --count !== 0;
}
@ -523,7 +523,7 @@ function stosw(cpu)
}
do
{
cpu.memory.write_aligned16(phys_dest, data);
cpu.write_aligned16(phys_dest, data);
phys_dest += single_size;
cont = --count !== 0;
}
@ -579,7 +579,7 @@ function stosd(cpu)
}
do
{
cpu.memory.write_aligned32(phys_dest, data);
cpu.write_aligned32(phys_dest, data);
phys_dest += single_size;
cont = --count !== 0;
}
@ -631,7 +631,7 @@ function lodsb(cpu)
}
do
{
cpu.reg8[reg_al] = cpu.memory.read8(phys_src);
cpu.reg8[reg_al] = cpu.read8(phys_src);
phys_src += size;
cont = --count !== 0;
}
@ -736,7 +736,7 @@ function scasb(cpu)
}
do
{
data_dest = cpu.memory.read8(phys_dest);
data_dest = cpu.read8(phys_dest);
phys_dest += size;
cont = --count !== 0 && (data_src === data_dest) === is_repz;
}
@ -784,7 +784,7 @@ function scasw(cpu)
}
do
{
data_dest = cpu.memory.read_aligned16(phys_dest);
data_dest = cpu.read_aligned16(phys_dest);
phys_dest += single_size;
cont = --count !== 0 && (data_src === data_dest) === is_repz;
}
@ -844,7 +844,7 @@ function scasd(cpu)
}
do
{
data_dest = cpu.memory.read_aligned32(phys_dest);
data_dest = cpu.read_aligned32(phys_dest);
phys_dest += single_size;
cont = --count !== 0 && (data_src === data_dest) === is_repz;
}
@ -901,7 +901,7 @@ function insb(cpu)
}
do
{
cpu.memory.write8(phys_dest, cpu.io.port_read8(port));
cpu.write8(phys_dest, cpu.io.port_read8(port));
phys_dest += size;
cont = --count !== 0;
}
@ -948,7 +948,7 @@ function insw(cpu)
}
do
{
cpu.memory.write_aligned16(phys_dest, cpu.io.port_read16(port));
cpu.write_aligned16(phys_dest, cpu.io.port_read16(port));
phys_dest += single_size;
cont = --count !== 0;
}
@ -1007,7 +1007,7 @@ function insd(cpu)
}
do
{
cpu.memory.write_aligned32(phys_dest, cpu.io.port_read32(port));
cpu.write_aligned32(phys_dest, cpu.io.port_read32(port));
phys_dest += single_size;
cont = --count !== 0;
}
@ -1063,7 +1063,7 @@ function outsb(cpu)
}
do
{
cpu.io.port_write8(port, cpu.memory.read8(phys_src));
cpu.io.port_write8(port, cpu.read8(phys_src));
phys_src += size;
cont = --count !== 0;
}
@ -1110,7 +1110,7 @@ function outsw(cpu)
}
do
{
cpu.io.port_write16(port, cpu.memory.read_aligned16(phys_src));
cpu.io.port_write16(port, cpu.read_aligned16(phys_src));
phys_src += single_size;
cont = --count !== 0;
}
@ -1169,7 +1169,7 @@ function outsd(cpu)
}
do
{
cpu.io.port_write32(port, cpu.memory.read_aligned32(phys_src));
cpu.io.port_write32(port, cpu.read_aligned32(phys_src));
phys_src += single_size;
cont = --count !== 0;
}

View file

@ -131,9 +131,9 @@ function VirtIO(cpu, bus, filesystem)
var ring_start = queue_start + 16 * this.queue_size;
var ring_desc_start = ring_start + 4;
var //flags = this.memory.read16(ring_start),
var //flags = this.cpu.read16(ring_start),
// index of the next free ring
idx = this.memory.read16(ring_start + 2);
idx = this.cpu.read16(ring_start + 2);
dbg_log("idx=" + h(idx, 4), LOG_VIRTIO);
//dbg_assert(idx < this.queue_size);
@ -143,7 +143,7 @@ function VirtIO(cpu, bus, filesystem)
while(this.last_idx !== idx)
{
var desc_idx = this.memory.read16(ring_desc_start + this.last_idx * 2);
var desc_idx = this.cpu.read16(ring_desc_start + this.last_idx * 2);
this.handle_descriptor(desc_idx);
this.last_idx = this.last_idx + 1 & mask;
@ -167,9 +167,6 @@ function VirtIO(cpu, bus, filesystem)
this.queue_size = 32;
this.queue_address = 0;
/** @const @type {Memory} */
this.memory = cpu.memory;
for(var i = 0; i < 128; i++)
{
io.register_read(0xA814 + i, this, function(port)
@ -249,7 +246,7 @@ VirtIO.prototype.handle_descriptor = function(idx)
do
{
var addr = desc_start + next * 16;
var flags = this.memory.read16(addr + 12);
var flags = this.cpu.read16(addr + 12);
if(flags & VRING_DESC_F_WRITE)
{
@ -260,9 +257,9 @@ VirtIO.prototype.handle_descriptor = function(idx)
dbg_assert(false, "unsupported");
}
var addr_low = this.memory.read32s(addr);
var addr_high = this.memory.read32s(addr + 4);
var len = this.memory.read32s(addr + 8) >>> 0;
var addr_low = this.cpu.read32s(addr);
var addr_high = this.cpu.read32s(addr + 4);
var len = this.cpu.read32s(addr + 8) >>> 0;
buffers.push({
addr_low: addr_low,
@ -275,7 +272,7 @@ VirtIO.prototype.handle_descriptor = function(idx)
if(flags & VRING_DESC_F_NEXT)
{
next = this.memory.read16(addr + 14);
next = this.cpu.read16(addr + 14);
dbg_assert(next < this.queue_size);
}
else
@ -313,7 +310,7 @@ VirtIO.prototype.handle_descriptor = function(idx)
pointer = 0;
}
return this.memory.read8(addr_low + pointer++);
return this.cpu.read8(addr_low + pointer++);
}.bind(this));
};
@ -337,7 +334,7 @@ VirtIO.prototype.device_reply = function(queueidx, infos)
do
{
var addr = desc_start + next * 16;
var flags = this.memory.read16(addr + 12);
var flags = this.cpu.read16(addr + 12);
if((flags & VRING_DESC_F_WRITE) === 0)
{
@ -345,9 +342,9 @@ VirtIO.prototype.device_reply = function(queueidx, infos)
break;
}
var addr_low = this.memory.read32s(addr);
var addr_high = this.memory.read32s(addr + 4);
var len = this.memory.read32s(addr + 8) >>> 0;
var addr_low = this.cpu.read32s(addr);
var addr_high = this.cpu.read32s(addr + 4);
var len = this.cpu.read32s(addr + 8) >>> 0;
buffers.push({
addr_low: addr_low,
@ -360,7 +357,7 @@ VirtIO.prototype.device_reply = function(queueidx, infos)
if(flags & VRING_DESC_F_NEXT)
{
next = this.memory.read16(addr + 14);
next = this.cpu.read16(addr + 14);
dbg_assert(next < this.queue_size);
}
else
@ -392,22 +389,22 @@ VirtIO.prototype.device_reply = function(queueidx, infos)
pointer = 0;
}
this.memory.write8(addr_low + pointer++, data);
this.cpu.write8(addr_low + pointer++, data);
}
var used_desc_start = (this.queue_address << 12) + 16 * this.queue_size + 4 + 2 * this.queue_size;
used_desc_start = used_desc_start + 4095 & ~4095;
var flags = this.memory.read16(used_desc_start);
var used_idx = this.memory.read16(used_desc_start + 2);
this.memory.write16(used_desc_start + 2, used_idx + 1);
var flags = this.cpu.read16(used_desc_start);
var used_idx = this.cpu.read16(used_desc_start + 2);
this.cpu.write16(used_desc_start + 2, used_idx + 1);
dbg_log("used descriptor: addr=" + h(used_desc_start, 8) + " flags=" + h(flags, 4) + " idx=" + h(used_idx, 4), LOG_VIRTIO);
used_idx &= mask;
var used_desc_offset = used_desc_start + 4 + used_idx * 8;
this.memory.write32(used_desc_offset, infos.start);
this.memory.write32(used_desc_offset + 4, result_length);
this.cpu.write32(used_desc_offset, infos.start);
this.cpu.write32(used_desc_offset + 4, result_length);
this.isr |= 1;
this.cpu.device_raise_irq(this.irq);