我是 ASM 的新手,我试图锻炼如何为以下代码创建延迟:
org $1000
loop: inc $d021
jmp loop
我猜评论很清楚。
每帧更改颜色的代码示例(1/50 秒)
sei ; enable interrupts
loop1: lda #$fb ; wait for vertical retrace
loop2: cmp $d012 ; until it reaches 251th raster line ($fb)
bne loop2 ; which is out of the inner screen area
inc $d021 ; increase background color
lda $d012 ; make sure we reached
loop3: cmp $d012 ; the next raster line so next time we
beq loop3 ; should catch the same line next frame
jmp loop1 ; jump to main loop
每秒更改颜色的代码示例
counter = $fa ; a zeropage address to be used as a counter
lda #$00 ; reset
sta counter ; counter
sei ; enable interrupts
loop1: lda #$fb ; wait for vertical retrace
loop2: cmp $d012 ; until it reaches 251th raster line ($fb)
bne loop2 ; which is out of the inner screen area
inc counter ; increase frame counter
lda counter ; check if counter
cmp #$32 ; reached 50
bne out ; if not, pass the color changing routine
lda #$00 ; reset
sta counter ; counter
inc $d021 ; increase background color
out:
lda $d012 ; make sure we reached
loop3: cmp $d012 ; the next raster line so next time we
beq loop3 ; should catch the same line next frame
jmp loop1 ; jump to main loop
例如:
loop: ldx $d021
inx
stx $d021
cpx #100
bne loop
这个怎么样?这应该会改变背景,等待 4 秒,然后再改变它。永远重复。
请注意,您可以将秒数更改为 0 到 255 之间的任何值。
这适用于NTSC
机器,但您可以将其更改60
为50
for PAL
。
main:
inc $D021
ldx #4 // Wait 4 seconds
loop1:
ldy #60
loop2:
waitvb:
bit $D011
bpl waitvb
waitvb2:
bit $D011
bmi waitvb2
dey
bne loop2
dex
bne loop1
jmp main
如果您可以确保代码不跨越页面边界,一个有用的方法是在 RAM 中的某处有一对字节,该字节将保存计算的跳转地址,并使用间接跳转到如下内容:
TableStart:
cmp #$C9
cmp #$C9
cmp #$C9
cmp #$C9
cmp #$C9
...
TableEnd:
nop
如果跳转向量指向 tableEnd,则代码将在七个周期后到达 NOP 之后的指令。如果它指向前一个字节,则为八个周期。提前两个字节,九个周期等。设置跳转向量可能需要一点时间,但延迟本身可以从七个周期平滑地调整到单周期增量中的任何更高值。标志将被丢弃,但不会影响任何寄存器。