tiny_music: have it playing three channels

This commit is contained in:
Vince Weaver 2021-11-02 16:48:35 -04:00
parent 16908b61c6
commit 0fb112fb3c
5 changed files with 266 additions and 25 deletions

View File

@ -27,6 +27,7 @@ MUSIC: music.o
music.o: music.s \
zp.inc hardware.inc nozp.inc \
yankee_music.s \
interrupt_handler.s mockingboard_setup.s
ca65 -o music.o music.s -l music.lst

View File

@ -35,31 +35,76 @@ interrupt_handler:
pt3_irq_handler:
bit MOCK_6522_T1CL ; clear 6522 interrupt by reading T1C-L ; 4
; set note A
; see if still counting down
lda SONG_COUNTDOWN
bpl done_update_song
try_again:
ldy SONG_OFFSET
set_notes_loop:
; see if hit end
lda (SONG_L),Y
cmp #$FF
bne all_ok
; if at end, reset
lda #0
sta SONG_OFFSET
beq try_again
all_ok:
; see if note
tax
and #$C0
cmp #$C0
bne note_only
; was timing
txa
and #$3f
sta SONG_COUNTDOWN
iny
sty SONG_OFFSET
jmp done_update_song
note_only:
txa
; CCOONNNN -- c=channel, o=octave, n=note
; FIXME: OONNNNCC instead?
pha
lsr
lsr
lsr
lsr
lsr
and #$FE
sta out_smc+1
pla
and #$3F
tax
lda frequency_lookup,X
sty y_smc+1
out_smc:
ldx #$00
lda #$F4
jsr pt3_write_reg
jsr pt3_write_reg ; trashes A/X/Y
; set coarse note A
; set coarse note A (assume 0)
; could get extra octave by putting 1 here
ldx #$01
lda #$00
jsr pt3_write_reg
; set mixer ABC enabled
ldx #$07
lda #$38
jsr pt3_write_reg
; A volume 14
ldx #$08
lda #$E
jsr pt3_write_reg
y_smc:
ldy #0
iny
jmp set_notes_loop
done_update_song:
dec SONG_COUNTDOWN
;=================================
@ -134,3 +179,6 @@ pt3_write_reg:
sta MOCK_6522_ORB2 ; write on PB2 ; 4
sty MOCK_6522_ORB2 ; 4
rts

View File

