mirror of
https://github.com/deater/dos33fsprogs.git
synced 2024-06-01 12:41:35 +00:00
tracker6: make it interrupt-run
This commit is contained in:
parent
28fb6d13ba
commit
27516de7f9
|
@ -37,7 +37,8 @@ d4.o: d4.s \
|
||||||
zp.inc hardware.inc \
|
zp.inc hardware.inc \
|
||||||
mA2E_4.s \
|
mA2E_4.s \
|
||||||
mockingboard_init.s play_frame.s \
|
mockingboard_init.s play_frame.s \
|
||||||
tracker_init.s ay3_write_regs.s
|
tracker_init.s ay3_write_regs.s interrupt_handler.s \
|
||||||
|
mockingboard_constants.s
|
||||||
ca65 -o d4.o d4.s -l d4.lst
|
ca65 -o d4.o d4.s -l d4.lst
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,4 +54,4 @@ text_to_tiny.o: text_to_tiny.c
|
||||||
####
|
####
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *~ *.o *.lst D2 HELLO text_to_tiny mA2E_2.s mA2E_3.s mA2E_4.s
|
rm -f *~ *.o *.lst D4 HELLO text_to_tiny mA2E_2.s mA2E_3.s mA2E_4.s
|
||||||
|
|
|
@ -6,21 +6,8 @@
|
||||||
.include "zp.inc"
|
.include "zp.inc"
|
||||||
.include "hardware.inc"
|
.include "hardware.inc"
|
||||||
|
|
||||||
; for a 256 entry we need to fit in 252 bytes
|
|
||||||
|
|
||||||
; 310 bytes -- initial
|
d4:
|
||||||
; 268 bytes -- strip out interrupts
|
|
||||||
; 262 bytes -- simplify init
|
|
||||||
; 261 bytes -- optimize init more
|
|
||||||
; 253 bytes -- optimize var init
|
|
||||||
; 252 bytes -- bne vs jmp
|
|
||||||
; 250 bytes -- song only has 16 notes so can never be negative
|
|
||||||
; 249 bytes -- make terminating value $80 instead of $FF
|
|
||||||
; 247 bytes -- combine note loop. makes song a bit faster
|
|
||||||
; 245 bytes -- try to optimize writing out volume
|
|
||||||
; 255 bytes -- add in some visualization
|
|
||||||
; 252 bytes -- re-arrange decode code
|
|
||||||
d2:
|
|
||||||
|
|
||||||
;===================
|
;===================
|
||||||
; music Player Setup
|
; music Player Setup
|
||||||
|
@ -37,26 +24,14 @@ tracker_song = peasant_song
|
||||||
|
|
||||||
jsr SETGR ; enable lo-res graphics
|
jsr SETGR ; enable lo-res graphics
|
||||||
|
|
||||||
|
cli ; enable music
|
||||||
game_loop:
|
game_loop:
|
||||||
; typically A=0, X=FF, Y=0 here
|
|
||||||
|
|
||||||
; play a frame of music
|
|
||||||
|
|
||||||
.include "play_frame.s"
|
jmp game_loop
|
||||||
.include "ay3_write_regs.s"
|
|
||||||
|
|
||||||
; delay 20Hz, or 1/20s = 50ms
|
.include "interrupt_handler.s"
|
||||||
|
.include "mockingboard_constants.s"
|
||||||
lda #140
|
|
||||||
jsr WAIT
|
|
||||||
|
|
||||||
lda #140
|
|
||||||
jsr WAIT
|
|
||||||
|
|
||||||
lda #140
|
|
||||||
jsr WAIT
|
|
||||||
|
|
||||||
beq game_loop
|
|
||||||
|
|
||||||
; music
|
; music
|
||||||
.include "mA2E_4.s"
|
.include "mA2E_4.s"
|
||||||
|
|
68
music/tiny_tracker6/interrupt_handler.s
Normal file
68
music/tiny_tracker6/interrupt_handler.s
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
;================================
|
||||||
|
;================================
|
||||||
|
; 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
|
||||||
|
cld ; clear decimal mode
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
ay3_irq_handler:
|
||||||
|
bit MOCK_6522_T1CL ; clear 6522 interrupt by reading T1C-L ; 4
|
||||||
|
|
||||||
|
|
||||||
|
.include "play_frame.s"
|
||||||
|
.include "ay3_write_regs.s"
|
||||||
|
|
||||||
|
;=================================
|
||||||
|
; Finally done with this interrupt
|
||||||
|
;=================================
|
||||||
|
|
||||||
|
done_ay3_irq_handler:
|
||||||
|
|
||||||
|
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 ; restore flags
|
||||||
|
|
||||||
|
rti ; return from interrupt ; 6
|
||||||
|
|
||||||
|
;============
|
||||||
|
; typical
|
||||||
|
; ???? cycles
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
21
music/tiny_tracker6/mockingboard_constants.s
Normal file
21
music/tiny_tracker6/mockingboard_constants.s
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
init_addresses:
|
||||||
|
.byte <MOCK_6522_DDRB1,<MOCK_6522_DDRA1 ; set the data direction for all pins of PortA/PortB to be output
|
||||||
|
.byte <MOCK_6522_ACR,<MOCK_6522_IER ; Continuous interrupts, clear all interrupts
|
||||||
|
.byte <MOCK_6522_IFR,<MOCK_6522_IER ; enable interrupt on timer overflow
|
||||||
|
.byte <MOCK_6522_T1CL,<MOCK_6522_T1CH ; set oflow value, start counting
|
||||||
|
.byte <MOCK_6522_ORB1,<MOCK_6522_ORB1 ; reset ay-3-8910
|
||||||
|
|
||||||
|
; note, terminated by the $ff below
|
||||||
|
|
||||||
|
init_values:
|
||||||
|
.byte $ff,$ff ; set the data direction for all pins of PortA/PortB to be output
|
||||||
|
.byte $40,$7f
|
||||||
|
.byte $C0,$C0
|
||||||
|
.byte $e7,$4f ; c7ce / 1.023e6 = .050s, 20Hz
|
||||||
|
.byte MOCK_AY_RESET,MOCK_AY_INACTIVE
|
||||||
|
|
||||||
|
; c7ce / 1.023e6 = .050s, 20Hz
|
||||||
|
; 9c40 / 1.023e6 = .040s, 25Hz
|
||||||
|
; 4fe7 / 1.023e6 = .020s, 50Hz
|
||||||
|
; 411a / 1.023e6 = .016s, 60Hz
|
||||||
|
|
|
@ -66,12 +66,54 @@ mockingboard_init:
|
||||||
; Reset Left AY-3-8910
|
; Reset Left AY-3-8910
|
||||||
;===========================
|
;===========================
|
||||||
|
|
||||||
ldx #$FF
|
; ldx #$FF
|
||||||
stx MOCK_6522_DDRB1
|
; stx MOCK_6522_DDRB1
|
||||||
stx MOCK_6522_DDRA1
|
; stx MOCK_6522_DDRA1
|
||||||
|
|
||||||
inx ; #MOCK_AY_RESET $0
|
; inx ; #MOCK_AY_RESET $0
|
||||||
stx MOCK_6522_ORB1
|
; stx MOCK_6522_ORB1
|
||||||
ldx #MOCK_AY_INACTIVE ; $4
|
; ldx #MOCK_AY_INACTIVE ; $4
|
||||||
stx MOCK_6522_ORB1
|
; stx MOCK_6522_ORB1
|
||||||
|
|
||||||
|
|
||||||
|
; sei ; disable interrupts, is this necessary?
|
||||||
|
|
||||||
|
;=========================
|
||||||
|
; Setup Interrupt Handler
|
||||||
|
;=========================
|
||||||
|
|
||||||
|
; NOTE: we don't support IIc as it's a hack
|
||||||
|
; traditionally Mockingboard on IIc was rare
|
||||||
|
|
||||||
|
;========================
|
||||||
|
; set up interrupt
|
||||||
|
; Vector address goes to 0x3fe/0x3ff
|
||||||
|
|
||||||
|
; can save 10 bytes if we load in memory so this
|
||||||
|
; is in the right place automatically
|
||||||
|
|
||||||
|
lda #<interrupt_handler ; 2
|
||||||
|
sta $03fe ; 3
|
||||||
|
lda #>interrupt_handler ; 2
|
||||||
|
sta $03ff ; 3
|
||||||
|
;=========
|
||||||
|
; 10
|
||||||
|
;=========================
|
||||||
|
; Initialize the 6522s
|
||||||
|
; Reset Left AY-3-8910
|
||||||
|
;===========================
|
||||||
|
|
||||||
|
; entries=10
|
||||||
|
; 14 + 2*entries = 34 bytes
|
||||||
|
|
||||||
|
; assume Y=0 on entry?
|
||||||
|
|
||||||
|
ldy #0 ; 2
|
||||||
|
init_it_loop:
|
||||||
|
lda init_values,Y ; 3
|
||||||
|
ldx init_addresses,Y ; 3
|
||||||
|
bmi doneit ; 2
|
||||||
|
iny ; 1
|
||||||
|
sta $c400,X ; 3
|
||||||
|
bne init_it_loop ; 2
|
||||||
|
doneit:
|
||||||
|
|
|
@ -3,6 +3,15 @@ play_frame:
|
||||||
;============================
|
;============================
|
||||||
; see if still counting down
|
; see if still counting down
|
||||||
|
|
||||||
|
lda SONG_COUNTDOWN
|
||||||
|
; rotate through channel A volume
|
||||||
|
|
||||||
|
tya
|
||||||
|
and #$7
|
||||||
|
tay
|
||||||
|
lda channel_a_volume,Y
|
||||||
|
sta AY_REGS+8
|
||||||
|
|
||||||
lda SONG_COUNTDOWN
|
lda SONG_COUNTDOWN
|
||||||
bpl done_update_song
|
bpl done_update_song
|
||||||
|
|
||||||
|
@ -17,9 +26,8 @@ set_notes_loop:
|
||||||
;==================
|
;==================
|
||||||
; see if hit end
|
; see if hit end
|
||||||
|
|
||||||
; this song only 16 notes so valid notes always positive
|
cmp #$ff
|
||||||
; cmp #$80
|
bne not_end
|
||||||
bpl not_end
|
|
||||||
|
|
||||||
;====================================
|
;====================================
|
||||||
; if at end, loop back to beginning
|
; if at end, loop back to beginning
|
||||||
|
@ -30,14 +38,15 @@ set_notes_loop:
|
||||||
|
|
||||||
not_end:
|
not_end:
|
||||||
|
|
||||||
|
|
||||||
; NNNNNNEC -- c=channel, e=end, n=note
|
; NNNNNNEC -- c=channel, e=end, n=note
|
||||||
|
|
||||||
pha ; save note
|
pha ; save note
|
||||||
|
|
||||||
and #1
|
and #1
|
||||||
tax
|
; tax
|
||||||
ldy #$0E
|
; ldy #$0E
|
||||||
sty AY_REGS+8,X ; $08 set volume A,B
|
; sty AY_REGS+8,X ; $08 set volume A,B
|
||||||
|
|
||||||
asl
|
asl
|
||||||
tax ; put channel offset in X
|
tax ; put channel offset in X
|
||||||
|
@ -46,6 +55,9 @@ not_end:
|
||||||
pla ; restore note
|
pla ; restore note
|
||||||
tay
|
tay
|
||||||
and #$2
|
and #$2
|
||||||
|
asl
|
||||||
|
asl
|
||||||
|
asl
|
||||||
sta SONG_COUNTDOWN ; always 2 long?
|
sta SONG_COUNTDOWN ; always 2 long?
|
||||||
|
|
||||||
tya
|
tya
|
||||||
|
@ -76,3 +88,9 @@ blah_urgh:
|
||||||
done_update_song:
|
done_update_song:
|
||||||
dec SONG_COUNTDOWN
|
dec SONG_COUNTDOWN
|
||||||
bmi set_notes_loop
|
bmi set_notes_loop
|
||||||
|
bpl skip_data
|
||||||
|
|
||||||
|
channel_a_volume:
|
||||||
|
.byte 14,14,14,14,11,11,10,10
|
||||||
|
|
||||||
|
skip_data:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user