Прерывание, которое загружает растровое изображение и воспроизводит файл 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.
это стандартный способ сначала запустить ваш код, а затем продолжить процедуру службы ядра.
работает быстрее. Он просто помещает значения регистров из стека и завершает прерывание. Ничего другого не произошло. Если вы выберете этот вариант, вы сможете вручную вызвать SCNKEY для обновления буфера клавиатуры.
Вместо ретрансляции в ядро вы можете делать все вручную. то есть:
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
.