Classic Computer Magazine Archive COMPUTE! ISSUE 38 / JULY 1983 / PAGE 212

VIC MUSICIAN

Blake Wilson

You can have your VIC playing a song in the background while some other BASIC program is RUNning. It will even play while you're programming. This article will also show you how to take music from a printed score and enter it into your VIC.

I have always believed that music in any form was above my head. I own a computer retail store, and several customers have asked how they could produce music that would run continuously, without delays, during a program. My wife helped me to understand just what all those incomprehensible symbols on a piece of sheet music actually mean. I wanted the explanation in terms that I (and VIC) could understand. The only musical instrument that I can play is the VIC. Here's her response:

Don't be concerned that some shafts go up and some down, or that notes may be joined with arcs or bar-like flags. These exist only to confuse computer people. You need be concerned only with the duration of a note (filled in or open, whether it has a shaft or not, and the number of bars or flags. By the way, a dot after a note increases its duration by 50 percent) and its pitch (as determined by its altitude on the staff). Any pitch of less than 128 is a rest or silence.

If notes are stacked, just take the highest one. There are generally two staffs (groups of lines). The lower set is often for harmony; usually we can ignore them.

Compare the data at line 190 with the musical score above. Notice that the first item is duration. The first note is filled in and has a shaft and one flag. That means that it is an eighth note and will be played for 15 jiffies. The next data item represents the pitch — it is 201 because the note is tangent to the lowest line. The next two notes are the same. The fourth note is open and has a shaft. So it is a half note and gets 60 jiffies. Since that note is on the third line, its pitch is 'G' = 215. See how it works?

Inspect a musical score and write data for each note, first duration and then pitch. Place the data in the program to replace lines 190 through 260. The actual line numbers mean nothing, but the first 71 data items representing the program must come first.

The program is limited to 61 notes due to the size of the cassette buffer. In practice, the 61 notes should be enough for most programs. I use only 37 notes in the sample program. If your creation uses fewer than 61 notes, end your data with 1, 1. This instructs the computer to replay from the first.

Once the data has been POKEd into the buffer and you've done a SYS to 830, the music plays continuously even if you execute NEW or write another program. The music will continue until:

  1. You type a RUN/STOP RESTORE
  2. Attempt to use the cassette
  3. Or get so tired of it that you shut off the VIC.

The program is driven by the hardware interrupt. Each jiffy (1/60 of a second), a counter ($033D = 829) is reduced by one. If this decrement results in a value of zero, the next duration is placed in the counter, the next note is placed in the sound generator ($900C = 36876), and the note count is increased by two and stored at ($033C = 828). The computer then goes on its way, updating the realtime clock and scanning its keyboard.

The computer is not slowed appreciably. Most of the time, unless the note is to be changed, the time wasted is 120 microseconds per second or 120 parts per million. If the note must be changed, then the time lost is a few thousandths of a second.

Note: A complete listing of musical pitch values, including sharps and flats, is in the VIC-20 Programmer's Reference Guide.

Program 1 : VIC Musician

