3

我正在尝试设置一个简单的光栅中断处理程序来更改给定条纹中的背景颜色。但是,我的中断处理程序似乎一直被调用。(代码使用CA65的格式)

.include "c64.inc"

ROW = 100

.segment "ZPSAVE"

.segment "STARTUP"

        sei

        ;; Turn off BASIC and KERNAL ROM
        lda #$35
        sta $01

        ;; Flush CIA IRQs
        bit CIA1_ICR
        bit CIA2_ICR

        ;; Turn off CIA interrupts
        lda #%011111111
        sta CIA1_ICR
        sta CIA2_ICR

        ;; Set target raster line
        lda #%01111111
        and VIC_CTRL1
        sta VIC_CTRL1

        lda #ROW
        sta VIC_HLINE

        ;; Enable VIC interrupt
        lda #%00000001
        sta VIC_IMR

        ;; Install interrupt handler
        lda #<isr
        sta $fffe
        lda #>isr
        sta $ffff
        cli

        rts

.macro isr_pre
        pha
        txa
        pha
        tya
        pha
.endmacro

.macro isr_post
        pla
        tay
        pla
        tax
        rti
.endmacro

;;; Acknowledge VIC interrupt
.macro ack_vic
        lda VIC_IRR
        and #$01
        sta VIC_IRR
.endmacro

.proc isr
        isr_pre
        ack_vic

        ;; Uncommenting these lines works around the problem
        ;; lda VIC_HLINE
        ;; cmp #ROW
        ;; bne exit

        lda #1
        sta VIC_BORDERCOLOR
        sta VIC_BG_COLOR0

        ldx #50
:       dex
        bne :-

        lda #0
        sta VIC_BORDERCOLOR
        sta VIC_BG_COLOR0

exit:   isr_post
.endproc

如果我在上面的代码中注释掉标记为“解决方法”的三行,那么我的中断处理程序会一直被调用,而不仅仅是在(开始)行ROW

没有解决方法

如果我取消注释这三行,那么它可以工作,但它非常不稳定,我猜是因为那些相同的意外中断:

有解决方法

4

1 回答 1

2

我发现上面发布的代码存在几个问题,并且修复了所有问题:

  1. 用于关闭CIA中断的位掩码是错误的(它意外地长了 9 位)——这就是导致所有这些额外中断触发的原因......
  2. ISRpostscriptum 宏缺少一个pla来恢复寄存器 -这完全A搞砸了状态,所以旧代码发生的任何事情或多或少都是偶然的......
  3. VIC中断设置代码中没有刷新中断——所以在修复了前两个问题之后,现在中断从未被触发。
  4. 设置代码的末尾没有什么rts可做的,因为我们关闭了内核和 BASIC ROM

所以固定代码如下:

.include "c64.inc"

ROW = 100

;;; Acknowledge VIC interrupt
.macro ack_vic
        lda VIC_IRR
        and #$01
        sta VIC_IRR
.endmacro

.segment "ZPSAVE"

.segment "STARTUP"

        sei

        ;; Turn off BASIC and KERNAL ROM
        lda #$35
        sta $01

        ;; Flush CIA IRQs
        bit CIA1_ICR
        bit CIA2_ICR
        ack_vic

        ;; Turn off CIA interrupts
        lda #%01111111
        sta CIA1_ICR
        sta CIA2_ICR

        ;; Set target raster line
        lda #%01111111
        and VIC_CTRL1
        sta VIC_CTRL1

        lda #ROW
        sta VIC_HLINE

        ;; Enable VIC interrupt
        lda #%00000001
        sta VIC_IMR

        ;; Install interrupt handler
        lda #<isr
        sta $fffe
        lda #>isr
        sta $ffff
        cli    
        jmp *

.macro isr_pre
        pha
        txa
        pha
        tya
        pha
.endmacro

.macro isr_post
        pla
        tay
        pla
        tax
        pla
        rti
.endmacro

.proc isr
        isr_pre
        ack_vic

        lda #1
        sta VIC_BORDERCOLOR
        sta VIC_BG_COLOR0

        ldx #50
:       dex
        bne :-

        lda #0
        sta VIC_BORDERCOLOR
        sta VIC_BG_COLOR0

exit:   isr_post
.endproc

正如预期的那样,这会产生纯白色条纹。由于某种未知的原因,条纹从屏幕中间水平开始,但我想这将是一个单独的 SO 问题。

于 2013-05-22T16:04:27.433 回答