Hello, I am starting with the ti84 pce, not really much experience in z80 assembly, but understand the basics.

I wrote a simple ball bouncing program to get myself started. Writing/Erasing the sprite directly on the vRAM is pretty fast (both in 16bpp and 8bpp) but results in some flickering as the ball moves across the screen. I then tried double buffering (with 8bpp) but I am still getting some flickering and much reduced speed. I was wondering if there is any good tutorial/info on changing the LCD base instead of copying the whole buffer that seems to slow down the code.

I think Mateo posted something on that but a more detailed explanation will be appreciated.

Thanks in advance!
The CE LCD has a flag that is set when a new address is able to be loaded into the LCD base address. This is enabled using the following code:


Code:
   currDrawBuffer          equ 0e30014h

   ; ... other initialization code

   ld   hl,currDrawBuffer
   ld   de,vram+(320*240)
   ld   (hl),de
   ld   l,mpLcdIcr&$ff
   ld   (hl),4                       ; allow interrupts status for double buffering


Then when you want to swap the pointers, simply call this function:


Code:
SwapDraw:
; Safely swap the vram buffer pointers for double buffered output
   ld   hl,vram
   ld   de,(mpLcdBase)
   or   a,a
   sbc   hl,de
   add   hl,de
   jr   nz,+_
   ld   hl,vram+(320*240)
_:   
   ld   (currDrawBuffer),de          ; set up the new buffer location
   ld   (mpLcdBase),hl               ; set the new pointer location
   ld   hl,mpLcdIcr
   set   2,(hl)                      ; clear the previous intrpt set
   ld   l,mpLcdRis&$ff
_:   
   bit   2,(hl)                      ; wait until the interrupt triggers
   jr   z,-_
   ret


currDrawBuffer is used to specify which buffer you are drawing to, so use it as the base drawing offset Smile
Thanks a lot Mateo!

I was wondering if the code for enabling the interrupt should be (in the first code fragment of your reply)
ld l, mpLcdImsc&$ff
instead of
ld l, mpLcdIcr&$ff

Anyway, I see that clearing & waiting for the interrupt makes the code way slower. Was that your experience as well?

I am currently swapping the two buffers by changing the mpLcdBase manually after finishing drawing in the buffer that is currently not displaying. This results in a pretty fast code with minimal visual artefacts.

It may be of course that I am missing something Smile
Hello,

Based on Mateo's comment above, my current implementation for page-flipping is shown below (pseudocode with some Z80 assembly)


Code:

Main:   
      initialisation code here
      
      set 8bpp & Palette
      call setup_bufs   

Loop:   
      draw in back buffer as required      
      call swap_bufs
      jr to Loop unless done
      
      call restore_buf       
      ret


setup_bufs:      
            ld hl, vRam
            ld (mpLcdBase), hl
            ld hl, vRam+76800
            ld (backbufer), hl
            ld hl, mpLcdImsc      ; set interrupt
            ld (hl), 4
            ret


swap_bufs:      
            ld hl, (backbuffer)
            ld de, (mpLcdBase)
            ld (backbuffer), de
            ld (mpLcdBase), hl
clear_int:      
            ld hl, mpLcdIcr
            set 2, (hl)            ; clear interrupt
            ld hl, mpLcdRis
wait_int:      
            bit 2, (hl)
            jr z, wait_int         ; wait for interrupt
            ret


restore_buf:
            ld hl, vRam
            ld  (mpLcdBase), hl
            call set_16bpp
            ret



Please feel free to comment and improve!

Thanks

PS: An interesting article on double-buffering and page-flipping can be found at https://docs.oracle.com/javase/tutorial/extra/fullscreen/doublebuf.html
I probably dont know what im talking about, but i am pretty sure the CE is ez80, not z80 (dont know if that changes anything)
Yep, that's basically it, although don't forget to erase the buffer before drawing to it Razz

(Also, I prefer writing numbers as a logical expression. 76800 doesn't make sense to a beginner, while 320*240 does Smile)
Thanks guys.

I agree Pienman7373, should had put down eZ80, not Z80 in my post

Thanks for the tip PT, 320*240 clearly makes more sense than 76800. Also I do erase the back buffer, but you are right I should had clarified this in the pseudocode above.

Smile
Also, in many programs, you see like LCD_WIDTH * LCD_HEIGHT which makes even more sense Wink
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement