Z80 软件延迟
Z80 Software Delay
我正在尝试创建软件延迟。这是我正在做的示例程序:
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。知道我该如何计算吗?谢谢。 P.S 这里是手册中的递减(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
如果 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
我有点像个优化狂,所以这是我使用我最熟悉的语法(来自 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
这样的循环。这在功耗方面节省了很多。
我正在尝试创建软件延迟。这是我正在做的示例程序:
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。知道我该如何计算吗?谢谢。 P.S 这里是手册中的递减(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
如果 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
我有点像个优化狂,所以这是我使用我最熟悉的语法(来自 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
这样的循环。这在功耗方面节省了很多。