6

我正在尝试创建软件延迟。这是我正在做的示例程序:

    Address  Data   Opcode  Comment    
    1800      06    LD, B   Load register B with fix value
    1801      “ “           Fixed value
    1802      05    DEC, B  Decrement value in register B
    1803      C2    JP cc   Jump to 1802 if value is not 0
    1804      02    -       Address XX
    1805      18    -       Address XX

我的问题是如何计算加载到寄存器 B 所需的固定值,以便将值递减到 0 的过程需要 2 秒?

在我的手册中,运行指令的时间基于 4MHz CPU,但我使用的 Z80 CPU 的速度为 1.8MHz。知道如何计算吗?谢谢。PS这里是手册中的递减(DEC)和跳转(JP cc)说明:

Instruction    M Cycles    T states   4 MHz E.t
DEC r             1           4         1.00
JP cc             3       10 (4,3,3)    2.50
4

2 回答 2

4

如果 1.8MHz 的意思是 1,800,000 Hz,那么要获得 2 秒的延迟,您需要延迟 3,600,000 个 T 状态。您当前的延迟循环每次迭代需要 14 个 T 状态,这意味着您的初始值B必须是 3600000/14 == 257143,这显然不适合一个字节。

您可以使用 8 位寄存器指定的最大迭代次数是 256 次,要通过 256 次迭代达到 3,600,000 个 T 状态,每次迭代必须采用 14,062 个 T 状态。那是一个循环体。

如果我们使用 16 位计数器,事情就会变得更易于管理。在 65,536 次迭代中,我们每次迭代只需要 55 个 T 状态即可达到总共 3,600,000 个 T 状态。下面是一个例子:

    ; Clobbers A, B and C
    ld      bc,#0
1$:
    bit     #0,a    ; 8
    bit     #0,a    ; 8
    bit     #0,a    ; 8
    and     a,#255  ; 7
    dec     bc      ; 6
    ld      a,c     ; 4
    or      a,b     ; 4
    jp      nz,1$   ; 10, total = 55 states/iteration
    ; 65536 iterations * 55 states = 3604480 states = 2.00248 seconds
于 2015-03-21T17:28:56.213 回答
2

我有点喜欢优化,所以这里是我使用我最熟悉的语法(来自 TASM 汇编器和类似的):

Instruction   opcode    timing
ld bc,$EE9D   ;01EE9D   10cc
ex (sp),hl    ;E3       19*(256C+B)
ex (sp),hl    ;E3       19*(256C+B)
ex (sp),hl    ;E3       19*(256C+B)
ex (sp),hl    ;E3       19*(256C+B)
djnz $-4      ;10FA     13cc*(256C+B) - 5*C
dec c         ;0D       4*C
jr nz,$-7     ;20F7     12*C-5

此代码为 12 个字节和 3600002 个时钟周期。

编辑:似乎我的部分答案已经消失了!为了更好地回答您的问题,您的 Z80 可以在一秒钟内处理 1800000 个时钟周期,因此您需要两倍(3600000)。如果你把我的代码中给出的时间加起来,你会得到:

=10+(256C+B)(19*4+13)-5C+4C+12C-5

=5+(256C+B)89+11C

=5+22795C+89B

所以代码时序很大程度上取决于C。3600000/22795大约是157,所以我们用157(0x9D)初始化C。将其重新插入,我们得到 B 大约为 237.9775,因此我们将其四舍五入为 238 (0xEE)。将这些插入我们的最终时间为 3600002cc 或大约 2.000001 秒。这假设处理器运行在恰好 1.8MHz 的频率下,这是非常不可能的。

同样,如果您可以使用中断,请大致计算出每秒触发多少次,并使用类似halt \ djnz $-1 . 这在功耗方面节省了很多。

于 2015-03-22T04:16:31.097 回答