Yesterday I found out why the parallax intro in Blade Lords doesn't run correctly in openMSX and blueMSX. The reason is quite simple but I need help to find out what the real problem is.
The parallax intro code that fails is running with disabled interrupts and waiting for the HBLANK status bit to be set. When set, it outs new data to the VDP to make the nice effect. The problem is that the intro expects to read the value 0x20 from SR2 once per scan line (0x20 is the HBLANK status bit) but in the emus the bit is read twice per scan line in some cases.
The code is really simple:
ld e,$20
.Loop:
in a,[$99] ; 12
and e ; 5
jr z,.Loop ; 8/13
outi ; 18
jp nz,.Loop ; 11
As you see, the first half loops while bit 5 in SR2 is cleared (i.e. during the display area) and then the loop breaks when the bit is set (i.e. on the border). Then the new value is out'ed and it continues with the next scan line.
Now, the issue here is that the time between bit 6 is read as one and the next read is 54 cpu cycles. In the emus, the HBLANK is set from the display area ends until it starts on the next scan line, This means its set 1368-1024=344 vdp cycles and cleared otherwise.
This means that the HBLANK bit is set for 344/6 = 57 cpu cycles. So it is a small chance that the parallax intro reads the status bit and it is set twice per scan line, which screws up everything.
Me and Quibus did some testing yesterday and was able to write a short test program to test this behavior and we were able to reproduce it. If you're interested, the test program is at
www.bluemsx.com/demos/hblank.zip. The zip contains a dsk and an the source code. The program is quite stupid, if you run the test, it will hang on real MSXes and return to basic in the emus. So if it returns to basic, it means that the test failed. If it hangs it's good
So, now you know why the bug happens in the emus and now I need some ideas why.
I can think of three different reasons:
- The hblank period in the emus are too long (we have other tests that show that the ratio of the HBLANK bit being set/cleared is 1024/1368, i.e. cleared during display area)
- The HBLANK bit is cleared when read (we have other tests that show that this is not the case)
- Some z80 instructions have bad timing in the emus (not that likely. I checked the timing of the involved instructions and they match the data cheet)
So none of my three suggestions are really good but I'd really appreciate if you could comment these and if you have other suggestions.