加载位图和播放SID文件的中断没有返回到主程序- (6510 ASM, CBM Prog Studio)



我一直在尝试使用IRQ中断同时加载位图到屏幕并播放sid文件。我让它工作了,位图显示得很好,SID文件播放得很好,但仅此而已。我希望能够移动到我的程序的下一个序列,无论是定时器或按下空格键。但是整个程序已经冻结在检查计时器的循环中,或者在这个例子中,我提供了按空格键,但是什么也没有发生。

查看调试器(我使用可视化调试器C64 65XE NES调试器v0.64.58.4)时,我可以看到唯一的活动区域是Sid文件位于$6000以上的内存。似乎我在这里错过了一些非常明显的东西,但没有一个教程有答案。我试图通过删除位图来隔离问题,但同样的事情发生了,所以它必须在代码的中断部分,也许我使用SEI或CEI不正确,我不知道!我已经尝试了其他sid文件并使用了不同的内存位置,但没有任何工作。

代码如下:

; 10 SYS (2064)
*=$0801
BYTE    $0E, $08, $0A, $00, $9E, $20, $28,  $32, $30, $36, $34, $29, $00, $00, $00
;Assign labels to memory
chapter_no = $1000
timer = $1001
;C64 Kernal Instructions used in this simulation
print_line = $AB1E
plot = $FFF0
chrout = $FFD2
C_Raster_Line = $d012

*=$0810  
play_music

;Initiate the music. This is done but putting the value 00 into the x- and 
;y-registers, and call the subroutine that resets the SID-chip. The properties 
;in the SID file stated that the init routine for the music is at $6000
lda #$00
tax
tay
jsr $6000

;Turn off the interrupts
sei 
lda #$7f
sta $dc0d
sta $dd0d
lda #$01
sta $d01a
lda #$1b
ldx #$08
ldy #$14
sta $d011
stx $d016
sty $d018
lda #<irq
ldx #>irq
ldy #$7e
sta $0314
stx $0315
sty $d012
lda $dc0d
lda $dd0d
asl $d019
cli

lda #$00   ; enable CIA I and CIA II interrupts
sta $dc0d
sta $dd0d
lda #$10   ; enable VIC interrupts
sta $d011
lda #$01   ; enable IRQ interrupts
sta $d01a
start_BitmapLoader  
;Set the chapter to...
;CHAPTER ONE!
lda #01
sta chapter_no
lda #147
jsr chrout

chapter_1
clc
lda #$00
ldx #00
ldy #00
;Load the bitmap to screen
lda $4710
sta $d020
sta $d021
ldx #$00
loaddccimage
lda $3f40,x
sta $0400,x
lda $4040,x
sta $0500,x
lda $4140,x
sta $0600,x
lda $4240,x
sta $0700,x
lda $4328,x
sta $d800,x
lda $4428,x
sta $d900,x
lda $4528,x
sta $da00,x
lda $4628,x
sta $db00,x
inx
bne loaddccimage
lda #$3b
sta $d011
lda #$18
sta $d016
lda #$18
sta $d018

start_screen_jmp

; Check for space bar input
jsr $FFE4      ; C64 Kernal GETIN routine
cmp #$20       ; Check if input is space bar
bne start_screen_jmp ; If not space bar, continue infinite loop

; If space bar pressed, clear screen and switch to character mode
jsr $FFE4      ; Clear keyboard buffer
lda #$93       ; C64 Kernal CLRSCR routine
jsr $E544
lda #$0C       ; Switch to character mode
sta $D011
lda #$00
sta $D016
lda #$00
sta $D018
;Stop the music
lda #$00
tax
tay
jsr $6000

start_screen_jmp2      
;Loop forever and ever
jmp start_screen_jmp2

*=$1ffe    
incbin "MainBmp.prg"
irq      
jsr $6003
asl $d019
jmp $ea81

; music code and data 
*=$6000
music_player
incbin "future60.sid", $7e  

在Commodore 64上有三种结束中断的方法。

  1. jmp $ea31是先运行代码然后继续内核服务例程的标准方式。

  2. jmp $ea81工作速度更快。它只是从堆栈中放入寄存器值并结束中断。它没有做别的。如果你选择这个选项,你可以手动调用SCNKEY来更新键盘缓冲区。

  3. 您可以手动执行所有操作,而不是中继到内核。例如:

PLA
TAY
PLA
TAX
PLA
RTI

解决方案当您使用jmp $ea81时,您有两个选项。要么先调用SCNKEY:

; Check for space bar input
jsr $ea87      ; Call SCNKEY
jsr $FFE4      ; C64 Kernal GETIN routine
cmp #$20       ; Check if input is space bar
bne start_screen_jmp ; If not space bar, continue infinite loop

或使用自己的键盘扫描

; Check for space bar
lda $dc01      ; Check Data Port B
cmp #$ef       ; For space bar
bne start_scree_jmp ; If not space bar, continue infinite loop 

另一个解决方案是使用jmp $ea31代替jmp $ea81