我正在尝试向使用Zilog eZ80 CPU的TI-84 Plus CE-T计算器的VRAM写入两个字节(颜色值)。 VRAM从0xD40000开始,长度为0x25800字节。计算器具有一个称为MemSet
的内置系统调用,该系统调用用一个字节填充了一块内存,但是我希望它在两个不同的值之间交替并将它们存储在内存中。我尝试使用以下代码:
#include "includes\ti84pce.inc"
.assume ADL=1
.org userMem-2
.db tExtTok,tAsm84CeCmp
call _homeup
call _ClrScrnFull
ld hl,13893632 ; = D40000, vram start
ld bc,153600 ; = 025800, count/vram length
j1:
ld (hl),31 ; set first byte
inc hl
dec bc
jr z,j2 ; jump to end if count==0
ld (hl),0 ; set second byte
inc hl
dec bc
jr z,j2 ; jump to end if count==0
jp j1 ; loop
j2:
call _GetKey
call _ClrScrnFull
ret
我希望它将31 00 31 00 31 00 ...输出到从0xD40000开始的内存中,但是相反,它似乎只更改第一个字节,然后跳到末尾。有想法该怎么解决这个吗?
最佳答案
tum_'s答案的变化比dec bc
快于零测试机制,从而实现了循环。
LD SP,$D65800 ; <end of VRAM>: 0xD40000+0x25800
LD BC,$004B ; 0x4B many times (in C) the 256x inner loop (B=0)
; that results into 0x4B00 repeats of loop, which when 8 bytes per loop
; are set makes the total 0x25800 bytes (VRAM size)
; (if you would unroll it for more than 8 bytes, it will be a bit more
; tricky to calculate the initial BC to get correct amount of looping)
; (not that much tricky, just a tiny bit)
LD HL,31 ; H <- 0, L <- 31
.L1
PUSH HL ; (SP – 2) <- L, (SP – 1) <- H, SP <- SP - 2
PUSH HL ; set 8 bytes in each iteration
PUSH HL
PUSH HL
DJNZ .L1 ; loop by B value (in this example it starts as 0 => 256x loop)
DEC C ; loop by C ("outer" counter)
JR NZ,.L1 ; btw JP is faster than JR on original Z80, but not on eZ80
.END
(顺便说一句,我从来没有做过eZ80编程,也没有在调试器中验证这一点,所以这有点假设...实际上是在考虑,eZ80上的
push
不是32位吗?hl
的初始化应该是ld hl,$001F001F
用单个push
设置四个字节,并且循环的内部应该只有两个push hl
)(但是我做了Z80编程的 ton ,所以这就是为什么我什至不愿对此主题发表评论,即使我以前从未见过eZ80代码)
编辑:事实证明eZ80推送是24位的,即上面的代码将产生错误的结果。它当然可以很容易地解决(因为问题是实现细节,而不是原则),例如:
LD SP,$D65800 ; <end of VRAM>: 0xD40000+0x25800
LD BC,$0014 ; 0x14 many times (in C) the 256x inner loop (B=0)
; that results into 0x1400 repeats of loop, which with 30 bytes per
; loop set makes the total 0x25800 bytes (VRAM size)
LD HL,$1F001F ; will set bytes 31, 0, 31
LD DE,$001F00 ; will set bytes 0, 31, 0
.L1
PUSH DE
PUSH HL
; here SP = SP-6, and 6 bytes 31, 0, 31, 0, 31, 0 were set
PUSH DE
PUSH HL
PUSH DE
PUSH HL
PUSH DE
PUSH HL
PUSH DE
PUSH HL ; unrolled 5 times to set 30 bytes in total
DJNZ .L1 ; loop by B value (in this example it starts as 0 => 256x loop)
DEC C ; loop by C ("outer" counter)
JR NZ,.L1
关于assembly - 如何在Z80 ASM中重复将两个字节写入RAM block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57483503/