Sharp logo

MZ-800 course Chapter 6 
6. Musical applications


In this chapter we shall discuss the musical functions of the SHARP. The SHARP has 3 chords and 6 octaves, so there are more than enough possibilities. All instructions that have something to do with making sounds or music will also be discussed in this chapter. An instruction like BEEP shall also come to the attention, because this instruction produces a short beep.

6.1 Port $F2

The port responsible for making your SHARP produce sound and music is port $F2. It is also known as the PSG-port, in which PSG stands for programmable sound generator. This generator consists of three normal, independent generators and one noise generator. Each generator also has a reducer with a range of 28 dB.

From page A-7 up to A-9 of the manual you can also find a bit of information about the PSG. The way the PSG is discussed in the manual is not the most straight forward one, that is why we will discuss this port thoroughly in this chapter.

Many books on the SHARP MZ-800 cover the PSG. We got our information from the manual, Alles ueber den MZ-800 from BBG, the book Programmeren in de Toongenerator from SCCE and the Technical Reference Manual from SHARP itself.

Controlling port $F2 is not straightforward. Most of the times some calculation is necessary to control this port properly.

Each of the three tone generators contains a 10-bit wide counter that is software controllable and is used as a variable frequency divider.

We can use a formula to convert the frequency to values that are usable by the PSG. The output of the formula consists of two values. One must be added to a value and then be sent to port $F2 and the other one must be sent to port $F2 directly.

For each tone generator there is a default value to which the output of the formula must be added, these initial values are:

128 for tone generator 1.
160 for tone generator 2.
192 for tone generator 3.

Now we will give a program which you can use to convert the frequency to the values used by the PSG. This program is from the book Alles ueber den MZ-800 from BBG.

10 CLS
20 INPUT "Frequency in Hertz? "; FR
30 F0=11094/(FR/10)
40 B6=INT(F0/16)
50 B4=FRAC(F0/16)*16
60 IF FRAC(B4)>=.5 THEN B4=INT(B4)+1:ELSE B4=INT(B4)
70 IF FRAC(F0)>=.5 THEN F0=INT(F0)+1:ELSE F0=INT(F0)
80 PRINT "6 Bit part: "; B6
90 PRINT "4 Bit part: "; B4
100 PRINT "F0: "; F0
110 PRINT:PRINT:GOTO 20

As you can see, a 4-bit and a 6-bit part are calculated. They add up to 10 bits which makes the 10 bit counter. The value of the 4 bits part is added to the initial value of the tone generator end the value of the 6 bits part is sent to port $F2 separately.

An example:

You want to get a frequency of 442 Hz from tone generator 1. You use the program to calculate the 4 bits and the 6 bits part. Then you sent the calculated values to port $F2 in the correct way and you will hear a tone with a frequency of 442 Hz.

If you have done everything right, the 4 bits part will be 11 and the 6 bits part will be 15.

Send the values to port $F2 in the following manner:

OUT@$F2,160+11:OUT@$F2,15

You have sent a tone with a frequency of 442 Hz to tone generator 2, but you do not hear anything yet. This is because you still have to set the volume. For each tone generator there is a unique domain.

Tone generator 1 : 144 - 159
Tone generator 2 : 176 - 191
Tone generator 3 : 208 - 223
Noise generator : 240 - 255

In this table the minimum value is the maximum volume for a tone generator. If for example you want to hear the tone of 442 Hz as loud as possible, you must enter:

OUT@$F2,176

If you do not want to hear the tone at all, you enter:

OUT@$F2,191

You can vary the volume of the tone from loud to inaudible in the following way:

OUT@$F2,160+11:OUT@$F2,15:FOR A=176 TO 191:OUT@$F2,A:WAIT 150:NEXT A

You can also make a wave pattern by varying the volume from loud to soft, then from soft to loud and by repeating this. You will encounter this later on in this chapter.

There is another important thing worth knowing and that is that it is not possible to use more than 3 generators at the same time. This means that you can produce 3 tones or 2 tones and one noise.

With the NOISE instruction you can only produce 1 tone and 1 noise. By addressing port $F2 directly you can do more than with a BASIC-instruction.

