gbz80 Sleep Cycle How To

129 Views Asked by At

I just can't figure out how to code a simple sleep/delay cycle in gbz80 "assembly"

I must confess that my gbz80 knowledge virtually none, but I was thinking something like:

ld bc,XXX
call WaitCyclEx

WaitCyclEx:
        ld bc,(&FF05)
        dec bc
        jr nz,WaitCyclEx
   ret

The idea behind that was that by modifying the "bc" register value, once called the "WaitCyclEx" function the value would have been loaded in register FF05, which is the timer counter, and the only counter of the gbz80. Then the value is decremented and the function gets repeated until the value reaches zero.

To know if the cycle is working I've added some sound like this...

;some noise
ld a,%00010101
ld (&FF10),a
ld a,%10010110
ld (&FF11),a
ld a,%01110011
ld (&FF12),a
ld a,187
ld (&FF13),a
ld a,%10000101
ld (&FF14),a
;delay
ld bc,65535 ; loading the "wait time" value
call WaitCyclEx
;some noise again
ld a,%00010101
ld (&FF10),a
ld a,%10010110
ld (&FF11),a
ld a,%01110011
ld (&FF12),a
ld a,187
ld (&FF13),a
ld a,%10000101
ld (&FF14),a

di
halt

According to vasm everything works... but I'm hearing only one sound instead of two...

Considering the 4Mhz of the processor, repeating the cycle 65535 times should at least give me the time to notice a slight delay between the two sounds...

Any help will be really appreciated

1

There are 1 best solutions below

1
Zeda On

You have a few issues, so I'll instead give some working code and hopefully you can use that to do what you want.

Unlike their 8-bit counterparts, the 16-bit increments and decrements don't affect the z flag. There are a few ways around this:

    ld bc,XXXX
WaitCyclEx:
    dec bc
    ld a,b
    or c      ; if B and C are 0, then ORed together they'll be zero, setting the Z flag
    jr nz,WaitCyclEx
   ret

Instead of just delays, you may be interested in 16-bit looping in general. For delays, size optimizations are appropriate, but general looping might warrant speed optimization. Here is a loop that has BC as a counter, but swaps the role of B and C to take advantage of djnz in the inner loop:

    ld bc,XXXX
    dec bc
    inc b
    inc c 
    ld a,b
    ld b,c
    ld c,a
loop:
    ; <do stuff>
    djnz loop
    dec c
    jr nz,loop
   ret

I can't remember if the GB Z80 has the cpi and cpd instructions, but if it does, you can use those to increment/decrement HL and use BC as a loop counter:

    ld bc,XXXX
loop:
    ; do stuff
    cpi
    jp pe,loop
    ret