mirror of
https://github.com/deater/dos33fsprogs.git
synced 2025-02-27 15:29:47 +00:00
monkey: play some music
This commit is contained in:
parent
c1ee40a69b
commit
489a9e5d52
@ -36,7 +36,9 @@ loader.o: loader.s
|
|||||||
TITLE: title.o
|
TITLE: title.o
|
||||||
ld65 -o TITLE title.o -C ../linker_scripts/apple2_2000.inc
|
ld65 -o TITLE title.o -C ../linker_scripts/apple2_2000.inc
|
||||||
|
|
||||||
title.o: title.s
|
title.o: title.s \
|
||||||
|
graphics_intro/title_graphics.inc \
|
||||||
|
interrupt_handler.s mockingboard.s ym_play.s
|
||||||
ca65 -o title.o title.s -l title.lst
|
ca65 -o title.o title.s -l title.lst
|
||||||
|
|
||||||
|
|
||||||
@ -59,6 +61,9 @@ monkey.o: monkey.s zp.inc hardware.inc common_defines.inc \
|
|||||||
graphics/graphics.inc:
|
graphics/graphics.inc:
|
||||||
cd graphics && make
|
cd graphics && make
|
||||||
|
|
||||||
|
graphics_intro/title_graphics.inc:
|
||||||
|
cd graphics_intro && make
|
||||||
|
|
||||||
####
|
####
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
301
monkey/interrupt_handler.s
Normal file
301
monkey/interrupt_handler.s
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
; This plays KRG files, stripped down ym5 files
|
||||||
|
; this is a limited format: the envelope values are ignored
|
||||||
|
; the fields with don't-care values are packed together
|
||||||
|
; they are played at 25Hz
|
||||||
|
|
||||||
|
; FRAME0 = AFINE (r0)
|
||||||
|
; FRAME1 = BFINE (r2)
|
||||||
|
; FRAME2 = CFINE (r4)
|
||||||
|
; FRAME3 = NOISE PERIOD (r6)
|
||||||
|
; FRAME4 = ENABLE (r7)
|
||||||
|
; FRAME5 = ACOARSE/BCOARSE (r1/r3)
|
||||||
|
; FRAME6 = CCOARSE/AAMP (r5/r8)
|
||||||
|
; FRAME7 = BAMP/CAMP (r9/r10)
|
||||||
|
|
||||||
|
;================================
|
||||||
|
;================================
|
||||||
|
; 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
|
||||||
|
|
||||||
|
CHUNKSIZE = 15 ; hardcoded, based on krg file
|
||||||
|
|
||||||
|
interrupt_handler:
|
||||||
|
php
|
||||||
|
pha ; save A ; 3
|
||||||
|
txa
|
||||||
|
pha
|
||||||
|
tya
|
||||||
|
pha
|
||||||
|
|
||||||
|
inc $0404 ; debug (flashes char onscreen)
|
||||||
|
|
||||||
|
bit $C404 ; clear 6522 interrupt by reading T1C-L ; 4
|
||||||
|
|
||||||
|
|
||||||
|
lda DONE_PLAYING ; 3
|
||||||
|
beq mb_play_music ; if song done, don't play music ; 3/2nt
|
||||||
|
jmp done_interrupt ; 3
|
||||||
|
;============
|
||||||
|
; 13
|
||||||
|
|
||||||
|
mb_play_music:
|
||||||
|
|
||||||
|
|
||||||
|
;======================================
|
||||||
|
; Write frames to Mockingboard
|
||||||
|
;======================================
|
||||||
|
; actually plays frame loaded at end of
|
||||||
|
; last interrupt, so 20ms behind?
|
||||||
|
|
||||||
|
mb_write_frame:
|
||||||
|
|
||||||
|
;==================================
|
||||||
|
; loop through the 11 registers
|
||||||
|
; reading the value, then write out
|
||||||
|
;==================================
|
||||||
|
ldx #0 ; set up reg count ; 2
|
||||||
|
|
||||||
|
mb_write_loop_left:
|
||||||
|
lda REGISTER_DUMP,X ; load register value ; 4
|
||||||
|
cmp REGISTER_OLD,X ; compare with old values ; 4
|
||||||
|
beq mb_no_write_left ; 3/2nt
|
||||||
|
;=============
|
||||||
|
; typ 11
|
||||||
|
|
||||||
|
; address
|
||||||
|
stx MOCK_6522_ORA1 ; put address on PA1 ; 4
|
||||||
|
lda #MOCK_AY_LATCH_ADDR ; latch_address for PB1 ; 2
|
||||||
|
sta MOCK_6522_ORB1 ; latch_address on PB1 ; 4
|
||||||
|
lda #MOCK_AY_INACTIVE ; go inactive ; 2
|
||||||
|
sta MOCK_6522_ORB1 ; 4
|
||||||
|
|
||||||
|
; value
|
||||||
|
lda REGISTER_DUMP,X ; load register value ; 4
|
||||||
|
sta MOCK_6522_ORA1 ; put value on PA1 ; 4
|
||||||
|
lda #MOCK_AY_WRITE ; ; 2
|
||||||
|
sta MOCK_6522_ORB1 ; write on PB1 ; 4
|
||||||
|
lda #MOCK_AY_INACTIVE ; go inactive ; 2
|
||||||
|
sta MOCK_6522_ORB1 ; 4
|
||||||
|
|
||||||
|
;===========
|
||||||
|
; 36
|
||||||
|
mb_no_write_left:
|
||||||
|
inx ; point to next register ; 2
|
||||||
|
cpx #11 ; if 11 we're done ; 2
|
||||||
|
bmi mb_write_loop_left ; otherwise, loop ; 3/2nt
|
||||||
|
;============
|
||||||
|
; 7
|
||||||
|
|
||||||
|
ldx #0 ; set up reg count ; 2
|
||||||
|
mb_write_loop_right:
|
||||||
|
lda REGISTER_DUMP,X ; load register value ; 4
|
||||||
|
cmp REGISTER_OLD,X ; compare with old values ; 4
|
||||||
|
beq mb_no_write_right ; 3/2nt
|
||||||
|
;=============
|
||||||
|
; typ 11
|
||||||
|
|
||||||
|
; address
|
||||||
|
stx MOCK_6522_ORA2 ; put address on PA2 ; 4
|
||||||
|
lda #MOCK_AY_LATCH_ADDR ; latch_address for PB1 ; 2
|
||||||
|
sta MOCK_6522_ORB2 ; latch_address on PB2 ; 4
|
||||||
|
lda #MOCK_AY_INACTIVE ; go inactive ; 2
|
||||||
|
sta MOCK_6522_ORB2 ; 4
|
||||||
|
|
||||||
|
; value
|
||||||
|
lda REGISTER_DUMP,X ; load register value ; 4
|
||||||
|
sta MOCK_6522_ORA2 ; put value on PA2 ; 4
|
||||||
|
lda #MOCK_AY_WRITE ; ; 2
|
||||||
|
sta MOCK_6522_ORB2 ; write on PB2 ; 4
|
||||||
|
lda #MOCK_AY_INACTIVE ; go inactive ; 2
|
||||||
|
sta MOCK_6522_ORB2 ; 4
|
||||||
|
|
||||||
|
;===========
|
||||||
|
; 36
|
||||||
|
mb_no_write_right:
|
||||||
|
inx ; point to next register ; 2
|
||||||
|
cpx #11 ; if 11 we're done ; 2
|
||||||
|
bmi mb_write_loop_right ; otherwise, loop ; 3/2nt
|
||||||
|
;============
|
||||||
|
; 7
|
||||||
|
|
||||||
|
;=====================================
|
||||||
|
; Copy registers to old
|
||||||
|
;=====================================
|
||||||
|
; 11 coming in
|
||||||
|
|
||||||
|
ldx #10 ; 2
|
||||||
|
mb_reg_copy:
|
||||||
|
lda REGISTER_DUMP,X ; load register value ; 4
|
||||||
|
sta REGISTER_OLD,X ; compare with old values ; 4
|
||||||
|
dex ; 2
|
||||||
|
bpl mb_reg_copy ; 2nt/3
|
||||||
|
;=============
|
||||||
|
; 171
|
||||||
|
|
||||||
|
;===================================
|
||||||
|
; Load all 11 registers in advance
|
||||||
|
;===================================
|
||||||
|
; note, assuming not cross page boundary, not any slower
|
||||||
|
; then loading from zero page?
|
||||||
|
|
||||||
|
mb_load_values:
|
||||||
|
|
||||||
|
ldy MB_CHUNK_OFFSET ; get chunk offset ; 3
|
||||||
|
|
||||||
|
; afine
|
||||||
|
lda (MB_ADDRL),y ; load register value ; 5
|
||||||
|
sta A_FINE_TONE ; 3
|
||||||
|
clc ; point to next interleaved ; 2
|
||||||
|
lda MB_ADDRH ; page by adding CHUNKSIZE ; 3
|
||||||
|
adc #CHUNKSIZE ; 3
|
||||||
|
sta MB_ADDRH ; 3
|
||||||
|
|
||||||
|
; bfine
|
||||||
|
lda (MB_ADDRL),y ; load register value ; 5
|
||||||
|
sta B_FINE_TONE ; 3
|
||||||
|
clc ; point to next interleaved ; 2
|
||||||
|
lda MB_ADDRH ; page by adding CHUNKSIZE ; 3
|
||||||
|
adc #CHUNKSIZE ; 3
|
||||||
|
sta MB_ADDRH ; 3
|
||||||
|
|
||||||
|
; cfine
|
||||||
|
lda (MB_ADDRL),y ; load register value ; 5
|
||||||
|
sta C_FINE_TONE ; 3
|
||||||
|
clc ; point to next interleaved ; 2
|
||||||
|
lda MB_ADDRH ; page by adding CHUNKSIZE ; 3
|
||||||
|
adc #CHUNKSIZE ; 3
|
||||||
|
sta MB_ADDRH ; 3
|
||||||
|
|
||||||
|
; noise
|
||||||
|
lda (MB_ADDRL),y ; load register value ; 5
|
||||||
|
sta NOISE ; 3
|
||||||
|
clc ; point to next interleaved ; 2
|
||||||
|
lda MB_ADDRH ; page by adding CHUNKSIZE ; 3
|
||||||
|
adc #CHUNKSIZE ; 3
|
||||||
|
sta MB_ADDRH ; 3
|
||||||
|
|
||||||
|
; enable
|
||||||
|
lda (MB_ADDRL),y ; load register value ; 5
|
||||||
|
sta ENABLE ; 3
|
||||||
|
clc ; point to next interleaved ; 2
|
||||||
|
lda MB_ADDRH ; page by adding CHUNKSIZE ; 3
|
||||||
|
adc #CHUNKSIZE ; 3
|
||||||
|
sta MB_ADDRH ; 3
|
||||||
|
|
||||||
|
; acoarse/bcoarse
|
||||||
|
lda (MB_ADDRL),y ; load register value ; 5
|
||||||
|
and #$f ; 2
|
||||||
|
sta B_COARSE_TONE ; 3
|
||||||
|
lda (MB_ADDRL),y ; load register value ; 5
|
||||||
|
lsr ; 2
|
||||||
|
lsr ; 2
|
||||||
|
lsr ; 2
|
||||||
|
lsr ; 2
|
||||||
|
sta A_COARSE_TONE ; 3
|
||||||
|
clc ; point to next interleaved ; 2
|
||||||
|
lda MB_ADDRH ; page by adding CHUNKSIZE ; 3
|
||||||
|
adc #CHUNKSIZE ; 3
|
||||||
|
sta MB_ADDRH ; 3
|
||||||
|
|
||||||
|
; CCOARSE/AAMP
|
||||||
|
lda (MB_ADDRL),y ; load register value ; 5
|
||||||
|
and #$f ; 2
|
||||||
|
sta A_VOLUME ; 3
|
||||||
|
lda (MB_ADDRL),y ; load register value ; 5
|
||||||
|
lsr ; 2
|
||||||
|
lsr ; 2
|
||||||
|
lsr ; 2
|
||||||
|
lsr ; 2
|
||||||
|
sta C_COARSE_TONE ; 3
|
||||||
|
clc ; point to next interleaved ; 2
|
||||||
|
lda MB_ADDRH ; page by adding CHUNKSIZE ; 3
|
||||||
|
adc #CHUNKSIZE ; 3
|
||||||
|
sta MB_ADDRH ; 3
|
||||||
|
inx ; point to next register ; 2
|
||||||
|
|
||||||
|
; BAMP/CAMP
|
||||||
|
lda (MB_ADDRL),y ; load register value ; 5
|
||||||
|
and #$f ; 2
|
||||||
|
sta C_VOLUME ; 3
|
||||||
|
lda (MB_ADDRL),y ; load register value ; 5
|
||||||
|
lsr ; 2
|
||||||
|
lsr ; 2
|
||||||
|
lsr ; 2
|
||||||
|
lsr ; 2
|
||||||
|
sta B_VOLUME ; 3
|
||||||
|
|
||||||
|
;=========================================
|
||||||
|
; if NOISE is $ff then we are done
|
||||||
|
|
||||||
|
lda NOISE ; 3
|
||||||
|
cmp #$ff
|
||||||
|
bne mb_not_done
|
||||||
|
; bpl mb_not_done ; 3/2nt
|
||||||
|
|
||||||
|
; lda #1
|
||||||
|
sta DONE_PLAYING
|
||||||
|
jsr clear_ay_both
|
||||||
|
|
||||||
|
jmp done_interrupt ; 3
|
||||||
|
;===========
|
||||||
|
; typ 6
|
||||||
|
mb_not_done:
|
||||||
|
|
||||||
|
;==============================================
|
||||||
|
; incremement offset. If 0 move to next chunk
|
||||||
|
;==============================================
|
||||||
|
|
||||||
|
increment_offset:
|
||||||
|
|
||||||
|
inc MB_CHUNK_OFFSET ; increment offset ; 5
|
||||||
|
bne increment_done ; if not zero, done ; 3/2nt
|
||||||
|
|
||||||
|
inc WHICH_CHUNK
|
||||||
|
lda WHICH_CHUNK
|
||||||
|
cmp #CHUNKSIZE
|
||||||
|
bne increment_done
|
||||||
|
|
||||||
|
lda #0
|
||||||
|
sta WHICH_CHUNK
|
||||||
|
|
||||||
|
increment_done:
|
||||||
|
|
||||||
|
lda #>music_start
|
||||||
|
clc
|
||||||
|
adc WHICH_CHUNK
|
||||||
|
sta MB_ADDRH
|
||||||
|
|
||||||
|
;=================================
|
||||||
|
; Finally done with this interrupt
|
||||||
|
;=================================
|
||||||
|
|
||||||
|
done_interrupt:
|
||||||
|
|
||||||
|
|
||||||
|
exit_interrupt:
|
||||||
|
pla
|
||||||
|
tay
|
||||||
|
pla
|
||||||
|
tax
|
||||||
|
|
||||||
|
pla
|
||||||
|
|
||||||
|
lda $45
|
||||||
|
plp
|
||||||
|
|
||||||
|
rti ; return from interrupt ; 6
|
||||||
|
|
||||||
|
;============
|
||||||
|
; typical
|
||||||
|
; ???? cycles
|
||||||
|
|
||||||
|
|
||||||
|
REGISTER_OLD:
|
||||||
|
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
@ -348,3 +348,4 @@ done_split:
|
|||||||
lda #$c ; load to page $c00
|
lda #$c ; load to page $c00
|
||||||
jsr decompress_lzsa2_fast
|
jsr decompress_lzsa2_fast
|
||||||
|
|
||||||
|
rts
|
||||||
|
162
monkey/mockingboard.s
Normal file
162
monkey/mockingboard.s
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
; 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:
|
||||||
|
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
|
||||||
|
lda #MOCK_AY_INACTIVE ; go inactive ; 2
|
||||||
|
sta MOCK_6522_ORB1 ; 3
|
||||||
|
sta 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
|
||||||
|
lda #MOCK_AY_INACTIVE ; go inactive ; 2
|
||||||
|
sta MOCK_6522_ORB1 ; 3
|
||||||
|
sta MOCK_6522_ORB2 ; 3
|
||||||
|
|
||||||
|
rts ; 6
|
||||||
|
;===========
|
||||||
|
; 53
|
||||||
|
;=======================================
|
||||||
|
; 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 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
|
||||||
|
|
@ -7,6 +7,8 @@
|
|||||||
.include "hardware.inc"
|
.include "hardware.inc"
|
||||||
.include "common_defines.inc"
|
.include "common_defines.inc"
|
||||||
|
|
||||||
|
music_start = $4800
|
||||||
|
|
||||||
title_start:
|
title_start:
|
||||||
;===================
|
;===================
|
||||||
; init screen
|
; init screen
|
||||||
@ -17,12 +19,30 @@ title_start:
|
|||||||
bit SET_GR
|
bit SET_GR
|
||||||
bit PAGE0
|
bit PAGE0
|
||||||
bit LORES
|
bit LORES
|
||||||
bit TEXTGR
|
bit FULLGR
|
||||||
|
|
||||||
|
lda #0
|
||||||
|
sta clear_all_color+1
|
||||||
|
jsr clear_all
|
||||||
|
|
||||||
lda #0
|
lda #0
|
||||||
sta ANIMATE_FRAME
|
sta ANIMATE_FRAME
|
||||||
sta FRAMEL
|
sta FRAMEL
|
||||||
sta FRAMEH
|
sta FRAMEH
|
||||||
|
sta DRAW_PAGE
|
||||||
|
sta DISP_PAGE
|
||||||
|
|
||||||
|
setup_music:
|
||||||
|
; decompress music
|
||||||
|
|
||||||
|
lda #<theme_lzsa
|
||||||
|
sta LZSA_SRC_LO
|
||||||
|
lda #>theme_lzsa
|
||||||
|
sta LZSA_SRC_HI
|
||||||
|
lda #$48 ; load to page $4800
|
||||||
|
jsr decompress_lzsa2_fast
|
||||||
|
|
||||||
|
jsr mockingboard_detect
|
||||||
|
|
||||||
title_loop:
|
title_loop:
|
||||||
|
|
||||||
@ -30,6 +50,14 @@ title_loop:
|
|||||||
; load LF logo
|
; load LF logo
|
||||||
;====================================
|
;====================================
|
||||||
|
|
||||||
|
lda #<logo_lzsa
|
||||||
|
sta LZSA_SRC_LO
|
||||||
|
lda #>logo_lzsa
|
||||||
|
sta LZSA_SRC_HI
|
||||||
|
lda #$c ; load to page $c00
|
||||||
|
jsr decompress_lzsa2_fast
|
||||||
|
|
||||||
|
|
||||||
jsr gr_copy_to_current
|
jsr gr_copy_to_current
|
||||||
|
|
||||||
logo_loop:
|
logo_loop:
|
||||||
@ -64,6 +92,30 @@ room_frame_no_oflo:
|
|||||||
jsr wait_until_keypressed
|
jsr wait_until_keypressed
|
||||||
|
|
||||||
|
|
||||||
|
;====================================
|
||||||
|
; load LF logo
|
||||||
|
;====================================
|
||||||
|
|
||||||
|
lda #<title_lzsa
|
||||||
|
sta LZSA_SRC_LO
|
||||||
|
lda #>title_lzsa
|
||||||
|
sta LZSA_SRC_HI
|
||||||
|
lda #$c ; load to page $c00
|
||||||
|
jsr decompress_lzsa2_fast
|
||||||
|
|
||||||
|
|
||||||
|
jsr gr_copy_to_current
|
||||||
|
|
||||||
|
jsr wait_until_keypressed
|
||||||
|
|
||||||
|
;==========================
|
||||||
|
; turn off music
|
||||||
|
;==========================
|
||||||
|
|
||||||
|
sei ; clear interrupts
|
||||||
|
|
||||||
|
jsr clear_ay_both
|
||||||
|
|
||||||
;==========================
|
;==========================
|
||||||
; load main program
|
; load main program
|
||||||
;==========================
|
;==========================
|
||||||
@ -78,22 +130,20 @@ room_frame_no_oflo:
|
|||||||
;==========================
|
;==========================
|
||||||
|
|
||||||
; level graphics
|
; level graphics
|
||||||
; .include "graphics/graphics.inc"
|
.include "graphics_intro/title_graphics.inc"
|
||||||
|
|
||||||
; level data
|
|
||||||
; .include "leveldata_monkey.inc"
|
|
||||||
|
|
||||||
|
|
||||||
; .include "end_level.s"
|
; .include "end_level.s"
|
||||||
; .include "text_print.s"
|
; .include "text_print.s"
|
||||||
.include "gr_offsets.s"
|
.include "gr_offsets.s"
|
||||||
; .include "gr_fast_clear.s"
|
.include "gr_fast_clear.s"
|
||||||
; .include "keyboard.s"
|
; .include "keyboard.s"
|
||||||
.include "gr_copy.s"
|
.include "gr_copy.s"
|
||||||
; .include "gr_putsprite_crop.s"
|
; .include "gr_putsprite_crop.s"
|
||||||
; .include "joystick.s"
|
; .include "joystick.s"
|
||||||
; .include "gr_pageflip.s"
|
; .include "gr_pageflip.s"
|
||||||
; .include "decompress_fast_v2.s"
|
.include "decompress_fast_v2.s"
|
||||||
; .include "draw_pointer.s"
|
; .include "draw_pointer.s"
|
||||||
; .include "common_sprites.inc"
|
; .include "common_sprites.inc"
|
||||||
; .include "guy.brush"
|
; .include "guy.brush"
|
||||||
@ -101,10 +151,24 @@ room_frame_no_oflo:
|
|||||||
; .include "monkey_actions.s"
|
; .include "monkey_actions.s"
|
||||||
; .include "update_bottom.s"
|
; .include "update_bottom.s"
|
||||||
|
|
||||||
|
.include "ym_play.s"
|
||||||
|
.include "interrupt_handler.s"
|
||||||
|
.include "mockingboard.s"
|
||||||
|
|
||||||
wait_until_keypressed:
|
wait_until_keypressed:
|
||||||
lda KEYPRESS
|
lda KEYPRESS
|
||||||
bmi wait_until_keypressed
|
bpl wait_until_keypressed
|
||||||
|
|
||||||
bit KEYRESET
|
bit KEYRESET
|
||||||
|
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
; music is compressed
|
||||||
|
; decompressed it is 30720 bytes
|
||||||
|
; we decompress to $4800
|
||||||
|
; so total size of our code can't be biggr than $2800 = 10k
|
||||||
|
|
||||||
|
theme_lzsa:
|
||||||
|
.incbin "music/theme.lzsa"
|
||||||
|
|
||||||
|
87
monkey/ym_play.s
Normal file
87
monkey/ym_play.s
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
|
||||||
|
mockingboard_detect:
|
||||||
|
|
||||||
|
;================================
|
||||||
|
; Mockingboard detect
|
||||||
|
;================================
|
||||||
|
|
||||||
|
jsr mockingboard_detect_slot4 ; call detection routine
|
||||||
|
stx MB_DETECTED
|
||||||
|
|
||||||
|
;================================
|
||||||
|
; Mockingboard start
|
||||||
|
;================================
|
||||||
|
|
||||||
|
mockingboard_setup:
|
||||||
|
sei ; disable interrupts just in case
|
||||||
|
|
||||||
|
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
|
||||||
|
;============================
|
||||||
|
|
||||||
|
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
|
||||||
|
; 9c40 / 1e6 = .040s, 25Hz
|
||||||
|
|
||||||
|
;============================
|
||||||
|
; Start Playing
|
||||||
|
;============================
|
||||||
|
main_loop:
|
||||||
|
lda MB_DETECTED
|
||||||
|
beq mockingboard_setup_done
|
||||||
|
|
||||||
|
lda #0
|
||||||
|
sta DONE_PLAYING
|
||||||
|
sta WHICH_CHUNK
|
||||||
|
sta MB_CHUNK_OFFSET
|
||||||
|
sta MB_ADDRL ; we are aligned, so should be 0
|
||||||
|
|
||||||
|
lda #>music_start
|
||||||
|
sta MB_ADDRH
|
||||||
|
|
||||||
|
;=====================================
|
||||||
|
; clear register area
|
||||||
|
;=====================================
|
||||||
|
ldx #13 ; 2
|
||||||
|
lda #0 ; 2
|
||||||
|
mb_setup_clear_reg:
|
||||||
|
sta REGISTER_DUMP,X ; clear register value ; 4
|
||||||
|
sta REGISTER_OLD,X ; clear old values ; 4
|
||||||
|
dex ; 2
|
||||||
|
bpl mb_setup_clear_reg ; 2nt/3
|
||||||
|
|
||||||
|
cli ; start interrupts
|
||||||
|
|
||||||
|
mockingboard_setup_done:
|
||||||
|
|
||||||
|
rts
|
@ -22,11 +22,12 @@ MASK = $2E
|
|||||||
COLOR_MASK = $2F
|
COLOR_MASK = $2F
|
||||||
COLOR = $30
|
COLOR = $30
|
||||||
|
|
||||||
|
|
||||||
SEEDL = $4e
|
SEEDL = $4e
|
||||||
SEEDH = $4f
|
SEEDH = $4f
|
||||||
XMAX = $50
|
XMAX = $50
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; MIST zero page addresses
|
; MIST zero page addresses
|
||||||
|
|
||||||
FRAMEL = $60
|
FRAMEL = $60
|
||||||
@ -45,6 +46,7 @@ BTC_L = $6C
|
|||||||
BTC_H = $6D
|
BTC_H = $6D
|
||||||
|
|
||||||
; pt3 player registers
|
; pt3 player registers
|
||||||
|
REGISTER_DUMP = $70
|
||||||
AY_REGISTERS = $70
|
AY_REGISTERS = $70
|
||||||
A_FINE_TONE = $70
|
A_FINE_TONE = $70
|
||||||
A_COARSE_TONE = $71
|
A_COARSE_TONE = $71
|
||||||
@ -61,8 +63,9 @@ C_VOLUME = $7A
|
|||||||
ENVELOPE_FINE = $7B
|
ENVELOPE_FINE = $7B
|
||||||
ENVELOPE_COARSE = $7C
|
ENVELOPE_COARSE = $7C
|
||||||
ENVELOPE_SHAPE = $7D
|
ENVELOPE_SHAPE = $7D
|
||||||
PATTERN_L = $7E
|
COPY_OFFSET = $7E
|
||||||
PATTERN_H = $7F
|
DECODER_STATE = $7F
|
||||||
|
|
||||||
|
|
||||||
; note 70-7f also used by disk code
|
; note 70-7f also used by disk code
|
||||||
|
|
||||||
@ -114,24 +117,16 @@ DISP_PAGE = $ED ; ALL
|
|||||||
DRAW_PAGE = $EE ; ALL
|
DRAW_PAGE = $EE ; ALL
|
||||||
|
|
||||||
; rest of pt3_player
|
; rest of pt3_player
|
||||||
PT3_TEMP = $EF
|
MB_DETECTED = $EF
|
||||||
ORNAMENT_L = $F0
|
WHICH_CHUNK = $F0
|
||||||
ORNAMENT_H = $F1
|
MB_CHUNK_OFFSET = $F1
|
||||||
SAMPLE_L = $F2
|
|
||||||
SAMPLE_H = $F3
|
|
||||||
LOOP = $F4
|
LOOP = $F4
|
||||||
MB_VALUE = $F5
|
MB_VALUE = $F5
|
||||||
MB_ADDR_L = $F6
|
MB_ADDRL = $F6
|
||||||
MB_ADDR_H = $F7
|
MB_ADDRH = $F7
|
||||||
DONE_PLAYING = $F8
|
DONE_PLAYING = $F8
|
||||||
DONE_SONG = $F9
|
DONE_SONG = $F9
|
||||||
|
|
||||||
;TINL = $F0
|
|
||||||
;TINH = $F1
|
|
||||||
;BINL = $F2
|
|
||||||
;BINH = $F3
|
|
||||||
;SCROLL_COUNT = $F9
|
|
||||||
|
|
||||||
TEMP = $FA
|
TEMP = $FA
|
||||||
TEMPY = $FB
|
TEMPY = $FB
|
||||||
INL = $FC
|
INL = $FC
|
||||||
|
Loading…
x
Reference in New Issue
Block a user