Beginnings of a dual tone synthesizer for the Apple II
Go to file
Charles Mangin db4ecb58bc Audio samples
MP3 files of the songs listed in the README
2016-09-13 21:11:40 -04:00
B-flat-scale.mp3 Audio samples 2016-09-13 21:11:40 -04:00
daisy-bell.mp3 Audio samples 2016-09-13 21:11:40 -04:00
README.md Update README.md 2016-09-13 15:34:44 -04:00
victory.mp3 Audio samples 2016-09-13 21:11:40 -04:00

KSynth

Beginnings of a dual tone synthesizer for the Apple II

Everything is in this README, since it's small enough to copy and paste into an emulator for now.

##Two Tone Generator##

0300-   A5 FD       LDA   $FD	;	load second oscillator value into $FE
0302-   85 FE       STA   $FE	;
0304-   A9 FF       LDA   #$FF	;	load duration multiplier into $FC
0306-   85 FC       STA   $FC	;
0308-   A4 FA       LDY   $FA	;	load duration into Y
030A-   A6 FB       LDX   $FB	;	load oscillator into X
030C-   CA          DEX			;	start countdown first oscillator, X
030D-   EA          NOP			;	wait...
030E-   EA          NOP			;
030F-   D0 05       BNE   $0316	;	if X = 0, click. otherwise, skip
0311-   8D 30 C0    STA   $C030	;	click
0314-   A6 FB       LDX   $FB	;	reset X to beginning of countdown
0316-   C6 FE       DEC   $FE	;	countdown second oscillator, $FE
0318-   EA          NOP			;	wait...
0319-   EA          NOP			;
031A-   D0 07       BNE   $0323	;	if $FE = 0, click. otherwise, skip
031C-   8D 30 C0    STA   $C030	;	click
031F-   A5 FD       LDA   $FD	;	reset $FE to beginning of countdown
0321-   85 FE       STA   $FE	;
0323-   88          DEY			;	countdown duration
0324-   D0 E6       BNE   $030C	;	if duration hasn't expired, return and count down oscillators
0326-   A4 FA       LDY   $FA	;	if duration has expired, reset duration 
0328-   C6 FC       DEC   $FC	;	decrement duration multiplier
032A-   D0 E0       BNE   $030C	;	if multiplier hasn't expired, return and count down oscillators
032C-   60          RTS			;	all done

300: A5 FD 85 FE A9 FF 85 FC A4 FA A6 FB CA EA EA D0 05 8D 30 C0 A6 FB C6 FE EA EA D0 07 8D 30 C0 A5 FD 85 FE 88 D0 E6 A4 FA C6 FC D0 E0 60       

##Player##

0330-   A9 00       LDA   #$00		;	start at zero
0332-   AA          TAX				;	X = 0; LOOP
0333-   BD 00 10    LDA   $1000,X	;	load note duration
0336-   F0 31       BEQ   $0369		;	if note is 0 duration, end the song
0338-   85 FA       STA   $FA		;	store duration at $FA
033A-   E8          INX				;	increment to note value
033B-   BD 00 10    LDA   $1000,X	;	load note value
033E-   85 FB       STA   $FB		;	store note value at $FB
0340-   85 FD       STA   $FD		; 	store note value at $FD
0342-   C9 FF       CMP   #$FF		;	if note value is FF, rest
0344-   D0 06       BNE   $034C		;	skip over if !=FF
0346-   8D 1E 03    STA   $031E		;	change the $C030 click to $$FF30	
0349-   8D 13 03    STA   $0313		;	change the $C030 click to $$FF30	
034C-   C6 FD       DEC   $FD		;	decrement $FD for That Karateka Sound™
034E-   8A          TXA				;	put current note address in Accumulator
034F-   85 FF       STA   $FF		;	store that in $FF						
0351-   20 00 03    JSR   $0300		;	play the actual note
0354-   AD 13 03    LDA   $0313		;	did we mess with the C030 click?
0357-   C9 FF       CMP   #$FF		;	if it's FF, we did. change it back.
0359-   D0 08       BNE   $0363		;	skip if !=FF
035B-   A9 C0       LDA   #$C0		;	set click points back to $c030
035D-   8D 1E 03    STA   $031E		;
0360-   8D 13 03    STA   $0313		;	
0363-   E6 FF       INC   $FF		;	increment to next note address
0365-   A5 FF       LDA   $FF		;	load Accumulator with next note address
0367-   D0 C9       BNE   $0332		;	branch to LOOP
0369-   60          RTS				;

330: A9 00 AA BD 00 10 F0 31 85 FA E8 BD 00 10 85 FB 85 FD C9 FF D0 06 8D 1E 03 8D 13 03 C6 FD 8A 85 FF 20 00 03 AD 13 03 C9 FF D0 08 A9 C0 8D 1E 03 8D 13 03 E6 FF A5 FF D0 C9 60       

##Creating Music

Music is stored in the following format, beginning (by default) at $1000.

Starting address = A ($1000)

A+0 = duration

e.g. FF = 1.63 seconds

A+1 = note

e.g. 59 = 440Hz A

per chart at [https://www.seventhstring.com/resources/notefrequencies.html]
NOTE C C# D Eb E F F# G G# A Bb B
FREQ 155.6 164.8 174.6 185.0 196.0 207.7 220.0 233.1 246.9
BYTE FC EF E1 D5 C9 BD B3 A9 9F
FREQ 261.6 277.2 293.7 311.1 329.6 349.2 370.0 392.0 415.3 440.0 466.2 493.9
BYTE 96 8E 86 7E 77 71 6A 64 5E 59 54 4F
FREQ 523.3 554.4 587.3 622.3 659.3 698.5 740.0 784.0 830.6 880.0 932.3 987.8
BYTE 4B 47 43 3F 3C 38 35 32 2F 2D 2A 27

##Bb scale:##

1000: 20 A9 20 96 20 86 20 7E 20 71 20 64 20 59 20 54 20 59 20 64 20 71 20 7E 20 86 20 96 FF A9 FF FF 10 A9 10 86 10 71 10 54 10 71 10 86 FF A9 00

##Karateka victory:##

1000: 10 a8 20 FF 8 c7 5 FF 10 a8 15 FF 25 7e 20 FF 10 63 08 FF 80 63 00 00

This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States License. [http://creativecommons.org/licenses/by-sa/3.0/us/]