- Joined: 15 Jul 2010
- Posts: 15
- Location: Essen, Germany
|
Correct way of using the VDP
Posted: Thu Jul 15, 2010 11:09 pm
|
I have a little problem that i sometimes miss chars when printing on the real machine.
Here is my code that gets called for outputting a single char:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Outputs a single character
;;; Register input:
;;; a = Char to output
WriteSingleChar:
push af
Macro_SetVDPInUse ;This is for the IRQ so that it wont disturb me.
ld a, (Var_ScreenPointerLo) ;Set somewhere else, this points to the screen.
out ($bf),a
nop
nop
ld a, (Var_ScreenPointerHi)
or $40 ; Set write bit
out ($bf),a
nop
nop
pop af
out ($be),a
nop
nop
Macro_ClearVDPInUse
I cant add NOPs all over the place so, how can i check if the VDP is ready for the next byte or if its puffer is full so that i pause?
|
- Site Admin
- Joined: 19 Oct 1999
- Posts: 14770
- Location: London
|
Posted: Fri Jul 16, 2010 9:02 am
|
You can't poll the VDP to see if it's ready to let you access it.
If it's during the active display then you need to have bigger gaps, the official docs suggest 28 or 29 clock cycles are needed. If you include the out opcodes themselves, your code seems to have gaps of 39 and 29 cycles, but if you don't then the second one is too small.
The "standard" delay is to push ix; pop ix, but that may be overkill.
It's better to do all your VDP work in the VBlank if at all possible.
|
- Joined: 15 Jul 2010
- Posts: 15
- Location: Essen, Germany
|
Posted: Fri Jul 16, 2010 10:58 am
|
Thanks.
Quote Maxim wrote:
It's better to do all your VDP work in the VBlank if at all possible.
That timing issue "should" be handled, at the moment i am having missing chars with some HEX output routine so that i can look at values inside the SMSs memory.
Helper_Debug256Bytes:
ld a, $00
ld b, $00
call SetCursorPos
;Amount
ld bc, $00ff
- ld a,(hl)
push bc
push hl
ld de, Var_TempSpace
call ByteToHexstring
ld hl, Var_TempSpace
call WriteStringHL
pop hl
pop bc
inc hl
dec bc
ld a,b
or c
jr nz, -
ret
And WriteStringHL:
WriteStringHL:
push af
- ld a,(hl) ;Read char
cp $00 ;End of string?
jr z, WriteStringHLEnd
cp $0a ;Newline char?
jr nz, WriteStringHL_NoNewline
call Newline
jr WriteStringHLContinue
WriteStringHL_NoNewline:
call WriteSingleChar
WriteStringHLContinue:
inc hl
jr -
WriteStringHLEnd:
pop af
ret
Ill try your idea with the PUSH and POP and remove those NOPs.
BTW: I hope my code doesnt cry "my programmer comes from 6502 land" too much. ;)
|
- Joined: 28 Sep 1999
- Posts: 1198
|
Posted: Sat Jul 17, 2010 5:41 am
|
It looks like this function is doing a lot of work. If it takes more time than VBlank allows, you can always turn the screen off first, then on again when your routine is done.
Otherwise you may have to split the VRAM writing across several frames. Some games keep a FIFO of data to write to VRAM that is filled during the active display, and a VBlank routine empties the FIFO to VRAM. There's always a tradeoff with memory use and performance, so no easy solution. :)
|