Path: blob/master/libsnes/bsnes/snes/chip/armdsp/armdsp.cpp
2 views
#include <snes/snes.hpp>12#define ARMDSP_CPP3namespace SNES {45//zero 01-sep-2014 - dont clobber these when reconstructing!6uint8 *ArmDSP::firmware;7uint8 *ArmDSP::programROM;8uint8 *ArmDSP::dataROM;910static bool trace = 0;1112#include "opcodes.cpp"13#include "memory.cpp"14#include "disassembler.cpp"15#include "serialization.cpp"16ArmDSP armdsp;1718void ArmDSP::Enter() { armdsp.enter(); }1920void ArmDSP::enter() {21//reset hold delay22while(bridge.reset) {23tick();24continue;25}2627//reset sequence delay28if(bridge.ready == false) {29tick(65536);30bridge.ready = true;31}3233while(true) {34if(scheduler.sync == Scheduler::SynchronizeMode::All) {35scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);36}3738if(exception) {39print("* ARM unknown instruction\n");40print("\n", disassemble_registers());41print("\n", disassemble_opcode(pipeline.instruction.address), "\n");42while(true) tick(frequency);43}4445if(pipeline.reload) {46pipeline.reload = false;47pipeline.prefetch.address = r[15];48pipeline.prefetch.opcode = bus_readword(r[15]);49r[15].step();50}5152pipeline.instruction = pipeline.prefetch;53pipeline.prefetch.address = r[15];54pipeline.prefetch.opcode = bus_readword(r[15]);55r[15].step();5657//todo: bus_readword() calls tick(); so we need to prefetch this as well58//pipeline.mdr.address = r[15];59//pipeline.mdr.opcode = bus_readword(r[15]);6061//if(pipeline.instruction.address == 0x00000208) trace = 1;62if(trace) {63print("\n", disassemble_registers(), "\n");64print(disassemble_opcode(pipeline.instruction.address), "\n");65usleep(200000);66}67//trace = 0;6869instruction = pipeline.instruction.opcode;70if(!condition()) continue;71if((instruction & 0x0fc000f0) == 0x00000090) { op_multiply(); continue; }72if((instruction & 0x0fb000f0) == 0x01000000) { op_move_to_register_from_status_register(); continue; }73if((instruction & 0x0fb000f0) == 0x01200000) { op_move_to_status_register_from_register(); continue; }74if((instruction & 0x0e000010) == 0x00000000) { op_data_immediate_shift(); continue; }75if((instruction & 0x0e000090) == 0x00000010) { op_data_register_shift(); continue; }76if((instruction & 0x0e000000) == 0x02000000) { op_data_immediate(); continue; }77if((instruction & 0x0e000000) == 0x04000000) { op_move_immediate_offset(); continue; }78if((instruction & 0x0e000010) == 0x06000000) { op_move_register_offset(); continue; }79if((instruction & 0x0e000000) == 0x08000000) { op_move_multiple(); continue; }80if((instruction & 0x0e000000) == 0x0a000000) { op_branch(); continue; }8182exception = true;83}84}8586void ArmDSP::tick(unsigned clocks) {87if(bridge.timer && --bridge.timer == 0) bridge.busy = false;8889step(clocks);90synchronize_cpu();91}9293//MMIO: $00-3f|80-bf:3800-38ff94//3800-3807 mirrored throughout95//a0 ignored9697uint8 ArmDSP::mmio_read(unsigned addr) {98cpu.synchronize_coprocessors();99100uint8 data = 0x00;101addr &= 0xff06;102103if(addr == 0x3800) {104if(bridge.armtocpu.ready) {105bridge.armtocpu.ready = false;106data = bridge.armtocpu.data;107}108}109110if(addr == 0x3802) {111bridge.timer = 0;112bridge.busy = false;113}114115if(addr == 0x3804) {116data = bridge.status();117}118119return data;120}121122void ArmDSP::mmio_write(unsigned addr, uint8 data) {123cpu.synchronize_coprocessors();124125addr &= 0xff06;126127if(addr == 0x3802) {128bridge.cputoarm.ready = true;129bridge.cputoarm.data = data;130}131132if(addr == 0x3804) {133data &= 1;134if(!bridge.reset && data) arm_reset();135bridge.reset = data;136}137}138139void ArmDSP::init() {140}141142void ArmDSP::load() {143}144145void ArmDSP::unload() {146}147148void ArmDSP::power() {149for(unsigned n = 0; n < 16 * 1024; n++) programRAM[n] = random(0x00);150}151152void ArmDSP::reset() {153bridge.reset = false;154arm_reset();155}156157void ArmDSP::arm_reset() {158create(ArmDSP::Enter, 21477272);159160bridge.ready = false;161bridge.timer = 0;162bridge.timerlatch = 0;163bridge.busy = false;164bridge.cputoarm.ready = false;165bridge.armtocpu.ready = false;166167for(auto &rd : r) rd = 0;168shiftercarry = 0;169exception = 0;170pipeline.reload = true;171r[15].write = [&] { pipeline.reload = true; };172}173174ArmDSP::ArmDSP() {175firmware = new uint8[160 * 1024]();176programRAM = new uint8[16 * 1024]();177178programROM = &firmware[0];179dataROM = &firmware[128 * 1024];180}181182ArmDSP::~ArmDSP() {183delete[] firmware;184delete[] programRAM;185}186187}188189190