Forums

Sega Master System / Mark III / Game Gear
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew

View topic - Correct way of using the VDP

Reply to topic
Author Message
  • Joined: 15 Jul 2010
  • Posts: 15
  • Location: Essen, Germany
Reply with quote
Correct way of using the VDP
Post 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?
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14745
  • Location: London
Reply with quote
Post 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.
  View user's profile Send private message Visit poster's website
  • Joined: 15 Jul 2010
  • Posts: 15
  • Location: Essen, Germany
Reply with quote
Post 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. ;)
  View user's profile Send private message
  • Joined: 28 Sep 1999
  • Posts: 1197
Reply with quote
Post 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. :)
  View user's profile Send private message Visit poster's website
Reply to topic



Back to the top of this page

Back to SMS Power!