Прерывание, которое загружает растровое изображение и воспроизводит файл SID, НЕ возвращается в основную программу - (6510 ASM, CBM Prog Studio)

Я пытался загрузить растровое изображение на экран и одновременно воспроизвести sid-файл, используя прерывание IRQ. У меня он работает, растровое изображение отображается великолепно, а файл SID воспроизводится прекрасно, но это все. Я хочу иметь возможность перейти к следующей последовательности моей программы либо с помощью таймера, либо с помощью нажатия клавиши пробела. Но вся программа зависла на цикле проверки таймера, или в примере я даю нажатие пробела, но ничего не происходит.

Глядя на отладчик (я использую визуальный отладчик C64 65XE NES 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  

1 ответ

Есть три способа завершить прерывания на Commodore 64.

  1. это стандартный способ сначала запустить ваш код, а затем продолжить процедуру службы ядра.

  2. работает быстрее. Он просто помещает значения регистров из стека и завершает прерывание. Ничего другого не произошло. Если вы выберете этот вариант, вы сможете вручную вызвать SCNKEY для обновления буфера клавиатуры.

  3. Вместо ретрансляции в ядро ​​вы можете делать все вручную. то есть:

      PLA
TAY
PLA
TAX
PLA
RTI

Решение

При использовании у вас есть два варианта. Либо сначала вызовите 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.

Другие вопросы по тегам