diff --git a/apu/bapu/smp/core.cpp b/apu/bapu/smp/core.cpp index bbaf3ba6..3c814770 100644 --- a/apu/bapu/smp/core.cpp +++ b/apu/bapu/smp/core.cpp @@ -27,14 +27,27 @@ void SMP::op_io(unsigned clocks) { uint8 SMP::op_read(uint16 addr) { tick(); if((addr & 0xfff0) == 0x00f0) return mmio_read(addr); - if(addr >= 0xffc0 && status.iplrom_enable) return iplrom[addr & 0x3f]; return apuram[addr]; } void SMP::op_write(uint16 addr, uint8 data) { tick(); - if((addr & 0xfff0) == 0x00f0) mmio_write(addr, data); - apuram[addr] = data; //all writes go to RAM, even MMIO writes + if((addr & 0xfff0) == 0x00f0 || addr >= 0xffc0) + mmio_write(addr, data); + else + apuram[addr] = data; +} + +uint8 SMP::op_readstack() +{ + tick(); + return apuram[0x0100 | ++regs.sp]; +} + +void SMP::op_writestack(uint8 data) +{ + tick(); + apuram[0x0100 | regs.sp--] = data; } void SMP::op_step() { @@ -43,8 +56,6 @@ void SMP::op_step() { #define op_writedp(addr, data) op_write((regs.p.p << 8) + ((addr) & 0xff), data) #define op_readaddr(addr) op_read(addr) #define op_writeaddr(addr, data) op_write(addr, data) - #define op_readstack() op_read(0x0100 | ++regs.sp) - #define op_writestack(data) op_write(0x0100 | regs.sp--, data) if(opcode_cycle == 0) { diff --git a/apu/bapu/smp/memory.cpp b/apu/bapu/smp/memory.cpp index 46698d8a..29cbfce7 100644 --- a/apu/bapu/smp/memory.cpp +++ b/apu/bapu/smp/memory.cpp @@ -51,10 +51,31 @@ unsigned SMP::mmio_read(unsigned addr) { } void SMP::mmio_write(unsigned addr, unsigned data) { + + if (addr >= 0xffc0) { + if (status.iplrom_enable) + highmem[addr & 0x3f] = data; + else + apuram[addr] = data; + return; + } + switch(addr) { case 0xf1: - status.iplrom_enable = data & 0x80; + if (((data & 0x80) > 0) != status.iplrom_enable) { + if (status.iplrom_enable) + { + status.iplrom_enable = false; + memcpy(&apuram[0xffc0], highmem, 64); + } + else + { + status.iplrom_enable = true; + memcpy(highmem, &apuram[0xffc0], 64); + memcpy(&apuram[0xffc0], iplrom, 64); + } + } if(data & 0x30) { if(data & 0x20) { @@ -122,6 +143,7 @@ void SMP::mmio_write(unsigned addr, unsigned data) { case 0xfc: timer2.target = data; break; - } + + apuram[addr] = data; //all writes go to RAM, even MMIO writes } diff --git a/apu/bapu/smp/smp.cpp b/apu/bapu/smp/smp.cpp index 2cf58afd..247589aa 100644 --- a/apu/bapu/smp/smp.cpp +++ b/apu/bapu/smp/smp.cpp @@ -50,6 +50,8 @@ void SMP::reset() { //$00f1 status.iplrom_enable = true; + memset(highmem, 0, 64); + memcpy(&apuram[0xffc0], iplrom, 64); //$00f2 status.dsp_addr = 0x00; diff --git a/apu/bapu/smp/smp.hpp b/apu/bapu/smp/smp.hpp index 5596c1f2..41546ef4 100644 --- a/apu/bapu/smp/smp.hpp +++ b/apu/bapu/smp/smp.hpp @@ -1,6 +1,7 @@ class SMP : public Processor { public: static const uint8 iplrom[64]; + uint8 highmem[64]; uint8 *apuram; unsigned port_read(unsigned port); @@ -94,6 +95,8 @@ public: debugvirtual alwaysinline uint8 op_read(uint16 addr); debugvirtual alwaysinline void op_write(uint16 addr, uint8 data); debugvirtual alwaysinline void op_step(); + alwaysinline void op_writestack(uint8 data); + alwaysinline uint8 op_readstack(); static const unsigned cycle_count_table[256]; uint64 cycle_table_cpu[256]; unsigned cycle_table_dsp[256]; diff --git a/apu/bapu/smp/smp_state.cpp b/apu/bapu/smp/smp_state.cpp index 536850fa..97095ccb 100644 --- a/apu/bapu/smp/smp_state.cpp +++ b/apu/bapu/smp/smp_state.cpp @@ -74,6 +74,10 @@ void SMP::save_state(uint8 **block) { uint8 *ptr = *block; memcpy(ptr, apuram, 64 * 1024); ptr += 64 * 1024; + if (status.iplrom_enable) + { + memcpy (&ptr[0xffc0], highmem, 64); + } #undef INT32 #define INT32(i) set_le32(ptr, (i)); ptr += sizeof(int32) @@ -160,6 +164,11 @@ void SMP::load_state(uint8 **block) { INT32(regs.p.c); INT32(status.iplrom_enable); + if (status.iplrom_enable) + { + memcpy(highmem, &apuram[0xffc0], 64); + memcpy(&apuram[0xffc0], iplrom, 64); + } INT32(status.dsp_addr);