Autor
| BlueMSX direct VDP registers access
|
Metalion msx freak Mensajes: 235 | Publicado: Septiembre 03 2007, 10:58   |
Hi,
Is there known problems when accessing the VDP registers directly in BlueMSX ?
I get unexplained crashes in a ASM program I wrote.
I am accessing directly the VDP registers by making OUTs to the read/write ports.
|
|
dvik msx master Mensajes: 1311 | Publicado: Septiembre 03 2007, 11:15   |
That should work just fine. I'm always accessing the VDP registers directly in my programs.
|
|
Metalion msx freak Mensajes: 235 | Publicado: Septiembre 03 2007, 12:13   |
Thanks for your answer, although it means the problem lies in my code !
Here is the subroutine I wrote to dump data in the VDP registers 32 to 46, with the HL register containing the address of the data. Maybe someone will see the obvious thing I do not see !
Fast_VDP:
di
push af
push bc
push de
ld a,[6]
inc a
ld d,a
ld a,[7]
inc a
ld e,a
call Wait_VDP
ld c,e
ld a,32
out [c],a
ld a,080h+17
out [c],a
inc c
inc c
ld b,15
otir
pop de
pop bc
pop af
ei
ret
Wait_VDP:
ld c,e
ld a,2
out [c],a
ld a,080h+15
out [c],a
ld c,d
in a,[c]
and 1
jr nz,Wait_VDP
ret
|
|
SLotman msx professional Mensajes: 539 | Publicado: Septiembre 03 2007, 14:31   |
Actually, you better test this code on BrMSX with -vdptiming -- it's the only emulator which can accuratly emulates the vdptiming...
I myself just had some crazy problems when converting jungle hunt due to some otir/inir working on openmsx/bluemsx/etc and not on a real MSX1!
The only emulator which reproduced the error somehow was BRMSX, with -vdptiming! And fixing it on BrMSX also fixed it on the real MSX1
So if you're working with VDP and OUTI/OTIR (or INI/INIR) and you don't have a real MSX1 to test it, better get that old BRMSX... it could catch things other emulators can't! (Although MSX2 emulations is not that precise on it  )
And in the code, you could replace OTIR with a bunch of OUTIs, which would be faster (just remember to put 2 NOPs between them)
Also, what are those [6] and [7]? Are you reading from 0006h and 0007h? If not, you shouldn't have those [ ] there... |
|
jltursan msx professional Mensajes: 873 | Publicado: Septiembre 03 2007, 14:59   |
This code only works on MSX2 machines....
Anyway, what's that vdptiming feature?, I can't remember this option on BRMSX and I'm still not sure if it's in development now or is abandoned. Since what version is supported?. Do you know what kind of timing is being used?, 28 states I guess...
The [6] and [7] addresses are where the real VDP data and command ports are stored. This way a machine could use different ports than $98 and $99 and still be compatible by means the BIOS or safe programming.
|
|
manuel msx guru Mensajes: 3446 | Publicado: Septiembre 03 2007, 15:42   |
Slotman: if you happen to know the details, please tell them to us, so that the timing problems can be fixed in the other emulators.
Metalion: you should always test on a real machine to make sure something is working or not.
|
|
Metalion msx freak Mensajes: 235 | Publicado: Septiembre 03 2007, 16:41   |
Quote:
| Metalion: you should always test on a real machine to make sure something is working or not.
|
Yeah I know, but it is a lot easier to develop on a cross-assembler these days  (I am working on asMSX). Furthermore, my real machine (a Panasonic MSX2+) is in a box in my attic right now ... (I know, shame on me).
I feel that maybe I should explain the situation a little bit more : I am developing a MSX2 game, and the draft version was using the BLTVV or NWVRM subroutines in the BIOS subrom. Everything was working OK. I then switched to this direct VDP writing subroutine, without changing anything else (except what was needed to call this routine), and then it started crashing where it did not before.
The strange thing is that, when the crash occurs, I find through the debugger in BlueMSX that the MSX is actually lost somewhere in the BIOS. But if I set a breakpoint before running the program and do a step by step from there, everything seems to be going fine
Even more strange : I have a WAIT subroutine (your basic DEC HL stuff) called after that VDP subroutine and depending on the value in HL, the crash happens at different times ...
I verified my code (I was thinking of a wrong de-stacking during a RET) but I do not find the problem. So I thought of a behaviour of the emulator instead ... |
|
dvik msx master Mensajes: 1311 | Publicado: Septiembre 03 2007, 16:45   |
Its most likely a bug somewhere in your code. (quick and short answer  ) |
|
turbor msx freak Mensajes: 175 | Publicado: Septiembre 03 2007, 16:55   |
Something that is very important and that didn't show in your code:
If you are using the regular bios interrupt service routine, then you need to set vdp register 15 back to zero after you have transfered your data in the VDP registers 32 to 46. The bios will blindly assume that status register 0 is selected for reading so if you leave VDP #15 pointing to status register 2 then the bios will "crash" as you've describe yourself when debugging it.
Because register 0 is not selected the interrupt line doesn't get cleared so it will continuously going to perform an RST #38...again and again and again, without leaving CPU cycles for anything else...
It will take a while since after your routine a VDP interrupt must be generated first so if you step through your program it will seem if all goes well unless you step a few seconds but at 3.14 MHz that's quite some 'debug steps' away
|
|
ARTRAG msx master Mensajes: 1680 | Publicado: Septiembre 03 2007, 17:48   |
the bug is here:
Wait_VDP:
ld c,e
ld a,2
out [c],a
ld a,080h+15
out [c],a
ld c,d
in a,[c]
and 1
jr nz,Wait_VDP
ret
1) you do not need to set S2 each time
2) you need to disable interrupts while S2 is different from 0
3) you need to set to 0 S2 after having finished and before re-enabling the interrupts
Actually IMHO you can also skip all the reading of (6) and (7) location and use directly 99h and 98h
One of the advantages of a dead standard is that you know in advance ALL the HW that has been produced and owned by the users.
Using 99h and 98h no HW currently in use will fail, except few hundreds user of an exotic converter from msx1 to mxs2 (how many of them still active ? none ?).
Moreover (6) and (7) are equal also in the unique case above, so you can save the use of D or E
BTW try something like this:
Wait_VDP:
di
ld c,e
ld a,2
out [c],a
ld a,080h+15
out [c],a
ld c,d
loop:
in a,[c]
and 1
jr nz,loop
ld c,e
xor a
out [c],a
ld a,080h+15
out [c],a
ei
ret
|
|
Metalion msx freak Mensajes: 235 | Publicado: Septiembre 03 2007, 20:12   |
Quote:
| turbor:
you need to set vdp register 15 back to zero after you have transfered your data in the VDP registers
|
Quote:
| ARTRAG:
you need to set to 0 S2 after having finished and before re-enabling the interrupts
|
PROBLEM SOLVED !! 
Thanks a zillion for your help, I was about to throw my code in the garbage and go back to BIOS routines !!
Quote:
| ARTRAG
Actually IMHO you can also skip all the reading of (6) and (7) location and use directly 99h and 98h
|
Yes, you are probably right but it does not cost that much in code just to keep those exotic users happy 
And I can always modify them later if I feel they are slowing down the game.
Thanks for the tip, anyway !
Thanks again for everyone who helped me  |
|
|
|
|