使用6510组装商品64,我试图创造一个稳定的光栅效果。使用双IRQ原理,我在屏幕上画了一些光栅线。我垫与NOPs匹配63个周期的每一个正常扫描线,和23个周期为每坏线。我意识到,我需要设置一个特定的起跑线,以便将我的第8次迭代与一条坏线相匹配,但是无论我把第一行放在哪一行,或者我使用什么NOPs组合,我都不能正确地确定时间。我想要完整的线条,而不是“断裂”。有人能看出我做错了什么吗?代码是在踢汇编程序格式。这是一张截图:

.pc = $0801 "Basic upstart"
:BasicUpstart($8000)
.pc = $8000 "Program"
jsr $ff81
sei
lda #$35
sta $01
jsr setupInterrupts
cli
jmp *
setupInterrupts:
lda #<int1
ldy #>int1
sta $fffe
sty $ffff
lda #$01
sta $d01a
lda #$7f
sta $dc0d
sta $dd0d
lda $dc0d
lda $dd0d
lda #$1b
sta $d011
lda #$01
sta $d019
lda start
sta $d012
rts
start:
.byte 56
int1:
pha txa pha tya pha
:STABILIZE()
.for (var i=0; i<7; i++) {
inc $d020 // 6 cycles
inc $d021 // 6 cycles
nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop // 24*2=48 cycles
bit $ea // 3 cycles
// = 63 cycles
}
inc $d020 // 6 cycles
inc $d021 // 6 cycles
nop nop nop nop // 4*2=8 cycles
bit $ea // 3 cycles
// = 23 cycles (badline)
lda #$00
sta $d020
sta $d021
lda start
sta $d012
lda #<int1
ldy #>int1
sta $fffe
sty $ffff
lda #$01
sta $d019
pla tay pla tax pla
rti
.macro STABILIZE() {
lda #<nextRasterLineIRQ
sta $fffe
lda #>nextRasterLineIRQ
sta $ffff
inc $d012
lda #$01
sta $d019
tsx
cli
nop nop nop nop nop nop nop nop
nextRasterLineIRQ:
txs
ldx #$08
dex
bne *-1
bit $00
lda $d012
cmp $d012
beq *+2
}发布于 2014-09-01 22:10:10
据我所知,你的问题不是你的光栅条在闪烁(即你的光栅中断是稳定的),而是你在屏幕上画的光栅条的第二行不是完全红色的。
你的问题是台词不好。(见1)
当你稳定了你的光栅中断,与你张贴的代码,你的“实际代码”将开始运行在第4周期的光栅线$3A。
你的光栅条的第二行,你想要背景色和边框颜色是红色,是一条不好的线条。(这是光栅行的30亿美元。因为$D011 = $1B,这是一个坏行,因为$D011和$D012的下3位是相同的)
在这条糟糕的线路上,第一个INC (INC . $D020)设法运行,因此边框颜色变成红色。然后,第二个公司(公司$D021)开始运行,但国际中心接管之前,它完成,因此,您的公司的$D021是没有完成后,国际中心已将巴士送回。(这是43个周期后-即将背景颜色设置为红色被延迟了43个周期)。
您几乎得到了它,但是坏行位于与您的代码预期不同的栅格线上,您需要“推送几个周期”,以便两个INC在被国际中心中断之前都在坏行上执行。(如果您希望在国际中心接管之前执行这两个INC,那么在坏行的第4周期开始执行这两个INC就为时已晚了)
更新示例:
尝试替换代码的以下部分:
.for (var i=0; i<7; i++) {
inc $d020 // 6 cycles
inc $d021 // 6 cycles
nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop // 24*2=48 cycles
bit $ea // 3 cycles
// = 63 cycles
}
inc $d020 // 6 cycles
inc $d021 // 6 cycles
nop nop nop nop // 4*2=8 cycles
bit $ea // 3 cycles
// = 23 cycles (badline)在这方面:
// a delay to get to some cycle at the end of the raster-line, so we have time to execute both inc's on
// each successive raster-line - in particular on the badlines before the VIC takes over the bus.
.for (var i=0; i<28; i++) nop
// just for illustrative purposes - not cool code :)
.for (var i=0; i<8*6; i++) {
inc $d020 // 6 cycles
inc $d021 // 6 cycles
.if ([i & %111] == 0) {
// badline
nop nop nop nop // 4*2=8 cycles
} else {
// non-badline
nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop // 24*2=48 cycles
bit $ea // 3 cycles
// = 63 cycles
}
}(警告:就内存而言,这段代码非常浪费内存-同样的效果可以很容易地用普通循环来实现)(如果您不打算显示字符图形,则可以通过修改$D011,而不是改变延迟,而不是将坏行推开)。
尝试签出HOXS64模拟器中的机器代码监视器。对于调试时间相关的问题来说,这是非常完美的。它显示了在任何给定时间你所处的光栅线的哪个周期(+它可以在中断时中断)。
希望这有所帮助:)
注意,我还没有仔细检查过你的稳定光栅程序中的陷阱,但它似乎是好的-方法是正确的,你没有任何闪烁。如果你开始得到闪烁的光栅条,你知道该修复什么。;)
如果有人读了这篇文章,不知道什么是坏话:
酷参考文献:
1在vic文章中读到了更多关于“坏行”的文章(或“vic-圣经”,它应该被称为):http://csdb.dk/release/?id=44685 (PDF)或http://vice-emu.sourceforge.net/plain/VIC-Article.txt (TXT)。另见增编:http://vice-emu.sourceforge.net/plain/VIC-Addendum.txt
基本上,当国际中心芯片开始绘制第一条光栅线的文本线,它从CPU偷40-43周期(见下文为什么不总是43)。这些光栅线被称为“坏线条”。在一条糟糕的线路上,只有20-23个周期可用,而不是63个周期。
(更准确地说,当$D011的3位最低位等于$D012的3位(我们不在边框,屏幕没有被$D011的4位“关闭”)时,就会出现坏行)
国际中心芯片使用这43个周期中的最后40个来读取将显示在文本行上的40个字符。在这40个周期中,CPU不能执行任何指令。
然而,在这43个周期的前3个周期中,CPU实际上可以执行其指令的“写周期”--但只执行写周期,而不是读周期。(请参阅2)因此,如果您的操作码时间正确,您可以在这三个周期内执行您的指令的一些周期。(注意:只有三个写周期的指令是"brk",这通常是无用的,所以在实践中,您最多只能使用这3个周期中的2个来做有用的事情)。
注意,除了偷坏线的周期外,国际中心还将从光栅线上的CPU窃取带有精灵的循环。
2 (参见"64doc“)以了解c64不同指令的哪个周期是写周期:http://vice-emu.sourceforge.net/plain/64doc.txt。
(表中写周期标记为"W“,读周期标记为"R")
X ...And在http://codebase64.org上有很多好文章
发布于 2014-07-01 07:47:48
为了使光栅线自由闪烁,需要一些额外的诡计来稳定时间。原因是,您永远无法确定光栅例程是在行的开头执行的,但取决于CPU“离开”主程序代码的位置,浪费了大量未知的周期来执行最后一次操作。要达到这个目标,有不同的方法,您应该查看Codebase64上的Codebase64页面,以了解更多关于这个主题的内容,并获得一些示例代码。然而,一旦你建立了一个稳定的光栅时机,你的方法看起来不错。
发布于 2014-06-24 02:31:45
如果我没记错的话(几年前的20+ )。
由于小的中断抖动,不太可能获得完全稳定的光栅效果的时间;因此,无论您在软件中做什么,您将有一个“闪烁”点在一条扫描线开始。
要解决这个问题,请使用精灵来隐藏闪烁的点。
https://stackoverflow.com/questions/24375150
复制相似问题