tiny_tracker: more work

This commit is contained in:
Vince Weaver 2022-01-11 02:59:52 -05:00
parent b7cd2f386a
commit 2226c02233
15 changed files with 414 additions and 162 deletions

View File

@ -1,69 +0,0 @@
; Apple II graphics/music in 1k
; by deater (Vince Weaver) <vince@deater.net>
; Zero Page
.include "zp.inc"
.include "hardware.inc"
; 466 bytes -- original from D2 demo
; 436 bytes -- left channel only
; 427 bytes -- optimize init a bit
; 426 bytes -- terminate init with $FF rather than extra $00
; 424 bytes -- move inits to zero together
; 414 bytes -- update ay output to write all registers
; 405 bytes -- more optimizing the interrupt handler
; 398 bytes -- only put song address one place
; 393 bytes -- don't keep song offset in Y
; 390 bytes -- use Y instead of X
; 388 bytes -- optimizing octave selection
; 373 bytes -- completely redo file format to avoid freq table
d2:
;===================
; music Player Setup
tracker_song = peasant_song
; lda #<peasant_song
; sta SONG_L
; lda #>peasant_song
; sta SONG_H
; assume mockingboard in slot#4
; inline mockingboard_init
.include "mockingboard_init.s"
.include "tracker_init.s"
; start the music playing
cli
bob:
jmp bob
;================
; halt music
; stop playing
; turn off sound
its_over:
sei
lda #$3f
sta AY_REGS+7
jsr ay3_write_regs
stuck_forever:
bne stuck_forever
; music
.include "mA2E_2.s"
.include "interrupt_handler.s"
; must be last
.include "mockingboard_setup.s"

View File

@ -1,12 +0,0 @@
tracker_init:
; setup initial ay-3-8910 values (this depends on song)
lda #$38
sta AY_REGS+7 ; $07 mixer (ABC on)
lda #$0E
sta AY_REGS+8 ; $08 volume A
lda #$0C
sta AY_REGS+9 ; $09 volume B
sta AY_REGS+10 ; $0A volume C

View File

@ -43,6 +43,11 @@ peasant_music.s: peasant.txt text_to_tiny
mA2E_2.s: mA2E_2.txt text_to_tiny
./text_to_tiny mA2E_2.txt > mA2E_2.s
####
mA2E_3.s: mA2E_3.txt text_to_tiny
./text_to_tiny mA2E_3.txt > mA2E_3.s
####
@ -51,9 +56,9 @@ D2: d2.o
d2.o: d2.s \
zp.inc hardware.inc \
mA2E_2.s \
interrupt_handler.s mockingboard_setup.s mockingboard_init.s \
tracker_init.s
mA2E_2.s mA2E_3.s \
interrupt_handler.s mockingboard_init.s \
tracker_init.s mockingboard_constants.s ay3_write_regs.s
ca65 -o d2.o d2.s -l d2.lst
####

View File

@ -6,7 +6,7 @@
;=====================
;=====================
;=====================
; write all 13 registers
; write all 14 registers
; address in X
; data in A
@ -23,7 +23,7 @@ ay3_write_reg_loop:
sty MOCK_6522_ORB1 ; 4
; value
lda $70,X
lda AY_REGS,X
sta MOCK_6522_ORA1 ; put value on PA1 ; 4
lda #MOCK_AY_WRITE ; ; 2
sta MOCK_6522_ORB1 ; write on PB1 ; 4
@ -32,23 +32,6 @@ ay3_write_reg_loop:
dex
bpl ay3_write_reg_loop
rts
; rts
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 $CE,$C7 ; c7ce / 1.023e6 = .050s, 20Hz
.byte MOCK_AY_RESET,MOCK_AY_INACTIVE

54
demos/l/d4/d2.s Normal file
View File

