Move memory to cpu
This commit is contained in:
parent
272273ebf0
commit
70ad2f9031
15
src/arith.js
15
src/arith.js
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
183
src/cpu.js
183
src/cpu.js
|
@ -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;
|
||||
|
|
52
src/debug.js
52
src/debug.js
|
@ -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();
|
||||
//}
|
||||
|
|
16
src/dma.js
16
src/dma.js
|
@ -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);
|
||||
}
|
||||
|
|
27
src/ide.js
27
src/ide.js
|
@ -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)
|
||||
|
|
30
src/io.js
30
src/io.js
|
@ -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;
|
||||
}
|
||||
|
|
102
src/memory.js
102
src/memory.js
|
@ -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++)
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue