0

我只是不知道如何在 gbz80“汇编”中编写一个简单的睡眠/延迟周期

我必须承认我的 gbz80 知识几乎没有,但我在想类似的事情:

ld bc,XXX
call WaitCyclEx

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

其背后的想法是,通过修改“bc”寄存器值,一旦调用“WaitCyclEx”函数,该值将被加载到寄存器 FF05,它是定时器计数器,也是 gbz80 的唯一计数器。然后该值递减并且该函数被重复直到该值达到零。

要知道循环是否正常工作,我添加了一些这样的声音......

;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

根据 vasm 的说法,一切正常......但我只听到一种声音而不是两种声音......

考虑到处理器的 4Mhz,重复循环 65535 次至少应该让我有时间注意到两个声音之间的轻微延迟......

任何帮助将不胜感激

4

1 回答 1

2

你有一些问题,所以我会提供一些工作代码,希望你可以用它来做你想做的事。

与它们的 8 位对应物不同,16 位递增和递减不会影响z标志。有几种方法可以解决这个问题:

    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

通常,您可能对 16 位循环感兴趣,而不仅仅是延迟。对于延迟,大小优化是合适的,但一般循环可能需要速度优化。这是一个以 BC 作为计数器的循环,但交换了 B 和 C 的角色以利用djnz内部循环:

    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

我不记得 GB Z80 是否有cpiandcpd指令,但如果有,您可以使用这些指令来增加/减少 HL并将BC 用作循环计数器:

    ld bc,XXXX
loop:
    ; do stuff
    cpi
    jp pe,loop
    ret
于 2022-02-03T13:17:11.903 回答