MZ-800 course Chapter 6
|6. Musical applications|
There is the possibility to make use of a very simple machine language program to make music. The big advantage of this method is that you can do something else with your computer while playing music (you do not have to wait until the music is done) and the program in machine code will use less memory.
In this part of chapter 6 we shall explain how to convert the data to machine code and we shall give a couple of examples of music samples which we will convert to machine code.
In the machine language of BASIC (MB) you can not enter the notes you want to play literally. In MB you must enter special codes.
Each note has a different code and one single note can itself differ per octave.
In the table below you can see which codes you must use in MB to get the notes in different octaves:
MUSIC "02#D" is code 27 in MB.
In BASIC transformation is denoted by S and the transformation speed by M, for example MUSIC "S2M7".
In MB there are special codes as well and these codes you must calculate yourself in the following way:
For the transformation: 144 + transformation. So S2 becomes 146 in MB.
For the transformation speed: 160, speed. So first you give the code 160 and then the code of the transformation speed. M7 becomes 160,7 in MB and M255 becomes 160,255.
The example above will become: 146,160,7 in MB.
With tempo we also use a standard code to which we must add our tempo. For tempo in MB is 105 + tempo. This makes TEMPO 1 106 in MB and TEMPO 5 becomes 110 and so on.
Duration of the notes
In BASIC the duration of the notes is given by a number after the note. In MB the duration must be placed before the note.
An example: MUSIC "02A3" becomes 99,33 in MB. So for the duration goes the same as for the tempo and the transformation. We must use a standard code to which the duration must be added. For the duration of a note:
The duration in MB is calculated by adding the duration to 96. Length 3 becomes 99. Length 6 becomes 102 and so on.
With the adjustment of the volume we also use a standard code to which the volume must be added.
The volume in MB is calculated by adding the volume to 128. Volume 3 becomes 131. Volume 15 becomes 143, and so on.
With the information given up to now, you can convert a normal musical application to machine code. However, there are some things we have not discussed yet, things like +, - and things like that. In MB it is very easy to convert these characters into codes. Just increase the octave on + and and decrease the octave on - and .
For example: MUSIC O2+A3 becomes 99,45 in MB.
The machine code program
In the machine code program that produces the music you can decide for yourself how many chords you would like to use. In a very simple way you can use 1, 2 or 3 chords. We can place the program from address $F000. This wastes a lot of memory of course, but this is just an example.
From address $F000 on we put all music codes. It is important to close the music string in MB with a termination code, this code is $FF (255 decimal).
We shall place these values in memory from address $F000 on and we shall terminate it with the termination code. First we shall limit the memory after $EFFF to ensure that we do not accidentally write BASIC over the program. All in all it looks like this:
LIMIT $EFFF :POKE $F000,135,111,99,33,146,160,27,25,101,33,$FF
Of course you also need a program to play this music string. Now follows a program that does just that. The program is placed at address $F500 in memory.
(The underlined values are the values that are really important).
You can call this routine with USR($F500), you will hear the music after calling this.
The assembler listing of the program looks like this:
F500 ORG F500H F509 RST 3 F500 LD B,03H F50A DEFB 21H F502 RST 3 F50B LD B,01H F503 DEFB 23H F50D RST 3 F504 LD A,00H F50E DEFB 23H F506 LD DE,F00H F50F RET
The value in register A (in this case 0) denotes the chord and the value in register DE is the address where the codes can be found (in this case F000H).
The rest of this program is always the same, even when we use more chords at the same time.
Register A can contain the following values:
A=0 - Chord 1.
A machine code program that uses two chords and the NOISE at the same time looks like this:
POKE $6,$3,$DF,$23,$3E,$0,$11,$00,$F0,$DF,$21,$3E,$1,$11,$4E,$F7,$DF,$21,$3E,$3, $11,$34,$F7,DF,$21,$6,$1,$DF,$23,$C9
The underlined area is added to make use of chord 2 and the NOISE.
The codes for chord 2 will reside at address $F74E.
The codes for NOISE will reside at address $F734.
As you can see it is not so difficult to convert a piece of music from BASIC to machine code and what is even easier is that you can look in memory to see how a BASIC-music string will look like in MB, because a normal BASIC-music string also has to be converted before it can be played.
Finally we shall give a program that places three music strings in memory at address $F000 in MB and it will also tell from which address on the strings will reside in memory.
10 LIMIT $EFFF:TEMPO 5 20 CLS:ADDRESS=$F000:READ=$2ED0:VOICE=1 30 A$="03V15S0M10+C5B1+C+D+CBA+C3+C1A+C5B1+C" 40 B$="O2V10S0M10E5D1CDCDFE3G1FE5D1C" 50 C$="01V11S0M5C3C1C0CC3C1C0CC3CCE1E0EE3E1E0E":MUSIC A$;B$;C$ 60 FOR F=0 TO 2 70 PRINT "VOICE";VOICE;" STARTS AT ADDRESS ";HEX$(ADDRESS):VOICE=VOICE+1 80 P=PEEK(READ) 90 POKE ADDRESS,P:ADDRESS=ADDRESS+1:READ=READ+1 100 IF P=255 AND PEEK(READ-1)<>160 THEN NEXT F:END 110 GOTO 80
The first line of the BOLERO (a piece of music from the next part of this chapter) will be converted to machine code. You will see instantly where the different voices (chords) will reside in memory. With the following program you can also make this piece of music audible:
POKE $F500,$6,$3,$DF,$23,$3E,$0,$11,$00,$F0,$DF,$21,$3E,$1,$11,$18,$F0,$DF,$21, $3E,$2,$11,$30,$F0,$DF,$21,$6,$1,$DF,$23,$C9 :USR($F500)