mirror of
https://github.com/deater/dos33fsprogs.git
synced 2024-06-27 07:29:29 +00:00
ootw: add mockingboard sound to the ending
This commit is contained in:
parent
9cc71625ba
commit
da080ca97c
|
@ -274,6 +274,7 @@ ENDING: ending.o
|
||||||
ld65 -o ENDING ending.o -C ../linker_scripts/apple2_1700.inc
|
ld65 -o ENDING ending.o -C ../linker_scripts/apple2_1700.inc
|
||||||
|
|
||||||
ending.o: ending.s \
|
ending.o: ending.s \
|
||||||
|
pt3_lib.s mockingboard_a.s pt3_setup.s interrupt_handler.s \
|
||||||
ootw_graphics/l15final/ootw_c15_final.inc \
|
ootw_graphics/l15final/ootw_c15_final.inc \
|
||||||
ootw_graphics/l16end/ootw_c16_end.inc
|
ootw_graphics/l16end/ootw_c16_end.inc
|
||||||
ca65 -o ending.o ending.s -l ending.lst
|
ca65 -o ending.o ending.s -l ending.lst
|
||||||
|
|
|
@ -90,6 +90,20 @@ ending:
|
||||||
; ending sequence
|
; ending sequence
|
||||||
;============================
|
;============================
|
||||||
|
|
||||||
|
|
||||||
|
;=========================
|
||||||
|
; set up sound
|
||||||
|
;=========================
|
||||||
|
|
||||||
|
jsr pt3_setup
|
||||||
|
|
||||||
|
cli ; enable interrupts
|
||||||
|
|
||||||
|
|
||||||
|
;=========================
|
||||||
|
; set up bg
|
||||||
|
;=========================
|
||||||
|
|
||||||
lda #>(sky_bg_rle)
|
lda #>(sky_bg_rle)
|
||||||
sta GBASH
|
sta GBASH
|
||||||
lda #<(sky_bg_rle)
|
lda #<(sky_bg_rle)
|
||||||
|
@ -185,17 +199,22 @@ wait_until_keypressed:
|
||||||
.include "gr_unrle.s"
|
.include "gr_unrle.s"
|
||||||
.include "gr_fast_clear.s"
|
.include "gr_fast_clear.s"
|
||||||
.include "gr_copy.s"
|
.include "gr_copy.s"
|
||||||
;.include "gr_copy_offset.s"
|
|
||||||
;.include "gr_putsprite.s"
|
|
||||||
;.include "gr_putsprite_flipped.s"
|
|
||||||
;.include "gr_putsprite_crop.s"
|
|
||||||
.include "gr_offsets.s"
|
.include "gr_offsets.s"
|
||||||
;.include "gr_offsets_hl.s"
|
|
||||||
;.include "gr_hlin.s"
|
|
||||||
;.include "keyboard.s"
|
|
||||||
.include "gr_overlay.s"
|
.include "gr_overlay.s"
|
||||||
|
|
||||||
|
.include "pt3_setup.s"
|
||||||
|
.include "pt3_lib.s"
|
||||||
|
.include "interrupt_handler.s"
|
||||||
|
.include "mockingboard_a.s"
|
||||||
|
|
||||||
; backgrounds
|
; backgrounds
|
||||||
.include "ootw_graphics/l15final/ootw_c15_final.inc"
|
.include "ootw_graphics/l15final/ootw_c15_final.inc"
|
||||||
.include "ootw_graphics/l16end/ootw_c16_end.inc"
|
.include "ootw_graphics/l16end/ootw_c16_end.inc"
|
||||||
|
|
||||||
|
PT3_LOC = song
|
||||||
|
|
||||||
|
; must be page aligned
|
||||||
|
.align 256
|
||||||
|
song:
|
||||||
|
.incbin "ootw_audio/ootw_intro.pt3"
|
||||||
|
|
||||||
|
|
167
ootw/interrupt_handler.s
Normal file
167
ootw/interrupt_handler.s
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
;================================
|
||||||
|
;================================
|
||||||
|
; mockingboard interrupt handler
|
||||||
|
;================================
|
||||||
|
;================================
|
||||||
|
; On Apple II/6502 the interrupt handler jumps to address in 0xfffe
|
||||||
|
; This is in the ROM, which saves the registers
|
||||||
|
; on older IIe it saved A to $45 (which could mess with DISK II)
|
||||||
|
; newer IIe doesn't do that.
|
||||||
|
; It then calculates if it is a BRK or not (which trashes A)
|
||||||
|
; Then it sets up the stack like an interrupt and calls 0x3fe
|
||||||
|
|
||||||
|
; Note: the IIc is much more complicated
|
||||||
|
; its firmware tries to decode the proper source
|
||||||
|
; based on various things, including screen hole values
|
||||||
|
; we bypass that by switching out ROM and replacing the
|
||||||
|
; $fffe vector with this, but that does mean we have
|
||||||
|
; to be sure status flag and accumulator set properly
|
||||||
|
|
||||||
|
interrupt_handler:
|
||||||
|
php ; save status flags
|
||||||
|
pha ; save A ; 3
|
||||||
|
; A is saved in $45 by firmware
|
||||||
|
txa
|
||||||
|
pha ; save X
|
||||||
|
tya
|
||||||
|
pha ; save Y
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; inc $0404 ; debug (flashes char onscreen)
|
||||||
|
|
||||||
|
bit $C404 ; clear 6522 interrupt by reading T1C-L ; 4
|
||||||
|
|
||||||
|
lda DONE_PLAYING ; 3
|
||||||
|
beq pt3_play_music ; if song done, don't play music ; 3/2nt
|
||||||
|
jmp exit_interrupt ; 3
|
||||||
|
;============
|
||||||
|
; 13
|
||||||
|
|
||||||
|
pt3_play_music:
|
||||||
|
|
||||||
|
; decode a frame of music
|
||||||
|
|
||||||
|
jsr pt3_make_frame
|
||||||
|
|
||||||
|
; handle song over condition
|
||||||
|
lda DONE_SONG
|
||||||
|
beq mb_write_frame ; if not done, continue
|
||||||
|
|
||||||
|
lda LOOP ; see if looping
|
||||||
|
beq move_to_next
|
||||||
|
|
||||||
|
pt3_loop_smc:
|
||||||
|
lda #0 ; looping, move to loop location
|
||||||
|
sta current_pattern
|
||||||
|
lda #$0
|
||||||
|
sta current_line
|
||||||
|
sta current_subframe
|
||||||
|
sta DONE_SONG ; undo the next song
|
||||||
|
|
||||||
|
beq done_interrupt ; branch always
|
||||||
|
|
||||||
|
move_to_next:
|
||||||
|
; same as "press right"
|
||||||
|
ldx #$20
|
||||||
|
jmp quiet_exit
|
||||||
|
|
||||||
|
;======================================
|
||||||
|
; Write frames to Mockingboard
|
||||||
|
;======================================
|
||||||
|
; for speed could merge this into
|
||||||
|
; the decode code
|
||||||
|
|
||||||
|
mb_write_frame:
|
||||||
|
|
||||||
|
|
||||||
|
tax ; set up reg count ; 2
|
||||||
|
;============
|
||||||
|
; 2
|
||||||
|
|
||||||
|
;==================================
|
||||||
|
; loop through the 14 registers
|
||||||
|
; reading the value, then write out
|
||||||
|
;==================================
|
||||||
|
|
||||||
|
mb_write_loop:
|
||||||
|
lda AY_REGISTERS,X ; load register value ; 4
|
||||||
|
|
||||||
|
; special case R13. If it is 0xff, then don't update
|
||||||
|
; otherwise might spuriously reset the envelope settings
|
||||||
|
|
||||||
|
cpx #13 ; 2
|
||||||
|
bne mb_not_13 ; 3/2nt
|
||||||
|
cmp #$ff ; 2
|
||||||
|
beq mb_skip_13 ; 3/2nt
|
||||||
|
;============
|
||||||
|
; typ 5
|
||||||
|
mb_not_13:
|
||||||
|
|
||||||
|
|
||||||
|
; address
|
||||||
|
stx MOCK_6522_ORA1 ; put address on PA1 ; 4
|
||||||
|
stx MOCK_6522_ORA2 ; put address on PA2 ; 4
|
||||||
|
lda #MOCK_AY_LATCH_ADDR ; latch_address for PB1 ; 2
|
||||||
|
sta MOCK_6522_ORB1 ; latch_address on PB1 ; 4
|
||||||
|
sta MOCK_6522_ORB2 ; latch_address on PB2 ; 4
|
||||||
|
ldy #MOCK_AY_INACTIVE ; go inactive ; 2
|
||||||
|
sty MOCK_6522_ORB1 ; 4
|
||||||
|
sty MOCK_6522_ORB2 ; 4
|
||||||
|
|
||||||
|
; value
|
||||||
|
lda AY_REGISTERS,X ; load register value ; 4
|
||||||
|
sta MOCK_6522_ORA1 ; put value on PA1 ; 4
|
||||||
|
sta MOCK_6522_ORA2 ; put value on PA2 ; 4
|
||||||
|
lda #MOCK_AY_WRITE ; ; 2
|
||||||
|
sta MOCK_6522_ORB1 ; write on PB1 ; 4
|
||||||
|
sta MOCK_6522_ORB2 ; write on PB2 ; 4
|
||||||
|
sty MOCK_6522_ORB1 ; 4
|
||||||
|
sty MOCK_6522_ORB2 ; 4
|
||||||
|
;===========
|
||||||
|
; 60
|
||||||
|
mb_no_write:
|
||||||
|
inx ; point to next register ; 2
|
||||||
|
cpx #14 ; if 14 we're done ; 2
|
||||||
|
bmi mb_write_loop ; otherwise, loop ; 3/2nt
|
||||||
|
;============
|
||||||
|
; 7
|
||||||
|
mb_skip_13:
|
||||||
|
|
||||||
|
|
||||||
|
jmp exit_interrupt
|
||||||
|
|
||||||
|
;=================================
|
||||||
|
; Finally done with this interrupt
|
||||||
|
;=================================
|
||||||
|
|
||||||
|
done_interrupt:
|
||||||
|
|
||||||
|
quiet_exit:
|
||||||
|
stx DONE_PLAYING
|
||||||
|
jsr clear_ay_both
|
||||||
|
|
||||||
|
;ldx #$ff ; also mute the channel
|
||||||
|
stx AY_REGISTERS+7 ; just in case
|
||||||
|
|
||||||
|
done_key:
|
||||||
|
exit_interrupt:
|
||||||
|
|
||||||
|
pla
|
||||||
|
tay ; restore Y
|
||||||
|
pla
|
||||||
|
tax ; restore X
|
||||||
|
pla ; restore a ; 4
|
||||||
|
|
||||||
|
; on II+/IIe (but not IIc) we need to do this?
|
||||||
|
interrupt_smc:
|
||||||
|
lda $45 ; restore A
|
||||||
|
plp
|
||||||
|
|
||||||
|
rti ; return from interrupt ; 6
|
||||||
|
|
||||||
|
;============
|
||||||
|
; typical
|
||||||
|
; ???? cycles
|
||||||
|
|
||||||
|
|
241
ootw/mockingboard_a.s
Normal file
241
ootw/mockingboard_a.s
Normal file
|
@ -0,0 +1,241 @@
|
||||||
|
; Mockingboad programming:
|
||||||
|
; + Has two 6522 I/O chips connected to two AY-3-8910 chips
|
||||||
|
; + Optionally has some speech chips controlled via the outport on the AY
|
||||||
|
; + Often in slot 4
|
||||||
|
; TODO: how to auto-detect?
|
||||||
|
; References used:
|
||||||
|
; http://macgui.com/usenet/?group=2&id=8366
|
||||||
|
; 6522 Data Sheet
|
||||||
|
; AY-3-8910 Data Sheet
|
||||||
|
|
||||||
|
;========================
|
||||||
|
; Mockingboard card
|
||||||
|
; Essentially two 6522s hooked to the Apple II bus
|
||||||
|
; Connected to AY-3-8910 chips
|
||||||
|
; PA0-PA7 on 6522 connected to DA0-DA7 on AY
|
||||||
|
; PB0 on 6522 connected to BC1
|
||||||
|
; PB1 on 6522 connected to BDIR
|
||||||
|
; PB2 on 6522 connected to RESET
|
||||||
|
|
||||||
|
|
||||||
|
; left speaker
|
||||||
|
MOCK_6522_ORB1 = $C400 ; 6522 #1 port b data
|
||||||
|
MOCK_6522_ORA1 = $C401 ; 6522 #1 port a data
|
||||||
|
MOCK_6522_DDRB1 = $C402 ; 6522 #1 data direction port B
|
||||||
|
MOCK_6522_DDRA1 = $C403 ; 6522 #1 data direction port A
|
||||||
|
|
||||||
|
; right speaker
|
||||||
|
MOCK_6522_ORB2 = $C480 ; 6522 #2 port b data
|
||||||
|
MOCK_6522_ORA2 = $C481 ; 6522 #2 port a data
|
||||||
|
MOCK_6522_DDRB2 = $C482 ; 6522 #2 data direction port B
|
||||||
|
MOCK_6522_DDRA2 = $C483 ; 6522 #2 data direction port A
|
||||||
|
|
||||||
|
; AY-3-8910 commands on port B
|
||||||
|
; RESET BDIR BC1
|
||||||
|
MOCK_AY_RESET = $0 ; 0 0 0
|
||||||
|
MOCK_AY_INACTIVE = $4 ; 1 0 0
|
||||||
|
MOCK_AY_READ = $5 ; 1 0 1
|
||||||
|
MOCK_AY_WRITE = $6 ; 1 1 0
|
||||||
|
MOCK_AY_LATCH_ADDR = $7 ; 1 1 1
|
||||||
|
|
||||||
|
|
||||||
|
;========================
|
||||||
|
; Mockingboard Init
|
||||||
|
;========================
|
||||||
|
; Initialize the 6522s
|
||||||
|
; set the data direction for all pins of PortA/PortB to be output
|
||||||
|
|
||||||
|
mockingboard_init:
|
||||||
|
lda #$ff ; all output (1)
|
||||||
|
sta MOCK_6522_DDRB1
|
||||||
|
sta MOCK_6522_DDRA1
|
||||||
|
sta MOCK_6522_DDRB2
|
||||||
|
sta MOCK_6522_DDRA2
|
||||||
|
rts
|
||||||
|
|
||||||
|
;======================
|
||||||
|
; Reset Left AY-3-8910
|
||||||
|
;======================
|
||||||
|
reset_ay_both:
|
||||||
|
lda #MOCK_AY_RESET
|
||||||
|
sta MOCK_6522_ORB1
|
||||||
|
lda #MOCK_AY_INACTIVE
|
||||||
|
sta MOCK_6522_ORB1
|
||||||
|
|
||||||
|
;======================
|
||||||
|
; Reset Right AY-3-8910
|
||||||
|
;======================
|
||||||
|
;reset_ay_right:
|
||||||
|
;could be merged with both
|
||||||
|
lda #MOCK_AY_RESET
|
||||||
|
sta MOCK_6522_ORB2
|
||||||
|
lda #MOCK_AY_INACTIVE
|
||||||
|
sta MOCK_6522_ORB2
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
; Write sequence
|
||||||
|
; Inactive -> Latch Address -> Inactive -> Write Data -> Inactive
|
||||||
|
|
||||||
|
;=========================================
|
||||||
|
; Write Right/Left to save value AY-3-8910
|
||||||
|
;=========================================
|
||||||
|
; register in X
|
||||||
|
; value in MB_VALUE
|
||||||
|
|
||||||
|
write_ay_both:
|
||||||
|
; address
|
||||||
|
stx MOCK_6522_ORA1 ; put address on PA1 ; 3
|
||||||
|
stx MOCK_6522_ORA2 ; put address on PA2 ; 3
|
||||||
|
lda #MOCK_AY_LATCH_ADDR ; latch_address on PB1 ; 2
|
||||||
|
sta MOCK_6522_ORB1 ; latch_address on PB1 ; 3
|
||||||
|
sta MOCK_6522_ORB2 ; latch_address on PB2 ; 3
|
||||||
|
ldy #MOCK_AY_INACTIVE ; go inactive ; 2
|
||||||
|
sty MOCK_6522_ORB1 ; 3
|
||||||
|
sty MOCK_6522_ORB2 ; 3
|
||||||
|
|
||||||
|
; value
|
||||||
|
lda MB_VALUE ; 3
|
||||||
|
sta MOCK_6522_ORA1 ; put value on PA1 ; 3
|
||||||
|
sta MOCK_6522_ORA2 ; put value on PA2 ; 3
|
||||||
|
lda #MOCK_AY_WRITE ; ; 2
|
||||||
|
sta MOCK_6522_ORB1 ; write on PB1 ; 3
|
||||||
|
sta MOCK_6522_ORB2 ; write on PB2 ; 3
|
||||||
|
sty MOCK_6522_ORB1 ; 3
|
||||||
|
sty MOCK_6522_ORB2 ; 3
|
||||||
|
|
||||||
|
rts ; 6
|
||||||
|
;===========
|
||||||
|
; 51
|
||||||
|
;=======================================
|
||||||
|
; clear ay -- clear all 14 AY registers
|
||||||
|
; should silence the card
|
||||||
|
;=======================================
|
||||||
|
clear_ay_both:
|
||||||
|
ldx #14
|
||||||
|
lda #0
|
||||||
|
sta MB_VALUE
|
||||||
|
clear_ay_left_loop:
|
||||||
|
jsr write_ay_both
|
||||||
|
dex
|
||||||
|
bpl clear_ay_left_loop
|
||||||
|
rts
|
||||||
|
|
||||||
|
;=======================================
|
||||||
|
; Detect a Mockingboard card
|
||||||
|
;=======================================
|
||||||
|
; Based on code from the French Touch "Pure Noise" Demo
|
||||||
|
; Attempts to time an instruction sequence with a 6522
|
||||||
|
;
|
||||||
|
; If found, puts in bMB
|
||||||
|
; MB_ADDRL:MB_ADDRH has address of Mockingboard
|
||||||
|
; returns X=0 if not found, X=1 if found
|
||||||
|
|
||||||
|
mockingboard_detect:
|
||||||
|
lda #0
|
||||||
|
sta MB_ADDRL
|
||||||
|
|
||||||
|
mb_detect_loop: ; self-modifying
|
||||||
|
lda #$07 ; we start in slot 7 ($C7) and go down to 0 ($C0)
|
||||||
|
ora #$C0 ; make it start with C
|
||||||
|
sta MB_ADDRH
|
||||||
|
ldy #04 ; $CX04
|
||||||
|
ldx #02 ; 2 tries?
|
||||||
|
mb_check_cycle_loop:
|
||||||
|
lda (MB_ADDRL),Y ; timer 6522 (Low Order Counter)
|
||||||
|
; count down
|
||||||
|
sta TEMP ; 3 cycles
|
||||||
|
lda (MB_ADDRL),Y ; + 5 cycles = 8 cycles
|
||||||
|
; between the two accesses to the timer
|
||||||
|
sec
|
||||||
|
sbc TEMP ; subtract to see if we had 8 cycles
|
||||||
|
cmp #$f8 ; -8
|
||||||
|
bne mb_not_in_this_slot
|
||||||
|
dex ; decrement, try one more time
|
||||||
|
bne mb_check_cycle_loop ; loop detection
|
||||||
|
inx ; Mockingboard found (X=1)
|
||||||
|
done_mb_detect:
|
||||||
|
;stx bMB ; store result to bMB
|
||||||
|
rts ; return
|
||||||
|
|
||||||
|
mb_not_in_this_slot:
|
||||||
|
dec mb_detect_loop+1 ; decrement the "slot" (self_modify)
|
||||||
|
bne mb_detect_loop ; loop down to one
|
||||||
|
ldx #00
|
||||||
|
beq done_mb_detect
|
||||||
|
|
||||||
|
;alternative MB detection from Nox Archaist
|
||||||
|
; lda #$04
|
||||||
|
; sta MB_ADDRL
|
||||||
|
; ldx #$c7
|
||||||
|
;
|
||||||
|
;find_mb:
|
||||||
|
; stx MB_ADDRH
|
||||||
|
;
|
||||||
|
; ;detect sound I
|
||||||
|
;
|
||||||
|
; sec
|
||||||
|
; ldy #$00
|
||||||
|
; lda (MB_ADDRL), y
|
||||||
|
; sbc (MB_ADDRL), y
|
||||||
|
; cmp #$05
|
||||||
|
; beq found_mb
|
||||||
|
; dex
|
||||||
|
; cpx #$c0
|
||||||
|
; bne find_mb
|
||||||
|
; ldx #$00 ;no mockingboard found
|
||||||
|
; rts
|
||||||
|
;
|
||||||
|
;found_mb:
|
||||||
|
; ldx #$01 ;mockingboard found
|
||||||
|
; rts
|
||||||
|
;
|
||||||
|
; ;optionally detect sound II
|
||||||
|
;
|
||||||
|
; sec
|
||||||
|
; ldy #$80
|
||||||
|
; lda (MB_ADDRL), y
|
||||||
|
; sbc (MB_ADDRL), y
|
||||||
|
; cmp #$05
|
||||||
|
; beq found_mb
|
||||||
|
|
||||||
|
|
||||||
|
;=======================================
|
||||||
|
; Detect a Mockingboard card in Slot4
|
||||||
|
;=======================================
|
||||||
|
; Based on code from the French Touch "Pure Noise" Demo
|
||||||
|
; Attempts to time an instruction sequence with a 6522
|
||||||
|
;
|
||||||
|
; MB_ADDRL:MB_ADDRH has address of Mockingboard
|
||||||
|
; returns X=0 if not found, X=1 if found
|
||||||
|
|
||||||
|
mockingboard_detect_slot4:
|
||||||
|
lda #0
|
||||||
|
sta MB_ADDRL
|
||||||
|
|
||||||
|
mb4_detect_loop: ; self-modifying
|
||||||
|
lda #$04 ; we're only looking in Slot 4
|
||||||
|
ora #$C0 ; make it start with C
|
||||||
|
sta MB_ADDRH
|
||||||
|
ldy #04 ; $CX04
|
||||||
|
ldx #02 ; 2 tries?
|
||||||
|
mb4_check_cycle_loop:
|
||||||
|
lda (MB_ADDRL),Y ; timer 6522 (Low Order Counter)
|
||||||
|
; count down
|
||||||
|
sta TEMP ; 3 cycles
|
||||||
|
lda (MB_ADDRL),Y ; + 5 cycles = 8 cycles
|
||||||
|
; between the two accesses to the timer
|
||||||
|
sec
|
||||||
|
sbc TEMP ; subtract to see if we had 8 cycles
|
||||||
|
cmp #$f8 ; -8
|
||||||
|
bne mb4_not_in_this_slot
|
||||||
|
dex ; decrement, try one more time
|
||||||
|
bne mb4_check_cycle_loop ; loop detection
|
||||||
|
inx ; Mockingboard found (X=1)
|
||||||
|
done_mb4_detect:
|
||||||
|
rts ; return
|
||||||
|
|
||||||
|
mb4_not_in_this_slot:
|
||||||
|
ldx #00
|
||||||
|
beq done_mb4_detect
|
||||||
|
|
2342
ootw/pt3_lib.s
Normal file
2342
ootw/pt3_lib.s
Normal file
File diff suppressed because it is too large
Load Diff
168
ootw/pt3_setup.s
Normal file
168
ootw/pt3_setup.s
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
|
||||||
|
;=============================
|
||||||
|
; Setup
|
||||||
|
;=============================
|
||||||
|
pt3_setup:
|
||||||
|
|
||||||
|
;===========================
|
||||||
|
; Check for Apple II/II+/IIc
|
||||||
|
;===========================
|
||||||
|
; this is used to see if we have lowecase support
|
||||||
|
|
||||||
|
lda $FBB3 ; IIe and newer is $06
|
||||||
|
cmp #6
|
||||||
|
beq apple_iie_or_newer
|
||||||
|
|
||||||
|
lda #1 ; set if older than a IIe
|
||||||
|
sta apple_ii
|
||||||
|
jmp done_apple_detect
|
||||||
|
apple_iie_or_newer:
|
||||||
|
lda $FBC0 ; 0 on a IIc
|
||||||
|
bne done_apple_detect
|
||||||
|
apple_iic:
|
||||||
|
; activate IIc mockingboard?
|
||||||
|
; this might only be necessary to allow detection
|
||||||
|
; I get the impression the Mockingboard 4c activates
|
||||||
|
; when you access any of the 6522 ports in Slot 4
|
||||||
|
lda #$ff
|
||||||
|
sta $C403
|
||||||
|
sta $C404
|
||||||
|
|
||||||
|
; bypass the firmware interrupt handler
|
||||||
|
; should we do this on IIe too? probably faster
|
||||||
|
|
||||||
|
sei ; disable interrupts
|
||||||
|
lda $c08b ; disable ROM (enable language card)
|
||||||
|
lda $c08b
|
||||||
|
lda #<interrupt_handler
|
||||||
|
sta $fffe
|
||||||
|
lda #>interrupt_handler
|
||||||
|
sta $ffff
|
||||||
|
|
||||||
|
lda #$EA ; nop out the "lda $45" in the irq hand
|
||||||
|
sta interrupt_smc
|
||||||
|
sta interrupt_smc+1
|
||||||
|
|
||||||
|
done_apple_detect:
|
||||||
|
|
||||||
|
;===============
|
||||||
|
; init variables
|
||||||
|
;===============
|
||||||
|
|
||||||
|
lda #0
|
||||||
|
sta DONE_PLAYING
|
||||||
|
sta LOOP
|
||||||
|
|
||||||
|
;=======================
|
||||||
|
; Detect mockingboard
|
||||||
|
;========================
|
||||||
|
|
||||||
|
; Note, we do this, but then ignore it, as sometimes
|
||||||
|
; the test fails and then you don't get music.
|
||||||
|
; In theory this could do bad things if you had something
|
||||||
|
; easily confused in slot4, but that's probably not an issue.
|
||||||
|
|
||||||
|
; print detection message
|
||||||
|
|
||||||
|
; lda #<mocking_message ; load loading message
|
||||||
|
; sta OUTL
|
||||||
|
; lda #>mocking_message
|
||||||
|
; sta OUTH
|
||||||
|
; jsr move_and_print ; print it
|
||||||
|
|
||||||
|
jsr mockingboard_detect_slot4 ; call detection routine
|
||||||
|
cpx #$1
|
||||||
|
beq mockingboard_found
|
||||||
|
|
||||||
|
; lda #<not_message ; if not found, print that
|
||||||
|
; sta OUTL
|
||||||
|
; lda #>not_message
|
||||||
|
; sta OUTH
|
||||||
|
; inc CV
|
||||||
|
; jsr move_and_print
|
||||||
|
|
||||||
|
; jmp forever_loop ; and wait forever
|
||||||
|
|
||||||
|
mockingboard_found:
|
||||||
|
; lda #<found_message ; print found message
|
||||||
|
; sta OUTL
|
||||||
|
; lda #>found_message
|
||||||
|
; sta OUTH
|
||||||
|
; inc CV
|
||||||
|
; jsr move_and_print
|
||||||
|
|
||||||
|
;============================
|
||||||
|
; Init the Mockingboard
|
||||||
|
;============================
|
||||||
|
|
||||||
|
jsr mockingboard_init
|
||||||
|
jsr reset_ay_both
|
||||||
|
jsr clear_ay_both
|
||||||
|
|
||||||
|
;=========================
|
||||||
|
; Setup Interrupt Handler
|
||||||
|
;=========================
|
||||||
|
; Vector address goes to 0x3fe/0x3ff
|
||||||
|
; FIXME: should chain any existing handler
|
||||||
|
|
||||||
|
lda #<interrupt_handler
|
||||||
|
sta $03fe
|
||||||
|
lda #>interrupt_handler
|
||||||
|
sta $03ff
|
||||||
|
|
||||||
|
;============================
|
||||||
|
; Enable 50Hz clock on 6522
|
||||||
|
;============================
|
||||||
|
|
||||||
|
sei ; disable interrupts just in case
|
||||||
|
|
||||||
|
lda #$40 ; Continuous interrupts, don't touch PB7
|
||||||
|
sta $C40B ; ACR register
|
||||||
|
lda #$7F ; clear all interrupt flags
|
||||||
|
sta $C40E ; IER register (interrupt enable)
|
||||||
|
|
||||||
|
lda #$C0
|
||||||
|
sta $C40D ; IFR: 1100, enable interrupt on timer one oflow
|
||||||
|
sta $C40E ; IER: 1100, enable timer one interrupt
|
||||||
|
|
||||||
|
lda #$E7
|
||||||
|
sta $C404 ; write into low-order latch
|
||||||
|
lda #$4f
|
||||||
|
sta $C405 ; write into high-order latch,
|
||||||
|
; load both values into counter
|
||||||
|
; clear interrupt and start counting
|
||||||
|
|
||||||
|
; 4fe7 / 1e6 = .020s, 50Hz
|
||||||
|
|
||||||
|
|
||||||
|
;==================
|
||||||
|
; init song
|
||||||
|
;==================
|
||||||
|
|
||||||
|
jsr pt3_init_song
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
;==============================-=========
|
||||||
|
;========================================
|
||||||
|
|
||||||
|
; Helper routines below
|
||||||
|
|
||||||
|
;========================================
|
||||||
|
;========================================
|
||||||
|
|
||||||
|
;=========
|
||||||
|
; vars
|
||||||
|
;=========
|
||||||
|
|
||||||
|
time_frame: .byte $0
|
||||||
|
apple_ii: .byte $0
|
||||||
|
|
||||||
|
;=========
|
||||||
|
; strings
|
||||||
|
;=========
|
||||||
|
;mocking_message: .asciiz "LOOKING FOR MOCKINGBOARD IN SLOT #4"
|
||||||
|
not_message: .byte "NOT "
|
||||||
|
found_message: .asciiz "FOUND"
|
||||||
|
;done_message: .asciiz "DONE PLAYING"
|
||||||
|
|
56
ootw/zp.inc
56
ootw/zp.inc
|
@ -56,10 +56,10 @@ LETTERD = $67
|
||||||
LETTER = $68
|
LETTER = $68
|
||||||
BLARGH = $69
|
BLARGH = $69
|
||||||
|
|
||||||
INTRO_REPEAT = $7E ; INTRO
|
|
||||||
ZPOS = $78
|
|
||||||
|
|
||||||
REGISTER_DUMP = $70
|
;ZPOS = $78
|
||||||
|
|
||||||
|
AY_REGISTERS = $70
|
||||||
A_FINE_TONE = $70
|
A_FINE_TONE = $70
|
||||||
A_COARSE_TONE = $71
|
A_COARSE_TONE = $71
|
||||||
B_FINE_TONE = $72
|
B_FINE_TONE = $72
|
||||||
|
@ -75,46 +75,21 @@ ENVELOPE_FINE = $7B
|
||||||
ENVELOPE_COARSE = $7C
|
ENVELOPE_COARSE = $7C
|
||||||
ENVELOPE_SHAPE = $7D
|
ENVELOPE_SHAPE = $7D
|
||||||
|
|
||||||
|
PATTERN_L = $7E
|
||||||
|
PATTERN_H = $7F
|
||||||
|
ORNAMENT_L = $80
|
||||||
|
ORNAMENT_H = $81
|
||||||
|
SAMPLE_L = $82
|
||||||
|
SAMPLE_H = $83
|
||||||
|
|
||||||
COPY_OFFSET = $7E
|
LOOP = $84
|
||||||
DECODER_STATE = $7F
|
MB_VALUE = $85
|
||||||
|
MB_ADDRL = $86
|
||||||
|
MB_ADDRH = $87
|
||||||
|
DONE_PLAYING = $88
|
||||||
|
DONE_SONG = $89
|
||||||
|
|
||||||
|
|
||||||
REGISTER_DUMP2 = $80
|
|
||||||
A_FINE_TONE2 = $80
|
|
||||||
A_COARSE_TONE2 = $81
|
|
||||||
B_FINE_TONE2 = $82
|
|
||||||
B_COARSE_TONE2 = $83
|
|
||||||
C_FINE_TONE2 = $84
|
|
||||||
C_COARSE_TONE2 = $85
|
|
||||||
NOISE2 = $86
|
|
||||||
ENABLE2 = $87
|
|
||||||
A_VOLUME2 = $88
|
|
||||||
B_VOLUME2 = $89
|
|
||||||
C_VOLUME2 = $8A
|
|
||||||
ENVELOPE_FINE2 = $8B
|
|
||||||
ENVELOPE_COARS2 = $8C
|
|
||||||
ENVELOPE_SHAPE2 = $8D
|
|
||||||
LYRICSL = $8E
|
|
||||||
LYRICSH = $8F
|
|
||||||
|
|
||||||
FRAME_COUNT = $90
|
|
||||||
MB_VALUE = $91
|
|
||||||
MB_ADDRL = $91
|
|
||||||
MB_ADDRH = $92
|
|
||||||
DONE_PLAYING = $93
|
|
||||||
MB_CHUNK_OFFSET = $94
|
|
||||||
MB_FRAME = $94
|
|
||||||
MB_PATTERN = $95
|
|
||||||
CHUNKSIZE = $95
|
|
||||||
LZ4_DONE = $96
|
|
||||||
;DECODE_ERROR = $97
|
|
||||||
;COPY_TIME = $98
|
|
||||||
;DECOMPRESS_TIME = $99
|
|
||||||
;TIME_TAKEN = $9A
|
|
||||||
;LYRICS_ACTIVE = $9B
|
|
||||||
;FORTYCOL = $9C
|
|
||||||
;CURSOR = $9D
|
|
||||||
|
|
||||||
; More zero-page addresses
|
; More zero-page addresses
|
||||||
; we try not to conflict with anything DOS, MONITOR or BASIC related
|
; we try not to conflict with anything DOS, MONITOR or BASIC related
|
||||||
|
@ -134,6 +109,7 @@ DOOR_XMAX_H = $C9
|
||||||
BEAST_ZAPPING = $CA ; 1
|
BEAST_ZAPPING = $CA ; 1
|
||||||
BEAST_DEAD = $CB ; 1
|
BEAST_DEAD = $CB ; 1
|
||||||
VENT_OPEN = $CC ; 2
|
VENT_OPEN = $CC ; 2
|
||||||
|
INTRO_REPEAT = $CD ; INTRO
|
||||||
|
|
||||||
LEFT_SHOOT_TARGET = $CF ; ALL
|
LEFT_SHOOT_TARGET = $CF ; ALL
|
||||||
RIGHT_SHOOT_TARGET = $D0 ; ALL
|
RIGHT_SHOOT_TARGET = $D0 ; ALL
|
||||||
|
|
Loading…
Reference in New Issue
Block a user