gpt4 book ai didi

assembly - C64 上的稳定光栅

转载 作者:行者123 更新时间:2023-12-04 01:00:22 24 4
gpt4 key购买 nike

在 Commodore 64 上使用 6510 组件,我正在尝试创建稳定的光栅效果。使用双 IRQ 原理,我在屏幕上绘制了一些光栅线。我用 NOP 填充以匹配每个正常扫描线的 63 个周期,以及每个坏线的 23 个周期。我意识到我需要设置一个特定的起始行,以便将我的第 8 次迭代与 badline 相匹配,但是无论我把第一行放在哪一行,或者我使用什么 NOP 组合,我都无法得到时机正确。我想要没有“断”的完整线条。谁能看到我做错了什么?代码采用 Kick Assembler 格式。这是一个屏幕截图:

Screenshot

.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
}

最佳答案

据我了解,您的问题不是您的光栅条闪烁(即您的光栅中断稳定),而是您在屏幕上绘制的光栅条的第二行不是完全红色。

你的问题是线路不好。 (见[1])

在您稳定光栅中断后,使用您发布的代码,您的“实际代码”将在光栅线 $3A 的周期 4 开始运行。

您希望将背景颜色和边框颜色设置为红色的光栅条的第二行是一条坏线。 (它是光栅线 $3B。由于 $D011 = $1B,这是一条坏线,因为 $D011 和 $D012 的低 3 位是相同的)

在这条坏线上,第一个 INC (INC $D020) 成功运行,因此边框颜色变为红色。然后第二个 INC (INC $D021) 开始运行,但 VIC 在它完成之前接管,因此您的 INC $D021 直到 VIC 将总线返回后才会完成。 (这是 43 个周期后 - 即设置背景颜色为红色延迟了 43 个周期)。

您几乎拥有它,但是 badline 与您的代码预期的光栅行不同,您需要“推几个周期”,以便两个 INC 在被 VIC 中断之前都在 badlines 上执行。 (如果您希望在 VIC 接管之前执行这两个 INC,那么在 badline 的第 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 或者将坏行推开,如果您不这样做' t计划显示字符图形)

尝试检查 HOXS64 模拟器中的机器代码监视器。它非常适合调试与时序相关的问题。它向您显示在任何给定时间您所在的光栅线的哪个周期(+它可以在中断时中断)。

希望这有帮助:)

请注意,我没有彻底查看您的稳定光栅例程中的陷阱,但似乎没问题 - 方法是正确的,您没有任何闪烁。如果您开始出现闪烁的光栅条,您就知道要修复什么。 ;)

如果有人阅读本文不知道 badlines 是什么:

酷引用:

[1]:在 vic-article(或称其为“vic-bible”)中阅读更多关于“坏台词”的信息: http://csdb.dk/release/?id=44685 (PDF) 或 http://vice-emu.sourceforge.net/plain/VIC-Article.txt (文本)。另见附录: http://vice-emu.sourceforge.net/plain/VIC-Addendum.txt

基本上,当 VIC 芯片开始绘制文本行的第一条光栅线时,它会从 CPU 中窃取 40-43 个周期(有关为什么不总是 43,请参见下文)。这些光栅线称为“坏线”。
因此,在坏线上只有 20-23 个周期可用,而不是 63 个。

(更准确地说,当 $D011 的最低 3 位等于 $D012 的最低 3 位(并且我们不在边界并且屏幕没有被 $D011 的第 4 位“关闭”)时,就会出现一条坏线。 D011))

VIC 芯片使用这 43 个周期中的最后 40 个来读取要显示在文本行上的 40 个字符。 CPU 在这 40 个周期内不能执行任何指令。

然而,在这 43 个周期的前 3 个周期中,CPU 实际上可以执行其指令的“写周期”——但只能执行写周期,不能执行读周期。 (见[2])
因此,如果您对操作码进行正确计时,则可以在这 3 个周期内执行一些指令周期。
(注意:具有 3 个写周期的唯一指令是“brk”,这通常是无用的,因此在实践中,您最多只能使用这 3 个周期中的 2 个来获得有用的东西)。

请注意,除了在 badlines 上窃取周期外,VIC 还会从带有 sprite 的光栅行上的 CPU 窃取周期。

[2]:请参阅“64doc”以了解 C64 不同指令的哪些周期是写周期: http://vice-emu.sourceforge.net/plain/64doc.txt
(表中写周期标记为“W”,读周期标记为“R”)

[X]: ...还有很多好文章 http://codebase64.org

关于assembly - C64 上的稳定光栅,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24375150/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com