Кто вызывает мой обработчик прерываний, если у меня отключены оба ЦРУ?
Я пытаюсь настроить простой обработчик растровых прерываний, чтобы изменить цвет фона в заданной полосе. Однако мой обработчик прерываний, кажется, вызывается все время. (код использует формат 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
:
Если я раскомментирую эти три строки, то это сработает, но очень нестабильно, наверное, из-за тех же непреднамеренных прерываний:
1 ответ
Я обнаружил несколько проблем с моим кодом, опубликованным выше, и исправление всех из них устранило проблему:
- Битовая маска для выключения
CIA
прерывания были неправильными (это было случайно 9 бит длиной) - это то, что вызывало все эти дополнительные прерывания... ISR
Макрос постскриптума отсутствовалpla
восстановитьA
регистр - это испорченное состояние по-королевски, так что все, что случилось со старым кодом, было более или менее случайно...VIC
прерывание не было сброшено в коде установки прерываний - поэтому после устранения двух предыдущих проблем прерывания никогда не запускались.- Там нет ничего
rts
в конце установочного кода, так как мы выключаем Kernal и 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.