From fc67ef8f21a5bf5d1a32ef8a08ce6a3de3d0a9e5 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 20 Jan 2019 16:20:57 +0100 Subject: [PATCH] added SID registers and sound example program --- compiler/res/prog8lib/c64lib.p8 | 209 +++++++++++++++++++------------- examples/bdmusic.p8 | 87 +++++++++++++ examples/compiled/bdmusic.prg | Bin 0 -> 907 bytes examples/compiled/examples.d64 | Bin 174848 -> 174848 bytes 4 files changed, 211 insertions(+), 85 deletions(-) create mode 100644 examples/bdmusic.p8 create mode 100644 examples/compiled/bdmusic.prg diff --git a/compiler/res/prog8lib/c64lib.p8 b/compiler/res/prog8lib/c64lib.p8 index 68465aaa5..c78835093 100644 --- a/compiler/res/prog8lib/c64lib.p8 +++ b/compiler/res/prog8lib/c64lib.p8 @@ -45,103 +45,142 @@ memory ubyte[8] SPRPTR = 2040 ; the 8 sprite pointers as an array. -; ---- VIC-II registers ---- +; ---- VIC-II 6567/6569/856x registers ---- - memory ubyte SP0X = $d000 - memory ubyte SP0Y = $d001 - memory ubyte SP1X = $d002 - memory ubyte SP1Y = $d003 - memory ubyte SP2X = $d004 - memory ubyte SP2Y = $d005 - memory ubyte SP3X = $d006 - memory ubyte SP3Y = $d007 - memory ubyte SP4X = $d008 - memory ubyte SP4Y = $d009 - memory ubyte SP5X = $d00a - memory ubyte SP5Y = $d00b - memory ubyte SP6X = $d00c - memory ubyte SP6Y = $d00d - memory ubyte SP7X = $d00e - memory ubyte SP7Y = $d00f - memory ubyte[16] SPXY = $d000 ; the 8 sprite X and Y registers as an array. - memory uword[8] SPXYW = $d000 ; the 8 sprite X and Y registers as a combined xy word array. + memory ubyte SP0X = $d000 + memory ubyte SP0Y = $d001 + memory ubyte SP1X = $d002 + memory ubyte SP1Y = $d003 + memory ubyte SP2X = $d004 + memory ubyte SP2Y = $d005 + memory ubyte SP3X = $d006 + memory ubyte SP3Y = $d007 + memory ubyte SP4X = $d008 + memory ubyte SP4Y = $d009 + memory ubyte SP5X = $d00a + memory ubyte SP5Y = $d00b + memory ubyte SP6X = $d00c + memory ubyte SP6Y = $d00d + memory ubyte SP7X = $d00e + memory ubyte SP7Y = $d00f + memory ubyte[16] SPXY = $d000 ; the 8 sprite X and Y registers as an array. + memory uword[8] SPXYW = $d000 ; the 8 sprite X and Y registers as a combined xy word array. - memory ubyte MSIGX = $d010 - memory ubyte SCROLY = $d011 - memory ubyte RASTER = $d012 - memory ubyte LPENX = $d013 - memory ubyte LPENY = $d014 - memory ubyte SPENA = $d015 - memory ubyte SCROLX = $d016 - memory ubyte YXPAND = $d017 - memory ubyte VMCSB = $d018 - memory ubyte VICIRQ = $d019 - memory ubyte IREQMASK = $d01a - memory ubyte SPBGPR = $d01b - memory ubyte SPMC = $d01c - memory ubyte XXPAND = $d01d - memory ubyte SPSPCL = $d01e - memory ubyte SPBGCL = $d01f + memory ubyte MSIGX = $d010 + memory ubyte SCROLY = $d011 + memory ubyte RASTER = $d012 + memory ubyte LPENX = $d013 + memory ubyte LPENY = $d014 + memory ubyte SPENA = $d015 + memory ubyte SCROLX = $d016 + memory ubyte YXPAND = $d017 + memory ubyte VMCSB = $d018 + memory ubyte VICIRQ = $d019 + memory ubyte IREQMASK = $d01a + memory ubyte SPBGPR = $d01b + memory ubyte SPMC = $d01c + memory ubyte XXPAND = $d01d + memory ubyte SPSPCL = $d01e + memory ubyte SPBGCL = $d01f - memory ubyte EXTCOL = $d020 ; border color - memory ubyte BGCOL0 = $d021 ; screen color - memory ubyte BGCOL1 = $d022 - memory ubyte BGCOL2 = $d023 - memory ubyte BGCOL4 = $d024 - memory ubyte SPMC0 = $d025 - memory ubyte SPMC1 = $d026 - memory ubyte SP0COL = $d027 - memory ubyte SP1COL = $d028 - memory ubyte SP2COL = $d029 - memory ubyte SP3COL = $d02a - memory ubyte SP4COL = $d02b - memory ubyte SP5COL = $d02c - memory ubyte SP6COL = $d02d - memory ubyte SP7COL = $d02e - memory ubyte[8] SPCOL = $d027 + memory ubyte EXTCOL = $d020 ; border color + memory ubyte BGCOL0 = $d021 ; screen color + memory ubyte BGCOL1 = $d022 + memory ubyte BGCOL2 = $d023 + memory ubyte BGCOL4 = $d024 + memory ubyte SPMC0 = $d025 + memory ubyte SPMC1 = $d026 + memory ubyte SP0COL = $d027 + memory ubyte SP1COL = $d028 + memory ubyte SP2COL = $d029 + memory ubyte SP3COL = $d02a + memory ubyte SP4COL = $d02b + memory ubyte SP5COL = $d02c + memory ubyte SP6COL = $d02d + memory ubyte SP7COL = $d02e + memory ubyte[8] SPCOL = $d027 ; ---- end of VIC-II registers ---- -; ---- CIA 1 & 2 registers ---- +; ---- CIA 6526 1 & 2 registers ---- - memory ubyte CIA1PRA = $DC00 ; CIA 1 DRA, keyboard column drive - memory ubyte CIA1PRB = $DC01 ; CIA 1 DRB, keyboard row port - memory ubyte CIA1DDRA = $DC02 ; CIA 1 DDRA, keyboard column - memory ubyte CIA1DDRB = $DC03 ; CIA 1 DDRB, keyboard row - memory ubyte CIA1TALO = $DC04 ; CIA 1 timer A low byte - memory ubyte CIA1TAHI = $DC05 ; CIA 1 timer A high byte - memory ubyte CIA1TBLO = $DC06 ; CIA 1 timer B low byte - memory ubyte CIA1TBHI = $DC07 ; CIA 1 timer B high byte - memory ubyte CIA1TOD10 = $DC08 ; time of day, 1/10 sec. - memory ubyte CIA1TODS = $DC09 ; time of day, seconds - memory ubyte CIA1TODM = $DC0A ; time of day, minutes - memory ubyte CIA1TODH = $DC0B ; time of day, hours - memory ubyte CIA1SDR = $DC0C ; Serial Data Register - memory ubyte CIA1ICR = $DC0D - memory ubyte CIA1CRA = $DC0E - memory ubyte CIA1CRB = $DC0F + memory ubyte CIA1PRA = $DC00 ; CIA 1 DRA, keyboard column drive + memory ubyte CIA1PRB = $DC01 ; CIA 1 DRB, keyboard row port + memory ubyte CIA1DDRA = $DC02 ; CIA 1 DDRA, keyboard column + memory ubyte CIA1DDRB = $DC03 ; CIA 1 DDRB, keyboard row + memory ubyte CIA1TAL = $DC04 ; CIA 1 timer A low byte + memory ubyte CIA1TAH = $DC05 ; CIA 1 timer A high byte + memory ubyte CIA1TBL = $DC06 ; CIA 1 timer B low byte + memory ubyte CIA1TBH = $DC07 ; CIA 1 timer B high byte + memory ubyte CIA1TOD10 = $DC08 ; time of day, 1/10 sec. + memory ubyte CIA1TODSEC = $DC09 ; time of day, seconds + memory ubyte CIA1TODMMIN = $DC0A ; time of day, minutes + memory ubyte CIA1TODHR = $DC0B ; time of day, hours + memory ubyte CIA1SDR = $DC0C ; Serial Data Register + memory ubyte CIA1ICR = $DC0D + memory ubyte CIA1CRA = $DC0E + memory ubyte CIA1CRB = $DC0F - memory ubyte CIA2PRA = $DD00 ; CIA 2 DRA, serial port and video address - memory ubyte CIA2PRB = $DD01 ; CIA 2 DRB, RS232 port / USERPORT - memory ubyte CIA2DDRA = $DD02 ; CIA 2 DDRA, serial port and video address - memory ubyte CIA2DDRB = $DD03 ; CIA 2 DDRB, RS232 port / USERPORT - memory ubyte CIA2TALO = $DD04 ; CIA 2 timer A low byte - memory ubyte CIA2TAHI = $DD05 ; CIA 2 timer A high byte - memory ubyte CIA2TBLO = $DD06 ; CIA 2 timer B low byte - memory ubyte CIA2TBHI = $DD07 ; CIA 2 timer B high byte - memory ubyte CIA2TOD10 = $DD08 ; time of day, 1/10 sec. - memory ubyte CIA2TODS = $DD09 ; time of day, seconds - memory ubyte CIA2TODM = $DD0A ; time of day, minutes - memory ubyte CIA2TODH = $DD0B ; time of day, hours - memory ubyte CIA2SDR = $DD0C ; Serial Data Register - memory ubyte CIA2ICR = $DD0D - memory ubyte CIA2CRA = $DD0E - memory ubyte CIA2CRB = $DD0F + memory ubyte CIA2PRA = $DD00 ; CIA 2 DRA, serial port and video address + memory ubyte CIA2PRB = $DD01 ; CIA 2 DRB, RS232 port / USERPORT + memory ubyte CIA2DDRA = $DD02 ; CIA 2 DDRA, serial port and video address + memory ubyte CIA2DDRB = $DD03 ; CIA 2 DDRB, RS232 port / USERPORT + memory ubyte CIA2TAL = $DD04 ; CIA 2 timer A low byte + memory ubyte CIA2TAH = $DD05 ; CIA 2 timer A high byte + memory ubyte CIA2TBL = $DD06 ; CIA 2 timer B low byte + memory ubyte CIA2TBH = $DD07 ; CIA 2 timer B high byte + memory ubyte CIA2TOD10 = $DD08 ; time of day, 1/10 sec. + memory ubyte CIA2TODSEC = $DD09 ; time of day, seconds + memory ubyte CIA2TODMIN = $DD0A ; time of day, minutes + memory ubyte CIA2TODHR = $DD0B ; time of day, hours + memory ubyte CIA2SDR = $DD0C ; Serial Data Register + memory ubyte CIA2ICR = $DD0D + memory ubyte CIA2CRA = $DD0E + memory ubyte CIA2CRB = $DD0F ; ---- end of CIA registers ---- -; @todo SID sound chip registers +; ---- SID 6581/8580 registers ---- + + memory ubyte FREQLO1 = $D400 ; channel 1 freq lo + memory ubyte FREQHI1 = $D401 ; channel 1 freq hi + memory uword FREQ1 = $D400 ; channel 1 freq (word) + memory ubyte PWLO1 = $D402 ; channel 1 pulse width lo (7-0) + memory ubyte PWHI1 = $D403 ; channel 1 pulse width hi (11-8) + memory uword PW1 = $D402 ; channel 1 pulse width (word) + memory ubyte CR1 = $D404 ; channel 1 voice control register + memory ubyte AD1 = $D405 ; channel 1 attack & decay + memory ubyte SR1 = $D406 ; channel 1 sustain & release + memory ubyte FREQLO2 = $D407 ; channel 2 freq lo + memory ubyte FREQHI2 = $D408 ; channel 2 freq hi + memory uword FREQ2 = $D407 ; channel 2 freq (word) + memory ubyte PWLO2 = $D409 ; channel 2 pulse width lo (7-0) + memory ubyte PWHI2 = $D40A ; channel 2 pulse width hi (11-8) + memory uword PW2 = $D409 ; channel 2 pulse width (word) + memory ubyte CR2 = $D40B ; channel 2 voice control register + memory ubyte AD2 = $D40C ; channel 2 attack & decay + memory ubyte SR2 = $D40D ; channel 2 sustain & release + memory ubyte FREQLO3 = $D40E ; channel 3 freq lo + memory ubyte FREQHI3 = $D40F ; channel 3 freq hi + memory uword FREQ3 = $D40E ; channel 3 freq (word) + memory ubyte PWLO3 = $D410 ; channel 3 pulse width lo (7-0) + memory ubyte PWHI3 = $D411 ; channel 3 pulse width hi (11-8) + memory uword PW3 = $D410 ; channel 3 pulse width (word) + memory ubyte CR3 = $D412 ; channel 3 voice control register + memory ubyte AD3 = $D413 ; channel 3 attack & decay + memory ubyte SR3 = $D414 ; channel 3 sustain & release + memory ubyte FCLO = $D415 ; filter cutoff lo (2-0) + memory ubyte FCHI = $D416 ; filter cutoff hi (10-3) + memory uword FC = $D415 ; filter cutoff (word) + memory ubyte RESFILT = $D417 ; filter resonance and routing + memory ubyte MVOL = $D418 ; filter mode and main volume control + memory ubyte POTX = $D419 ; potentiometer X + memory ubyte POTY = $D41A ; potentiometer Y + memory ubyte OSC3 = $D41B ; channel 3 oscillator value read + memory ubyte ENV3 = $D41C ; channel 3 envelope value read + +; ---- end of SID registers ---- diff --git a/examples/bdmusic.p8 b/examples/bdmusic.p8 new file mode 100644 index 000000000..36e5a3814 --- /dev/null +++ b/examples/bdmusic.p8 @@ -0,0 +1,87 @@ +%import c64utils ; @todo make this import automatic if output is basic prg + +~ main { + +sub start() { + + const ubyte waveform = %0001 ; triangle + + c64.AD1 = %00011010 + c64.SR1 = %00000000 + c64.AD2 = %00011010 + c64.SR2 = %00000000 + c64.MVOL = 15 + + c64scr.print("will play the music from boulderdash,\nmade in 1984 by peter liepa.\npress enter to start: ") + c64.CHRIN() + c64.CLEARSCR() + + while(true) { + for uword note in notes { + ubyte n1 = lsb(note) + ubyte n2 = msb(note) + c64.FREQ1 = music_freq_table[n1] ; set lo+hi freq of voice 1 + c64.FREQ2 = music_freq_table[n2] ; set lo+hi freq of voice 2 + + ; retrigger voice 1 and 2 ADSR + c64.CR1 = waveform <<4 | 0 + c64.CR2 = waveform <<4 | 0 + c64.CR1 = waveform <<4 | 1 + c64.CR2 = waveform <<4 | 1 + + print_notes(n1, n2) + delay() + } + } + + sub delay() { + for ubyte d in 0 to 12 { + while(c64.RASTER!=0) { + ; tempo delay synced to screen refresh + } + } + } + + sub print_notes(ubyte n1, ubyte n2) { + c64.CHROUT('\n') + c64.PLOT(0, n1/2, 24) + c64.COLOR=7 + c64.CHROUT('Q') + c64.PLOT(0, n2/2, 24) + c64.COLOR=4 + c64.CHROUT('Q') + } +} + + ; details about the boulderdash music can be found here: + ; https://www.elmerproductions.com/sp/peterb/sounds.html#Theme%20tune + + uword[128] notes = [ + $1622, $1d26, $2229, $252e, $1424, $1f27, $2029, $2730, + $122a, $122c, $1e2e, $1231, $202c, $3337, $212d, $3135, + $1622, $162e, $161d, $1624, $1420, $1430, $1424, $1420, + $1622, $162e, $161d, $1624, $1e2a, $1e3a, $1e2e, $1e2a, + $142c, $142c, $141b, $1422, $1c28, $1c38, $1c2c, $1c28, + $111d, $292d, $111f, $292e, $0f27, $0f27, $1633, $1627, + $162e, $162e, $162e, $162e, $222e, $222e, $162e, $162e, + $142e, $142e, $142e, $142e, $202e, $202e, $142e, $142e, + $162e, $322e, $162e, $332e, $222e, $322e, $162e, $332e, + $142e, $322e, $142e, $332e, $202c, $302c, $142c, $312c, + $162e, $163a, $162e, $3538, $222e, $2237, $162e, $3135, + $142c, $1438, $142c, $1438, $202c, $2033, $142c, $1438, + $162e, $322e, $162e, $332e, $222e, $322e, $162e, $332e, + $142e, $322e, $142e, $332e, $202c, $302c, $142c, $312c, + $2e32, $292e, $2629, $2226, $2c30, $272c, $2427, $1420, + $3532, $322e, $2e29, $2926, $2730, $242c, $2027, $1420 + ] + + + uword[59] music_freq_table = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 732, 778, 826, 876, 928, 978, 1042, 1100, 1170, 1238, 1312, 1390, 1464, 1556, + 1652, 1752, 1856, 1956, 2084, 2200, 2340, 2476, 2624, 2780, 2928, 3112, 3304, + 3504, 3712, 3912, 4168, 4400, 4680, 4952, 5248, 5560, 5856, 6224, 6608, 7008, + 7424, 7824, 8336, 8800, 9360, 9904, 10496, 11120, 11712 + ] + +} diff --git a/examples/compiled/bdmusic.prg b/examples/compiled/bdmusic.prg new file mode 100644 index 0000000000000000000000000000000000000000..e8356cccad8d7f69582720b7a3671e09566f76ac GIT binary patch literal 907 zcmah`O-vI(7~OVDJ8eN|9XD0l^0BGiZrKj~flzy**lKIGv}sF(gJzE&jN#xxZG4siw=-6fis& z^ocyV8o6N@8ug?_`2V6uHdWGHuCs6mF#S^~GFzGBH&}JNo(|UrQb`VpOVJL= zQNoW=|7c9YNt#GsNPvOV`%izI5K#;U`KTlbLI7}ll*C066r+L^5CHJm4WGv&vx7~s z_t`b}fOT7B%QMSo3v@l`+Udg9ht@;uxb3AafS#j({f&LxapahFhPsctw|eF-` zQCH4AeQ^%&T>8e9Jk85WKjT~RuYkg@1h#^VI6L$%qFqtDbd6E1I%VAk>(RAd)uU^} zYX}}Y;bW`DF6A~@$o#0W_ck|JDiP6wxh^8d=H4ROT|%$SY6LA4RF5Dvgz5yTf*}aC z1@_$~I~6ecvPq{!;e64iFC$&+Q!Tpc)HPQJsZW&<6{?r;SZcwO lmS$C=5Go?TrgM;g2-Vu$#T?9BhH~)|$8k{ct@lDk&&%@u z^=;WOplTE@L!+caWxifM4;N~46_}ZuH;Q_#Sg4mYvr;JPP@aYKH@VZ!%c^=quYpn4 zs|9LSYkIv7`fNjQ)}S#5^+uuA$O9)!v2j(V6H%g^R3W7#f?AM9(m@TTv&pZf(y~OQ zaVaVRNs%Z4^7%Ot$wz1;5z&Z7P7s;I!?~~)j)%ublj_M)swx2`kd+kHeH1d4`x$9c z67b)de3`VqG~KqvnL{?q{7yD(TLCjA&#%s%(3)qP;3#Ray31U6oX?O^v2*LiJm&J0=K;U3rN z{`o0^+X?(?xchFwGGV{h*08gF6?G1Gxz6A$>meZofA_W!;OU!UuSB26IF(yH zveRQOx~yLvr6&KS)I{I*^^l{~5mo3@js2b@^%c~4ggR@F&!Eb!zJLFRZ_Z|ZLhfI3 p=uDFL?R?lidkviu#2*4^rr7@_xBt41##~z?P5