Dr. Sound for the 64
Don MaloneMusic enthusiasts will have a field day with this Commodore 64 program, which allows you to experiment with a great variety of different sound parameters while the music plays. A disk drive is required.
"Dr. Sound" is an algorithmic note sequencer which plays notes according to parameters which you choose in realtime. Using the 64's built-in SID (Sound Interface Device) chip, it simulates a single-voice electronic synthesizer with dynamic timbre (tone color) control. If you're familiar with conventional electronic synthesizers, you'll probably recognize the screen display as a flowchart of the synthesizer's current patch or configuration. By changing different elements of the patch, you can alter the character of the music dramatically. After you create a patch you like, you can save it to disk for later reloading and use within the program. If you're new to computer-generated music, you'll enjoy experimenting and you can also learn a good deal from this program. Experts will appreciate all the features available in Dr. Sound.
Type in the program as listed and save a copy before you try to run it. Dr. Sound always begins with a short pause while it initializes. Then you will see the main display screen. The top portion of the screen contains a flowchart of the synthesizer's current patch. At the bottom are several prompts indicating parameters you can change by pressing various function keys. The bottom screen line is reserved for your input.
Music In The Background
When the display screen appears, you'll notice that background music begins playing immediately. The music will continue to play at all times while the program runs, except during disk operations.
Using Dr. Sound involves changing various program parameters to alter the character of the music. As a rule, whenever you change the synthesizer's patch, the screen display changes color to indicate which part of the synthesizer you are affecting. The different program options are selected by pressing one of the eight special function keys, f1-f8. Once an option is selected, the bottom screen line changes color and displays the keys you may press to select a choice within that option. In some cases, pressing the indicated key increases the value associated with that parameter; for these options, pressing the SHIFT key along with the indicated key decreases the same value.
Waveform And ADSR
One of the most fundamental changes involves waveforms. To choose a different waveform, press the f1 key. The bottom screen line then indicates your choices. To change the waveform, press the W key. There are four wave shapes available. The triangle is the sweetest of these, containing only odd-numbered overtones decreasing in loudness exponentially. The sawtooth is the brightest, containing all of the harmonic overtones. The pulse wave depends on its width (duty cycle) for its harmonic content. The closer to 99 percent or 1 percent, the more nasal (oboe-like) the pulse wave sounds. The closer to a 50 percent duty cycle, the more hollow (clarinet-like) it will be. Press P to change the pulse width. The noise waveshape is the most unpitched.
Ring modulation is a special SID effect, which you can toggle on and off by pressing the M key. When an M appears in the flowchart between the sound source and the modulator, you can see that modulation is on. Ring modulation is possibly the most sophisticated timbre control on the SID chip, making nonharmonic, bell-like overtones. The timbre of the sound depends on the frequency relationship between the sound source and the modulator. (Because of the way the SID chip circuitry is designed, only triangle waveshapes are available for this option.)
Pressing H toggles the harmony option on and off, which forces the sound source to be harmonic—that is, synchronous at an exact integer multiple with the modulator. When the harmony option is selected, an H appears in the display between the modulator and the sound source. This can be used to shift the A440 tuning of the sound source or to insure harmonic (more pitched) modulation. Modulation—like most of the other terms in this article—can be best understood by listening to the effect it has on different sounds.
The A, D, S, and R keys control attack, decay, sustain, and release, respectively. Attack is the amount of time it takes to begin the note. Decay is the amount of time it takes to drop to the sustain level, which is indicated as a percentage of the loudest sound possible. Release is the amount of time it takes to return to silence.
Special Effects
The f3 key allows you to change the low-pass filter parameters. Q changes the electronic resonance, which at 100 percent almost whistles, indicating sonically the changes in the cutoff frequency. F changes the percentage of the envelope generator (ADSR) used to control the cutoff frequency, and therefore the timbre, during each note. The lower the percentage, the more muffled the sound will be.
The f5 key selects the modulator section. W and P work just like the sound source section. T toggles on and off a trigger that allows the modulator to be heard while also modulating the sound source. I toggles parallel/oblique modes of the interval relationship between the modulator and the sound source. In the parallel mode the frequency follows the sound source at an interval indicated as a percentage of the sound source frequency. M and L change this relationship in 10 percent and 1 percent increments, respectively. Note that there is a delay of about six seconds to calculate these increments. In the oblique mode the frequency of the modulator is always the same. That frequency is tunable from 1 to 3995 Hz (cycles per second). The F, Q, C, and Y keys change the frequency in 1000 Hz, 100Hz, 10 Hz, and 1 Hz increments, respectively. The ADSR articulation control for the modulator is apparent only when the modulator trigger is on.
The f7 key selects the control section. The W, P, F, Q, C, and Y keys work the same way here as they do in the modulator section. However, in this case the waveshape and the relationship of the frequency to the duration of the current note determine the next note. The triangle and sawtooth waveshapes will produce easily recognizable patterns. The pulse produces a more austere pattern, and the noise waveform produces a random pattern.
G and A change the gate length. During the gate, the attack, decay, and sustain portions of the envelope generators are active. The gate time does not necessarily need to be longer than the attack time plus the decay time, but if it isn't, strange effects, including complete silence, may occur. R and E change the release time. During the release time, the release portion of the envelope generators are active. After the gate and release time, it takes about 223 microseconds to look at the keyboard. This delay becomes much longer if a key has been pressed. It takes another 104-195 microseconds to calculate the next note. However, if the release time of the sound source envelope generator is long enough, these delays will not be apparent.
Pitch Sets
The f2 key allows a choice of one of the 16 pitch sets. The patterns generated by Dr. Sound will be restricted to one of these sets at a time. They are defined as shown here:
0 | Major scale |
1 | Tonic |
2 | Supertonic |
3 | Mediant |
4 | Subdominant |
5 | Dominant |
6 | Submediant |
7 | Diminished |
8 | Subtonic |
9 | Augmented |
A | Chromatic |
B | Whole tone |
C | East |
D | Harmonic minor |
E | Pure minor |
F | Phrygian |
The f4 key allows control over the pitch range. The octaves are labeled from 0 to 7, with octave 0 being the lowest. The octave of each note is chosen from a set of eight possibilities, all of which are displayed on the screen. Pressing a number from 0 to 7 changes the next octave number in the set.
The f6 key allows control over the rhythm. This is also a set of eight, controlled like the octaves. The release time is multiplied by a factor from 1 to 8.
The f8 key permits you to save all of the current Dr. Sound settings with a filename of your choice, or to load a file of previously saved settings.
Dr. Sound For The 64
For instructions on entering this listing, please refer to "COMPUTE!'s Guide to Typing In Programs" in this issue of COMPUTE!.
CB 10 POKE 53280,0:POKE 53281,0:PRINT CHR$(142)CHR$(8):PRINT "[<8>]{CLR}": POKE 214,10:PRINT DM 20 PRINT TAB(16)"DR. SOUND":PRINT TAB(13)"{DOWN}WILL BE RUNNING" RK 30 PRINT TAB(14)"{DOWN}IN 24 SECONDS":C$=CHR$(13) FD 40 DIM PI$(11),PT$(15),OC$(7),RH$(7),PI(12),PM(12),A$(15),R$(16),S$(15),P$(15) GS 50 FOR C=0 TO 7:POKE 49920+C,4*16:NEXT:FOR C=0 TO 7:POKE 49936+C,1:NEXT:SI=54272 FJ 60 FOR C=SITOSI+24:POKE C,0:NEXT:POKE SI+24,9*16+15:POKE 53236,31:POKE 53239,128 CR 70 M$(0)="B":M$(1)="M":H$(0)="B":H$(1)="H":T$(0)="*OFF*":T$(1)="*****" CG 80 WS$(0)=" TRIANGLE":WS$(1)=" SAWTOOTH":WS$(2)="{4 SPACES}PULSE": WS$(3)="{2 SPACES}NOISE{2 SPACES}" SR 90 F$(0)="100% ":F$(1)="50%{2 SPACES}":F$(2)="25%{2 SPACES}":F$(3)="12.5%" MB 100 FOR C=50176 TO 50399:READ D:POKE C,D:NEXT:FOR C=0 TO 12:READ D:PI(C)=D:NEXT AR 110 FOR I=0 TO 15:READ PT$(I):FOR C=0 TO 15:READ D:POKE 49664+I*16+C,D:NEXT:NEXT MF 120 FORC=0TO15:READA$(C):NEXT:FORC=0TO16:READR$(C):NEXT:FORC=0TO7:E(C)=2^C:NEXT QQ 130 FOR C=0 TO 15:S$(C)=STR$(INT(C*6.66666667)):S$(C)=S$(C)+"%{2 SPACES}":NEXT KJ 140 FOR C=0 TO 15:P$(C)=STR$(INT(C*256/40.95)):P$(C)=P$(C)+"% ":NEXT KR 150 ML=.99:GOSUB 550:GOSUB 620:CW=1:H=0:M=0:PC=0:AC=0:DC=0:SC=15:RC=4:GOSUB 710 XK 160 RS=4:FC=1:AF=7:DF=3:SF=13:RF=5:GOSUB 780:PW=0:PC=0:AP=0:DP=0:SP=8:RP=15 SD 170 TP=1:FM=1:FP=0:GOSUB 830:WW=1:FQ=112:GG=20:RR=22:GOSUB 940:PT=13 FP 180 IN$="TRUMPET":POKE 53232,PT*16:GOSUB 1050 :GOSUB 1080:GOSUB 1120 :GOSUB 1150 PB 190 SYS 50176:GET K$:IF K$<>"" THEN 1170 FB 200 GOTO 190 QF 210 DATA 162,0,173,27,212,41,7,170,189,16,195,170,173,244,207,202 JP 220 DATA 48,6,109,244,207,76,15,196,141,243,207,162,0,173,27,212 DP 230 DATA 41,15,141,239,207,173,240,207,109,239,207,170,189,0,194,170 QC 240 DATA 173,27,212,41,7,168,185,0,195,141,238,207,138,109,238,207 XH 250 DATA 170,189,0,192,141,7,212,189,128,192,141,8,212,173,248,207 GA 260 DATA 208,12,189,0,193,141,0,212,189,128,193,141,1,212,173,252 BG 270 DATA 207,105,1,141,18,212,173,251,207,105,1,141,11,212,173,250 SB 280 DATA 207,109,249,207,141,4,212,173,247,207,141,255,207,173,246,207 KC 290 DATA 141,237,207,172,245,207,173,28,212,174,253,207,240,4,74,202 HB 300 DATA 208,252,141,22,212,136,208,238,206,237,207,208,230,206,255,207 MS 310 DATA 208,219,173,252,207,141,18,212,173,251,207,141,11,212,173,250 XQ 320 DATA 207,141,4,212,173,243,207,141,254,207,173,242,207,141,237,207 PH 330 DATA 172,241,207,173,28,212,174,253,207,240,4,74,202,208,252,141 KF 340 DATA 22,212,136,208,238,206,237,207,208,230,206,254,207,208,219,96 XG 350 DATA 268,284,301,318,337,358,379,401,425,451,477,506,536 BQ 360 DATA "MAJOR{10 SPACES}",5,7,9,10,12,5,4,2,0,0,12,9,5,9,5,0 XS 370 DATA "TONIC{10 SPACES}",5,9,12,0,5,9,12,0,5,9,12,0,5,9,12,0 GR 380 DATA "SUPERTONIC 7TH ",7,10,2,5,7,10,2,5,7,10,2,5,7,10,2,5 HP 390 DATA "MEDIANT{8 SPACES}",9,12,0,3,9,12,0,3,9,12,0,3,9,12,0,3 XP 400 DATA "SUBDOMINANT{4 SPACES}",10,2,5,10,2,5,10,2,5,10,2,5,10,2,5,10 HS 410 DATA "DOMINANT 7TH{3 SPACES}",0,4,7,10,12,0,4,7,10,12,0,4,7,10,12,0 KC 420 DATA "SUBMEDIANT{5 SPACES}",2,5,9,12,0,2,5,9,2,5,9,2,5,9,12,0 MC 430 DATA "DIMINISHED 7TH ",4,7,10,1,4,7,10,1,4,7,10,1,4,7,10,1 DJ 440 DATA "SUBTONIC{7 SPACES}",3,7,10,3,7,10,3,7,10,3,7,10,3,7,10,3 CE 450 DATA "AUGMENTED{6 SPACES}",0,4,8,12,0,4,8,12,0,4,8,12,0,4,8,12 MG 460 DATA "CHROMATIC{6 SPACES}",0,1,2,3,4,5,6,7,8,9,10,11,12,0,12,6 MJ 470 DATA "WHOLETONE{6 SPACES}",0,2,4,6,8,10,12,10,8,6,4,2,0,2,10,12 KD 480 DATA "EAST{11 SPACES}",0,2,5,7,9,12,0,2,5,7,9,12,5,2,5,7 EE 490 DATA "HARMONIC MINOR ",5,7,8,10,12,10,8,7,5,4,1,0,1,4,5,8 CA 500 DATA "PURE MINOR{5 SPACES}",5,7,8,10,12,10,8,7,5,3,1,0,1,3,5,8 JQ 510 DATA "PHRYGIAN{7 SPACES}",5,6,8,10,12,10,8,6,5,3,2,0,2,3,5,8 XF 520 DATA .002S,.008S,.016S,.024S,.038S,.056S,.068S,.08S ,.1S{2 SPACES}, .25S ,.5S{2 SPACES},.8S GE 530 DATA 1S{3 SPACES},3S{3 SPACES},5S{3 SPACES},8S{3 SPACES},.006S, .024S,.048S,.072S,.114S,.168S,.204S PS 540 DATA .24S ,.3S{2 SPACES},.75S ,1.5S ,2.4S ,3S{3 SPACES},9S{3 SPACES}, 15S{2 SPACES},"24S{2 SPACES}","{7 SPACES}" EK 550 FOR C=0 TO 12:FOR I=0 TO 7:PI=PI(C)*E(I):HP=INT(PI/256):IF HP>255 THENHP=255 EM 560 POKE 49280+I*16+C,HP:POKE 49152+I*16+C,PI-256*HP AND 255:NEXT:NEXT GP 570 IF LEN(STR$(ML))>5 THEN ML=INT(ML*100)/100 CP 580 FOR C=0 TO 12:PM(C)=PI(C)*ML:NEXT BX 590 FOR C=0 TO 12:FOR I=0 TO 7:PI=PM(C)*E(I):HP=INT(PI/256):IF HP> 255 THENHP=255 XP 600 POKE 49536+I*16+C,HP:Z=PI-256*HP:IF Z>255 THEN Z=255 SB 610 POKE 49408+I*16+C,Z:NEXT:NEXT:RETURN CE 620 PRINT "{CLR}{2 DOWN}"SPC(10)"CCC>AMPC*CCCC[<S>]" BP 630 PRINT TAB(4)"^"SPC(10)"^"SPC(7)"B" MB 640 PRINT TAB(4)"B"SPC(18)"B" GB 650 PRINT TAB(4)"B"SPC(18)"B" JQ 660 PRINT TAB(4)"B"SPC(18)"[<Q>]**>FILTER**>OUT" CR 670 PRINT TAB(4)"B"SPC(18)"B"SPC(5)"^" MQ 680 PRINT TAB(4)"B"SPC(18)"B" GQ 690 PRINT TAB(23)"B"SPC(5)"^":PRINT TAB(9)"*****>AMP"SPC(5)"[<X>]":PRINT TAB(16)"^" RA 700 RETURN CE 710 PRINT "{HOME}{DOWN}":IF M=1 THEN CW=0 QH 720 PRINT TAB(2)WS$(CW):IF CW=2 THEN PRINT " {UP}"P$(PC) SG 730 PRINT TAB(7)"{DOWN}[F1]"SPC(3)"A "A$(AC):PRINT TAB(4)M$(M)SPC(9)"D "R$(DC) XP 740 PRINT TAB(14)"S"S$(SC):PRINT TAB(4)H$(H)SPC(9)"R "R$(RC) PP 750 WC=2^(CW+4):IF M=1 THEN WC=20 SA 760 IF H=1 THEN WC=WC+2 CD 770 POKE 53243,WC:POKE SI+10,PC:POKE SI+12,AC*16+DC:POKE SI+13,SC*16+RC:RETURN JE 780 POKE 214,4:PRINT:PRINT TAB(28)"Q"S$(RS) SG 790 PRINT TAB(28)"{2 DOWN}"F$(FC):PRINT TAB(34)"{UP}[F3]" BJ 800 PRINT TAB(28)"{DOWN}A "A$(AF):PRINT TAB(28)"D "R$(DF) FC 810 PRINT TAB(28)"S"S$(SF):PRINT TAB(28)"R "R$(RF) CB 820 POKESI+23,RS*16+3:POKE53245,FC:POKESI+19,AF*16+DF:POKESI+20,SF*16+RF:RETURN AH 830 POKE 214,8:PRINT:IF M=1 THEN PW=0 CS 840 PRINT "{DOWN} "WS$(PW)SPC(8)T$(TP):IF PW=2 THEN PRINT "{UP}"P$(PP) QS 850 IF FP=1 THEN PRINT "{4 SPACES}FQCY{4 SPACES}":PRINT TAB(4)STR$(FM)+"HZ{3 SPACES}" EJ 860 IF FP=1 THEN Z=FM/.06097:PH=INT(Z/256):PL=Z-PH*256:POKE SI,PL:POKE SI+1,PH JA 870 IF FP=0 THEN PRINT "{4 SPACES}PARALLEL":PRINT TAB(4)"ML"STR$(INT(ML*100+.5))+ "%{2 SPACES}" GC 880 IF TP=1 THEN PRINT TAB(15)"{UP}A "A$(AP):PRINT TAB(15)"D "R$(DP) RH 890 IF TP=0 THEN PRINT TAB(15)"{UP}"R$(16):PRINT TAB(15)R$(16) PF 900 IF TP=1 THEN PRINT TAB(9)"[F5]"SPC(2)"S"S$(SP):PRINT TAB(15)"R "R$(RP) SA 910 IF TP=0 THEN PRINT TAB(9)"[F5]"SPC(2)R$(16):PRINT TAB(15)R$(16) XQ 920 WP=2^(PW+4):POKE 53242,WP:POKE SI+3,PP:POKE 53241,TP:POKE 53240,FP FQ 930 POKE SI+5,AP*16+DP:POKE SI+6,SP*16+RP:RETURN QC 940 POKE 214,16:PRINT EC 950 PRINT"[F7] "WS$(WW)SPC(1)"FQCY"STR$(FQ)+"HZ{3 SPACES}" RP 960 IF WW=2 THEN PRINT TAB(4)"{UP}"P$(CP) RF 970 SS=2^(WW+4):POKE53244,SS:POKESI+17,CP:Z=FQ/.06097:CH=INT(Z/256):CL=Z-CH*256 FR 980 POKE SI+14,CL:POKE SI+15,CH:GY=(GG AND 127)+1:GL=1:IF GG>127 THEN GL=128 GG 990 GT=(40+(((8+(((4+(((8+((7*FC)+2)+9)*GY)-1)+9)*GL)-1)+9)*128)-1))/1020000 FF 1000 GT=INT(GT*1000)/1000:PRINT TAB(27)"{2 UP}GA"STR$(GT)+"S{2 SPACES}" CE 1010 RY=(RR AND 127)+1:RL=1:IF RR>127 THEN RL=128 FG 1020 RT=(32+(((8+(((4+(((8+((7*FC)+2)+9)*RY)-1)+9)*RL)-1)+9)*31)-1))/1020000 KP 1030 RT=INT(RT*1000)/1000:PRINT TAB(27)"RE"STR$(RT)+"S{2 SPACES}" EX 1040 POKE 53238,GL:POKE 53237,GY:POKE 53234,RL:POKE 53233,RY:RETURN CS 1050 POKE214,18:PRINT:PRINT"[F2] PITCH SET(0-F)";:IFPT<10THENPRINT PT;PT$(PT) GD 1060 IF PT>9 THEN PRINT " "CHR$(PT+55)" "PT$(PT) FP 1070 POKE 53232,PT*16:RETURN RJ 1080 POKE 214,19:PRINT AE 1090 FOR C=0 TO 7:OC$(C)=RIGHT$(STR$((PEEK(49920+C))/16),1):NEXT AD 1100 PRINT"[F4] OCTAVE (0-7) ";:FORC=0TO7:PRINTOC$(C);CHR$(44);:NEXT:PRINT"{LEFT} " CE 1110 RETURN SF 1120 POKE214,20:PRINT:FORC=0TO7:RH$(C)=RIGHT$(STR$((PEEK(49936+C))+1),1):NEXT PG 1130 PRINT"[F6] RHYTHM (1-8) ";:FORC=0TO7:PRINTRH$(C);CHR$(44);:NEXT: PRINT"{LEFT} {HOME}" KG 1140 RETURN XA 1150 POKE 214,21:PRINT:PRINT "[F8] DISK ACCESS{HOME}" FX 1160 POKE 214,0:PRINT:PRINT TAB(27)IN$:RETURN KX 1170 K=ASC(K$+CHR$(0)):IF K>=132 AND K<=140 THEN GOSUB 1190 GE 1180 ON J GOSUB 1230,1380,1520,1800,2040,2080,2110,2140:GOTO 190 KS 1190 IF J=0 THEN 1210 RK 1200 PRINT "[<8>]":ON J GOSUB 1230,1380,1520,1800,2040,2080,2110,2140 XP 1210 J=K-132:PRINT "[<4>]":RETURN RR 1220 RETURN HJ 1230 POKE 214,22:PRINT:PRINT "{RVS} SOUND SOURCE{5 SPACES}W P M H A D {SPACE}S R{6 SPACES}{OFF}" JQ 1240 IF K$="W" THEN CW=(CW+1) AND 3 PP 1250 IF K$="H" THEN H=H+1 AND 1 EP 1260 IF K$="M" THEN M=M+1 AND 1 AM 1270 IF K$="P" THEN PC=PC+1 AND 15 JA 1280 IF K$="P" THEN PC=ABS(PC-1) EH 1290 IF K$="A" THEN AC=AC+1 AND 15 FX 1300 IF K$="D" THEN DC=DC+1 AND 15 KB 1310 IF K$="S" THEN SC=SC+1 AND 15 EC 1320 IF K$="R" THEN RC=RC+1 AND 15 EB 1330 IF K$="A" THEN AC=ABS(AC-1) QE 1340 IF K$="D" THEN DC=ABS(DC-1) CF 1350 IF K$="S" THEN SC=ABS(SC-1) FH 1360 IF K$="R" THEN RC=ABS(RC-1) SJ 1370 K$="":GOTO 710 SB 1380 POKE 214,22:PRINT:PRINT"{RVS} FILTER{4 SPACES}Q F A D S R{17 SPACES}{OFF}" BG 1390 IF K$="Q" THEN RS=RS+1 AND 15 MP 1400 IF K$="Q" THEN RS=ABS(RS-1) BP 1410 IF K$="F" THEN FC=FC+1 AND 3 AP 1420 IF K$="F" THEN FC=ABS(FC-1) CG 1430 IF K$="A" THEN AF=AF+1 AND 15 FQ 1440 IF K$="D" THEN DF=DF+1 AND 15 FB 1450 IF K$="S" THEN SF=SF+1 AND 15 GD 1460 IF K$="R" THEN RF=RF+1 AND 15 CX 1470 IF K$="A" THEN AF=ABS(AF-1) MC 1480 IF K$="D" THEN DF=ABS(DF-1) ED 1490 IF K$="S" THEN SF=ABS(SF-1) KH 1500 IF K$="R" THEN RF=ABS(RF-1) RP 1510 K$="":GOTO 780 EJ 1520 POKE 214,22:PRINT:PRINT"{RVS} MODULATOR W P T I M/L F/Q/C/Y A D S R {OFF}" JQ 1530 IF K$="W" THEN PW=(PW+1) AND 3 FM 1540 IF K$="P" THEN PP=PP+1 AND 15 BX 1550 IF K$="P" THEN PP=ABS(PP-1) MP 1560 IF K$="T" THEN TP=TP+1 AND 1 SA 1570 IF K$="I" THEN FP=FP+1 AND 1 AH 1580 IF K$="F" THEN FM=FM+1000 RK 1590 IF K$="Q" THEN FM=FM+100 PD 1600 IF K$="C" THEN FM=FM+10 SP 1610 IF K$="Y" THEN FM=FM+1 HR 1620 IF FM>3995 THEN FM=3995 CF 1630 IF K$="F" THEN FM=ABS(FM-1000) BK 1640 IF K$="Q" THEN FM=ABS(FM-100) BP 1650 IF K$="C" THEN FM=ABS(FM-10) HD 1660 IF K$="Y" THEN FM=ABS(FM-1) RK 1670 IF K$="M" THEN ML=ML+.1:GOSUB 570 RJ 1680 IF K$="L" THEN ML=ML+.01:GOSUB 570 BD 1690 IF K$="M" THEN ML=ABS(ML-.1):GOSUB 570 DA 1700 IF K$="L" THEN ML=ABS(ML-.01):GOSUB 570 MQ 1710 IF K$="A" THEN AP=AP+1 AND 15 MC 1720 IF K$="D" THEN DP=DP+1 AND 15 AH 1730 IF K$="S" THEN SP=SP+1 AND 15 GK 1740 IF K$="R" THEN RP=RP+1 AND 15 DD 1750 IF K$="A" THEN AP=ABS(AP-1) KG 1760 IF K$="D" THEN DP=ABS(DP-1) BF 1770 IF K$="S" THEN SP=ABS(SP-1) KJ 1780 IF K$="R" THEN RP=ABS(RP-1) RM 1790 K$="":GOTO 830 RM 1800 POKE 214,22:PRINT: PRINT "{RVS} CONTROL{4 SPACES}W P F/Q/C/Y{2 SPACES}G/A{2 SPACES}R/E{6 SPACES}{OFF}" JM 1810 IF K$="W" THEN WW=(WW+1) AND 3 SG 1820 IF K$="P" THEN CP=CP+1 AND 15 XQ 1830 IF K$="P" THEN CP=ABS(CP-1) PK 1840 IF K$="F" THEN FQ=FQ+1000 RD 1850 IF K$="Q" THEN FQ=FQ+100 PH 1860 IF K$="C" THEN FQ=FQ+10 GS 1870 IF K$="Y" THEN FQ=FQ+1 XF 1880 IF FQ>3995 THEN FQ=3995 RJ 1890 IF K$="F" THEN FQ=ABS(FQ-1000) KS 1900 IF K$="Q" THEN FQ=ABS(FQ-100) KB 1910 IF K$="C" THEN FQ=ABS(FQ-10) DH 1920 IF K$="Y" THEN FQ=ABS(FQ-1) PJ 1930 IF K$="G" THEN GG=GG+25 MQ 1940 IF K$="A" THEN GG=GG+1 QM 1950 IF GG>255 THEN GG=255 XJ 1960 IF K$="G" THEN GG=ABS(GG-25) MR 1970 IF K$="A" THEN GG=ABS(GG-1) BK 1980 IF K$="R" THEN RR=RR+25 XH 1990 IF K$="E" THEN RR=RR+1 KG 2000 IF RR>255 THEN RR=255 PF 2010 IF K$="R" THEN RR=ABS(RR-25) AS 2020 IF K$="E" THEN RR=ABS(RR-1) QF 2030 K$="":GOTO 940 QD 2040 POKE 214,22:PRINT: PRINT "{RVS} PITCH SET{2 SPACES}0 1 2 3 ...{SPACE}9 A B C D E F{2 SPACES}{OFF}" HE 2050 IF K<58 AND K>47 THEN PT=K-48 PM 2060 IF K<71 AND K>64 THEN PT=K-55 GJ 2070 K$="":GOTO 1050 KR 2080 POKE 214,22:PRINT:PRINT"{RVS} OCTAVES{4 SPACES}0,1,2,3,4,5,6,7{12 SPACES}{OFF}" DJ 2090 IF K<56 AND K>47 THEN K=K-48:CT=CT+1 AND 7:POKE 49920+CT,K*16 JQ 2100 K$="":GOTO 1080 AC 2110 POKE 214,22:PRINT:PRINT"{RVS} RHYTHMS{6 SPACES}1,2,3,4,5,6,7,8{10 SPACES}{OFF}" RA 2120 IF K<57 AND K>48 THEN K=K-49:YT=YT+1 AND 7:POKE 49936+YT,K KK 2130 K$="":GOTO 1120 AS 2140 POKE 214,22:PRINT:PRINT"{RVS}{2 SPACES}DISK ACCESS{5 SPACES}S L{18 SPACES}{OFF}" SC 2150 IF K$="S" THEN GOSUB 2180 FR 2160 IF K$="L" THEN GOSUB 2300:GOSUB 2440 BD 2170 K$="":GOTO 1150 AA 2180 POKE 214,22:PRINT:PRINT"{RVS} SAVE FILE NAME{21 SPACES}{OFF}" BS 2190 PRINT TAB(18)"{UP}{RVS}";:INPUT IN$:PRINT "{UP}{OFF}":IN$=LEFT$(IN$,12) AX 2200 OPEN 15,8,15:OPEN 2,8,2,"0:"+IN$+",S,W" QS 2210 GOSUB 2410:IF EN>1 THEN FOR C=0 TO 5000:NEXT:CLOSE 2:CLOSE 15:RETURN CD 2220 PRINT #2,CW;C$;H;C$;M;C$;PC;C$;AC;C$;DC;C$;SC;C$;RC EG 2230 PRINT #2,RS;C$;FC;C$;AF;C$;DF;C$;SF;C$;RF AH 2240 MD=ML:PRINT #2,PW;C$;PP;C$;MD;C$;FM;C$;TP;C$;FP;C$;AP;C$;DP;C$;SP;C$;RP SQ 2250 PRINT #2,WW;C$;CP;C$;FQ;C$;GG;C$;RR;C$;PT:GOSUB 2410 GF 2260 FOR C=0 TO 7:PRINT #2,PEEK(49920+C) GJ 2270 NEXT:FOR C=0 TO 7:PRINT #2,PEEK(49936+C) ER 2280 NEXT:GOSUB 2410 XQ 2290 CLOSE 2:CLOSE 15:RETURN EJ 2300 POKE 214,22:PRINT:PRINT"{RVS} LOAD FILE NAME{21 SPACES}{OFF}" FA 2310 PRINT TAB(18)"{UP}{RVS}";:INPUT IN$:PRINT "{UP}{OFF}":IN$=LEFT$(IN$,12) JP 2320 OPEN 15,8,15:OPEN 2,8,2,"0:"+IN$+",S,R" RG 2330 GOSUB 2410:IF EN>1 THEN FOR C=0 TO 5000:NEXT:CLOSE 2:CLOSE 15:RETURN BF 2340 INPUT #2,CW,H,M,PC,AC,DC,SC,RC GK 2350 INPUT #2,RS,FC,AF,DF,SF,RF JX 2360 INPUT #2,PW,PP,MD,FM,TP,FP,AP,DP,SP,RP SE 2370 INPUT #2,WW,CP,FQ,GG,RR,PT:GOSUB 2410 RQ 2380 FOR C=0 TO 7:INPUT #2,X:POKE(49920+C),X:NEXT QP 2390 FOR C=0 TO 7:INPUT #2,X:POKE(49936+C),X:NEXT:GOSUB 2410 HG 2400 CLOSE 2:CLOSE 15:RETURN KG 2410 INPUT #15,EN,EM$,ET,ES SH 2420 IF EN>1 THEN POKE 214,22:PRINT:PRINT CHR$(18);EM$;CHR$(32);"{5 SPACES}" CK 2430 RETURN RK 2440 IF FP=0 THEN IF MD<>ML THEN ML=MD:GOSUB 570 RM 2450 PRINT "[<8>]{HOME}":GOSUB 710:GOSUB 780:GOSUB 830:GOSUB 940 EG 2460 GOSUB 1050:GOSUB 1080:GOSUB 1120:PRINT "[<4>]{HOME}":GOSUB 1150:RETURN
In the original text, line 140 had a typo so the checksum did not match. This has been corrected.