You set 135, in BIN representation it is 0b10000111
Where you set wrong control bit and address.
PS: Also check my sample, it working like a charm, without problems you talking about.
You set 135, in BIN representation it is 0b10000111
Where you set wrong control bit and address.
I set the control bit 128 for VDP register write and the 7 for register 7, and then the border color changes.
The demo should loop forever, changing the border color. But then it crashes! Out of nothing, suddenly it crashes! It shows that the issue exists.
Because the bios interrupt code has slipped in between the two OUT &h99. And what happens afterwards is not vdp(7) = i but things like vdp(i) = 135.
Oh funny, I didn't know that the VDP writes to a register instead of finishing setting the VRAM address if you set the control bit 128.
If I remember correctly SET PAGE synchronizes to the next VBLANK so in this example there won't be an interrupt between the two OUT's (but it might depend on which machine is used!).
similar problem happens when you set psg tone register. Because it's more than 8 bit in length you need two 8 bits out port.
So there is a small period when the psg can output not one want.
I've found that the sega md witrh the 68000 the VDP I/O is performed by loading an entire 16 bit value in the processor register, so i expect that similar issue do not exists on sega
hit9918, start reading manual already please.
If you want write to R7, why you set addres register first?
If you set address, why you not write data?
PS: Again, check my code above, its working in stock MSX Basic without problems.
Reading of the status register resets the value latched in a write pair to 99H. Therefore if this happens between a pair of values output to 99H, the write will fail. Because the BIOS interrupt handler reads the status register, if this interrupt occurs in an inconvenient place then this can have bad consequences.
For this reason assembly code always disables interrupts while writing to port 99H. Otherwise changes to the program code (which alter the timing of execution), or the BIOS interrupt handler (due to e.g. machine differences or a music replayer), can easily break it. In MSX-BASIC you can not disable interrupts, so if it works for you then this is due to pure timing coincidence, and very fragile.
Luckily, you can just use VPOKE instead. If that is changed, it would make it a great example.
Grauw, I know it better than others, thank you.
Just look on his example, and try understand what he doing.
I’m commenting specifically about this part:
80 VDP(15)=4:OUT&H99,0:OUT&H99,64 ' Set VRAM Addr &h10000 100 VDP(15)=4:OUT&H99,0:OUT&H99,64+12 ' Set VRAM Addr &h10C00
The OUTs are problematic. Just add a little wait between them to expose the timing problem:
80 VDP(15)=4:OUT&H99,0:FORW=0TO100:NEXT:OUT&H99,64 ' Set VRAM Addr &h10000 100 VDP(15)=4:OUT&H99,0:FORW=0TO100:NEXT:OUT&H99,64+12 ' Set VRAM Addr &h10C00
It fails because this wait loop guarantees an interrupt occurs between the OUTs.
However even without the wait loop in-between, the interrupt can still occur. This I can show by making only this single change (line 80 is changed back to the original example):
100 VDP(15)=4:FORW=0TO8:NEXT:OUT&H99,0:OUT&H99,64+12 ' Set VRAM Addr &h10C00
When emulating a Panasonic FS-A1WX in openMSX, this will break. All it does is add a little time before the OUTs.
Here I’m specifying the exact execution environment because timing is specific. On other machines just try to vary the length of the loop a few times and you should hit the issue as well. E.g. when emulating a Sony HB-F1XD in openMSX I need to use FORW=0TO1:NEXT
.
This is why even if it’s working for you, that is not enough to show correctness. Because the problem is sensitive to timing, even if it does not expose itself to you on your machine, it is still there and can make the program break seemingly randomly.
Here I’m specifying the exact execution environment because timing is specific. On other machines just try to vary the length of the loop a few times and you should hit the issue as well. E.g. when emulating a Sony HB-F1XD in openMSX I need to use FORW=0TO1:NEXT
.
In fact, if I run your example without modifications on a Philips NMS 8245 in openMSX, it does not work.
1. Topic starter did not indicate what Philips uses.
2. My example works on my machine.
3. If for someone it does not work, then this is another reason to sort out the issue for him personally.
PS: This was only a VISUAL example of setting tables. Why make some kind of fiasco out of this?
And yes, someone who doubt, will use TIME variable to prepare addresses in VRAM. Or even status reg (-2), for controll interrupt.
Also you show another sample, than he before.