@ -0,0 +1,54 @@
; Apple II graphics/music in 1k
; by deater (Vince Weaver) <vince@deater.net>
; Zero Page
.include "zp.inc"
.include "hardware.inc"
; goal is 332 bytes
; 319 bytes -- switch songs to mA2E_3
; 415 bytes -- double length of song
; 334 bytes -- merge length into value
; if can straddle interrupt vector, save 10 bytes
; if can guarantee Y is 0 on entry, save 2 bytes
d2:
;===================
; music Player Setup
tracker_song = peasant_song
; assume mockingboard in slot#4
; inline mockingboard_init
.include "mockingboard_init.s"
.include "tracker_init.s"
; start the music playing
cli
bob:
lda KEYPRESS
bpl bob
quiet:
lda #$3f
sta AY_REGS+7
end:
bne end
; music
.include "mA2E_3.s"
.include "interrupt_handler.s"
; must be last
.include "mockingboard_constants.s"

View File

@ -40,6 +40,18 @@ ay3_irq_handler:
bit MOCK_6522_T1CL
; drop note down after first
lda #$C
sta AY_REGS+8
sta AY_REGS+10
; lda #$0E
; sta AY_REGS+8 ; $08 volume A
; lda #$0C
; sta AY_REGS+9 ; $09 volume B
; sta AY_REGS+10 ; $0A volume C
;============================
; see if still counting down
@ -57,7 +69,7 @@ set_notes_loop:
;==================
; see if hit end
cmp #$C0
cmp #$FF
bne all_ok
;====================================
@ -71,25 +83,37 @@ all_ok:
; see if note
tay
and #$C0
cmp #$C0
beq handle_timing
; tay
; and #$C0
; cmp #$C0
; beq handle_timing
note_only:
; tya
; NNNNNLLC -- c=channel, n=note
tay
ldx #0
lsr
bcc channel_a
ldx #4 ; skip to C
channel_a:
and #$3
sta SONG_COUNTDOWN
; inc SONG_COUNTDOWN
tya
; CCXNNNNN -- c=channel, n=note
lsr
lsr
lsr
lsr
lsr
lsr
lsr
lsr
and #$FE ; fine register value, want in X
tax
; and #$FE ; fine register value, want in X
; tax
tya ; get note
and #$1F
; tya ; get note
; and #$1F
tay ; lookup in table
lda frequencies_low,Y
@ -98,27 +122,38 @@ note_only:
lda frequencies_high,Y
sta AY_REGS+1,X
jsr ay3_write_regs ; trashes A/X/Y
lda #$F
sta AY_REGS+8
;============================
; point to next
; assume less than 256 bytes
inc SONG_OFFSET
; assume less than 256 bytes
bne set_notes_loop ; bra
lda SONG_COUNTDOWN
beq set_notes_loop ; bra
.include "ay3_write_regs.s"
; jsr ay3_write_regs
handle_timing:
; was timing
tya
; tya
and #$3f
sta SONG_COUNTDOWN
; and #$3f
; sta SONG_COUNTDOWN
inc SONG_OFFSET
; inc SONG_OFFSET
done_update_song:
dec SONG_COUNTDOWN
@ -147,3 +182,8 @@ done_ay3_irq_handler:
; typical
; ???? cycles

145
demos/l/d4/mA2E_3.txt Normal file
View File