10 REM ******* VIC MUSICIAN **********
30 REM *** CONTINUOUSLY PLAYS *******
40 REM ** TUNE FROM STAR WARS ******
60 POKE 36878,15 : REM SET VOLUME TO MAX
70 FOR I = 830 TO 976 : READC : POKEI, C : NEXT
80 SYS 830 : REM STARTS MUSIC
90 REM ******* SET-UP FOLLOWS *******
100 DATA 120, 169, 5, 141, 60, 3, 169, 6, 141, 61, 3, 169
110 DATA 133, 133, 0, 169, 3, 133, 1, 169, 93, 141
120 DATA 20, 3, 169, 3, 141, 21, 3, 88, 96
130 REM **** MUSIC PGM FOLLOWS ******
140 DATA 206, 61, 3, 208, 28, 72, 152, 72, 172, 60
150 DATA 3, 200, 177, 0, 141, 61, 3, 200, 177, 0, 201
160 DATA 1, 240, 12, 141, 12, 144, 140, 60, 3, 104
170 DATA 168, 104, 76, 191, 234, 160, 255, 208, 243
180 REM *** MUSIC DATA FOLLOWS ******
190 DATA 15, 201, 15, 201, 15, 201, 60, 215, 60, 228, 15
200 DATA 225, 15, 223, 15, 219, 60, 235, 35, 228, 15
210 DATA 225, 15, 223, 15, 219, 60, 235, 35, 228, 15
220 DATA 225, 15, 223, 15, 225, 60, 219, 35, 201, 15
230 DATA 201, 60, 215, 60, 228, 15, 225, 15, 223, 15
240 DATA 219, 60, 235, 35, 228, 15, 225, 15, 223, 15
250 DATA 219, 60, 235, 35, 228, 15, 225, 15, 223, 15
260 DATA 219, 60, 235, 1, 1

Program 2: Disassembled Machine Language For VIC Musician

033E 78       SEI	;PROHIBIT INTERRUPTS (DON'T BOTHER ME)
033F A9 05    LDA #$05	;FIRST NOTE IS SILENCE
0341 8D 3C 03 STA $033C	;STORE NOTE
0344 A9 06    LDA #$06	;WAIT 6 JIFFIES
0346 8D 3D 03 STA $033D	;STORE DELAY
0349 A9 85    LDA #$85	;ADDRESS LOW OF START OF MUSIC DATA
034B 85 00    STA $00	;ZERO PAGE POINTER
034D A9 03    LDA #$03	;ADDRESS HI START OF MUSIC DATA
034F 85 01    STA $01	;ZERO PAGE POINTER
0351 A9 5D    LDA #$5D	;ADDRESS LOW OF MUSIC PROGRAM
0353 8D 14 03 STA $0314	;VECTOR INTERRUPT TO MUSIC PGM
0356 A9 03    LDA #$03	;ADDRESS HI OF MUSIC PROGRAM
0358 8D 15 03 STA $0315	;VECTOR INTERRUPT TO MUSIC PGM
035B 58       CLI	;OK TO INTERRUPT AGAIN
035C 60       RTS	;BACK TO BASICS
035D CE 3D 03 DEC $033D	;REDUCE DELAY COUNTER
0360 D0 1C    BNE $037E	;UMLESS DELAY IS FINISHED, EXIT
0362 48       PHA	;SAVE ACCUMULATOR ON STACK
0363 98       TYA	;TRANSFER Y TO ACCUMULATOR
0364 48	      PHA       ;SAVE IT TOO
0365 AC 3C 03 LDY $033C	;GET POINTER TO LAST NOTE FREQUENCY
0368 C8       INY	;MOVE POINTER TO NEXT DELAY
0369 Bl 00    LDA ($00) ,Y	;GET NEXT DELAY
036B 8D 3D 03 STA $033D	;SET DELAY DURATION
036E C8       INY	;MOVE POINTER TO NOTE FREQUENCY
036F Bl 00    LDA ($00) ,Y	;GET NOTE FREQUENCY OR TONE
0371 C9 01    CMP #$01	;IS FREQUENCY = 1 (START OVER FLAG)
0373 F0 0C    BEQ $0381	;IF SO, PLAY IT AGAIN SAM
0375 8D 0C 90 STA $900C	;START NOTE PLAYING
0378 8C 3C 03 STY $033C	;STORE NOTE FREQUENCY POINTER
037B 68       PLA	;RETRIEVE Y FROM STACK
037C A8       TAY	;PUT Y BACK IN Y
037D 68       PLA	;RETRIEVE ACCUMULATOR
037E 4C BF EA JMP $EABF	;GO ON ABOUT YOUR BUSINESS
0381 A0 FF    LDY #$FF	;SET NOTE POINTER TO START -1
0383 D0 F3    BNE $0378	;BRANCH ALWAYS TO STORE POINTER