mirror of https://github.com/bsnes-emu/bsnes.git
![]() blargg and I sat around for a good 8+ hours today hacking away at the S-SMP Pandora's Box: the TEST register. What better way to spend Pi Day, right? We came up with the following tests: http://byuusan.kuro-hitsuji.net/blargg_2010-03-14.zip First, controller_strobebehavior.smc improves emulation of $4016. When the joypad strobe latch = 1, reading $4016 returns the current value of the B button. As in, you can keep reading it over and over. It won't increment the shift register, and it will keep telling you the actual current state of the button. This is very much like the NES behavior. One more TODO in the S-CPU code taken care of. Next, all kinds of S-SMP TEST register improvements. Turns out d7-d6 alone controls the actual S-SMP clock rate. 0 = 100%, 1 = 50%, 2 = 0% (locks the S-SMP forever), 3 = 10%. Wild stuff, you can actually permanently slow the S-SMP relative to the S-CPU. d6-d5 is a timer tick control, but it actually uses d7-d4 overlaid. The algorithm is fucking nuts, and is really my only contribution to today's work. The rest was all blargg's research. We had d2 wrong, it's not MMIO disable, it's RAM disable. As in, disable read and write. Returns 0x5a on regular SNES, 0xff on mini- SNES. 0x5a is not the S-SMP MDR. IPLROM is still readable when RAM is disabled. d1 was correct, just RAM write disable. Can still write to $f8 and $f9, of course. But it won't go through to RAM. d3 and d0, we are still a little unsure on. The T0-T2 timers seem to have a low and high phase, and if you strobe them you can force ticks of stage 2 to happen, and you can disable them in such a manner than stage 2 never ticks at all. blargg is still uncovering all sorts of crazy things in $xB mode, so emulation of these two bits is not perfect. But overall we are leaps and bounds further now toward complete emulation. I'd say we went from 10% to 80% with today's work. But we'll have to see how deep the rabbit hole goes on d3+d0 first. Current register map: case 0xf0: { //TEST if(regs.p.p) break; //writes only valid when P flag is clear status.clock_speed = (data >> 6) & 3; //100%, 50%, 0%, 10% status.timer_speed = (data >> 4) & 3; //100%, ... status.timers_enabled = data & 0x08; status.ram_disabled = data & 0x04; status.ram_writable = data & 0x02; status.timers_disabled = data & 0x01; unsigned base = 1 + (1 << status.clock_speed); unsigned step = base + (15 >> (3 - status.timer_speed)); status.timer_step = 1.0 / (3.0 / step); t0.sync_stage1(); t1.sync_stage1(); t2.sync_stage1(); } break; Fairly confident that no emulator prior to this WIP could pass any of blargg's tests, so this is all brand new information. Fun stuff :) |
||
---|---|---|
src | ||
bsnes.exe |