As you see, addressing port $F2 is not as difficult as it might seem at first glance. To play a piece of music by addressing port $F2 is very difficult, for this end the BASIC-instruction MUSIC or a machine code routine is far more suitable. Both the MUSIC-instruction as well as the machine code solution will be discussed further on in this chapter.

First we will discuss a whole scale of options for port $F2. You can do about everything with this port, from the sound of a laser gun sounds to speech. Can the SHARP talk? Of course it can. It is just a matter of addressing port $F2 in the right way and that is not easy. We shall not go in to the talking capabilities of the SHARP. Those who want to hear the SHARP talk are directed to programs like SPRACHUHR.

Here are a couple of examples of all sorts of sounds we can make. Sometimes a short explanation will be present.

Example 1: Launch

This program produces the sound of a launching rocket.

10 REM LAUNCH
20 INIT "CRT:M1":PAL 0,1:CURSOR 0,24
30 IF PEEK($4DCF)>1 THEN PO=$4DD0 ELSE PO=$4DCF
40 POKE PO,$1:SYMBOL 152,184,CHR$(60),2,2:POKE PO,$0
50 P=242:REM P=port $F2
60 GOSUB "DELETE"
70 FOR A=0 TO 15
80 OUT@P,231:OUT@P,240
90 PRINT
100 FOR A=192 TO 207
110 OUT@P,A:OUT@P,L
120 NEXT A:PRINT
130 OUT@P,(L+240)
140 NEXT L
150 END
160 LABEL "DELETE"
170 OUT@P,159:OUT@P,191
180 OUT@P,223:OUT@P,255
190 RETURN

In line 80 the noise that is to be used is defined. You see that this program produces a tone and a noise that both get lower in frequency, this results in the desired effect.

In the subroutine denoted by LABEL "DELETE" all sound volumes are set to 0. After calling this routine nothing will be audible anymore. You get the same effect with USR(0071). Nothing will be audible either after this USR.

Example 2: Tick of a gas station

10 REM TICK
20 INIT "CRT:M1"
30 P=242:REM P=port $F2
40 GOSUB "DELETE"
50 OUT@P,131:OUT@P,10
60 OUT@P,175:OUT@P,9
70 FOR T=0 TO 11:CURSOR 0,0:PRINT T
80 FOR A=144 TO 159
90 OUT@P,A:OUT@P,(A+32)
100 WAIT 60
110 NEXT A
120 NEXT T
130 END
140 LABEL "DELETE"
150 OUT@P,159:OUT@P,191
160 OUT@P,223:OUT@P,255
170 RETURN

This program uses the two tone generators and the noise generator is not used.

Example 3: Two tones against each other

This program makes two tones audible that have an opposite frequency. The frequency of one tone gets higher while the other one gets lower. At a certain point in time both frequencies will be equal.

10 INIT "CRT:M1"
20 USR(71):P=242
30 FOR A=15 TO 0 STEP -1
40 FOR B=175 TO 160 STEP -1
50 OUT@P,B:OUT@P,A
60 OUT@P,367-B:OUT@P,15-A
70 OUT@P,176:OUT@P,208
80 NEXT B,A
90 USR(71)

Example 4: Increasingly faster running wave

This program will make a soft tone loud and vice versa and does this increasingly faster.

10 INIT "CRT:M1":USR(71):P=242:OUT@P,176:OUT@P,171:OUT@P,5
20 FOR A=25 TO 0 STEP -1
30 FOR B=177 TO 190
40 OUT@P,B:WAIT A*4
50 NEXT B
60 FOR B=189 TO 176 STEP -1
70 OUT@P,B:WAIT A*4
80 NEXT B
90 NEXT A
100 USR(71)

Example 5: Explosion

1 INIT "CRT:M1":X=20:C=3
2 USR(71):OUT@$F2,228
3 PAL 0,7:CURSOR X,12:PRINT [2]CHR$(200):WAIT 2000
4 IF PEEK($4DCF)>1 THEN PO=$4DD0 ELSE PO=$4DCF
5 POKE PO,1:CURSOR X,12:PRINT [0]CHR$(200):SYMBOL [1]X*8,96,CHR$(141),1,1
  :SYMBOL [1]X*8-8,88,CHR$(188),3,3
