|
@@ -1,44 +1,5 @@
|
|
|
"use strict";
|
|
|
|
|
|
-/** @const */
|
|
|
-var A20_MASK = ~(1 << 20);
|
|
|
-/** @const */
|
|
|
-var A20_MASK16 = ~(1 << 20 - 1);
|
|
|
-/** @const */
|
|
|
-var A20_MASK32 = ~(1 << 20 - 2);
|
|
|
-
|
|
|
-/** @const */
|
|
|
-var USE_A20 = false;
|
|
|
-
|
|
|
-
|
|
|
-// called by all memory writes
|
|
|
-CPU.prototype.debug_write = function(addr, size, value)
|
|
|
-{
|
|
|
- if(!DEBUG)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- dbg_assert(typeof value === "number" && !isNaN(value));
|
|
|
- dbg_assert(value >= -0x80000000 && addr < 0x80000000);
|
|
|
-
|
|
|
- this.debug_read(addr, size, true);
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * @param {boolean=} is_write
|
|
|
- */
|
|
|
-CPU.prototype.debug_read = function(addr, size, is_write)
|
|
|
-{
|
|
|
- if(!DEBUG)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- dbg_assert(typeof addr === "number");
|
|
|
- dbg_assert(!isNaN(addr));
|
|
|
-};
|
|
|
-
|
|
|
|
|
|
CPU.prototype.mmap_read8 = function(addr)
|
|
|
{
|
|
@@ -79,229 +40,16 @@ CPU.prototype.mmap_write32 = function(addr, value)
|
|
|
this.memory_map_write32[aligned_addr](addr, value);
|
|
|
};
|
|
|
|
|
|
-CPU.prototype.in_mapped_range = function(addr)
|
|
|
-{
|
|
|
- return (addr | 0) >= 0xA0000 && (addr | 0) < 0xC0000 || (addr >>> 0) >= (this.memory_size[0] >>> 0);
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * @param {number} addr
|
|
|
- */
|
|
|
-CPU.prototype.read8 = function(addr)
|
|
|
-{
|
|
|
- this.debug_read(addr, 1);
|
|
|
- if(USE_A20 && !this.a20_enabled[0]) addr &= A20_MASK;
|
|
|
-
|
|
|
- if(this.in_mapped_range(addr))
|
|
|
- {
|
|
|
- return this.mmap_read8(addr);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- return this.mem8[addr];
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * @param {number} addr
|
|
|
- */
|
|
|
-CPU.prototype.read16 = function(addr)
|
|
|
-{
|
|
|
- this.debug_read(addr, 2);
|
|
|
- if(USE_A20 && !this.a20_enabled[0]) addr &= A20_MASK;
|
|
|
-
|
|
|
- if(this.in_mapped_range(addr))
|
|
|
- {
|
|
|
- return this.mmap_read16(addr);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- return this.mem8[addr] | this.mem8[addr + 1 | 0] << 8;
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * @param {number} addr
|
|
|
- */
|
|
|
-CPU.prototype.read_aligned16 = function(addr)
|
|
|
-{
|
|
|
- dbg_assert(addr >= 0 && addr < 0x80000000);
|
|
|
- this.debug_read(addr << 1, 2);
|
|
|
- if(USE_A20 && !this.a20_enabled[0]) addr &= A20_MASK16;
|
|
|
-
|
|
|
- if(this.in_mapped_range(addr << 1))
|
|
|
- {
|
|
|
- return this.mmap_read16(addr << 1);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- return this.mem16[addr];
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * @param {number} addr
|
|
|
- */
|
|
|
-CPU.prototype.read32s = function(addr)
|
|
|
-{
|
|
|
- this.debug_read(addr, 4);
|
|
|
- if(USE_A20 && !this.a20_enabled[0]) addr &= A20_MASK;
|
|
|
-
|
|
|
- if(this.in_mapped_range(addr))
|
|
|
- {
|
|
|
- return this.mmap_read32(addr);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- return this.mem8[addr] | this.mem8[addr + 1 | 0] << 8 |
|
|
|
- this.mem8[addr + 2 | 0] << 16 | this.mem8[addr + 3 | 0] << 24;
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * @param {number} addr
|
|
|
- */
|
|
|
-CPU.prototype.read_aligned32 = function(addr)
|
|
|
-{
|
|
|
- dbg_assert(addr >= 0 && addr < 0x40000000);
|
|
|
- this.debug_read(addr << 2, 4);
|
|
|
- if(USE_A20 && !this.a20_enabled[0]) addr &= A20_MASK32;
|
|
|
-
|
|
|
- if(this.in_mapped_range(addr << 2))
|
|
|
- {
|
|
|
- return this.mmap_read32(addr << 2);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- return this.mem32s[addr];
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * @param {number} addr
|
|
|
- * @param {number} value
|
|
|
- */
|
|
|
-CPU.prototype.write8 = function(addr, value)
|
|
|
-{
|
|
|
- this.debug_write(addr, 1, value);
|
|
|
- if(USE_A20 && !this.a20_enabled[0]) addr &= A20_MASK;
|
|
|
-
|
|
|
- if(this.in_mapped_range(addr))
|
|
|
- {
|
|
|
- this.mmap_write8(addr, value);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- this.mem8[addr] = value;
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * @param {number} addr
|
|
|
- * @param {number} value
|
|
|
- */
|
|
|
-CPU.prototype.write16 = function(addr, value)
|
|
|
-{
|
|
|
- this.debug_write(addr, 2, value);
|
|
|
- if(USE_A20 && !this.a20_enabled[0]) addr &= A20_MASK;
|
|
|
-
|
|
|
- if(this.in_mapped_range(addr))
|
|
|
- {
|
|
|
- this.mmap_write16(addr, value);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- this.mem8[addr] = value;
|
|
|
- this.mem8[addr + 1 | 0] = value >> 8;
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * @param {number} addr
|
|
|
- * @param {number} value
|
|
|
- */
|
|
|
-CPU.prototype.write_aligned16 = function(addr, value)
|
|
|
-{
|
|
|
- dbg_assert(addr >= 0 && addr < 0x80000000);
|
|
|
-
|
|
|
- let phys_addr = addr << 1;
|
|
|
- this.debug_write(phys_addr, 2, value);
|
|
|
- if(USE_A20 && !this.a20_enabled[0]) addr &= A20_MASK16;
|
|
|
-
|
|
|
- if(this.in_mapped_range(phys_addr))
|
|
|
- {
|
|
|
- this.mmap_write16(phys_addr, value);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- this.mem16[addr] = value;
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * @param {number} addr
|
|
|
- * @param {number} value
|
|
|
- */
|
|
|
-CPU.prototype.write32 = function(addr, value)
|
|
|
-{
|
|
|
- this.debug_write(addr, 4, value);
|
|
|
- if(USE_A20 && !this.a20_enabled[0]) addr &= A20_MASK;
|
|
|
-
|
|
|
- if(this.in_mapped_range(addr))
|
|
|
- {
|
|
|
- this.mmap_write32(addr, value);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- this.mem8[addr] = value;
|
|
|
- this.mem8[addr + 1 | 0] = value >> 8;
|
|
|
- this.mem8[addr + 2 | 0] = value >> 16;
|
|
|
- this.mem8[addr + 3 | 0] = value >> 24;
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-CPU.prototype.write_aligned32 = function(addr, value)
|
|
|
-{
|
|
|
- dbg_assert(addr >= 0 && addr < 0x40000000);
|
|
|
-
|
|
|
- let phys_addr = addr << 2;
|
|
|
- this.debug_write(phys_addr, 4, value);
|
|
|
- if(USE_A20 && !this.a20_enabled[0]) addr &= A20_MASK32;
|
|
|
-
|
|
|
- if(this.in_mapped_range(phys_addr))
|
|
|
- {
|
|
|
- this.mmap_write32(phys_addr, value);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- this.mem32s[addr] = value;
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
/**
|
|
|
* @param {Array.<number>|Uint8Array} blob
|
|
|
* @param {number} offset
|
|
|
*/
|
|
|
CPU.prototype.write_blob = function(blob, offset)
|
|
|
{
|
|
|
- this.debug_write(offset, blob.length, 0);
|
|
|
- this.wm.exports["_jit_dirty_cache"](offset, offset + blob.length);
|
|
|
-
|
|
|
dbg_assert(blob && blob.length >= 0);
|
|
|
+ dbg_assert(!this.in_mapped_range(offset));
|
|
|
+ dbg_assert(!this.in_mapped_range(offset + blob.length));
|
|
|
|
|
|
+ this.wm.exports["_jit_dirty_cache"](offset, offset + blob.length);
|
|
|
this.mem8.set(blob, offset);
|
|
|
};
|
|
|
-
|
|
|
-/**
|
|
|
- * @param {Array.<number>|Int32Array} blob
|
|
|
- * @param {number} offset
|
|
|
- */
|
|
|
-CPU.prototype.write_blob32 = function(blob, offset)
|
|
|
-{
|
|
|
- dbg_assert(blob && blob.length);
|
|
|
- let phys_addr = offset << 2;
|
|
|
- this.wm.exports["_jit_dirty_cache"](phys_addr, phys_addr + blob.length);
|
|
|
-
|
|
|
- this.debug_write(offset, blob.length << 2, 0);
|
|
|
- this.mem32s.set(blob, offset);
|
|
|
-};
|