@ -241,8 +241,9 @@ done_iic_hack:
; Note, on Apple II the clock isn't 1MHz but is actually closer to
; roughly 1.023MHz, and every 65th clock is stretched (it's complicated)
; 4fe7 / 1.023e6 = .020s, 50Hz
; 9c40 / 1.023e6 = .040s, 25Hz
; 8534 / 1.023e6 = .033s, 30Hz
; 4fe7 / 1.023e6 = .020s, 50Hz
; 411a / 1.023e6 = .016s, 60Hz
; French Touch uses
@ -263,15 +264,61 @@ setup_irq_smc3:
setup_irq_smc4:
sta MOCK_6522_IER ; IER: 1100, enable timer one interrupt
lda #$E7
; lda #$20
lda #$34
; lda #$E7
setup_irq_smc5:
sta MOCK_6522_T1CL ; write into low-order latch
lda #$4f
; lda #$4E
lda #$85
; lda #$4f
setup_irq_smc6:
sta MOCK_6522_T1CH ; write into high-order latch,
; load both values into counter
; clear interrupt and start counting
rts
init_registers:
; set fine note A
ldx #$00
lda #$00
jsr pt3_write_reg
; set coarse note A
ldx #$01
lda #$00
jsr pt3_write_reg
; set mixer ABC enabled
ldx #$07
lda #$38
jsr pt3_write_reg
; A volume 14
ldx #$08
lda #$E
jsr pt3_write_reg
; B volume 12
ldx #$09
lda #$C
jsr pt3_write_reg
; C volume 12
ldx #$0A
lda #$C
jsr pt3_write_reg
rts

View File

@ -1,9 +1,16 @@
; Tiny Mockingboard Player
SONG_L = $70
SONG_H = $71
SONG_OFFSET = $72
SONG_COUNTDOWN = $73
; proposed format
; CCOONNNN -- c=channel, o=octave, n=note
; 11LLLLLL -- L=length
; 11LLLLLL -- wait time
; by deater (Vince Weaver) <vince@deater.net>
@ -27,6 +34,16 @@ tiny_music:
lda #1
sta LOOP
lda #<song_track_a
sta SONG_L
lda #>song_track_a
sta SONG_H
lda #0
sta SONG_OFFSET
sta SONG_COUNTDOWN
; assume mockingboard in slot#4
jsr mockingboard_init
@ -34,13 +51,17 @@ tiny_music:
jsr reset_ay_both
jsr clear_ay_both
jsr init_registers
start_interrupts:
cli
rts
forever:
jmp forever
.include "mockingboard_setup.s"
.include "interrupt_handler.s"
.include "nozp.inc"
.include "yankee_music.s"

View File

@ -0,0 +1,124 @@
; 0 1 2 3 4 5 6 7 8 9 10 11
; C C# D D# E F F# G G# A A# B
; CCOONNNN -- c=channel, o=octave, n=note
; 11LLLLLL -- L=length 1/32=1, 1/16=2, 1/8=4, 1/4=8 1/2=16 1=32
song_track_a:
.byte $17 ;00 01 0111 G3 1/4
.byte $4B ;01 00 1011 B2 1
.byte $87 ;10 00 0111 G2 1
.byte $C8 ;11 00 1000 wait 1/4
.byte $17 ;00 01 0111 G3
.byte $C8 ;11 00 1000 wait 1/4
.byte $19 ;00 01 1001 A3
.byte $C8 ;11 00 1000 wait 1/4
.byte $1B ;00 01 1011 B3
.byte $C8 ;11 00 1000 wait 1/4
;
.byte $17 ;00 01 0111 G3
.byte $4B ;01 00 1011 B2 1/2
.byte $87 ;10 00 0111 G2 1/2
.byte $C8 ;11 00 1000 wait 1/4
.byte $1B ;00 01 1011 B3
.byte $C8 ;11 00 1000 wait 1/4
.byte $19 ;00 01 1001 A3
.byte $58 ;01 01 1000 C3 1/2
.byte $82 ;10 00 0010 D2 1/2
.byte $C8 ;11 00 1000 wait 1/4
.byte $12 ;00 01 0010 D3
.byte $C8 ;11 00 1000 wait 1/4
;
.byte $17 ;00 01 0111 G3
.byte $4B ;01 00 1011 B2 1
.byte $87 ;10 00 0111 G2 1
.byte $C8 ;11 00 1000 wait 1/4
.byte $17 ;00 01 0111 G3
.byte $C8 ;11 00 1000 wait 1/4
.byte $19 ;00 01 1001 A3
.byte $C8 ;11 00 1000 wait 1/4
.byte $1B ;00 01 1011 B3
.byte $C8 ;11 00 1000 wait 1/4
;
.byte $17 ;00 01 0111 G3
.byte $4B ;01 00 1011 B2 1/2
.byte $87 ;10 00 0111 G2 1/2
.byte $D0 ;11 01 0000 wait 1/2
.byte $16 ;00 01 0110 F#3
.byte $42 ;01 00 0010 D2 1
.byte $90 ;10 01 0000 C3 1
.byte $C8 ;11 00 1000 wait 1/4
.byte $12 ;00 01 0010 D3
.byte $C8 ;11 00 1000 wait 1/4
;
.byte $17 ;00 01 0111 G3
.byte $4B ;01 00 1011 B2 1/2
.byte $87 ;10 00 0111 G2 1/2
.byte $C8 ;11 00 1000 wait 1/4
.byte $17 ;00 01 0111 G3
.byte $C8 ;11 00 1000 wait 1/4
.byte $19 ;00 01 1001 A3
.byte $46 ;01 00 0110 F#2 1/2
.byte $86 ;10 00 0110 F#2 1/2
.byte $C8 ;11 00 1000 wait 1/4
.byte $1B ;00 01 1011 B3
.byte $C8 ;11 00 1000 wait 1/4
;
.byte $20 ;00 10 0000 C4
.byte $44 ;01 00 0100 E2 1/2
.byte $84 ;10 00 0100 E2 1/2
.byte $C8 ;11 00 1000 wait 1/4
.byte $1B ;00 01 1011 B3
.byte $C8 ;11 00 1000 wait 1/4
.byte $19 ;00 01 1001 A3
.byte $41 ;01 00 0001 C#2 1/2
.byte $81 ;10 00 0001 C#2 1/2
.byte $C8 ;11 00 1000 wait 1/4
.byte $17 ;00 01 0111 G3
.byte $C8 ;11 00 1000 wait 1/4
;
.byte $16 ;00 01 0110 F#3
.byte $42 ;01 00 0020 D2 1
.byte $82 ;10 00 0020 D2 1
.byte $C8 ;11 00 1000 wait 1/4
.byte $12 ;00 01 0010 D3
.byte $C8 ;11 00 1000 wait 1/4
.byte $14 ;00 01 0100 E3
.byte $C8 ;11 00 1000 wait 1/4
.byte $16 ;00 01 0110 F#3
.byte $C8 ;11 00 1000 wait 1/4
;
.byte $17 ;00 01 0111 G3
.byte $47 ;01 00 0111 G2 1/2
.byte $87 ;10 00 0111 G2 1/2
.byte $D0 ;11 01 0000 wait 1/2
.byte $17 ;00 01 0111 G3
.byte $4B ;01 00 1011 B1 1/2
.byte $8B ;10 00 1011 B1 1/2
.byte $D0 ;11 01 0000 wait 1/2
.byte $FF