From 8b4da6c460ca2d1c6896735f143af196465148da Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Thu, 4 Nov 2021 17:19:21 -0400 Subject: [PATCH] tiny_tracker: make tiny tracker --- {demos => music}/tiny_music/Makefile | 0 {demos => music}/tiny_music/hardware.inc | 0 {demos => music}/tiny_music/hello.bas | 0 .../tiny_music/interrupt_handler.s | 0 .../tiny_music/mockingboard_setup.s | 0 .../music.s => music/tiny_music/yankee.s | 0 {demos => music}/tiny_music/yankee_music.s | 0 {demos => music}/tiny_music/zp.inc | 0 music/tiny_tracker/Makefile | 54 ++ .../tiny_tracker}/frequency.c | 0 music/tiny_tracker/hardware.inc | 87 +++ music/tiny_tracker/hello.bas | 2 + music/tiny_tracker/interrupt_handler.s | 136 ++++ music/tiny_tracker/mockingboard_setup.s | 243 +++++++ music/tiny_tracker/peasant.s | 57 ++ .../tiny_tracker}/peasant.txt | 112 ++-- music/tiny_tracker/peasant_music.s | 596 ++++++++++++++++++ music/tiny_tracker/text_to_tiny.c | 372 +++++++++++ music/tiny_tracker/zp.inc | 29 + 19 files changed, 1632 insertions(+), 56 deletions(-) rename {demos => music}/tiny_music/Makefile (100%) rename {demos => music}/tiny_music/hardware.inc (100%) rename {demos => music}/tiny_music/hello.bas (100%) rename {demos => music}/tiny_music/interrupt_handler.s (100%) rename {demos => music}/tiny_music/mockingboard_setup.s (100%) rename demos/tiny_music/music.s => music/tiny_music/yankee.s (100%) rename {demos => music}/tiny_music/yankee_music.s (100%) rename {demos => music}/tiny_music/zp.inc (100%) create mode 100644 music/tiny_tracker/Makefile rename {demos/tiny_music => music/tiny_tracker}/frequency.c (100%) create mode 100644 music/tiny_tracker/hardware.inc create mode 100644 music/tiny_tracker/hello.bas create mode 100644 music/tiny_tracker/interrupt_handler.s create mode 100644 music/tiny_tracker/mockingboard_setup.s create mode 100644 music/tiny_tracker/peasant.s rename {demos/tiny_music => music/tiny_tracker}/peasant.txt (91%) create mode 100644 music/tiny_tracker/peasant_music.s create mode 100644 music/tiny_tracker/text_to_tiny.c create mode 100644 music/tiny_tracker/zp.inc diff --git a/demos/tiny_music/Makefile b/music/tiny_music/Makefile similarity index 100% rename from demos/tiny_music/Makefile rename to music/tiny_music/Makefile diff --git a/demos/tiny_music/hardware.inc b/music/tiny_music/hardware.inc similarity index 100% rename from demos/tiny_music/hardware.inc rename to music/tiny_music/hardware.inc diff --git a/demos/tiny_music/hello.bas b/music/tiny_music/hello.bas similarity index 100% rename from demos/tiny_music/hello.bas rename to music/tiny_music/hello.bas diff --git a/demos/tiny_music/interrupt_handler.s b/music/tiny_music/interrupt_handler.s similarity index 100% rename from demos/tiny_music/interrupt_handler.s rename to music/tiny_music/interrupt_handler.s diff --git a/demos/tiny_music/mockingboard_setup.s b/music/tiny_music/mockingboard_setup.s similarity index 100% rename from demos/tiny_music/mockingboard_setup.s rename to music/tiny_music/mockingboard_setup.s diff --git a/demos/tiny_music/music.s b/music/tiny_music/yankee.s similarity index 100% rename from demos/tiny_music/music.s rename to music/tiny_music/yankee.s diff --git a/demos/tiny_music/yankee_music.s b/music/tiny_music/yankee_music.s similarity index 100% rename from demos/tiny_music/yankee_music.s rename to music/tiny_music/yankee_music.s diff --git a/demos/tiny_music/zp.inc b/music/tiny_music/zp.inc similarity index 100% rename from demos/tiny_music/zp.inc rename to music/tiny_music/zp.inc diff --git a/music/tiny_tracker/Makefile b/music/tiny_tracker/Makefile new file mode 100644 index 00000000..bf159ee3 --- /dev/null +++ b/music/tiny_tracker/Makefile @@ -0,0 +1,54 @@ +include ../../Makefile.inc + +DOS33 = ../../utils/dos33fs-utils/dos33 +EMPTY_DISK = ../../empty_disk +HGR2PNG = ../../utils/hgr-utils/png2hgr +LINKER_SCRIPTS = ../../linker_scripts +TOKENIZE = ../../utils/asoft_basic-utils/tokenize_asoft + +all: tiny_tracker.dsk text_to_tiny + +tiny_tracker.dsk: HELLO PEASANT + cp $(EMPTY_DISK)/empty.dsk ./tiny_tracker.dsk + $(DOS33) -y tiny_tracker.dsk SAVE A HELLO + $(DOS33) -y tiny_tracker.dsk -t BIN -a 0x2000 BSAVE PEASANT + +#### + +HELLO: hello.bas + $(TOKENIZE) < hello.bas > HELLO + +#### + +YANKEE: yankee.o + ld65 -o YANKEE yankee.o -C $(LINKER_SCRIPTS)/apple2_2000.inc + +yankee.o: yankee.s \ + zp.inc hardware.inc \ + yankee_music.s \ + interrupt_handler.s mockingboard_setup.s + ca65 -o yankee.o yankee.s -l yankee.lst + +#### + +PEASANT: peasant.o + ld65 -o PEASANT peasant.o -C $(LINKER_SCRIPTS)/apple2_2000.inc + +peasant.o: peasant.s \ + zp.inc hardware.inc \ + peasant_music.s \ + interrupt_handler.s mockingboard_setup.s + ca65 -o peasant.o peasant.s -l peasant.lst + +#### + +text_to_tiny: text_to_tiny.o + $(CC) -o text_to_tiny text_to_tiny.o -lm + +text_to_tiny.o: text_to_tiny.c + $(CC) $(CFLAGS) -c text_to_tiny.c + +#### + +clean: + rm -f *~ *.o *.lst YANKEE PEASANT HELLO text_to_tiny diff --git a/demos/tiny_music/frequency.c b/music/tiny_tracker/frequency.c similarity index 100% rename from demos/tiny_music/frequency.c rename to music/tiny_tracker/frequency.c diff --git a/music/tiny_tracker/hardware.inc b/music/tiny_tracker/hardware.inc new file mode 100644 index 00000000..2eb9901e --- /dev/null +++ b/music/tiny_tracker/hardware.inc @@ -0,0 +1,87 @@ +;; HARDWARE LOCATIONS + +KEYPRESS = $C000 +KEYRESET = $C010 + +;; SOFT SWITCHES +CLR80COL = $C000 ; PAGE0/PAGE1 normal +SET80COL = $C001 ; PAGE0/PAGE1 switches PAGE0 in Aux instead +EIGHTYCOLOFF = $C00C +EIGHTYCOLON = $C00D +SPEAKER = $C030 +SET_GR = $C050 +SET_TEXT = $C051 +FULLGR = $C052 +TEXTGR = $C053 +PAGE0 = $C054 +PAGE1 = $C055 +LORES = $C056 ; Enable LORES graphics +HIRES = $C057 ; Enable HIRES graphics +AN3 = $C05E ; Annunciator 3 + +PADDLE_BUTTON0 = $C061 +PADDL0 = $C064 +PTRIG = $C070 + +;; BASIC ROUTINES + +NORMAL = $F273 + +;; MONITOR ROUTINES + +HLINE = $F819 ;; HLINE Y,$2C at A +VLINE = $F828 ;; VLINE A,$2D at Y +CLRSCR = $F832 ;; Clear low-res screen +CLRTOP = $F836 ;; clear only top of low-res screen +SETGR = $FB40 ;; GR +SETCOL = $F864 ;; COLOR=A +TEXT = $FB36 +TABV = $FB5B ;; VTAB to A +BELL = $FBDD ;; ring the bell +BASCALC = $FBC1 ;; +VTAB = $FC22 ;; VTAB to CV +HOME = $FC58 ;; Clear the text screen +WAIT = $FCA8 ;; delay 1/2(26+27A+5A^2) us +CROUT1 = $FD8B +SETINV = $FE80 ;; INVERSE +SETNORM = $FE84 ;; NORMAL +COUT = $FDED ;; output A to screen +COUT1 = $FDF0 ;; output A to screen + + + + + + +COLOR_BLACK = 0 +COLOR_RED = 1 +COLOR_DARKBLUE = 2 +COLOR_PURPLE = 3 +COLOR_DARKGREEN = 4 +COLOR_GREY = 5 +COLOR_MEDIUMBLUE = 6 +COLOR_LIGHTBLUE = 7 +COLOR_BROWN = 8 +COLOR_ORANGE = 9 +COLOR_GREY2 = 10 +COLOR_PINK = 11 +COLOR_LIGHTGREEN = 12 +COLOR_YELLOW = 13 +COLOR_AQUA = 14 +COLOR_WHITE = 15 + +COLOR_BOTH_BLACK = $00 +COLOR_BOTH_RED = $11 +COLOR_BOTH_DARKBLUE = $22 +COLOR_BOTH_DARKGREEN = $44 +COLOR_BOTH_GREY = $55 +COLOR_BOTH_MEDIUMBLUE = $66 +COLOR_BOTH_LIGHTBLUE = $77 +COLOR_BOTH_BROWN = $88 +COLOR_BOTH_ORANGE = $99 +COLOR_BOTH_PINK = $BB +COLOR_BOTH_LIGHTGREEN = $CC +COLOR_BOTH_YELLOW = $DD +COLOR_BOTH_AQUA = $EE +COLOR_BOTH_WHITE = $FF + diff --git a/music/tiny_tracker/hello.bas b/music/tiny_tracker/hello.bas new file mode 100644 index 00000000..133a44bb --- /dev/null +++ b/music/tiny_tracker/hello.bas @@ -0,0 +1,2 @@ +5 HOME +10 PRINT CHR$(4);"CATALOG" diff --git a/music/tiny_tracker/interrupt_handler.s b/music/tiny_tracker/interrupt_handler.s new file mode 100644 index 00000000..4a9007d8 --- /dev/null +++ b/music/tiny_tracker/interrupt_handler.s @@ -0,0 +1,136 @@ + ;================================ + ;================================ + ; 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 + + ; 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 + jsr ay3_write_reg ; trashes A/X/Y + + ; set coarse note A (assume 0) + ; could get extra octave by putting 1 here + +y_smc: + ldy #0 + iny + jmp set_notes_loop + +done_update_song: + + dec SONG_COUNTDOWN + + + ;================================= + ; 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 + + + + + + + diff --git a/music/tiny_tracker/mockingboard_setup.s b/music/tiny_tracker/mockingboard_setup.s new file mode 100644 index 00000000..d6f66f47 --- /dev/null +++ b/music/tiny_tracker/mockingboard_setup.s @@ -0,0 +1,243 @@ +; 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 +MOCK_6522_T1CL = $C404 ; 6522 #1 t1 low order latches +MOCK_6522_T1CH = $C405 ; 6522 #1 t1 high order counter +MOCK_6522_T1LL = $C406 ; 6522 #1 t1 low order latches +MOCK_6522_T1LH = $C407 ; 6522 #1 t1 high order latches +MOCK_6522_T2CL = $C408 ; 6522 #1 t2 low order latches +MOCK_6522_T2CH = $C409 ; 6522 #1 t2 high order counters +MOCK_6522_SR = $C40A ; 6522 #1 shift register +MOCK_6522_ACR = $C40B ; 6522 #1 auxilliary control register +MOCK_6522_PCR = $C40C ; 6522 #1 peripheral control register +MOCK_6522_IFR = $C40D ; 6522 #1 interrupt flag register +MOCK_6522_IER = $C40E ; 6522 #1 interrupt enable register +MOCK_6522_ORANH = $C40F ; 6522 #1 port a data no handshake + + +; 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 + ;======================== + ;======================== + +mockingboard_init: + + ;========================= + ; Initialize the 6522s + ; set the data direction for all pins of PortA/PortB to be output + + + lda #$ff ; all output (1) + + sta MOCK_6522_DDRB1 ; set for 6522 #1 + sta MOCK_6522_DDRA1 + + sta MOCK_6522_DDRB2 ; set for 6522 #2 + sta MOCK_6522_DDRA2 + + +mockingboard_setup_interrupt: + + ;========================= + ; 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 + + lda #interrupt_handler + sta $03ff + + ;============================ + ; Enable 50Hz clock on 6522 + ;============================ + + + ; 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) + + ; 9c40 / 1.023e6 = .040s, 25Hz + ; 8534 / 1.023e6 = .033s, 30Hz + ; 4fe7 / 1.023e6 = .020s, 50Hz + ; 411a / 1.023e6 = .016s, 60Hz + + ; French Touch uses + ; 4e20 / 1.000e6 = .020s, 50Hz, which assumes 1MHz clock freq + + sei ; disable interrupts just in case + + lda #$40 ; Continuous interrupts, don't touch PB7 + sta MOCK_6522_ACR ; ACR register + + lda #$7F ; clear all interrupt flags + sta MOCK_6522_IER ; IER register (interrupt enable) + + lda #$C0 + sta MOCK_6522_IFR ; IFR: 1100, enable interrupt on timer one oflow + sta MOCK_6522_IER ; IER: 1100, enable timer one interrupt + + lda #$34 +; lda #$E7 + sta MOCK_6522_T1CL ; write into low-order latch + + lda #$85 +; lda #$4f + sta MOCK_6522_T1CH ; write into high-order latch, + ; load both values into counter + ; clear interrupt and start counting + + + + ;=================================== + ;=================================== + ; Reset Both AY-3-8910s + ;=================================== + ;=================================== + + ;=========================== + ; Reset Right/Left AY-3-8910 + ;=========================== + lda #MOCK_AY_RESET + sta MOCK_6522_ORB1 + sta MOCK_6522_ORB2 + lda #MOCK_AY_INACTIVE + sta MOCK_6522_ORB1 + sta MOCK_6522_ORB2 + +init_registers: + + ; init song data + + lda #0 + sta SONG_OFFSET + sta SONG_COUNTDOWN + + ; read 14 bytes from beginning of song to init + + ldx #13 +init_loop: +init_smc: + txa + tay + lda (SONG_L),Y + jsr ay3_write_reg ; trashes Y + dex + bne init_loop + + ; update SONG_L to point past the init + lda SONG_L + clc + adc #14 + sta SONG_L + bcc no_oflo + inc SONG_H +no_oflo: + + ; create Frequency Table + ldx #12 +make_freq_loop: + lda frequency_lookup,X + lsr + sta frequency_lookup+16,X + lsr + sta frequency_lookup+32,X + dex + bpl make_freq_loop + + rts + + + ;===================== + ;===================== + ;===================== + ; ay3 write reg + ;===================== + ;===================== + ;===================== + ; writes to both chips (so same output to both Right/Left) + ; address in X (preserved) + ; value in A + + ; NOTE: it looks like you could interleave things to save bytes + ; but technically this violates the AY-3-8910 spec sheet on + ; finishing accesses in less than 10us (10 cycles) + +ay3_write_reg: + pha + lda #MOCK_AY_LATCH_ADDR ; latch_address for PB1 ; 2 + ldy #MOCK_AY_INACTIVE ; go inactive ; 2 + + stx MOCK_6522_ORA1 ; put address on PA1 ; 4 + sta MOCK_6522_ORB1 ; latch_address on PB1 ; 4 + sty MOCK_6522_ORB1 ; 4 + + stx MOCK_6522_ORA2 ; put address on PA2 ; 4 + sta MOCK_6522_ORB2 ; latch_address on PB2 ; 4 + sty MOCK_6522_ORB2 ; 4 + pla + + ; value + sta MOCK_6522_ORA1 ; put value on PA1 ; 4 + sta MOCK_6522_ORA2 ; put value on PA2 ; 4 + lda #MOCK_AY_WRITE ; ; 2 + + sta MOCK_6522_ORB1 ; write on PB1 ; 4 + sty MOCK_6522_ORB1 ; 4 + + sta MOCK_6522_ORB2 ; write on PB2 ; 4 + sty MOCK_6522_ORB2 ; 4 + + rts + + +; starts at C4 +frequency_lookup: +.byte $F4,$E6,$D9,$CD,$C1,$B7,$AC,$A3,$99,$91,$89,$81,$00 + +;.byte $00,$00,$00,$00 +;.byte $7A,$73,$6C,$66,$60,$5B,$56,$51,$4C,$48,$44,$40,$00,$00,$00,$00 +;.byte $3D,$39,$36,$33,$30,$2D,$2B,$28,$26,$24,$22,$20,$00,$00,$00,$00 diff --git a/music/tiny_tracker/peasant.s b/music/tiny_tracker/peasant.s new file mode 100644 index 00000000..1785fd60 --- /dev/null +++ b/music/tiny_tracker/peasant.s @@ -0,0 +1,57 @@ +; Tiny Mockingboard Player + +; 514B -- Initial implementation +; 423B -- inline everything +; 400B -- put register init at end of song +; 381B -- generate the frequency table + +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) + +; Zero Page + .include "zp.inc" + .include "hardware.inc" + + + ;========================================== + +tiny_music: + + ;=================== + ; + + ;=================== + ; Player Setup + + + lda #peasant_song + sta SONG_H + + ; assume mockingboard in slot#4 + jsr mockingboard_init + +start_interrupts: + cli + +forever: + jmp forever + + +.include "peasant_music.s" + +.include "interrupt_handler.s" + +; must be last +.include "mockingboard_setup.s" + diff --git a/demos/tiny_music/peasant.txt b/music/tiny_tracker/peasant.txt similarity index 91% rename from demos/tiny_music/peasant.txt rename to music/tiny_tracker/peasant.txt index 83d0d776..ea7be211 100644 --- a/demos/tiny_music/peasant.txt +++ b/music/tiny_tracker/peasant.txt @@ -15,7 +15,7 @@ ' ENDHEADER ------- ' 0 -0 C 2 3 ----- ----- +0 C 2-- R---- R---- 1 ----- ----- ----- 2 ----- ----- ----- 3 ----- ----- ----- @@ -26,20 +26,20 @@ 8 ----- ----- ----- 9 ----- ----- ----- A ----- ----- ----- -B ----- ----- ----- -C C 2 3 ----- ----- +B R---- ----- ----- +C C 2-- ----- ----- D ----- ----- ----- E ----- ----- ----- -F ----- ----- ----- -10 C 2 3 ----- ----- +F R---- ----- ----- +10 C 2-- ----- ----- 11 ----- ----- ----- 12 ----- ----- ----- -13 ----- ----- ----- -14 C 2 3 ----- ----- +13 R---- ----- ----- +14 C 2-- ----- ----- 15 ----- ----- ----- 16 ----- ----- ----- -17 ----- ----- ----- -18 C 2 3 ----- ----- +17 R---- ----- ----- +18 C 2-- ----- ----- 19 ----- ----- ----- 1A ----- ----- ----- 1B ----- ----- ----- @@ -50,19 +50,19 @@ F ----- ----- ----- 20 ----- ----- ----- 21 ----- ----- ----- 22 ----- ----- ----- -23 ----- ----- ----- -24 C 2 3 ----- ----- +23 R---- ----- ----- +24 C 2-- ----- ----- 25 ----- ----- ----- 26 ----- ----- ----- -27 ----- ----- ----- -28 C 2 3 ----- ----- +27 R---- ----- ----- +28 C 2-- ----- ----- 29 ----- ----- ----- 2A ----- ----- ----- -2B ----- ----- ----- -2C C 2 3 ----- ----- +2B R---- ----- ----- +2C C 2-- ----- ----- 2D ----- ----- ----- 2E ----- ----- ----- -2F ----- ----- ----- +2F R---- ----- ----- ' 0 again 0 C 2 3 ----- ----- 1 ----- ----- ----- @@ -75,19 +75,19 @@ F ----- ----- ----- 8 ----- ----- ----- 9 ----- ----- ----- A ----- ----- ----- -B ----- ----- ----- +B R---- ----- ----- C C 2 3 ----- ----- D ----- ----- ----- E ----- ----- ----- -F ----- ----- ----- +F R---- ----- ----- 10 C 2 3 ----- ----- 11 ----- ----- ----- 12 ----- ----- ----- -13 ----- ----- ----- +13 R---- ----- ----- 14 C 2 3 ----- ----- 15 ----- ----- ----- 16 ----- ----- ----- -17 ----- ----- ----- +17 R---- ----- ----- 18 C 2 3 ----- ----- 19 ----- ----- ----- 1A ----- ----- ----- @@ -99,15 +99,15 @@ F ----- ----- ----- 20 ----- ----- ----- 21 ----- ----- ----- 22 ----- ----- ----- -23 ----- ----- ----- +23 R---- ----- ----- 24 C 2 3 ----- ----- 25 ----- ----- ----- 26 ----- ----- ----- -27 ----- ----- ----- +27 R---- ----- ----- 28 C 2 3 ----- ----- 29 ----- ----- ----- 2A ----- ----- ----- -2B ----- ----- ----- +2B R---- ----- ----- 2C C 2 3 ----- ----- 2D ----- ----- ----- 2E ----- ----- ----- @@ -124,19 +124,19 @@ F ----- ----- ----- 8 ----- ----- ----- 9 ----- ----- ----- A ----- ----- ----- -B ----- ----- ----- +B R---- ----- ----- C F 2 3 ----- ----- D ----- ----- ----- E ----- ----- ----- -F ----- ----- ----- +F R---- ----- ----- 10 F 2 3 ----- ----- 11 ----- ----- ----- 12 ----- ----- ----- -13 ----- ----- ----- +13 R---- ----- ----- 14 F 2 3 ----- ----- 15 ----- ----- ----- 16 ----- ----- ----- -17 ----- ----- ----- +17 R---- ----- ----- 18 F 2 3 ----- ----- 19 ----- ----- ----- 1A ----- ----- ----- @@ -148,15 +148,15 @@ F ----- ----- ----- 20 ----- ----- ----- 21 ----- ----- ----- 22 ----- ----- ----- -23 ----- ----- ----- +23 R---- ----- ----- 24 F 2 3 ----- ----- 25 ----- ----- ----- 26 ----- ----- ----- -27 ----- ----- ----- +27 R---- ----- ----- 28 F 2 3 ----- ----- 29 ----- ----- ----- 2A ----- ----- ----- -2B ----- ----- ----- +2B R---- ----- ----- 2C F 2 3 ----- ----- 2D ----- ----- ----- 2E ----- ----- ----- @@ -173,19 +173,19 @@ F ----- ----- ----- 8 ----- ----- ----- 9 ----- ----- ----- A ----- ----- ----- -B ----- ----- ----- +B R---- ----- ----- C G 2 3 ----- ----- D ----- ----- ----- E ----- ----- ----- -F ----- ----- ----- +F R---- ----- ----- 10 G 2 3 ----- ----- 11 ----- ----- ----- 12 ----- ----- ----- -13 ----- ----- ----- +13 R---- ----- ----- 14 G 2 3 ----- ----- 15 ----- ----- ----- 16 ----- ----- ----- -17 ----- ----- ----- +17 R---- ----- ----- 18 G 2 3 ----- ----- 19 ----- ----- ----- 1A ----- ----- ----- @@ -197,15 +197,15 @@ F ----- ----- ----- 20 ----- ----- ----- 21 ----- ----- ----- 22 ----- ----- ----- -23 ----- ----- ----- +23 R---- ----- ----- 24 G 2 3 ----- ----- 25 ----- ----- ----- 26 ----- ----- ----- -27 ----- ----- ----- +27 R---- ----- ----- 28 G 2 3 ----- ----- 29 ----- ----- ----- 2A ----- ----- ----- -2B ----- ----- ----- +2B R---- ----- ----- 2C G 2 3 ----- ----- 2D ----- ----- ----- 2E ----- ----- ----- @@ -214,28 +214,28 @@ F ----- ----- ----- 0 C 2 3 C 4 4 ----- 1 ----- ----- ----- 2 ----- ----- ----- -3 ----- ----- ----- +3 ----- R---- ----- 4 ----- C 4 4 ----- 5 ----- ----- ----- 6 ----- ----- ----- -7 ----- ----- ----- +7 ----- R---- ----- 8 ----- C 4 4 ----- 9 ----- ----- ----- A ----- ----- ----- -B ----- ----- ----- +B R---- R---- ----- C C 2 3 C 4 4 ----- D ----- ----- ----- E ----- ----- ----- -F ----- ----- ----- +F R---- R---- ----- 10 C 2 3 C 4 4 ----- 11 ----- ----- ----- 12 ----- ----- ----- -13 ----- ----- ----- +13 R---- R---- ----- 14 C 2 3 C 4 4 ----- 15 ----- ----- ----- 16 ----- ----- ----- -17 ----- ----- ----- -18 C 2 3 ----- ----- +17 R---- ----- ----- +18 C 2 3 R---- ----- 19 ----- ----- ----- 1A ----- ----- ----- 1B ----- ----- ----- @@ -246,19 +246,19 @@ F ----- ----- ----- 20 ----- ----- ----- 21 ----- ----- ----- 22 ----- ----- ----- -23 ----- ----- ----- +23 R---- ----- ----- 24 C 2 3 ----- ----- 25 ----- ----- ----- 26 ----- ----- ----- -27 ----- ----- ----- +27 R---- ----- ----- 28 C 2 3 ----- ----- 29 ----- ----- ----- 2A ----- ----- ----- -2B ----- ----- ----- +2B R---- ----- ----- 2C C 2 3 ----- ----- 2D ----- ----- ----- 2E ----- ----- ----- -2F ----- ----- ----- +2F R---- ----- ----- ' 4 0 C 2 3 ----- ----- 1 ----- ----- ----- @@ -271,23 +271,23 @@ F ----- ----- ----- 8 ----- G 4 3 ----- 9 ----- ----- ----- A ----- ----- ----- -B ----- ----- ----- +B R---- R---- ----- C C 2 3 G 4 4 ----- D ----- ----- ----- E ----- ----- ----- -F ----- ----- ----- +F R---- R---- ----- 10 C 2 3 G 4 3 ----- 11 ----- ----- ----- 12 ----- ----- ----- -13 ----- ----- ----- +13 R---- ----- ----- 14 C 2 3 F 4 3 ----- 15 ----- ----- ----- 16 ----- ----- ----- -17 ----- ----- ----- +17 R---- R---- ----- 18 C 2 3 F 4 4 ----- 19 ----- ----- ----- 1A ----- ----- ----- -1B ----- ----- ----- +1B ----- R---- ----- 1C ----- F 4 3 ----- 1D ----- ----- ----- 1E ----- ----- ----- @@ -295,15 +295,15 @@ F ----- ----- ----- 20 ----- E 4 3 ----- 21 ----- ----- ----- 22 ----- ----- ----- -23 ----- ----- ----- +23 ----- R---- ----- 24 C 2 3 E 4 4 ----- 25 ----- ----- ----- 26 ----- ----- ----- -27 ----- ----- ----- +27 R---- R---- ----- 28 C 2 3 E 4 3 ----- 29 ----- ----- ----- 2A ----- ----- ----- -2B ----- ----- ----- +2B R---- ----- ----- 2C C 2 3 F 4 3 ----- 2D ----- ----- ----- 2E ----- ----- ----- diff --git a/music/tiny_tracker/peasant_music.s b/music/tiny_tracker/peasant_music.s new file mode 100644 index 00000000..d8e6584c --- /dev/null +++ b/music/tiny_tracker/peasant_music.s @@ -0,0 +1,596 @@ +peasant_song: +; register init + .byte $00,$00,$00,$00,$00,$00 ; $00: A/B/C fine/coarse + .byte $00 ; $06 + .byte $38 ; $07 mixer (ABC on) + .byte $0E,$0C,$0C ; $08 volume A/B/C + .byte $00,$00,$00,$00 ; $09 + + .byte $20 ; A = C 2 + .byte $4C ; B = R--3 + .byte $8C ; C = R--3 + .byte $CB ; L = 11 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $CB ; L = 11 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $CB ; L = 11 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $CB ; L = 11 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $C4 ; L = 4 + + .byte $25 ; A = F 2 + .byte $CB ; L = 11 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $25 ; A = F 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $25 ; A = F 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $25 ; A = F 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $25 ; A = F 2 + .byte $CB ; L = 11 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $25 ; A = F 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $25 ; A = F 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $25 ; A = F 2 + .byte $C4 ; L = 4 + + .byte $27 ; A = G 2 + .byte $CB ; L = 11 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $27 ; A = G 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $27 ; A = G 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $27 ; A = G 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $27 ; A = G 2 + .byte $CB ; L = 11 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $27 ; A = G 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $27 ; A = G 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $27 ; A = G 2 + .byte $C4 ; L = 4 + + .byte $20 ; A = C 2 + .byte $C3 ; L = 3 + + .byte $4C ; B = R--3 + .byte $C4 ; L = 4 + + .byte $4C ; B = R--3 + .byte $C4 ; L = 4 + + .byte $0C ; A = R--3 + .byte $4C ; B = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $4C ; B = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $4C ; B = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $4C ; B = R--3 + .byte $CB ; L = 11 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $C8 ; L = 8 + + .byte $47 ; B = G 4 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $4C ; B = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $47 ; B = G 4 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $4C ; B = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $47 ; B = G 4 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $45 ; B = F 4 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $4C ; B = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $45 ; B = F 4 + .byte $C3 ; L = 3 + + .byte $4C ; B = R--3 + .byte $C1 ; L = 1 + + .byte $45 ; B = F 4 + .byte $C4 ; L = 4 + + .byte $44 ; B = E 4 + .byte $C3 ; L = 3 + + .byte $4C ; B = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $44 ; B = E 4 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $4C ; B = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $44 ; B = E 4 + .byte $C3 ; L = 3 + + .byte $0C ; A = R--3 + .byte $C1 ; L = 1 + + .byte $20 ; A = C 2 + .byte $45 ; B = F 4 + .byte $C4 ; L = 4 + + .byte $25 ; A = F 2 + .byte $CC ; L = 12 + + .byte $25 ; A = F 2 + .byte $C4 ; L = 4 + + .byte $25 ; A = F 2 + .byte $C4 ; L = 4 + + .byte $25 ; A = F 2 + .byte $C4 ; L = 4 + + .byte $25 ; A = F 2 + .byte $CC ; L = 12 + + .byte $25 ; A = F 2 + .byte $C4 ; L = 4 + + .byte $25 ; A = F 2 + .byte $C4 ; L = 4 + + .byte $25 ; A = F 2 + .byte $C4 ; L = 4 + + .byte $27 ; A = G 2 + .byte $C8 ; L = 8 + + .byte $47 ; B = G 4 + .byte $C4 ; L = 4 + + .byte $27 ; A = G 2 + .byte $47 ; B = G 4 + .byte $C4 ; L = 4 + + .byte $27 ; A = G 2 + .byte $47 ; B = G 4 + .byte $C4 ; L = 4 + + .byte $27 ; A = G 2 + .byte $45 ; B = F 4 + .byte $C4 ; L = 4 + + .byte $27 ; A = G 2 + .byte $45 ; B = F 4 + .byte $C4 ; L = 4 + + .byte $45 ; B = F 4 + .byte $C4 ; L = 4 + + .byte $44 ; B = E 4 + .byte $C4 ; L = 4 + + .byte $27 ; A = G 2 + .byte $44 ; B = E 4 + .byte $C4 ; L = 4 + + .byte $27 ; A = G 2 + .byte $44 ; B = E 4 + .byte $C4 ; L = 4 + + .byte $27 ; A = G 2 + .byte $45 ; B = F 4 + .byte $C4 ; L = 4 + + .byte $20 ; A = C 2 + .byte $42 ; B = D 4 + .byte $C3 ; L = 3 + + .byte $42 ; B = D 4 + .byte $C1 ; L = 1 + + .byte $42 ; B = D 4 + .byte $C2 ; L = 2 + + .byte $42 ; B = D 4 + .byte $C3 ; L = 3 + + .byte $42 ; B = D 4 + .byte $C3 ; L = 3 + + .byte $20 ; A = C 2 + .byte $4A ; B = A#4 + .byte $C4 ; L = 4 + + .byte $20 ; A = C 2 + .byte $4A ; B = A#4 + .byte $C4 ; L = 4 + + .byte $20 ; A = C 2 + .byte $4A ; B = A#4 + .byte $C4 ; L = 4 + + .byte $20 ; A = C 2 + .byte $42 ; B = D 4 + .byte $C3 ; L = 3 + + .byte $42 ; B = D 4 + .byte $C1 ; L = 1 + + .byte $42 ; B = D 4 + .byte $C2 ; L = 2 + + .byte $42 ; B = D 4 + .byte $C4 ; L = 4 + + .byte $42 ; B = D 4 + .byte $C2 ; L = 2 + + .byte $20 ; A = C 2 + .byte $47 ; B = G 4 + .byte $C4 ; L = 4 + + .byte $20 ; A = C 2 + .byte $47 ; B = G 4 + .byte $C4 ; L = 4 + + .byte $20 ; A = C 2 + .byte $47 ; B = G 4 + .byte $C4 ; L = 4 + + .byte $20 ; A = C 2 + .byte $42 ; B = D 4 + .byte $C3 ; L = 3 + + .byte $42 ; B = D 4 + .byte $C1 ; L = 1 + + .byte $42 ; B = D 4 + .byte $C2 ; L = 2 + + .byte $42 ; B = D 4 + .byte $C2 ; L = 2 + + .byte $42 ; B = D 4 + .byte $C4 ; L = 4 + + .byte $20 ; A = C 2 + .byte $4A ; B = A#4 + .byte $C4 ; L = 4 + + .byte $20 ; A = C 2 + .byte $4A ; B = A#4 + .byte $C2 ; L = 2 + + .byte $42 ; B = D 4 + .byte $C2 ; L = 2 + + .byte $20 ; A = C 2 + .byte $C2 ; L = 2 + + .byte $42 ; B = D 4 + .byte $C2 ; L = 2 + + .byte $20 ; A = C 2 + .byte $47 ; B = G 4 + .byte $C4 ; L = 4 + + .byte $47 ; B = G 4 + .byte $C2 ; L = 2 + + .byte $42 ; B = D 4 + .byte $C4 ; L = 4 + + .byte $42 ; B = D 4 + .byte $C2 ; L = 2 + + .byte $20 ; A = C 2 + .byte $45 ; B = F 4 + .byte $C4 ; L = 4 + + .byte $20 ; A = C 2 + .byte $45 ; B = F 4 + .byte $C2 ; L = 2 + + .byte $47 ; B = G 4 + .byte $C2 ; L = 2 + + .byte $20 ; A = C 2 + .byte $C2 ; L = 2 + + .byte $47 ; B = G 4 + .byte $C2 ; L = 2 + + .byte $25 ; A = F 2 + .byte $CC ; L = 12 + + .byte $25 ; A = F 2 + .byte $C4 ; L = 4 + + .byte $25 ; A = F 2 + .byte $C4 ; L = 4 + + .byte $25 ; A = F 2 + .byte $C4 ; L = 4 + + .byte $25 ; A = F 2 + .byte $CC ; L = 12 + + .byte $25 ; A = F 2 + .byte $C4 ; L = 4 + + .byte $25 ; A = F 2 + .byte $C4 ; L = 4 + + .byte $25 ; A = F 2 + .byte $C4 ; L = 4 + + .byte $27 ; A = G 2 + .byte $C8 ; L = 8 + + .byte $47 ; B = G 4 + .byte $C4 ; L = 4 + + .byte $27 ; A = G 2 + .byte $47 ; B = G 4 + .byte $C4 ; L = 4 + + .byte $27 ; A = G 2 + .byte $47 ; B = G 4 + .byte $C4 ; L = 4 + + .byte $27 ; A = G 2 + .byte $45 ; B = F 4 + .byte $C4 ; L = 4 + + .byte $27 ; A = G 2 + .byte $45 ; B = F 4 + .byte $C4 ; L = 4 + + .byte $45 ; B = F 4 + .byte $C4 ; L = 4 + + .byte $44 ; B = E 4 + .byte $C4 ; L = 4 + + .byte $27 ; A = G 2 + .byte $44 ; B = E 4 + .byte $C4 ; L = 4 + + .byte $27 ; A = G 2 + .byte $44 ; B = E 4 + .byte $C4 ; L = 4 + + .byte $27 ; A = G 2 + .byte $45 ; B = F 4 + .byte $C4 ; L = 4 + + .byte $20 ; A = C 2 + .byte $47 ; B = G 4 + .byte $C4 ; L = 4 + + .byte $47 ; B = G 4 + .byte $C4 ; L = 4 + + .byte $47 ; B = G 4 + .byte $C4 ; L = 4 + + .byte $20 ; A = C 2 + .byte $C4 ; L = 4 + + .byte $20 ; A = C 2 + .byte $C4 ; L = 4 + + .byte $20 ; A = C 2 + .byte $C4 ; L = 4 + + .byte $20 ; A = C 2 + .byte $CC ; L = 12 + + .byte $20 ; A = C 2 + .byte $C4 ; L = 4 + + .byte $20 ; A = C 2 + .byte $C4 ; L = 4 + + .byte $20 ; A = C 2 + .byte $FF diff --git a/music/tiny_tracker/text_to_tiny.c b/music/tiny_tracker/text_to_tiny.c new file mode 100644 index 00000000..29f4446b --- /dev/null +++ b/music/tiny_tracker/text_to_tiny.c @@ -0,0 +1,372 @@ +/* make music for tiny_music player */ + +#define VERSION "1.0" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +// CCOONNNN -- c=channel, o=octave, n=note + +int note_to_ed(char note, int flat, int sharp, int octave) { + + int offset; + + switch(note) { + case 'C': offset=0; break; + case 'D': offset=2; break; + case 'E': offset=4; break; + case 'F': offset=5; break; + case 'G': offset=7; break; + case 'A': offset=9; break; + case 'B': offset=11; break; + + case 'R': offset=12; flat=0; sharp=0; octave=0; break; + + default: + fprintf(stderr,"Unknown note %c\n",note); + return -1; + } + if (flat==1) offset--; + if (sharp==1) offset++; + if (sharp==2) offset+=2; + + + offset=((octave&0x3)<<4)|offset; + + return offset; +} + + + +static int debug=0; + +static int octave_adjust=0; + +static int line=0; + +static int header_version=0; + + +struct note_type { + unsigned char which; + unsigned char note; + int sharp,flat; + int octave; + int len; + int enabled; + int freq; + int length; + int left; + int ed_freq; +}; + + + +static int get_note(char *string, int sp, struct note_type *n, int line) { + + int freq; + int ch; + +// fprintf(stderr,"VMW: Entering, sp=%d\n",sp); + + /* Skip white space */ + while((string[sp]==' ' || string[sp]=='\t')) sp++; + + if (string[sp]=='\n') return -1; + + /* return early if no change */ + ch=string[sp]; + +// fprintf(stderr,"VMW: %d %d\n",ch,sp); + + if (ch=='-') { + if (header_version==0) return sp+6; + else { + return sp+11; + } + } + + /* get note info */ + n->sharp=0; + n->flat=0; + n->ed_freq=0; + n->note=ch; + sp++; + if (string[sp]==' ') ; + else if (string[sp]=='#') n->sharp=1; + else if (string[sp]=='-') n->flat=1; + else if (string[sp]=='=') n->flat=2; + else { + fprintf(stderr,"Unknown note modifier %c, line %d:%d\n", + string[sp],line,sp); + fprintf(stderr,"String: %s\n",string); + } +// printf("Sharp=%d Flat=%d\n",n->sharp,n->flat); + sp++; + n->octave=string[sp]-'0'; + sp++; + sp++; + n->len=string[sp]-'0'; + sp++; + + + if (n->note!='-') { + + freq=note_to_ed(n->note,n->flat,n->sharp, + n->octave+octave_adjust); + + n->enabled=1; + n->length=0; + n->ed_freq=freq; + } + + if (header_version==2) sp+=6; + + return sp; +} + +static int get_string(char *string, char *key, char *output, int strip_linefeed) { + + char *found; + + found=strstr(string,key); + found=found+strlen(key); + + /* get rid of leading whitespace */ + while(1) { + if ((*found==' ') || (*found=='\t')) found++; + else break; + } + + strcpy(output,found); + + /* remove trailing linefeed */ + if (strip_linefeed) output[strlen(output)-1]=0; + + return 0; + +} + +static void print_help(int just_version, char *exec_name) { + + printf("\ntext_to_ed version %s by Vince Weaver \n\n",VERSION); + if (just_version) exit(0); + + printf("This created Electric Duet files\n\n"); + + printf("Usage:\n"); + printf("\t%s [-h] [-v] [-d] [-o X] [-i X] textfile outbase\n\n", + exec_name); + printf("\t-h: this help message\n"); + printf("\t-v: version info\n"); + printf("\t-d: print debug messages\n"); + printf("\t-o: Offset octave by X\n"); + printf("\t-i: set second instrument to X\n"); + + exit(0); +} + + +int main(int argc, char **argv) { + + char string[BUFSIZ]; + char *result; + char *in_filename; + char temp[BUFSIZ]; + FILE *in_file=NULL; + //int attributes=0; + int loop=0; + int sp,external_frequency,irq; + struct note_type a,b,c; + int copt; + + char song_name[BUFSIZ]; + char author_name[BUFSIZ]; + char comments[BUFSIZ]; + char *comments_ptr=comments; + + unsigned char sharp_char[]=" #-="; + + /* Parse command line arguments */ + while ((copt = getopt(argc, argv, "dhvo:i:"))!=-1) { + switch (copt) { + case 'd': + /* Debug messages */ + printf("Debug enabled\n"); + debug=1; + break; + case 'h': + /* help */ + print_help(0,argv[0]); + break; + case 'v': + /* version */ + print_help(1,argv[0]); + break; + case 'o': + /* octave offset */ + octave_adjust=atoi(optarg); + break; + default: + print_help(0,argv[0]); + break; + } + } + + if (argv[optind]!=NULL) { + /* Open the input file */ + if (argv[optind][0]=='-') { + in_file=stdin; + } + else { + in_filename=strdup(argv[optind]); + in_file=fopen(in_filename,"r"); + if (in_file==NULL) { + fprintf(stderr,"Couldn't open %s\n",in_filename); + return -1; + } + } + } + + + /* Get the info for the header */ + + while(1) { + result=fgets(string,BUFSIZ,in_file); + if (result==NULL) break; + line++; + if (strstr(string,"ENDHEADER")) break; + if (strstr(string,"HEADER:")) { + get_string(string,"HEADER:",temp,1); + header_version=atoi(temp); + printf("Found header version %d\n",header_version); + } + if (strstr(string,"TITLE:")) { + get_string(string,"TITLE:",song_name,1); + } + if (strstr(string,"AUTHOR:")) { + get_string(string,"AUTHOR:",author_name,1); + } + if (strstr(string,"COMMENTS:")) { + get_string(string,"COMMENTS:",comments_ptr,0); + comments_ptr=&comments[strlen(comments)]; + } + + if (strstr(string,"FREQ:")) { + get_string(string,"FREQ:",temp,1); + external_frequency=atoi(temp); + } + if (strstr(string,"IRQ:")) { + get_string(string,"IRQ:",temp,1); + irq=atoi(temp); + } + if (strstr(string,"LOOP:")) { + get_string(string,"LOOP:",temp,1); + loop=atoi(temp); + } + + } + + a.which='A'; b.which='B'; c.which='C'; + + + // algorithm + // get A,B,C + + +// int first=1; +// int a_last=0,b_last=0,same_count=0; +// int a_len=0,b_len=0,a_freq=0,b_freq=0; + int current_length=0; + int first=1; + +printf("peasant_song:\n"); +printf("; register init\n"); +printf("\t.byte $00,$00,$00,$00,$00,$00 ; $00: A/B/C fine/coarse\n"); +printf("\t.byte $00 ; $06\n"); +printf("\t.byte $38 ; $07 mixer (ABC on)\n"); +printf("\t.byte $0E,$0C,$0C ; $08 volume A/B/C\n"); +printf("\t.byte $00,$00,$00,$00 ; $09\n"); +printf("\n"); + + while(1) { + result=fgets(string,BUFSIZ,in_file); + if (result==NULL) break; + line++; + + a.ed_freq=0; + b.ed_freq=0; + c.ed_freq=0; + a.length=0; + b.length=0; + c.length=0; + + /* skip comments */ + if (string[0]=='\'') continue; + if (string[0]=='-') continue; + if (string[0]=='*') continue; + + sp=0; + + /* Skip line number */ + while((string[sp]!=' ' && string[sp]!='\t')) sp++; + + sp=get_note(string,sp,&a,line); + if (sp!=-1) sp=get_note(string,sp,&b,line); + if (sp!=-1) sp=get_note(string,sp,&c,line); + + + if ((a.ed_freq!=0)||(b.ed_freq!=0)||(c.ed_freq!=0)) { + if (!first) { + printf("\t.byte $%02X ; L = %d\n", + current_length|0xc0,current_length); + printf("\n"); + current_length=0; + } + + first=0; + + } + + + if (a.ed_freq!=0) { + printf("\t.byte $%02X ; A = %c%c%d\n", + a.ed_freq, + a.note,sharp_char[a.sharp+2*a.flat], + a.octave); + } + if (b.ed_freq!=0) { + printf("\t.byte $%02X ; B = %c%c%d\n", + b.ed_freq|0x40, + b.note,sharp_char[b.sharp+2*b.flat], + b.octave); + } + if (c.ed_freq!=0) { + printf("\t.byte $%02X ; C = %c%c%d\n", + c.ed_freq|0x80, + c.note,sharp_char[c.sharp+2*c.flat], + c.octave); + } + + current_length++; + + + } + + printf("\t.byte $FF\n"); + + (void) irq; + (void) loop; + (void) external_frequency; + + return 0; +} + diff --git a/music/tiny_tracker/zp.inc b/music/tiny_tracker/zp.inc new file mode 100644 index 00000000..0acb0414 --- /dev/null +++ b/music/tiny_tracker/zp.inc @@ -0,0 +1,29 @@ +; these need to be in zero page +; can we find a location that works? + +PATTERN_L = $06 +PATTERN_H = $07 +ORNAMENT_L = $08 +ORNAMENT_H = $09 +SAMPLE_L = $0A +SAMPLE_H = $0B +MB_ADDR_L = $0C +MB_ADDR_H = $0D + + +; only used for title screen... +TEMP = $FA +TEMPY = $FB +;INL = $FC +;INH = $FD +;OUTL = $FE +;OUTH = $FF + +; pre-defined applesoft vars + +CH = $24 +CV = $25 +GBASL = $26 +GBASH = $27 +BASL = $28 +BASH = $29