Path: blob/master/libsnes/bsnes/snes/smp/memory/memory.cpp
2 views
#ifdef SMP_CPP12alwaysinline uint8 SMP::ram_read(uint16 addr) {3if(addr >= 0xffc0 && status.iplrom_enable) return iplrom[addr & 0x3f];4if(status.ram_disable) return 0x5a; //0xff on mini-SNES5return apuram[addr];6}78alwaysinline void SMP::ram_write(uint16 addr, uint8 data) {9//writes to $ffc0-$ffff always go to apuram, even if the iplrom is enabled10if(status.ram_writable && !status.ram_disable) apuram[addr] = data;11}1213uint8 SMP::port_read(uint2 port) const {14return apuram[0xf4 + port];15}1617void SMP::port_write(uint2 port, uint8 data) {18apuram[0xf4 + port] = data;19}2021uint8 SMP::op_busread(uint16 addr) {22unsigned result;2324switch(addr) {25case 0xf0: //TEST -- write-only register26return 0x00;2728case 0xf1: //CONTROL -- write-only register29return 0x00;3031case 0xf2: //DSPADDR32return status.dsp_addr;3334case 0xf3: //DSPDATA35//0x80-0xff are read-only mirrors of 0x00-0x7f36return dsp.read(status.dsp_addr & 0x7f);3738case 0xf4: //CPUIO039case 0xf5: //CPUIO140case 0xf6: //CPUIO241case 0xf7: //CPUIO342synchronize_cpu_force();43return cpu.port_read(addr);4445case 0xf8: //RAM046return status.ram00f8;4748case 0xf9: //RAM149return status.ram00f9;5051case 0xfa: //T0TARGET52case 0xfb: //T1TARGET53case 0xfc: //T2TARGET -- write-only registers54return 0x00;5556case 0xfd: //T0OUT -- 4-bit counter value57result = timer0.stage3_ticks;58timer0.stage3_ticks = 0;59return result;6061case 0xfe: //T1OUT -- 4-bit counter value62result = timer1.stage3_ticks;63timer1.stage3_ticks = 0;64return result;6566case 0xff: //T2OUT -- 4-bit counter value67result = timer2.stage3_ticks;68timer2.stage3_ticks = 0;69return result;70}7172cdlInfo.set(eCDLog_AddrType_APURAM, addr);73return ram_read(addr);74}7576void SMP::op_buswrite(uint16 addr, uint8 data) {77switch(addr) {78case 0xf0: //TEST79if(regs.p.p) break; //writes only valid when P flag is clear8081status.clock_speed = (data >> 6) & 3;82status.timer_speed = (data >> 4) & 3;83status.timers_enable = data & 0x08;84status.ram_disable = data & 0x04;85status.ram_writable = data & 0x02;86status.timers_disable = data & 0x01;8788status.timer_step = (1 << status.clock_speed) + (2 << status.timer_speed);8990timer0.synchronize_stage1();91timer1.synchronize_stage1();92timer2.synchronize_stage1();93break;9495case 0xf1: //CONTROL96status.iplrom_enable = data & 0x80;9798if(data & 0x30) {99//one-time clearing of APU port read registers,100//emulated by simulating CPU writes of 0x00101synchronize_cpu_force();102if(data & 0x20) {103cpu.port_write(2, 0x00);104cpu.port_write(3, 0x00);105}106if(data & 0x10) {107cpu.port_write(0, 0x00);108cpu.port_write(1, 0x00);109}110}111112//0->1 transistion resets timers113if(timer2.enable == false && (data & 0x04)) {114timer2.stage2_ticks = 0;115timer2.stage3_ticks = 0;116}117timer2.enable = data & 0x04;118119if(timer1.enable == false && (data & 0x02)) {120timer1.stage2_ticks = 0;121timer1.stage3_ticks = 0;122}123timer1.enable = data & 0x02;124125if(timer0.enable == false && (data & 0x01)) {126timer0.stage2_ticks = 0;127timer0.stage3_ticks = 0;128}129timer0.enable = data & 0x01;130break;131132case 0xf2: //DSPADDR133status.dsp_addr = data;134break;135136case 0xf3: //DSPDATA137if(status.dsp_addr & 0x80) break; //0x80-0xff are read-only mirrors of 0x00-0x7f138dsp.write(status.dsp_addr & 0x7f, data);139break;140141case 0xf4: //CPUIO0142case 0xf5: //CPUIO1143case 0xf6: //CPUIO2144case 0xf7: //CPUIO3145synchronize_cpu_force();146port_write(addr, data);147break;148149case 0xf8: //RAM0150status.ram00f8 = data;151break;152153case 0xf9: //RAM1154status.ram00f9 = data;155break;156157case 0xfa: //T0TARGET158timer0.target = data;159break;160161case 0xfb: //T1TARGET162timer1.target = data;163break;164165case 0xfc: //T2TARGET166timer2.target = data;167break;168169case 0xfd: //T0OUT170case 0xfe: //T1OUT171case 0xff: //T2OUT -- read-only registers172break;173}174175ram_write(addr, data); //all writes, even to MMIO registers, appear on bus176}177178void SMP::op_io() {179add_clocks(24);180cycle_edge();181}182183uint8 SMP::op_read(uint16 addr, eCDLog_Flags flags) {184debugger.op_read(addr);185186add_clocks(12);187cdlInfo.currFlags = flags;188uint8 r = op_busread(addr);189add_clocks(12);190cycle_edge();191return r;192}193194void SMP::op_write(uint16 addr, uint8 data) {195debugger.op_write(addr, data);196197add_clocks(24);198op_buswrite(addr, data);199cycle_edge();200}201202#endif203204205