assembly 加载位图并播放SID文件的中断未返回主程序-(6510 ASM,CBM Prog Studio)

rekjcdws  于 2023-06-23  发布在  其他
关注(0)|答案(1)|浏览(71)

我一直在尝试加载位图到屏幕上,同时使用IRQ中断播放sid文件。我让它工作,位图显示很好,SID文件播放得很好,但仅此而已。我希望能够移动到我的程序的下一个序列,无论是与计时器或按下空格键。但是整个程序在检查计时器的循环中冻结了,或者在示例中,我提供了空格键的按下,但什么也没有发生。
在查看调试器时(我使用可视化调试器C64 65 XE内斯Debugger 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
wyyhbhjk

wyyhbhjk1#

在Commodore 64上有三种方式可以结束中断。

  1. jmp $ea31是先运行代码然后继续内核服务例程的标准方式。
  2. jmp $ea81工作得更快。它只是把寄存器的值从堆栈和结束中断。它没有别的。如果选择此选项,则可以手动调用SCNKEY来更新键盘缓冲区。
    1.而不是中继到内核,你可以做所有手动。即:
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

相关问题