diff --git a/bsnes/Makefile b/bsnes/Makefile index 84fb7743f..ea24f98a9 100755 --- a/bsnes/Makefile +++ b/bsnes/Makefile @@ -14,7 +14,7 @@ target := ui c := $(compiler) -std=gnu99 cpp := $(subst cc,++,$(compiler)) -std=gnu++0x flags := -I. -march=native -O3 -fomit-frame-pointer -link := +link := -s objects := libco # profile-guided optimization mode @@ -30,11 +30,11 @@ endif # platform ifeq ($(platform),x) - link += -s -ldl -lX11 -lXext + link += -ldl -lX11 -lXext else ifeq ($(platform),osx) else ifeq ($(platform),win) link += $(if $(findstring console,$(options)),-mconsole,-mwindows) - link += -mthreads -s -luuid -lkernel32 -luser32 -lgdi32 -lcomctl32 -lcomdlg32 -lshell32 -lole32 + link += -mthreads -luuid -lkernel32 -luser32 -lgdi32 -lcomctl32 -lcomdlg32 -lshell32 -lole32 link += -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc else unknown_platform: help; diff --git a/bsnes/base/base.hpp b/bsnes/base/base.hpp index 7d547a52c..a0e3414b4 100755 --- a/bsnes/base/base.hpp +++ b/bsnes/base/base.hpp @@ -1,7 +1,7 @@ #ifndef BASE_HPP #define BASE_HPP -static const char Version[] = "087.07"; +static const char Version[] = "087.08"; #include #include diff --git a/bsnes/gba/apu/apu.cpp b/bsnes/gba/apu/apu.cpp index 6d6eecdf5..bcadcb2ec 100755 --- a/bsnes/gba/apu/apu.cpp +++ b/bsnes/gba/apu/apu.cpp @@ -18,6 +18,13 @@ void APU::step(unsigned clocks) { if(clock >= 0) co_switch(cpu.thread); } +uint32 APU::read(uint32 addr, uint32 size) { + return 0u; +} + +void APU::write(uint32 addr, uint32 size, uint32 word) { +} + void APU::power() { create(APU::Enter, 16777216); } diff --git a/bsnes/gba/apu/apu.hpp b/bsnes/gba/apu/apu.hpp index 0544a012d..eb9816de8 100755 --- a/bsnes/gba/apu/apu.hpp +++ b/bsnes/gba/apu/apu.hpp @@ -1,8 +1,10 @@ -struct APU : Thread { +struct APU : Thread, Memory { static void Enter(); void enter(); void step(unsigned clocks); + uint32 read(uint32 addr, uint32 size); + void write(uint32 addr, uint32 size, uint32 word); void power(); }; diff --git a/bsnes/gba/cartridge/cartridge.cpp b/bsnes/gba/cartridge/cartridge.cpp index 498359ea9..a77ad5224 100755 --- a/bsnes/gba/cartridge/cartridge.cpp +++ b/bsnes/gba/cartridge/cartridge.cpp @@ -9,6 +9,9 @@ bool Cartridge::load(const string &markup, const uint8_t *data, unsigned size) { cartridge.rom.data = new uint8[cartridge.rom.size = size]; memcpy(cartridge.rom.data, data, size); + if(cartridge.ram.data) delete[] cartridge.ram.data; + cartridge.ram.data = new uint8[cartridge.ram.size = 64 * 1024](); + sha256 = nall::sha256(cartridge.rom.data, cartridge.rom.size); return loaded = true; diff --git a/bsnes/gba/cpu/cpu.cpp b/bsnes/gba/cpu/cpu.cpp index b4ffe4c68..80ed02ede 100755 --- a/bsnes/gba/cpu/cpu.cpp +++ b/bsnes/gba/cpu/cpu.cpp @@ -9,6 +9,8 @@ void CPU::Enter() { cpu.enter(); } void CPU::enter() { while(true) { if(exception) { + print(cpsr().t ? disassemble_thumb_instruction(pipeline.execute.address) + : disassemble_arm_instruction(pipeline.execute.address), "\n"); print(disassemble_registers(), "\n"); while(true) step(frequency); } @@ -38,13 +40,26 @@ void CPU::power() { create(CPU::Enter, 16777216); ARM::power(); - for(unsigned n = 0; n < iram.size; n++) iram.data[n] = 0; - for(unsigned n = 0; n < eram.size; n++) eram.data[n] = 0; + for(unsigned n = 0; n < iwram.size; n++) iwram.data[n] = 0; + for(unsigned n = 0; n < ewram.size; n++) ewram.data[n] = 0; + + bus.mmio[0x0300] = this; + bus.mmio[0x0301] = this; + bus.mmio[0x0302] = this; + bus.mmio[0x0303] = this; +} + +uint32 CPU::read(uint32 addr, uint32 size) { + if(addr == 0x04000300) return prng() & 1; + return 0u; +} + +void CPU::write(uint32 addr, uint32 size, uint32 word) { } CPU::CPU() { - iram.data = new uint8[iram.size = 32 * 1024]; - eram.data = new uint8[eram.size = 256 * 1024]; + iwram.data = new uint8[iwram.size = 32 * 1024]; + ewram.data = new uint8[ewram.size = 256 * 1024]; } } diff --git a/bsnes/gba/cpu/cpu.hpp b/bsnes/gba/cpu/cpu.hpp index c6988e8ca..f46cf90ef 100755 --- a/bsnes/gba/cpu/cpu.hpp +++ b/bsnes/gba/cpu/cpu.hpp @@ -1,6 +1,6 @@ -struct CPU : Processor::ARM, Thread { - StaticMemory iram; - StaticMemory eram; +struct CPU : Processor::ARM, Thread, Memory { + StaticMemory iwram; + StaticMemory ewram; static void Enter(); void enter(); @@ -10,6 +10,9 @@ struct CPU : Processor::ARM, Thread { void power(); + uint32 read(uint32 addr, uint32 size); + void write(uint32 addr, uint32 size, uint32 word); + CPU(); }; diff --git a/bsnes/gba/memory/memory.cpp b/bsnes/gba/memory/memory.cpp index b460c3d63..301db043e 100755 --- a/bsnes/gba/memory/memory.cpp +++ b/bsnes/gba/memory/memory.cpp @@ -4,6 +4,13 @@ namespace GBA { Bus bus; +struct UnmappedMemory : Memory { + uint32 read(uint32 addr, uint32 size) { return 0u; } + void write(uint32 addr, uint32 size, uint32 word) {} +}; + +static UnmappedMemory unmappedMemory; + uint32 StaticMemory::read(uint32 addr, uint32 size) { uint32 word = 0; @@ -63,9 +70,9 @@ uint32 Bus::read(uint32 addr, uint32 size) { switch(addr & 0x0f000000) { case 0x00000000: return system.bios.read(addr & 0x3fff, size); case 0x01000000: return system.bios.read(addr & 0x3fff, size); - case 0x02000000: return cpu.eram.read(addr & 0x3ffff, size); - case 0x03000000: return cpu.iram.read(addr & 0x7fff, size); - case 0x04000000: return 0u; //MMIO [0x400] + case 0x02000000: return cpu.ewram.read(addr & 0x3ffff, size); + case 0x03000000: return cpu.iwram.read(addr & 0x7fff, size); + case 0x04000000: return mmio[addr & 0x3ff]->read(addr, size); case 0x05000000: return ppu.pram.read(addr & 0x3ff, size); case 0x06000000: return ppu.vram.read(addr & 0x10000 ? (0x10000 + (addr & 0x7fff)) : (addr & 0xffff), size); case 0x07000000: return ppu.oam.read(addr & 0x3ff, size); @@ -84,9 +91,9 @@ void Bus::write(uint32 addr, uint32 size, uint32 word) { switch(addr & 0x0f000000) { case 0x00000000: return; case 0x01000000: return; - case 0x02000000: return cpu.eram.write(addr & 0x3ffff, size, word); - case 0x03000000: return cpu.iram.write(addr & 0x7fff, size, word); - case 0x04000000: return; //MMIO [0x400] + case 0x02000000: return cpu.ewram.write(addr & 0x3ffff, size, word); + case 0x03000000: return cpu.iwram.write(addr & 0x7fff, size, word); + case 0x04000000: return mmio[addr & 0x3ff]->write(addr, size, word); case 0x05000000: return ppu.pram.write(addr & 0x3ff, size, word); case 0x06000000: return ppu.vram.write(addr & 0x10000 ? (0x10000 + (addr & 0x7fff)) : (addr & 0xffff), size, word); case 0x07000000: return ppu.oam.write(addr & 0x3ff, size, word); @@ -101,4 +108,8 @@ void Bus::write(uint32 addr, uint32 size, uint32 word) { } } +void Bus::power() { + for(unsigned n = 0; n < 0x400; n++) mmio[n] = &unmappedMemory; +} + } diff --git a/bsnes/gba/memory/memory.hpp b/bsnes/gba/memory/memory.hpp index 69c20dc21..c39e700ad 100755 --- a/bsnes/gba/memory/memory.hpp +++ b/bsnes/gba/memory/memory.hpp @@ -3,7 +3,7 @@ struct Memory { virtual void write(uint32 addr, uint32 size, uint32 word) = 0; }; -struct StaticMemory { +struct StaticMemory : Memory { uint8_t *data; unsigned size; @@ -14,8 +14,11 @@ struct StaticMemory { }; struct Bus : Memory { + Memory *mmio[0x400]; + uint32 read(uint32 addr, uint32 size); void write(uint32 addr, uint32 size, uint32 word); + void power(); }; extern Bus bus; diff --git a/bsnes/gba/ppu/ppu.cpp b/bsnes/gba/ppu/ppu.cpp index 9658aa997..42dc62483 100755 --- a/bsnes/gba/ppu/ppu.cpp +++ b/bsnes/gba/ppu/ppu.cpp @@ -56,6 +56,13 @@ void PPU::frame() { scheduler.exit(Scheduler::ExitReason::FrameEvent); } +uint32 PPU::read(uint32 addr, uint32 size) { + return 0u; +} + +void PPU::write(uint32 addr, uint32 size, uint32 word) { +} + PPU::PPU() { vram.data = new uint8[vram.size = 96 * 1024]; oam.data = new uint8[oam.size = 1024]; diff --git a/bsnes/gba/ppu/ppu.hpp b/bsnes/gba/ppu/ppu.hpp index c75a3d414..68c4178a0 100755 --- a/bsnes/gba/ppu/ppu.hpp +++ b/bsnes/gba/ppu/ppu.hpp @@ -1,4 +1,4 @@ -struct PPU : Thread { +struct PPU : Thread, Memory { StaticMemory vram; StaticMemory oam; StaticMemory pram; @@ -10,6 +10,9 @@ struct PPU : Thread { void power(); void frame(); + uint32 read(uint32 addr, uint32 size); + void write(uint32 addr, uint32 size, uint32 word); + PPU(); }; diff --git a/bsnes/gba/system/system.cpp b/bsnes/gba/system/system.cpp index 93b8dcd89..976dbaf9e 100755 --- a/bsnes/gba/system/system.cpp +++ b/bsnes/gba/system/system.cpp @@ -24,6 +24,7 @@ void System::term() { } void System::power() { + bus.power(); cpu.power(); ppu.power(); apu.power(); diff --git a/bsnes/processor/Makefile b/bsnes/processor/Makefile index 27b48a700..4eb320265 100755 --- a/bsnes/processor/Makefile +++ b/bsnes/processor/Makefile @@ -1,6 +1,8 @@ processor_objects := processor_objects += $(if $(findstring arm,$(processors)),processor-arm) +processor_objects += $(if $(findstring hg51b,$(processors)),processor-hg51b) objects += $(processor_objects) processor := processor -obj/processor-arm.o: $(processor)/arm/arm.cpp $(call rwildcard,$(processor)/arm) +obj/processor-arm.o: $(processor)/arm/arm.cpp $(call rwildcard,$(processor)/arm) +obj/processor-hg51b.o: $(processor)/hg51b/hg51b.cpp $(call rwildcard,$(processor)/hg51b) diff --git a/bsnes/processor/arm/arm.cpp b/bsnes/processor/arm/arm.cpp index 7765c1e30..17ba12a92 100755 --- a/bsnes/processor/arm/arm.cpp +++ b/bsnes/processor/arm/arm.cpp @@ -10,6 +10,7 @@ namespace Processor { void ARM::power() { processor.power(); + vector(0x00000000, Processor::Mode::SVC); pipeline.reload = true; exception = false; r(15).modify = [&] { @@ -18,6 +19,17 @@ void ARM::power() { }; } +void ARM::vector(uint32 addr, Processor::Mode mode) { + auto psr = cpsr(); + processor.setMode(mode); + spsr() = psr; + cpsr().i = 1; + cpsr().f = mode == Processor::Mode::FIQ; + cpsr().t = 0; + r(14) = pipeline.decode.address; + r(15) = addr; +} + void ARM::serialize(serializer &s) { } diff --git a/bsnes/processor/arm/arm.hpp b/bsnes/processor/arm/arm.hpp index 6235a39ce..a4baf75e3 100755 --- a/bsnes/processor/arm/arm.hpp +++ b/bsnes/processor/arm/arm.hpp @@ -3,6 +3,8 @@ namespace Processor { +//ARMv3, ARMv4TM + struct ARM { enum : unsigned { Byte = 8, Half = 16, Word = 32 }; #include "registers.hpp" @@ -14,6 +16,8 @@ struct ARM { virtual void bus_write(uint32 addr, uint32 size, uint32 word) = 0; void power(); + void vector(uint32 addr, Processor::Mode mode); + void serialize(serializer&); }; diff --git a/bsnes/processor/arm/disassembler.cpp b/bsnes/processor/arm/disassembler.cpp index d51082e10..6a2d423c9 100755 --- a/bsnes/processor/arm/disassembler.cpp +++ b/bsnes/processor/arm/disassembler.cpp @@ -1,4 +1,6 @@ -string ARM::disassemble_arm_opcode(uint32 pc) { +#ifdef PROCESSOR_ARM_HPP + +string ARM::disassemble_arm_instruction(uint32 pc) { static string conditions[] = { "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", @@ -65,6 +67,21 @@ string ARM::disassemble_arm_opcode(uint32 pc) { return output; } + //memory_swap() + //swp{condition}{b} rd,rm,[rn] + if((instruction & 0x0fb000f0) == 0x01000090) { + uint4 condition = instruction >> 28; + uint1 byte = instruction >> 22; + uint4 rn = instruction >> 16; + uint4 rd = instruction >> 12; + uint4 rm = instruction; + + output.append("swp", conditions[condition], byte ? "b " : " "); + output.append(registers[rd], ",", registers[rm], "[", registers[rn], "]"); + + return output; + } + //move_to_status_from_register() //msr{condition} (c,s)psr:{fields},rm if((instruction & 0x0fb000f0) == 0x01200000) { @@ -98,6 +115,30 @@ string ARM::disassemble_arm_opcode(uint32 pc) { return output; } + //move_to_status_from_immediate() + //msr{condition} (c,s)psr:{fields},#immediate + if((instruction & 0x0fb00000) == 0x03200000) { + uint4 condition = instruction >> 28; + uint1 psr = instruction >> 22; + uint4 field = instruction >> 16; + uint4 rotate = instruction >> 8; + uint8 immediate = instruction; + + uint32 rm = (immediate >> (rotate * 2)) | (immediate << (32 - (rotate * 2))); + + output.append("msr", conditions[condition], " "); + output.append(psr ? "spsr:" : "cpsr:"); + output.append( + field & 1 ? "c" : "", + field & 2 ? "x" : "", + field & 4 ? "s" : "", + field & 8 ? "f" : "" + ); + output.append(",#0x", hex<8>(immediate)); + + return output; + } + //data_immediate_shift() //{opcode}{condition}{s} rd,rm {shift} #immediate //{opcode}{condition} rn,rm {shift} #immediate @@ -265,11 +306,21 @@ string ARM::disassemble_arm_opcode(uint32 pc) { return output; } + //software_interrupt() + //swi #immediate + if((instruction & 0x0f000000) == 0x0f000000) { + uint24 immediate = instruction; + + output.append("swi #0x", hex<6>(immediate)); + + return output; + } + output.append("???"); return output; } -string ARM::disassemble_thumb_opcode(uint32 pc) { +string ARM::disassemble_thumb_instruction(uint32 pc) { static string conditions[] = { "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", @@ -602,3 +653,5 @@ string ARM::disassemble_registers() { output.append( spsr().n ? "N" : "n", spsr().z ? "Z" : "z", spsr().c ? "C" : "c", spsr().v ? "V" : "v"); return output; } + +#endif diff --git a/bsnes/processor/arm/disassembler.hpp b/bsnes/processor/arm/disassembler.hpp index 9c5386351..3b61de82b 100755 --- a/bsnes/processor/arm/disassembler.hpp +++ b/bsnes/processor/arm/disassembler.hpp @@ -1,3 +1,3 @@ -string disassemble_arm_opcode(uint32 pc); -string disassemble_thumb_opcode(uint32 pc); +string disassemble_arm_instruction(uint32 pc); +string disassemble_thumb_instruction(uint32 pc); string disassemble_registers(); diff --git a/bsnes/processor/arm/instructions-arm.cpp b/bsnes/processor/arm/instructions-arm.cpp index 784034433..f3fc50b84 100755 --- a/bsnes/processor/arm/instructions-arm.cpp +++ b/bsnes/processor/arm/instructions-arm.cpp @@ -1,3 +1,5 @@ +#ifdef PROCESSOR_ARM_HPP + void ARM::arm_step() { if(pipeline.reload) { pipeline.reload = false; @@ -20,13 +22,17 @@ void ARM::arm_step() { step(2); //print(disassemble_registers(), "\n"); -//print(disassemble_arm_opcode(pipeline.execute.address), "\n"); +//print(disassemble_arm_instruction(pipeline.execute.address), "\n"); if(arm_condition() == false) return; + if((instruction() & 0x0fc000f0) == 0x00000090) { arm_op_multiply(); return; } if((instruction() & 0x0fb000f0) == 0x01000000) { arm_op_move_to_register_from_status(); return; } + if((instruction() & 0x0fb000f0) == 0x01000090) { arm_op_memory_swap(); return; } if((instruction() & 0x0fb000f0) == 0x01200000) { arm_op_move_to_status_from_register(); return; } - if((instruction() & 0x0ff000f0) == 0x01200010) { arm_op_branch_exchange_register(); return; } + if((instruction() & 0x0ff000f0) == 0x01200010) { arm_op_branch_exchange_register(); return; } //ARMv4 + if((instruction() & 0x0fb00000) == 0x03200000) { arm_op_move_to_status_from_immediate(); return; } + if((instruction() & 0x0e000010) == 0x00000000) { arm_op_data_immediate_shift(); return; } if((instruction() & 0x0e000090) == 0x00000010) { arm_op_data_register_shift(); return; } if((instruction() & 0x0e000000) == 0x02000000) { arm_op_data_immediate(); return; } @@ -34,6 +40,7 @@ void ARM::arm_step() { if((instruction() & 0x0e000010) == 0x06000000) { arm_op_move_register_offset(); return; } if((instruction() & 0x0e000000) == 0x08000000) { arm_op_move_multiple(); return; } if((instruction() & 0x0e000000) == 0x0a000000) { arm_op_branch(); return; } + if((instruction() & 0x0f000000) == 0x0f000000) { arm_op_software_interrupt(); return; } exception = true; } @@ -110,6 +117,35 @@ void ARM::arm_opcode(uint32 rm) { } } +void ARM::arm_move_to_status(uint32 rm) { + uint1 source = instruction() >> 22; + uint4 field = instruction() >> 16; + + if(source == 1) { + if(mode() == Processor::Mode::USR) return; + if(mode() == Processor::Mode::SYS) return; + } + + PSR &psr = source ? spsr() : cpsr(); + + if(field & 1) { + if(source == 1 || (Processor::Mode)cpsr().m != Processor::Mode::USR) { + psr.i = rm & 0x00000080; + psr.f = rm & 0x00000040; + psr.t = rm & 0x00000020; + psr.m = rm & 0x0000001f; + if(source == 0) processor.setMode((Processor::Mode)psr.m); + } + } + + if(field & 8) { + psr.n = rm & 0x80000000; + psr.z = rm & 0x40000000; + psr.c = rm & 0x20000000; + psr.v = rm & 0x10000000; + } +} + //logical shift left void ARM::lsl(bool &c, uint32 &rm, uint32 rs) { while(rs--) { @@ -167,23 +203,35 @@ void ARM::arm_op_multiply() { uint4 s = instruction() >> 8; uint4 m = instruction() >> 0; - //Booth's algorithm: two bit steps - uint32 temp = r(s); - while(temp) { - temp >>= 2; - step(1); - } - r(d) = r(m) * r(s); + auto &rd = r(d); + uint32 rs = r(s); + auto &rm = r(m); - if(accumulate) { + rd = accumulate ? r(n) : 0u; + step(1); + + //Modified Booth Encoding + bool carry = 0; + unsigned place = 0; + + do { step(1); - r(d) += r(n); - } + signed factor = (int2)rs + carry; + + if(factor == -2) rd -= rm << (place + 1); + if(factor == -1) rd -= rm << (place + 0); + if(factor == +1) rd += rm << (place + 0); + if(factor == +2) rd += rm << (place + 1); + + carry = rs & 2; + place += 2; + rs >>= 2; + } while(rs + carry && place < 32); if(save) { cpsr().n = r(d) >> 31; cpsr().z = r(d) == 0; - cpsr().c = 0; //undefined + cpsr().c = carry; } } @@ -204,6 +252,24 @@ void ARM::arm_op_move_to_register_from_status() { r(d) = source ? spsr() : cpsr(); } +//swp{condition}{b} rd,rm,[rn] +//cccc 0001 0b00 nnnn dddd ---- 1001 mmmm +//c = condition +//b = byte (0 = word) +//n = rn +//d = rd +//m = rm +void ARM::arm_op_memory_swap() { + uint1 byte = instruction() >> 22; + uint4 n = instruction() >> 16; + uint4 d = instruction() >> 12; + uint4 m = instruction(); + + uint32 word = bus_read(r(n), byte ? Byte : Word); + bus_write(r(n), byte ? Byte : Word, r(m)); + r(d) = word; +} + //msr{condition} (c,s)psr:{fields},rm //cccc 0001 0r10 ffff ++++ ---- 0000 mmmm //c = condition @@ -211,35 +277,9 @@ void ARM::arm_op_move_to_register_from_status() { //f = field mask //m = rm void ARM::arm_op_move_to_status_from_register() { - uint1 source = instruction() >> 22; - uint4 field = instruction() >> 16; uint4 m = instruction(); - if(source) { - if(mode() == Processor::Mode::USR) return; - if(mode() == Processor::Mode::SYS) return; - } - - PSR &psr = source ? spsr() : cpsr(); - uint32 rm = r(m); - - if(field & 1) { - psr.i = rm & 0x00000080; - psr.f = rm & 0x00000040; - psr.t = rm & 0x00000020; - psr.m = rm & 0x0000001f; - - if(source == 0) { - processor.setMode((Processor::Mode)psr.m); - } - } - - if(field & 8) { - psr.n = rm & 0x80000000; - psr.z = rm & 0x40000000; - psr.c = rm & 0x20000000; - psr.v = rm & 0x10000000; - } + arm_move_to_status(r(m)); } //bx{condition} rm @@ -253,6 +293,24 @@ void ARM::arm_op_branch_exchange_register() { cpsr().t = r(m) & 1; } +//msr{condition} (c,s)psr:{fields},#immediate +//cccc 0011 0r10 ffff ++++ rrrr iiii iiii +//c = condition +//r = SPSR (0 = CPSR) +//f = field mask +//r = rotate +//i = immediate +void ARM::arm_op_move_to_status_from_immediate() { + uint4 rotate = instruction() >> 8; + uint8 immediate = instruction(); + + uint32 rm = immediate; + bool c = cpsr().c; + if(rotate) ror(c, rm, 2 * rotate); + + arm_move_to_status(rm); +} + //{opcode}{condition}{s} rd,rm {shift} #immediate //{opcode}{condition} rn,rm {shift} #immediate //{opcode}{condition}{s} rd,rn,rm {shift} #immediate @@ -489,3 +547,15 @@ void ARM::arm_op_branch() { if(link) r(14) = r(15) - 4; r(15) += displacement * 4; } + +//swi #immediate +//cccc 1111 iiii iiii iiii iiii iiii iiii +//c = condition +//i = immediate +void ARM::arm_op_software_interrupt() { + uint24 immediate = instruction(); + + vector(0x00000008, Processor::Mode::SVC); +} + +#endif diff --git a/bsnes/processor/arm/instructions-arm.hpp b/bsnes/processor/arm/instructions-arm.hpp index ea7558dac..035e8863f 100755 --- a/bsnes/processor/arm/instructions-arm.hpp +++ b/bsnes/processor/arm/instructions-arm.hpp @@ -2,6 +2,7 @@ void arm_step(); bool arm_condition(); void arm_opcode(uint32 rm); +void arm_move_to_status(uint32 rm); void lsl(bool &c, uint32 &rm, uint32 rs); void lsr(bool &c, uint32 &rm, uint32 rs); @@ -11,8 +12,10 @@ void rrx(bool &c, uint32 &rm); void arm_op_multiply(); void arm_op_move_to_register_from_status(); +void arm_op_memory_swap(); void arm_op_move_to_status_from_register(); void arm_op_branch_exchange_register(); +void arm_op_move_to_status_from_immediate(); void arm_op_data_immediate_shift(); void arm_op_data_register_shift(); void arm_op_data_immediate(); @@ -20,3 +23,4 @@ void arm_op_move_immediate_offset(); void arm_op_move_register_offset(); void arm_op_move_multiple(); void arm_op_branch(); +void arm_op_software_interrupt(); diff --git a/bsnes/processor/arm/instructions-thumb.cpp b/bsnes/processor/arm/instructions-thumb.cpp index 4941c4125..1dae860ea 100755 --- a/bsnes/processor/arm/instructions-thumb.cpp +++ b/bsnes/processor/arm/instructions-thumb.cpp @@ -1,3 +1,5 @@ +#ifdef PROCESSOR_ARM_HPP + void ARM::thumb_step() { if(pipeline.reload) { pipeline.reload = false; @@ -20,7 +22,7 @@ void ARM::thumb_step() { step(1); //print(disassemble_registers(), "\n"); -//print(disassemble_thumb_opcode(pipeline.execute.address), "\n"); +//print(disassemble_thumb_instruction(pipeline.execute.address), "\n"); if((instruction() & 0xfc00) == 0x1800) { thumb_op_adjust_register(); return; } if((instruction() & 0xfc00) == 0x1c00) { thumb_op_adjust_immediate(); return; } @@ -483,13 +485,7 @@ void ARM::thumb_op_move_multiple() { void ARM::thumb_op_software_interrupt() { uint8 immediate = instruction(); - auto psr = cpsr(); - processor.setMode(Processor::Mode::SVC); - r(14) = r(15) - 2; - spsr() = psr; - cpsr().t = 0; - cpsr().i = 1; - r(15) = 0x00000008; + vector(0x00000008, Processor::Mode::SVC); } //b{condition} @@ -532,3 +528,5 @@ void ARM::thumb_op_branch_long_suffix() { r(14) = r(15) | 1; r(15) += displacement * 2; } + +#endif diff --git a/bsnes/processor/arm/registers.cpp b/bsnes/processor/arm/registers.cpp index 12f4dd38d..08e4d9947 100755 --- a/bsnes/processor/arm/registers.cpp +++ b/bsnes/processor/arm/registers.cpp @@ -1,3 +1,5 @@ +#ifdef PROCESSOR_ARM_HPP + void ARM::Processor::power() { r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = 0; usr.r8 = usr.r9 = usr.r10 = usr.r11 = usr.r12 = usr.sp = usr.lr = 0; @@ -26,8 +28,6 @@ void ARM::Processor::power() { r[7] = &r7; r[15] = &pc; - - setMode(Mode::SYS); } void ARM::Processor::setMode(Mode mode) { @@ -56,3 +56,5 @@ void ARM::Processor::setMode(Mode mode) { default: r[13] = &usr.sp; r[14] = &usr.lr; spsr = nullptr; break; } } + +#endif diff --git a/bsnes/processor/hg51b/hg51b.cpp b/bsnes/processor/hg51b/hg51b.cpp new file mode 100755 index 000000000..aaa5838b7 --- /dev/null +++ b/bsnes/processor/hg51b/hg51b.cpp @@ -0,0 +1,27 @@ +#include +#include "hg51b.hpp" + +namespace Processor { + +#include "registers.cpp" +#include "instructions.cpp" +#include "serialization.cpp" + +void HG51B::exec(uint24 addr) { + if(regs.halt) return; + addr = addr + regs.pc * 2; + opcode = bus_read(addr++) << 0; + opcode |= bus_read(addr++) << 8; + regs.pc = (regs.pc & 0xffff00) | ((regs.pc + 1) & 0x0000ff); + instruction(); +} + +void HG51B::power() { + regs.halt = true; + + regs.n = 0; + regs.z = 0; + regs.c = 0; +} + +} diff --git a/bsnes/processor/hg51b/hg51b.hpp b/bsnes/processor/hg51b/hg51b.hpp new file mode 100755 index 000000000..76b9a0277 --- /dev/null +++ b/bsnes/processor/hg51b/hg51b.hpp @@ -0,0 +1,31 @@ +#ifndef PROCESSOR_HG51B_HPP +#define PROCESSOR_HG51B_HPP + +namespace Processor { + +//Hitachi HG51B169 (HG51BS family/derivative?) + +struct HG51B { +//uint16 programROM[2][256]; + uint24 dataROM[1024]; + uint8 dataRAM[3072]; + #include "registers.hpp" + void exec(uint24 addr); + virtual uint8 bus_read(uint24 addr) = 0; + virtual void bus_write(uint24 addr, uint8 data) = 0; + + void power(); + void serialize(serializer&); + +protected: + void push(); + void pull(); + unsigned sa(); + unsigned ri(); + unsigned np(); + void instruction(); +}; + +} + +#endif diff --git a/bsnes/snes/chip/hitachidsp/opcodes.cpp b/bsnes/processor/hg51b/instructions.cpp similarity index 96% rename from bsnes/snes/chip/hitachidsp/opcodes.cpp rename to bsnes/processor/hg51b/instructions.cpp index 6fc9d2d73..430ff4e11 100755 --- a/bsnes/snes/chip/hitachidsp/opcodes.cpp +++ b/bsnes/processor/hg51b/instructions.cpp @@ -1,6 +1,6 @@ -#ifdef HITACHIDSP_CPP +#ifdef PROCESSOR_HG51B_HPP -void HitachiDSP::push() { +void HG51B::push() { stack[7] = stack[6]; stack[6] = stack[5]; stack[5] = stack[4]; @@ -11,7 +11,7 @@ void HitachiDSP::push() { stack[0] = regs.pc; } -void HitachiDSP::pull() { +void HG51B::pull() { regs.pc = stack[0]; stack[0] = stack[1]; stack[1] = stack[2]; @@ -24,7 +24,7 @@ void HitachiDSP::pull() { } //Shift-A: math opcodes can shift A register prior to ALU operation -unsigned HitachiDSP::sa() { +unsigned HG51B::sa() { switch(opcode & 0x0300) { default: case 0x0000: return regs.a << 0; case 0x0100: return regs.a << 1; @@ -34,18 +34,18 @@ unsigned HitachiDSP::sa() { } //Register-or-Immediate: most opcodes can load from a register or immediate -unsigned HitachiDSP::ri() { +unsigned HG51B::ri() { if(opcode & 0x0400) return opcode & 0xff; return reg_read(opcode & 0xff); } //New-PC: determine jump target address; opcode.d9 = long jump flag (1 = yes) -unsigned HitachiDSP::np() { +unsigned HG51B::np() { if(opcode & 0x0200) return (regs.p << 8) | (opcode & 0xff); return (regs.pc & 0xffff00) | (opcode & 0xff); } -void HitachiDSP::exec() { +void HG51B::instruction() { if((opcode & 0xffff) == 0x0000) { //0000 0000 0000 0000 //nop @@ -344,12 +344,12 @@ void HitachiDSP::exec() { else if((opcode & 0xffff) == 0xfc00) { //1111 1100 0000 0000 //halt - state = State::Idle; + regs.halt = true; } else { - print("Hitachi DSP: invalid opcode @ ", hex<4>(regs.pc - 1), " = ", hex<4>(opcode), "\n"); - state = State::Idle; + print("Hitachi DSP: unknown opcode @ ", hex<4>(regs.pc - 1), " = ", hex<4>(opcode), "\n"); + regs.halt = true; } } diff --git a/bsnes/snes/chip/hitachidsp/registers.cpp b/bsnes/processor/hg51b/registers.cpp similarity index 93% rename from bsnes/snes/chip/hitachidsp/registers.cpp rename to bsnes/processor/hg51b/registers.cpp index 396bdf3e6..597ef504e 100755 --- a/bsnes/snes/chip/hitachidsp/registers.cpp +++ b/bsnes/processor/hg51b/registers.cpp @@ -1,7 +1,7 @@ -#ifdef HITACHIDSP_CPP +#ifdef PROCESSOR_HG51B_HPP -unsigned HitachiDSP::reg_read(unsigned n) const { - switch(n) { +uint24 HG51B::reg_read(uint8 addr) const { + switch(addr) { case 0x00: return regs.a; case 0x01: return regs.acch; case 0x02: return regs.accl; @@ -46,8 +46,8 @@ unsigned HitachiDSP::reg_read(unsigned n) const { return 0x000000; } -void HitachiDSP::reg_write(unsigned n, unsigned data) { - switch(n) { +void HG51B::reg_write(uint8 addr, uint24 data) { + switch(addr) { case 0x00: regs.a = data; return; case 0x01: regs.acch = data; return; case 0x02: regs.accl = data; return; diff --git a/bsnes/processor/hg51b/registers.hpp b/bsnes/processor/hg51b/registers.hpp new file mode 100755 index 000000000..123660eed --- /dev/null +++ b/bsnes/processor/hg51b/registers.hpp @@ -0,0 +1,25 @@ +struct Registers { + bool halt; + + uint24 pc; + uint16 p; + bool n; + bool z; + bool c; + + uint24 a; + uint24 acch; + uint24 accl; + uint24 busdata; + uint24 romdata; + uint24 ramdata; + uint24 busaddr; + uint24 ramaddr; + uint24 gpr[16]; +} regs; + +uint24 stack[8]; +uint16 opcode; + +uint24 reg_read(uint8 addr) const; +void reg_write(uint8 addr, uint24 data); diff --git a/bsnes/processor/hg51b/serialization.cpp b/bsnes/processor/hg51b/serialization.cpp new file mode 100755 index 000000000..19ce5d817 --- /dev/null +++ b/bsnes/processor/hg51b/serialization.cpp @@ -0,0 +1,27 @@ +#ifdef PROCESSOR_HG51B_HPP + +void HG51B::serialize(serializer &s) { + s.array(dataRAM); + for(auto &n : stack) s.integer(n); + s.integer(opcode); + + s.integer(regs.halt); + + s.integer(regs.pc); + s.integer(regs.p); + s.integer(regs.n); + s.integer(regs.z); + s.integer(regs.c); + + s.integer(regs.a); + s.integer(regs.acch); + s.integer(regs.accl); + s.integer(regs.busdata); + s.integer(regs.romdata); + s.integer(regs.ramdata); + s.integer(regs.busaddr); + s.integer(regs.ramaddr); + for(auto &n : regs.gpr) s.integer(n); +} + +#endif diff --git a/bsnes/snes/chip/hitachidsp/hitachidsp.cpp b/bsnes/snes/chip/hitachidsp/hitachidsp.cpp index 1042267e5..36a0dc7ea 100755 --- a/bsnes/snes/chip/hitachidsp/hitachidsp.cpp +++ b/bsnes/snes/chip/hitachidsp/hitachidsp.cpp @@ -4,8 +4,6 @@ namespace SNES { #include "memory.cpp" -#include "opcodes.cpp" -#include "registers.cpp" #include "serialization.cpp" HitachiDSP hitachidsp; @@ -17,27 +15,17 @@ void HitachiDSP::enter() { scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); } - switch(state) { - case State::Idle: - step(1); - break; - case State::DMA: - for(unsigned n = 0; n < regs.dma_length; n++) { - bus.write(regs.dma_target + n, bus.read(regs.dma_source + n)); + if(mmio.dma) { + for(unsigned n = 0; n < mmio.dma_length; n++) { + bus.write(mmio.dma_target + n, bus.read(mmio.dma_source + n)); step(2); } - state = State::Idle; - break; - case State::Execute: - unsigned offset = regs.program_offset + regs.pc * 2; - opcode = bus_read(offset + 0) << 0; - opcode |= bus_read(offset + 1) << 8; - regs.pc = (regs.pc & 0xffff00) | ((regs.pc + 1) & 0x0000ff); - exec(); - step(1); - break; + mmio.dma = false; } + exec(mmio.program_offset); + step(1); + synchronize_cpu(); } } @@ -52,27 +40,24 @@ void HitachiDSP::unload() { } void HitachiDSP::power() { + mmio.dma = false; + + mmio.dma_source = 0x000000; + mmio.dma_length = 0x0000; + mmio.dma_target = 0x000000; + mmio.r1f48 = 0x00; + mmio.program_offset = 0x000000; + mmio.r1f4c = 0x00; + mmio.page_number = 0x0000; + mmio.program_counter = 0x00; + mmio.r1f50 = 0x33; + mmio.r1f51 = 0x00; + mmio.r1f52 = 0x01; } void HitachiDSP::reset() { create(HitachiDSP::Enter, frequency); - state = State::Idle; - - regs.n = 0; - regs.z = 0; - regs.c = 0; - - regs.dma_source = 0x000000; - regs.dma_length = 0x0000; - regs.dma_target = 0x000000; - regs.r1f48 = 0x00; - regs.program_offset = 0x000000; - regs.r1f4c = 0x00; - regs.page_number = 0x0000; - regs.program_counter = 0x00; - regs.r1f50 = 0x33; - regs.r1f51 = 0x00; - regs.r1f52 = 0x01; + HG51B::power(); } } diff --git a/bsnes/snes/chip/hitachidsp/hitachidsp.hpp b/bsnes/snes/chip/hitachidsp/hitachidsp.hpp index 40853c02e..9797969ae 100755 --- a/bsnes/snes/chip/hitachidsp/hitachidsp.hpp +++ b/bsnes/snes/chip/hitachidsp/hitachidsp.hpp @@ -1,15 +1,6 @@ -//Hitachi HG51B169 - -class HitachiDSP : public Coprocessor { -public: +struct HitachiDSP : Processor::HG51B, Coprocessor { unsigned frequency; -//uint16 programROM[2][256]; - uint24 dataROM[1024]; - uint8 dataRAM[3072]; - uint24 stack[8]; - uint16 opcode; - enum class State : unsigned { Idle, DMA, Execute } state; - #include "registers.hpp" + #include "mmio.hpp" static void Enter(); void enter(); @@ -20,28 +11,18 @@ public: void power(); void reset(); - //memory.cpp - uint8 bus_read(unsigned addr); - void bus_write(unsigned addr, uint8 data); + //HG51B read/write + uint8 bus_read(uint24 addr); + void bus_write(uint24 addr, uint8 data); + //CPU ROM read/write uint8 rom_read(unsigned addr); void rom_write(unsigned addr, uint8 data); + //CPU MMIO read/write uint8 dsp_read(unsigned addr); void dsp_write(unsigned addr, uint8 data); - //opcodes.cpp - void push(); - void pull(); - unsigned sa(); - unsigned ri(); - unsigned np(); - void exec(); - - //registers.cpp - unsigned reg_read(unsigned n) const; - void reg_write(unsigned n, unsigned data); - void serialize(serializer&); }; diff --git a/bsnes/snes/chip/hitachidsp/memory.cpp b/bsnes/snes/chip/hitachidsp/memory.cpp index 3c9c3af18..5eb245a2a 100755 --- a/bsnes/snes/chip/hitachidsp/memory.cpp +++ b/bsnes/snes/chip/hitachidsp/memory.cpp @@ -1,18 +1,18 @@ #ifdef HITACHIDSP_CPP -uint8 HitachiDSP::bus_read(unsigned addr) { +uint8 HitachiDSP::bus_read(uint24 addr) { if((addr & 0x408000) == 0x008000) return bus.read(addr); return 0x00; } -void HitachiDSP::bus_write(unsigned addr, uint8 data) { +void HitachiDSP::bus_write(uint24 addr, uint8 data) { if((addr & 0x40e000) == 0x006000) return bus.write(addr, data); } uint8 HitachiDSP::rom_read(unsigned addr) { if(co_active() == cpu.thread) { - if(state == State::Idle) return cartridge.rom.read(addr); - if((addr & 0x40ffe0) == 0x00ffe0) return regs.vector[addr & 0x1f]; + if(regs.halt) return cartridge.rom.read(addr); + if((addr & 0x40ffe0) == 0x00ffe0) return mmio.vector[addr & 0x1f]; return cpu.regs.mdr; } if(co_active() == hitachidsp.thread) { @@ -34,34 +34,34 @@ uint8 HitachiDSP::dsp_read(unsigned addr) { //MMIO switch(addr) { - case 0x1f40: return regs.dma_source >> 0; - case 0x1f41: return regs.dma_source >> 8; - case 0x1f42: return regs.dma_source >> 16; - case 0x1f43: return regs.dma_length >> 0; - case 0x1f44: return regs.dma_length >> 8; - case 0x1f45: return regs.dma_target >> 0; - case 0x1f46: return regs.dma_target >> 8; - case 0x1f47: return regs.dma_target >> 16; - case 0x1f48: return regs.r1f48; - case 0x1f49: return regs.program_offset >> 0; - case 0x1f4a: return regs.program_offset >> 8; - case 0x1f4b: return regs.program_offset >> 16; - case 0x1f4c: return regs.r1f4c; - case 0x1f4d: return regs.page_number >> 0; - case 0x1f4e: return regs.page_number >> 8; - case 0x1f4f: return regs.program_counter; - case 0x1f50: return regs.r1f50; - case 0x1f51: return regs.r1f51; - case 0x1f52: return regs.r1f52; + case 0x1f40: return mmio.dma_source >> 0; + case 0x1f41: return mmio.dma_source >> 8; + case 0x1f42: return mmio.dma_source >> 16; + case 0x1f43: return mmio.dma_length >> 0; + case 0x1f44: return mmio.dma_length >> 8; + case 0x1f45: return mmio.dma_target >> 0; + case 0x1f46: return mmio.dma_target >> 8; + case 0x1f47: return mmio.dma_target >> 16; + case 0x1f48: return mmio.r1f48; + case 0x1f49: return mmio.program_offset >> 0; + case 0x1f4a: return mmio.program_offset >> 8; + case 0x1f4b: return mmio.program_offset >> 16; + case 0x1f4c: return mmio.r1f4c; + case 0x1f4d: return mmio.page_number >> 0; + case 0x1f4e: return mmio.page_number >> 8; + case 0x1f4f: return mmio.program_counter; + case 0x1f50: return mmio.r1f50; + case 0x1f51: return mmio.r1f51; + case 0x1f52: return mmio.r1f52; case 0x1f53: case 0x1f54: case 0x1f55: case 0x1f56: case 0x1f57: case 0x1f58: case 0x1f59: case 0x1f5a: case 0x1f5b: case 0x1f5c: case 0x1f5d: case 0x1f5e: - case 0x1f5f: return ((state != State::Idle) << 6) | ((state == State::Idle) << 1); + case 0x1f5f: return ((regs.halt == false) << 6) | ((regs.halt == true) << 1); } //Vector if(addr >= 0x1f60 && addr <= 0x1f7f) { - return regs.vector[addr & 0x1f]; + return mmio.vector[addr & 0x1f]; } //GPRs @@ -85,37 +85,37 @@ void HitachiDSP::dsp_write(unsigned addr, uint8 data) { //MMIO switch(addr) { - case 0x1f40: regs.dma_source = (regs.dma_source & 0xffff00) | (data << 0); return; - case 0x1f41: regs.dma_source = (regs.dma_source & 0xff00ff) | (data << 8); return; - case 0x1f42: regs.dma_source = (regs.dma_source & 0x00ffff) | (data << 16); return; - case 0x1f43: regs.dma_length = (regs.dma_length & 0xff00) | (data << 0); return; - case 0x1f44: regs.dma_length = (regs.dma_length & 0x00ff) | (data << 8); return; - case 0x1f45: regs.dma_target = (regs.dma_target & 0xffff00) | (data << 0); return; - case 0x1f46: regs.dma_target = (regs.dma_target & 0xff00ff) | (data << 8); return; - case 0x1f47: regs.dma_target = (regs.dma_target & 0x00ffff) | (data << 16); - if(state == State::Idle) state = State::DMA; + case 0x1f40: mmio.dma_source = (mmio.dma_source & 0xffff00) | (data << 0); return; + case 0x1f41: mmio.dma_source = (mmio.dma_source & 0xff00ff) | (data << 8); return; + case 0x1f42: mmio.dma_source = (mmio.dma_source & 0x00ffff) | (data << 16); return; + case 0x1f43: mmio.dma_length = (mmio.dma_length & 0xff00) | (data << 0); return; + case 0x1f44: mmio.dma_length = (mmio.dma_length & 0x00ff) | (data << 8); return; + case 0x1f45: mmio.dma_target = (mmio.dma_target & 0xffff00) | (data << 0); return; + case 0x1f46: mmio.dma_target = (mmio.dma_target & 0xff00ff) | (data << 8); return; + case 0x1f47: mmio.dma_target = (mmio.dma_target & 0x00ffff) | (data << 16); + if(regs.halt) mmio.dma = true; return; - case 0x1f48: regs.r1f48 = data & 0x01; return; - case 0x1f49: regs.program_offset = (regs.program_offset & 0xffff00) | (data << 0); return; - case 0x1f4a: regs.program_offset = (regs.program_offset & 0xff00ff) | (data << 8); return; - case 0x1f4b: regs.program_offset = (regs.program_offset & 0x00ffff) | (data << 16); return; - case 0x1f4c: regs.r1f4c = data & 0x03; return; - case 0x1f4d: regs.page_number = (regs.page_number & 0x7f00) | ((data & 0xff) << 0); return; - case 0x1f4e: regs.page_number = (regs.page_number & 0x00ff) | ((data & 0x7f) << 8); return; - case 0x1f4f: regs.program_counter = data; - if(state == State::Idle) { - regs.pc = regs.page_number * 256 + regs.program_counter; - state = State::Execute; + case 0x1f48: mmio.r1f48 = data & 0x01; return; + case 0x1f49: mmio.program_offset = (mmio.program_offset & 0xffff00) | (data << 0); return; + case 0x1f4a: mmio.program_offset = (mmio.program_offset & 0xff00ff) | (data << 8); return; + case 0x1f4b: mmio.program_offset = (mmio.program_offset & 0x00ffff) | (data << 16); return; + case 0x1f4c: mmio.r1f4c = data & 0x03; return; + case 0x1f4d: mmio.page_number = (mmio.page_number & 0x7f00) | ((data & 0xff) << 0); return; + case 0x1f4e: mmio.page_number = (mmio.page_number & 0x00ff) | ((data & 0x7f) << 8); return; + case 0x1f4f: mmio.program_counter = data; + if(regs.halt) { + regs.pc = mmio.page_number * 256 + mmio.program_counter; + regs.halt = false; } return; - case 0x1f50: regs.r1f50 = data & 0x77; return; - case 0x1f51: regs.r1f51 = data & 0x01; return; - case 0x1f52: regs.r1f52 = data & 0x01; return; + case 0x1f50: mmio.r1f50 = data & 0x77; return; + case 0x1f51: mmio.r1f51 = data & 0x01; return; + case 0x1f52: mmio.r1f52 = data & 0x01; return; } //Vector if(addr >= 0x1f60 && addr <= 0x1f7f) { - regs.vector[addr & 0x1f] = data; + mmio.vector[addr & 0x1f] = data; return; } diff --git a/bsnes/snes/chip/hitachidsp/registers.hpp b/bsnes/snes/chip/hitachidsp/mmio.hpp similarity index 65% rename from bsnes/snes/chip/hitachidsp/registers.hpp rename to bsnes/snes/chip/hitachidsp/mmio.hpp index 73d2370f8..88d0e2fc6 100755 --- a/bsnes/snes/chip/hitachidsp/registers.hpp +++ b/bsnes/snes/chip/hitachidsp/mmio.hpp @@ -1,21 +1,6 @@ -struct Registers { - uint24 pc; - uint16 p; - bool n; - bool z; - bool c; +struct MMIO { + bool dma; //true during DMA transfers - uint24 a; - uint24 acch; - uint24 accl; - uint24 busdata; - uint24 romdata; - uint24 ramdata; - uint24 busaddr; - uint24 ramaddr; - uint24 gpr[16]; - - //MMIO uint24 dma_source; //$1f40-$1f42 uint24 dma_length; //$1f43-$1f44 uint24 dma_target; //$1f45-$1f47 @@ -28,4 +13,4 @@ struct Registers { uint8 r1f51; //$1f51 uint8 r1f52; //$1f52 uint8 vector[32]; //$1f60-$1f7f -} regs; +} mmio; diff --git a/bsnes/snes/chip/hitachidsp/serialization.cpp b/bsnes/snes/chip/hitachidsp/serialization.cpp index 838230b66..0ea9b2422 100755 --- a/bsnes/snes/chip/hitachidsp/serialization.cpp +++ b/bsnes/snes/chip/hitachidsp/serialization.cpp @@ -1,41 +1,22 @@ #ifdef HITACHIDSP_CPP void HitachiDSP::serialize(serializer &s) { + HG51B::serialize(s); Thread::serialize(s); - s.array(dataRAM); - for(auto &n : stack) s.integer(n); - s.integer(opcode); - s.integer((unsigned&)state); - - s.integer(regs.pc); - s.integer(regs.p); - s.integer(regs.n); - s.integer(regs.z); - s.integer(regs.c); - - s.integer(regs.a); - s.integer(regs.acch); - s.integer(regs.accl); - s.integer(regs.busdata); - s.integer(regs.romdata); - s.integer(regs.ramdata); - s.integer(regs.busaddr); - s.integer(regs.ramaddr); - for(auto &n : regs.gpr) s.integer(n); - - s.integer(regs.dma_source); - s.integer(regs.dma_length); - s.integer(regs.dma_target); - s.integer(regs.r1f48); - s.integer(regs.program_offset); - s.integer(regs.r1f4c); - s.integer(regs.page_number); - s.integer(regs.program_counter); - s.integer(regs.r1f50); - s.integer(regs.r1f51); - s.integer(regs.r1f52); - s.array(regs.vector); + s.integer(mmio.dma); + s.integer(mmio.dma_source); + s.integer(mmio.dma_length); + s.integer(mmio.dma_target); + s.integer(mmio.r1f48); + s.integer(mmio.program_offset); + s.integer(mmio.r1f4c); + s.integer(mmio.page_number); + s.integer(mmio.program_counter); + s.integer(mmio.r1f50); + s.integer(mmio.r1f51); + s.integer(mmio.r1f52); + s.array(mmio.vector); } #endif diff --git a/bsnes/snes/snes.hpp b/bsnes/snes/snes.hpp index ed3f58ec9..4eb32b6e0 100755 --- a/bsnes/snes/snes.hpp +++ b/bsnes/snes/snes.hpp @@ -3,6 +3,7 @@ #include #include +#include namespace SNES { namespace Info { diff --git a/bsnes/target-debugger/Makefile b/bsnes/target-debugger/Makefile index ebd4b0bb7..da4607f0f 100755 --- a/bsnes/target-debugger/Makefile +++ b/bsnes/target-debugger/Makefile @@ -1,6 +1,6 @@ options += debugger -processor := arm +processor := arm hg51b include processor/Makefile include $(snes)/Makefile diff --git a/bsnes/target-libsnes/Makefile b/bsnes/target-libsnes/Makefile index 0fbc1ed3d..322f8c970 100755 --- a/bsnes/target-libsnes/Makefile +++ b/bsnes/target-libsnes/Makefile @@ -1,4 +1,4 @@ -processor := arm +processor := arm hg51b include processor/Makefile include $(snes)/Makefile diff --git a/bsnes/target-ui/Makefile b/bsnes/target-ui/Makefile index 02a908c9a..aac705298 100755 --- a/bsnes/target-ui/Makefile +++ b/bsnes/target-ui/Makefile @@ -1,4 +1,4 @@ -processors := arm +processors := arm hg51b include processor/Makefile include $(nes)/Makefile