@ -0,0 +1,145 @@
'' TITLE: Mockingboard Tune 3 - 2021
' AUTHOR: mA2E / dSr
' COMMENTS:
'
' LOOP: 640
'
' BPM: 250
' TEMPO: 6
' FREQ: 1000000
' IRQ: 50
'
' LYRICS: 0
'
' ENDHEADER
-------
' 1
0 G 3-- ----- G 6--
1 ----- ----- -----
2 ----- ----- -----
3 G 4-- ----- D 6--
4 ----- ----- -----
5 F 3-- ----- -----
6 G 3- ----- A#5--
7 ----- ----- -----
8 G 3-- ----- G 5--
9 ----- ----- -----
A ----- ----- -----
B G 4-- ----- A#5--
C ----- ----- -----
D F 3-- ----- -----
E G 3-- ----- D 6--
F ----- ----- -----
10 D#3-- ----- G 6--
11 ----- ----- -----
12 ----- ----- -----
13 D#4-- ----- D#6--
14 ----- ----- -----
15 D 3- ----- -----
16 D#3-- ----- A#5--
17 ----- ----- -----
18 D#3-- ----- G 5--
19 ----- ----- -----
1A ----- ----- -----
1B D#4-- ----- A#5--
1C ----- ----- -----
1D D 3-- ----- -----
1E D#3-- ----- G 6--
1F ----- ----- -----
20 F 3-- ----- F 6--
21 ----- ----- -----
22 ----- ----- -----
23 F 4-- ----- -----
24 ----- ----- C 6--
25 D#3-- ----- -----
26 F 3-- ----- A 5--
27 ----- ----- -----
28 F 3-- ----- F 5--
29 ----- ----- -----
2A ----- ----- -----
2B F 4-- ----- A 5--
2C ----- ----- -----
2D D#3-- ----- -----
2E F 3-- ----- D#6--
2F ----- ----- -----
30 D 3-- ----- D 6--
31 ----- ----- -----
32 ----- ----- -----
33 D 4-- ----- D#6--
34 ----- ----- -----
35 C 3-- ----- -----
36 D 3-- ----- D 6--
37 ----- ----- -----
38 D 3-- ----- C 6--
39 ----- ----- -----
3A ----- ----- -----
3B D 4-- ----- A#5--
3C ----- ----- -----
3D C 3-- ----- -----
3E D 3-- ----- A 5--
3F ----- ----- -----
' 1
0 G 3-- ----- G 6--
1 ----- ----- -----
2 ----- ----- -----
3 G 4-- ----- -----
4 ----- ----- -----
5 F 3-- ----- -----
6 G 3- ----- F 6--
7 ----- ----- D 6--
8 G 3-- ----- G 5--
9 ----- ----- -----
A ----- ----- -----
B G 4-- ----- -----
C ----- ----- A#5--
D F 3-- ----- -----
E G 3-- ----- C 6--
F ----- ----- -----
10 D#3-- ----- G 6--
11 ----- ----- -----
12 ----- ----- -----
13 D#4-- ----- -----
14 ----- ----- -----
15 D 3- ----- -----
16 D#3-- ----- F 6--
17 ----- ----- G 6--
18 D#3-- ----- D#6--
19 ----- ----- -----
1A ----- ----- -----
1B D#4-- ----- -----
1C ----- ----- D 6--
1D D 3-- ----- -----
1E D#3-- ----- A#5--
1F ----- ----- -----
20 F 3-- ----- C 6--
21 ----- ----- -----
22 ----- ----- -----
23 F 4-- ----- -----
24 ----- ----- -----
25 D#3-- ----- -----
26 F 3-- ----- A#5--
27 ----- ----- C 6--
28 F 3-- ----- A 5--
29 ----- ----- -----
2A ----- ----- -----
2B F 4-- ----- -----
2C ----- ----- G 5--
2D D#3-- ----- -----
2E F 3-- ----- A 5--
2F ----- ----- -----
30 D 3-- ----- F 5--
31 ----- ----- -----
32 ----- ----- -----
33 D 4-- ----- G 5--
34 ----- ----- -----
35 C 3-- ----- -----
36 D 3-- ----- A 5--
37 ----- ----- -----
38 D 3-- ----- -----
39 ----- ----- C 6--
3A ----- ----- -----
3B D 4-- ----- -----
3C ----- ----- F 5--
3D C 3-- ----- -----
3E D 3-- ----- -----
3F ----- ----- -----

View File

@ -0,0 +1,16 @@
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 $CE,$C7 ; c7ce / 1.023e6 = .050s, 20Hz
.byte MOCK_AY_RESET,MOCK_AY_INACTIVE

View File

