diff --git a/bsnes/base/base.hpp b/bsnes/base/base.hpp index 21285066..8a8283fe 100755 --- a/bsnes/base/base.hpp +++ b/bsnes/base/base.hpp @@ -1,7 +1,7 @@ #ifndef BASE_HPP #define BASE_HPP -const char Version[] = "086.14"; +const char Version[] = "086.15"; #include #include diff --git a/bsnes/nall/snes/cartridge.hpp b/bsnes/nall/snes/cartridge.hpp index 6a350c2c..95dadc92 100755 --- a/bsnes/nall/snes/cartridge.hpp +++ b/bsnes/nall/snes/cartridge.hpp @@ -494,7 +494,7 @@ SnesCartridge::SnesCartridge(const uint8_t *data, unsigned size) { ); if(has_st010) markup.append( - " \n" + " \n" " \n" " \n" " \n" @@ -511,7 +511,7 @@ SnesCartridge::SnesCartridge(const uint8_t *data, unsigned size) { ); if(has_st011) markup.append( - " \n" + " \n" " \n" " \n" " \n" @@ -528,7 +528,7 @@ SnesCartridge::SnesCartridge(const uint8_t *data, unsigned size) { ); if(has_st018) markup.append( - " \n" + " \n" " \n" " \n" " \n" diff --git a/bsnes/snes/cartridge/markup.cpp b/bsnes/snes/cartridge/markup.cpp index 2957430a..e03da18c 100755 --- a/bsnes/snes/cartridge/markup.cpp +++ b/bsnes/snes/cartridge/markup.cpp @@ -336,7 +336,6 @@ void Cartridge::parse_markup_armdsp(XML::Node &root) { if(root.exists() == false) return; has_armdsp = true; - for(auto &byte : armdsp.programROM) byte = 0x00; string firmware = root["firmware"].data; string sha256 = root["sha256"].data; @@ -344,14 +343,14 @@ void Cartridge::parse_markup_armdsp(XML::Node &root) { file fp; if(fp.open(path, file::mode::read) == false) { interface->message({ "Warning: ARM DSP firmware ", firmware, " is missing." }); - } else if(fp.size() != 128 * 1024) { + } else if(fp.size() != 160 * 1024) { interface->message({ "Warning: ARM DSP firmware ", firmware, " is of the wrong file size." }); fp.close(); } else { - for(auto &byte : armdsp.programROM) byte = fp.read(); + fp.read(armdsp.firmware, fp.size()); if(!sha256.empty()) { - if(sha256 != nall::sha256(armdsp.programROM, 128 * 1024)) { + if(sha256 != nall::sha256(armdsp.firmware, fp.size())) { interface->message({ "Warning: ARM DSP firmware ", firmware, " SHA256 sum is incorrect." }); } } diff --git a/bsnes/snes/chip/armdsp/armdsp.cpp b/bsnes/snes/chip/armdsp/armdsp.cpp index 9fa79e39..474cb11e 100755 --- a/bsnes/snes/chip/armdsp/armdsp.cpp +++ b/bsnes/snes/chip/armdsp/armdsp.cpp @@ -14,6 +14,20 @@ ArmDSP armdsp; void ArmDSP::Enter() { armdsp.enter(); } void ArmDSP::enter() { + //reset hold delay + while(bridge.reset) { + step(4); + synchronize_cpu(); + continue; + } + + //reset sequence delay + if(bridge.ready == false) { + step(4096); //todo: verify cycle count + synchronize_cpu(); + bridge.ready = true; + } + while(true) { if(scheduler.sync == Scheduler::SynchronizeMode::All) { scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); @@ -44,12 +58,16 @@ void ArmDSP::enter() { pipeline.prefetch.opcode = bus_readword(r[15]); r[15].step(); - //if(pipeline.instruction.address == 0x0000ef5c) trace = 1; + pipeline.mdr.address = r[15]; + pipeline.mdr.opcode = bus_readword(r[15]); + + if(pipeline.instruction.address == 0x00000208) trace = 1; if(trace) { print("\n", disassemble_registers(), "\n"); print(disassemble_opcode(pipeline.instruction.address), "\n"); usleep(200000); } + trace = 0; instruction = pipeline.instruction.opcode; if(!condition()) continue; @@ -86,7 +104,8 @@ uint8 ArmDSP::mmio_read(unsigned addr) { } } - if(addr == 0x3802); + if(addr == 0x3802) { + } if(addr == 0x3804) { data = bridge.status(); @@ -116,7 +135,10 @@ void ArmDSP::mmio_write(unsigned addr, uint8 data) { print("* w3802 = ", hex<2>(data), "\n"); } - if(addr == 0x3804); + if(addr == 0x3804) { + if(!bridge.reset && data) arm_reset(); + bridge.reset = data; + } } void ArmDSP::init() { @@ -129,32 +151,44 @@ void ArmDSP::unload() { } void ArmDSP::power() { - string filename = interface->path(Cartridge::Slot::Base, "st0018d.rom"); + string filename = { dir(interface->path(Cartridge::Slot::Base, "st018.rom")), "disassembly.txt" }; file fp; - if(fp.open(filename, file::mode::read)) { - fp.read(dataROM, 32 * 1024); - fp.close(); - } - - filename = { dir(filename), "disassembly.txt" }; fp.open(filename, file::mode::write); for(unsigned n = 0; n < 128 * 1024; n += 4) { fp.print(disassemble_opcode(n), "\n"); } fp.close(); + + for(unsigned n = 0; n < 16 * 1024; n++) programRAM[n] = random(0x00); } void ArmDSP::reset() { + bridge.reset = false; + arm_reset(); +} + +void ArmDSP::arm_reset() { + bridge.ready = false; create(ArmDSP::Enter, 21477272); for(auto &rd : r) rd = 0; shiftercarry = 0; - - exception = false; - + exception = 0; pipeline.reload = true; - r[15].write = [&] { pipeline.reload = true; }; } +ArmDSP::ArmDSP() { + firmware = new uint8[160 * 1024]; + programRAM = new uint8[16 * 1024]; + + programROM = &firmware[0]; + dataROM = &firmware[128 * 1024]; +} + +ArmDSP::~ArmDSP() { + delete[] firmware; + delete[] programRAM; +} + } diff --git a/bsnes/snes/chip/armdsp/armdsp.hpp b/bsnes/snes/chip/armdsp/armdsp.hpp index ea9aa712..6f339609 100755 --- a/bsnes/snes/chip/armdsp/armdsp.hpp +++ b/bsnes/snes/chip/armdsp/armdsp.hpp @@ -1,9 +1,10 @@ //ARMv3 (ARM6) struct ArmDSP : public Coprocessor { - uint8 programROM[128 * 1024]; - uint8 programRAM[16 * 1024]; - uint8 dataROM[32 * 1024]; + uint8 *firmware; + uint8 *programROM; + uint8 *dataROM; + uint8 *programRAM; #include "registers.hpp" @@ -15,6 +16,10 @@ struct ArmDSP : public Coprocessor { void unload(); void power(); void reset(); + void arm_reset(); + + ArmDSP(); + ~ArmDSP(); uint8 mmio_read(unsigned addr); void mmio_write(unsigned addr, uint8 data); @@ -40,13 +45,13 @@ struct ArmDSP : public Coprocessor { void op_branch(); //memory.cpp - uint8 bus_iread(uint32 addr); - void bus_iwrite(uint32 addr, uint8 data); + uint8 bus_read(uint32 addr); + void bus_write(uint32 addr, uint8 data); uint32 bus_readbyte(uint32 addr); - uint32 bus_readword(uint32 addr); - void bus_writebyte(uint32 addr, uint32 data); + + uint32 bus_readword(uint32 addr); void bus_writeword(uint32 addr, uint32 data); //disassembler.cpp diff --git a/bsnes/snes/chip/armdsp/disassembler.cpp b/bsnes/snes/chip/armdsp/disassembler.cpp index 5366b5b5..ae6fc643 100755 --- a/bsnes/snes/chip/armdsp/disassembler.cpp +++ b/bsnes/snes/chip/armdsp/disassembler.cpp @@ -164,7 +164,7 @@ string ArmDSP::disassemble_opcode(uint32 pc) { if(p == 1) output.append("]"); if(p == 1 && w == 1) output.append("!"); - if(rn == 15) output.append(" (0x", hex<8>(pc + 8 + (u ? +immediate : -immediate)), ")"); + if(rn == 15) output.append(" =0x", hex<8>(bus_readword(pc + 8 + (u ? +immediate : -immediate)))); return output; } diff --git a/bsnes/snes/chip/armdsp/memory.cpp b/bsnes/snes/chip/armdsp/memory.cpp index 9bf9c321..0083146c 100755 --- a/bsnes/snes/chip/armdsp/memory.cpp +++ b/bsnes/snes/chip/armdsp/memory.cpp @@ -1,87 +1,73 @@ #ifdef ARMDSP_CPP -uint8 ArmDSP::bus_iread(uint32 addr) { - if(addr >= 0x00000000 && addr <= 0x0001ffff) { - return programROM[addr & 0x0001ffff]; +uint8 ArmDSP::bus_read(uint32 addr) { + switch(addr & 0xe0000000) { + case 0x00000000: return programROM[addr & 0x0001ffff]; + case 0x20000000: return pipeline.mdr.opcode >> ((addr & 3) << 3); + case 0x40000000: break; //MMIO + case 0x60000000: return 0x40404001 >> ((addr & 3) << 3); + case 0x80000000: return pipeline.mdr.opcode >> ((addr & 3) << 3); + case 0xa0000000: return dataROM[addr & 0x00007fff]; + case 0xc0000000: return pipeline.mdr.opcode >> ((addr & 3) << 3); + case 0xe0000000: return programRAM[addr & 0x00003fff]; } - if(addr >= 0x40000000 && addr <= 0x400000ff) { - if(addr == 0x40000000) return 0x00; + addr &= 0xe000003f; - if(addr == 0x40000010) { - if(bridge.cputoarm.ready) { - bridge.cputoarm.ready = false; - return bridge.cputoarm.data; - } + if(addr == 0x40000010) { + if(bridge.cputoarm.ready) { + bridge.cputoarm.ready = false; + return bridge.cputoarm.data; } - - if(addr == 0x40000020) { - return bridge.status(); - } - - if(addr == 0x40000024) return 0x00; - if(addr == 0x40000028) return 0x00; - if(addr == 0x4000002c) return 0x00; } - if(addr >= 0xa0000000 && addr <= 0xa0007fff) { - return dataROM[addr & 0x00007fff]; + if(addr == 0x40000020) { + return bridge.status(); } - if(addr >= 0xe0000000 && addr <= 0xe0003fff) { - return programRAM[addr & 0x00003fff]; - } - - if((addr & 3) == 0) print("* ARM r", hex<8>(addr), "\n"); return 0x00; } -void ArmDSP::bus_iwrite(uint32 addr, uint8 data) { - if(addr >= 0x40000000 && addr <= 0x400000ff) { - if(addr == 0x40000000) { - bridge.armtocpu.ready = true; - bridge.armtocpu.data = data; - return; - } - - if(addr == 0x40000020) return; - if(addr == 0x40000024) return; - if(addr == 0x40000028) return; - if(addr == 0x4000002c) return print("* w4000002c = ", hex<2>(data), "\n"); +void ArmDSP::bus_write(uint32 addr, uint8 data) { + switch(addr & 0xe0000000) { + case 0x40000000: break; //MMIO + case 0xe0000000: programRAM[addr & 0x00003fff] = data; return; + default: return; } - if(addr >= 0xe0000000 && addr <= 0xe0003fff) { - programRAM[addr & 0x00003fff] = data; + addr &= 0xe000003f; + + if(addr == 0x40000000) { + bridge.armtocpu.ready = true; + bridge.armtocpu.data = data; return; } - - if((addr & 3) == 0) print("* ARM w", hex<8>(addr), " = ", hex<2>(data), "\n"); } uint32 ArmDSP::bus_readbyte(uint32 addr) { - return bus_iread(addr); + return bus_read(addr); +} + +void ArmDSP::bus_writebyte(uint32 addr, uint32 data) { + return bus_write(addr, data); } uint32 ArmDSP::bus_readword(uint32 addr) { addr &= ~3; return ( - (bus_iread(addr + 0) << 0) - | (bus_iread(addr + 1) << 8) - | (bus_iread(addr + 2) << 16) - | (bus_iread(addr + 3) << 24) + (bus_read(addr + 0) << 0) + | (bus_read(addr + 1) << 8) + | (bus_read(addr + 2) << 16) + | (bus_read(addr + 3) << 24) ); } -void ArmDSP::bus_writebyte(uint32 addr, uint32 data) { - return bus_iwrite(addr, data); -} - void ArmDSP::bus_writeword(uint32 addr, uint32 data) { addr &= ~3; - bus_iwrite(addr + 0, data >> 0); - bus_iwrite(addr + 1, data >> 8); - bus_iwrite(addr + 2, data >> 16); - bus_iwrite(addr + 3, data >> 24); + bus_write(addr + 0, data >> 0); + bus_write(addr + 1, data >> 8); + bus_write(addr + 2, data >> 16); + bus_write(addr + 3, data >> 24); } #endif diff --git a/bsnes/snes/chip/armdsp/registers.hpp b/bsnes/snes/chip/armdsp/registers.hpp index e46461f0..fce1ee37 100755 --- a/bsnes/snes/chip/armdsp/registers.hpp +++ b/bsnes/snes/chip/armdsp/registers.hpp @@ -14,9 +14,11 @@ struct Bridge { }; Buffer cputoarm; Buffer armtocpu; + bool reset; + bool ready; uint8 status() const { - return 0x84 | (cputoarm.ready << 3) | (armtocpu.ready << 0); + return (ready << 7) | (cputoarm.ready << 3) | (armtocpu.ready << 0) | 4; } } bridge; @@ -111,6 +113,7 @@ struct Pipeline { }; Instruction instruction; Instruction prefetch; + Instruction mdr; } pipeline; uint32 instruction;