mirror of
https://github.com/deater/dos33fsprogs.git
synced 2024-11-03 14:05:58 +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
|
||||
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
|
||||
|
||||
|
||||
@ -59,6 +61,9 @@ monkey.o: monkey.s zp.inc hardware.inc common_defines.inc \
|
||||
graphics/graphics.inc:
|
||||
cd graphics && make
|
||||
|
||||
graphics_intro/title_graphics.inc:
|
||||
cd graphics_intro && make
|
||||
|
||||
####
|
||||
|
||||
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
|
||||
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 "common_defines.inc"
|
||||
|
||||
music_start = $4800
|
||||
|
||||
title_start:
|
||||
;===================
|
||||
; init screen
|
||||
@ -17,12 +19,30 @@ title_start:
|
||||
bit SET_GR
|
||||
bit PAGE0
|
||||
bit LORES
|
||||
bit TEXTGR
|
||||
bit FULLGR
|
||||
|
||||
lda #0
|
||||
sta clear_all_color+1
|
||||
jsr clear_all
|
||||
|
||||
lda #0
|
||||
sta ANIMATE_FRAME
|
||||
sta FRAMEL
|
||||
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:
|
||||
|
||||
@ -30,6 +50,14 @@ title_loop:
|
||||
; 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
|
||||
|
||||
logo_loop:
|
||||
@ -64,6 +92,30 @@ room_frame_no_oflo:
|
||||
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
|
||||
;==========================
|
||||
@ -78,22 +130,20 @@ room_frame_no_oflo:
|
||||
;==========================
|
||||
|
||||
; level graphics
|
||||
; .include "graphics/graphics.inc"
|
||||
.include "graphics_intro/title_graphics.inc"
|
||||
|
||||
; level data
|
||||
; .include "leveldata_monkey.inc"
|
||||
|
||||
|
||||
; .include "end_level.s"
|
||||
; .include "text_print.s"
|
||||
.include "gr_offsets.s"
|
||||
; .include "gr_fast_clear.s"
|
||||
.include "gr_fast_clear.s"
|
||||
; .include "keyboard.s"
|
||||
.include "gr_copy.s"
|
||||
; .include "gr_putsprite_crop.s"
|
||||
; .include "joystick.s"
|
||||
; .include "gr_pageflip.s"
|
||||
; .include "decompress_fast_v2.s"
|
||||
.include "decompress_fast_v2.s"
|
||||
; .include "draw_pointer.s"
|
||||
; .include "common_sprites.inc"
|
||||
; .include "guy.brush"
|
||||
@ -101,10 +151,24 @@ room_frame_no_oflo:
|
||||
; .include "monkey_actions.s"
|
||||
; .include "update_bottom.s"
|
||||
|
||||
.include "ym_play.s"
|
||||
.include "interrupt_handler.s"
|
||||
.include "mockingboard.s"
|
||||
|
||||
wait_until_keypressed:
|
||||
lda KEYPRESS
|
||||
bmi wait_until_keypressed
|
||||
bpl wait_until_keypressed
|
||||
|
||||
bit KEYRESET
|
||||
|
||||
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 = $30
|
||||
|
||||
|
||||
SEEDL = $4e
|
||||
SEEDH = $4f
|
||||
XMAX = $50
|
||||
|
||||
|
||||
|
||||
; MIST zero page addresses
|
||||
|
||||
FRAMEL = $60
|
||||
@ -45,6 +46,7 @@ BTC_L = $6C
|
||||
BTC_H = $6D
|
||||
|
||||
; pt3 player registers
|
||||
REGISTER_DUMP = $70
|
||||
AY_REGISTERS = $70
|
||||
A_FINE_TONE = $70
|
||||
A_COARSE_TONE = $71
|
||||
@ -61,8 +63,9 @@ C_VOLUME = $7A
|
||||
ENVELOPE_FINE = $7B
|
||||
ENVELOPE_COARSE = $7C
|
||||
ENVELOPE_SHAPE = $7D
|
||||
PATTERN_L = $7E
|
||||
PATTERN_H = $7F
|
||||
COPY_OFFSET = $7E
|
||||
DECODER_STATE = $7F
|
||||
|
||||
|
||||
; note 70-7f also used by disk code
|
||||
|
||||
@ -114,23 +117,15 @@ DISP_PAGE = $ED ; ALL
|
||||
DRAW_PAGE = $EE ; ALL
|
||||
|
||||
; rest of pt3_player
|
||||
PT3_TEMP = $EF
|
||||
ORNAMENT_L = $F0
|
||||
ORNAMENT_H = $F1
|
||||
SAMPLE_L = $F2
|
||||
SAMPLE_H = $F3
|
||||
LOOP = $F4
|
||||
MB_VALUE = $F5
|
||||
MB_ADDR_L = $F6
|
||||
MB_ADDR_H = $F7
|
||||
DONE_PLAYING = $F8
|
||||
DONE_SONG = $F9
|
||||
|
||||
;TINL = $F0
|
||||
;TINH = $F1
|
||||
;BINL = $F2
|
||||
;BINH = $F3
|
||||
;SCROLL_COUNT = $F9
|
||||
MB_DETECTED = $EF
|
||||
WHICH_CHUNK = $F0
|
||||
MB_CHUNK_OFFSET = $F1
|
||||
LOOP = $F4
|
||||
MB_VALUE = $F5
|
||||
MB_ADDRL = $F6
|
||||
MB_ADDRH = $F7
|
||||
DONE_PLAYING = $F8
|
||||
DONE_SONG = $F9
|
||||
|
||||
TEMP = $FA
|
||||
TEMPY = $FB
|
||||
|
Loading…
Reference in New Issue
Block a user