@ -61,7 +61,7 @@ MOCK_AY_LATCH_ADDR = $7 ; 1 1 1
mockingboard_init:
sei ; disable interrupts, is this necessary?
; sei ; disable interrupts, is this necessary?
;=========================
; Setup Interrupt Handler
@ -74,13 +74,15 @@ mockingboard_init:
; set up interrupt
; Vector address goes to 0x3fe/0x3ff
lda #<interrupt_handler
sta $03fe
lda #>interrupt_handler
sta $03ff
; 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
@ -88,9 +90,8 @@ mockingboard_init:
; entries=10
; 14 + 2*entries = 34 bytes
; to beat = 46 bytes
ldy #0
ldy #0 ; 2
init_it_loop:
lda init_values,Y ; 3
ldx init_addresses,Y ; 3
@ -101,18 +102,4 @@ init_it_loop:
doneit:
init_registers_to_zero:
ldx #13
lda #0
sta SONG_OFFSET ; also init song stuff
sta SONG_COUNTDOWN
init_loop:
sta AY_REGS,X
dex
bne init_loop
jsr ay3_write_regs

View File

@ -18,17 +18,22 @@ static int octave_adjust=0;
static int notes_used[64];
static int allocated_notes[64];
static int notes_allocated=0;
static int total_len=0;
unsigned short frequencies[]={
//C C# D D# E F F# G G# A A# B
//0x7A3,0x735,0x6CD,0x66C,0x60F,0x5B8,0x566,0x518,0x4CF,0x48A,0x449,0x40B,
0x3D1,0x39A,0x366,0x336,0x307,0x2DC,0x2B3,0x28C,0x267,0x245,0x224,0x205,
0x1E8,0x1CD,0x1B3,0x19B,0x183,0x16E,0x159,0x146,0x133,0x122,0x112,0x102, //3
0x0F4,0x0E6,0x0D9,0x0CD,0x0C1,0x0B7,0x0AC,0x0A3,0x099,0x091,0x089,0x081, //4
0x07A,0x073,0x06C,0x066,0x060,0x05B,0x056,0x051,0x04C,0x048,0x044,0x040, //5
0x03D,0x039,0x036,0x033,0x030,0x02D,0x02B,0x028,0x026,0x024,0x022,0x020, //6
//0x03D,0x039,0x036,0x033,0x030,0x02D,0x02B,0x028,0x026,0x024,0x022,0x020, //6
//0x01E,0x01C,0x01B,0x019,0x018,0x016,0x015,0x014,0x013,0x012,0x011,0x010,
//0x00F,0x00E,0x00D,0x00C,0x00C,0x00B,0x00A,0x00A,0x009,0x009,0x008,0x008,
};
// CCOONNNN -- c=channel, o=octave, n=note
// CLLNNNN
int note_to_ed(char note, int flat, int sharp, int octave) {
@ -315,6 +320,8 @@ int main(int argc, char **argv) {
// int a_len=0,b_len=0,a_freq=0,b_freq=0;
int current_length=0;
int first=1;
int a_last=-1,c_last=-1;
unsigned char temp_value;
printf("peasant_song:\n");
printf("; register init\n");
@ -354,44 +361,86 @@ printf("\n");
if (a.ed_freq>=0) {
a.offset=allocate_note(a.ed_freq);
notes_used[a.ed_freq]++;
fprintf(stderr,"A: %d\n",a.ed_freq);
printf("; A: %d\n",a.ed_freq);
}
if (b.ed_freq>=0) {
b.offset=allocate_note(b.ed_freq);
notes_used[b.ed_freq]++;
fprintf(stderr,"B: %d\n",b.ed_freq);
printf("; B: %d\n",b.ed_freq);
}
if (c.ed_freq>=0) {
c.offset=allocate_note(c.ed_freq);
notes_used[c.ed_freq]++;
fprintf(stderr,"C: %d\n",c.ed_freq);
printf("; C: %d\n",c.ed_freq);
}
if ((a.ed_freq>=0)||(b.ed_freq>=0)||(c.ed_freq>=0)) {
printf("; none: a=%d c=%d len=%d\n",a_last,c_last,current_length);
//NNNNNLLC
if (!first) {
printf("\t.byte $%02X ; L = %d\n",
current_length|0xc0,current_length);
printf("\n");
current_length=0;
if (a_last>=0) {
temp_value=(a_last<<3)|0;
if (c_last<0) temp_value|=(current_length<<1);
printf("\t.byte $%02X ; A=%d L=%d\n",
temp_value,
a_last,c_last>=0?0:current_length);
total_len++;
a_last=-1;
}
if (c_last>=0) {
printf("\t.byte $%02X ; C=%d L=%d\n",
(unsigned char)(c_last<<3)|((current_length)<<1)|1,
c_last,current_length);
total_len++;
c_last=-1;
}
}
current_length=0;
//if (!first) {
// printf("\t.byte $%02X ; L = %d\n",
// current_length|0xc0,current_length);
// printf("\n");
// current_length=0;
// total_len++;
//}
first=0;
}
if (a.ed_freq>=0) {
a_last=a.offset;
}
if (b.ed_freq>=0) {
}
if (c.ed_freq>=0) {
c_last=c.offset;
}
#if 0
if (a.ed_freq>=0) {
printf("\t.byte $%02X ; A = %c%c%d freq=%d offset=%d\n",
a.offset,
a.note,sharp_char[a.sharp+2*a.flat],
a.octave,
a.ed_freq,a.offset);
total_len++;
}
if (b.ed_freq>=0) {
printf("\t.byte $%02X ; B = %c%c%d\n",
b.offset|0x40,
b.note,sharp_char[b.sharp+2*b.flat],
b.octave);
total_len++;
}
if (c.ed_freq>=0) {
printf("\t.byte $%02X ; C = %c%c%d freq=%d offset=%d\n",
@ -399,14 +448,41 @@ printf("\n");
c.note,sharp_char[c.sharp+2*c.flat],
c.octave,
c.ed_freq,c.offset);
total_len++;
}
#endif
current_length++;
}
printf("\t.byte $C0 ; end\n");
printf("; last: a=%d c=%d len=%d\n",a_last,c_last,current_length);
if (a_last>=0) {
temp_value=(a_last<<3)|0;
if (c_last<0) temp_value|=(current_length<<1);
printf("\t.byte $%02X ; A=%d L=%d\n",
temp_value,
a_last,c_last>=0?0:current_length);
total_len++;
a_last=-1;
}
if (c_last>=0) {
printf("\t.byte $%02X ; C=%d L=%d\n",
(unsigned char)(c_last<<3)|((current_length)<<1)|1,
c_last,current_length);
total_len++;
c_last=-1;
}
// printf("\t.byte $%02X ; L = %d\n",
// current_length|0xc0,current_length);
// printf("\n");
printf("\t.byte $FF ; end\n");
total_len++;
int o,n;
@ -431,6 +507,7 @@ printf("\n");
for(n=0;n<notes_allocated;n++) {
printf("$%02X",(frequencies[allocated_notes[n]]>>8));
if (n!=(notes_allocated-1)) printf(",");
total_len++;
}
printf("\n");
@ -440,9 +517,12 @@ printf("\n");
for(n=0;n<notes_allocated;n++) {
printf("$%02X",(frequencies[allocated_notes[n]])&0xff);
if (n!=(notes_allocated-1)) printf(",");
total_len++;
}
printf("\n");
printf("; total len=%d\n",total_len);
(void) irq;
(void) loop;
(void) external_frequency;

23
demos/l/d4/tracker_init.s Normal file
View File

@ -0,0 +1,23 @@
tracker_init:
; setup initial ay-3-8910 values (this depends on song)
init_registers_to_zero:
ldx #13
lda #0
sta SONG_OFFSET ; also init song stuff
sta SONG_COUNTDOWN
init_loop:
sta AY_REGS,X
dex
bpl init_loop
; jsr ay3_write_regs
lda #$38
sta AY_REGS+7 ; $07 mixer (ABC on)
; lda #$0E
; sta AY_REGS+8 ; $08 volume A
; lda #$0C
; sta AY_REGS+9 ; $09 volume B
; sta AY_REGS+10 ; $0A volume C