6 OUT@$F2,$C8:FOR A=$F0 TO $FF:OUT@$F2,A:WAIT 200:GOSUB 8:NEXT A
7 POKE PO,0:END
8 C=C+2:CLS
9 SYMBOL [1]X*8-4*(C-1),88-4*(C-3),CHR$(188),C,C
10 SYMBOL [1]X*8-2*(C-3),96-2*(C-3),CHR$(141),C/2,C/2:RETURN

Example 6: 3 variable tones

This program produces two tones and one noise sound which you can alter yourself with the 1 - 6 and A - F keys. The pitch of the tones can be adjusted with the 1 - 6 keys and with the A - F keys you can reduce the volume. Reducing the sound for 30 dB means that you will no longer hear the tone.

You can end the program by pressing the CR-key.

1 USR(71)
2 INIT "CRT:M1":PAL 1,12:PAL 2,24
3 PRINT "1=PITCH PORT 1 UP"
4 PRINT "2=PITCH PORT 1 DOWN"
5 PRINT "3=PITCH PORT 2 UP"
6 PRINT "4=PITCH PORT 2 DOWN"
7 PRINT "5=PITCH NOISE PORT UP"
8 PRINT "6=PITCH NOISE PORT DOWN"
9 PRINT:PRINT "A=VOLUME PORT 1 UP"
10 PRINT "B=VOLUME PORT 1 DOWN"
11 PRINT "C=VOLUME PORT 2 UP"
12 PRINT "D=VOLUME PORT 2 DOWN"
13 PRINT "E=VOLUME NOISE PORT UP"
14 PRINT "F=VOLUME NOISE PORT DOWN"
15 COLOR 1
16 PRINT:PRINT:PRINT TAB(13) "freq. (Hz)";:PRINT TAB(27)"reduce (dB)":PRINT
17 PRINT " PORT 1"
18 PRINT:PRINT " PORT 2"
19 PRINT:PRINT " NOISE PORT"
20 COLOR 2
21 BOX 0,132,319,147
22 BOX 0,147,319,162
23 BOX 0,162,319,177
24 BOX 88,132,204,147
25 COLOR 3
26 CURSOR 0,24:PRINT "CR=END (C)1990 by NEPTUNES SOFTWARE.";
27 F1=400:M1=144
28 F2=500:M2=176
29 FN=600:MN=240
30 CURSOR 12,17:PRINT F1;" ":PRINT:PRINT TAB(12)F2;" ":PRINT:PRINT TAB(12)FN;" "
31 CURSOR 26,17:PRINT (M1-144)*2;" ":PRINT:PRINT TAB(26)(M2-176)*2;" ":PRINT
   :PRINT TAB(26)(MN-240)*2;" "
32 FQ=F1:ME=M1:GOSUB CALCULATE
33 FQ=F2:ME=M2:GOSUB CALCULATE
34 FQ=FN:ME=MN:GOSUB CALCULATE
35 GET A$:A=PEEK(4965):IF A=13 THEN USR(71):CLS:END
36 IF A<49 OR A>70 THEN 35
37 IF A>54 AND A<65 THEN 35
38 F1=F1+(5 AND A=49 AND F1<10000)-(5 AND A=50 AND F1>30)
39 F2=F2+(5 AND A=51 AND F2<10000)-(5 AND A=52 AND F2>30)
40 FN=FN+(5 AND A=53 AND FN<10000)-(5 AND A=54 AND FN>30)
41 M1=M1+(1 AND A=66 AND M1<159)-(1 AND A=65 AND M1>144)
   :M2=M2+(1 AND A=68 AND M2<191)-(1 AND A=67 AND M2>176)
42 MN=MN+(1 AND A=70 AND MN<255)-(1 AND A=69 AND MN>240):GOTO 30
43 LABEL "CALCULATE":F0=11094/(FQ/10):B6=INT(F0/16):B4=FRAC(F0/16)*16
44 IF FRAC(B4)>.5 THEN B4=INT(B4)+1:ELSE B4=INT(B4)
45 IF FRAC(F0)>.5 THEN F0=INT(F0)+1:ELSE F0=INT(F0)
46 OUT@$F2,DE-16+B4:OUT@$F2,B6
47 OUT@$F2,DE:RETURN

Previous page
Next page
Contents


Go to the top of this page Home

last updated March 22, 2006
Arjan Habing, Mark de Rover, Jeroen F. J. Laros, sharpmz@sharpmz.org