Beep

VERA PSG
The PSG on the VERA chip provides 16 channels, accessible through VRAM addresses $1F9C0 through $1F9FF, and consequently very easy to use with VPOKE. For now, we'll analyze channel 0, which uses VRAM addresses $1F9C0 through $1F9C3.

The registers of channel 0 look as follows:

Frequency word specifies the frequency of the wave, in intervals of 0.373 Hz (derived as 25 MHz / 226). To convert from MIDI note to frequency word, use the following formula:

FW = INT(EXP(N*0.0577622651)*21.9467431+0.5)

(derived as exp(n * ln 2 / 12) * (1 / exp(69 * ln 2 / 12) * 440 * 226 / 2.5e7))

Left and Right specify whether you want to use the left channel, right channel or both.

Volume is a simple volume slider going from 0 to 63.

Waveform controls the waveform of the sound:

Pulse width only matters when the waveform is 0 (pulse), and controls the duty cycle of the pulse waveform. A value of 63 will give a 50% duty cycle or square wave, 0 will give a very narrow pulse.

The very basic requirements to play sound on the VERA PSG are:
 * 1) Load the properties of the note into VRAM ($1F9C0, $1F9C1, $1F9C3)
 * 2) Load the volume into VRAM ($1F9C2)
 * 3) (wait)
 * 4) Reset the volume to 0 in VRAM ($1F9C2)

Example program that plays Twinkle Twinkle Little Star, and demonstrates how you would do things such as tempo control and volume decay in BASIC: 10 REM SINGLE CHANNEL PLAYBACK DEMO

20 REM MAIN FLOW - WHICH SEGMENTS TO PLAY AND HOW FAST

30 TEMPO = 120

40 RESTORE : S = 0 : GOSUB 500

50 RESTORE : S = 1 : GOSUB 500

60 RESTORE : S = 1 : GOSUB 500

70 RESTORE : S = 0 : GOSUB 500

80 END

500 REM SUBROUTINE FOR PLAYING A SEGMENT

510 TD = 7272/TEMPO-14

520 CS = 0

530 READ SL

540 FOR NL = 1 TO SL

550 READ N

560 READ VOL

570 READ ND

580 IF CS = S THEN GOSUB 1000 : REM SKIPS UNWANTED SEGMENTS

590 NEXT NL

600 IF CS = S THEN RETURN

610 CS = CS + 1

620 GOTO 530

1000 REM SUBROUTINE FOR PLAYBACK OF A SINGLE NOTE

1010 REM ARGUMENTS

1020 REM N - MIDI VALUE OF NOTE TO PLAY FROM 0 TO 127 ($7F)

1030 REM VOL - VOLUME OF NOTE TO PLAY FROM 0 TO 63 ($3F)

1040 REM ND - DURATION OF NOTE TO PLAY IN SIXTEENTHS

1100 REM CONVERT MIDI NOTE TO FREQWORD

1110 FW = INT(EXP(N*0.0577622651)*21.9467431+0.5)

1120 REM SPLIT FREQWORD TO HIGH AND LOW BYTES

1130 HB = INT(FW/$100)

1140 LB = FW-HB*$100

1150 REM SPECIFY THE FREQWORD AND INSTRUMENT WE WANT

1160 VPOKE 1,$F9C0,LB

1170 VPOKE 1,$F9C1,HB

1180 VPOKE 1,$F9C3,$80 : REM TRIANGLE AS DEMO

1190 REM PLAY THE NOTE

1200 FOR I = 0 TO ND*8-1

1210 VPOKE 1,$F9C2,VOL+$C0

1220 VOL = VOL - INT((VOL+$F)/$10) : REM CONTROLS VOLUME DECAY

1230 FOR J = 0 TO TD : NEXT J

1240 NEXT I

1250 VPOKE 1,$F9C2,$00

1260 RETURN

1500 REM DATA POWERING PLAYBACK - TWINKLE TWINKLE LITTLE STAR

2000 DATA 14 : REM SEGMENT 0

2010 DATA 60,$3F,4

2020 DATA 60,$3F,4

2030 DATA 67,$3F,4

2040 DATA 67,$3F,4

2050 DATA 69,$3F,4

2060 DATA 69,$3F,4

2070 DATA 67,$3F,8

2080 DATA 65,$3F,4

2090 DATA 65,$3F,4

2100 DATA 64,$3F,4

2110 DATA 64,$3F,4

2120 DATA 62,$3F,4

2130 DATA 62,$3F,4

2140 DATA 60,$3F,8

2500 DATA 7 : REM SEGMENT 1

2510 DATA 67,$3F,4

2520 DATA 67,$3F,4

2530 DATA 65,$3F,4

2540 DATA 65,$3F,4

2550 DATA 64,$3F,4

2560 DATA 64,$3F,4

2570 DATA 62,$3F,8

YM2151
The very basic requirements to play sound on the YM2151 chip are:
 * 1) Load a patch into the YM2151 registers for one of the 8 voices (channels).
 * 2) Set the note value for the channel
 * 3) Send a KeyDown message to play the note
 * 4) (wait)
 * 5) Send a KeyUP message to release the note when it has played for the intended duration

When playing multiple notes, if you have not released the previous note (KeyUP) yet, then sending a second KeyDN will NOT play the new note. This would be like trying to press a piano key that you're already holding down.

To talk to the YM2151, you POKE information into one of its two I/O memory locations:
 * Address Register ($9FE0) - tells the YM2151 which of its internal register addresses to use
 * Data Register ($9FE1) - send the actual values to this register
 * NOTE: These I/O addresses are very likely to change in the future, as they correspond to expansion port addresses, and if the YM2151 is approved for the system, it is likely to be built into the mainboard directly and will use a different IO address range than the expansion slots.

Example program to play two chime sounds in an ascending tone, which might serve as a positive audible feedback tone: 10 S=600               : REM NOTE SPEED

20 YA=$9FE0 : YD=$9FE1 : REM YM2151 ADDRESS/DATA PORTS

30 LN=$3A : HN=$44     : REM LN/HN = LO NOTE / HI NOTE

40 REM --- LOAD PATCH INTO VOICE 0 ---

50 FOR I=1 TO 5

60 READ A : READ D

70 POKE YA,A   : POKE YD,D

80 NEXT I

100 REM --- PLAY HAPPY SOUND ---

110 POKE YA,$28 : REM $28 IS VOICE 0 FREQ. SETTING

120 POKE YD,LN  : REM SET THE FREQ. TO LO NOTE VALUE

130 POKE YA,$08 : REM SELECT THE KEYUP/DN REGISTER

140 POKE YD,0   : REM RELEASE ANY PREVIOUS NOTE

150 POKE YD,$40 : REM PLAY THE NOTE

160 FOR I = 1 TO S : NEXT

170 POKE YD,0   : REM RELEASE THE NOTE

180 FOR I = 1 TO S : NEXT

190 POKE YA,$28

200 POKE YD,HN	: REM SET NEXT NOTE FREQ. TO HI-NOTE

210 POKE YA,$08

220 POKE YD,0

230 POKE YD,$40

240 FOR I = 1 TO S : NEXT

250 POKE YD,0   : REM RELEASE THE SECOND NOTE

260 END

1000 REM --- PATCH DATA ---

1010 DATA $20, $C0

1020 DATA $58, $01

1030 DATA $98, $1F

1040 DATA $B8, $0D

1050 DATA $F8, $F6 The patch data lines are arranged to make it easy to play around with them and see what they do.

The settings mean the following:

$20 = master channel configuration: $C0 = L & R volume ON, No Feedback, Use OP algorithm 0.

$58 = fine detuning / phase multiplier: $01 = no detune (hi nybble) / multiplier=1 (normal)

$98 = Key-scale / Attack Rate: $1F = no keyscale / max attack rate (keyscale = 3 MSB, attack = 5 LSB)

$B8 = Amplitude Mod ENA / 1st Decay Rate: $0D = no AM / Decay=13 (AM-ENA is 1 MSB / decay is 5 LSB)

$F8 = Sustain Level / Release Rate: $F6 = max sustain (0-F in hi nybble / release=6 .. 0-F in lo nybble)

Note that this patch is very simple, and only utilizes the 4th operator of voice 0. More advanced patches would require more settings to be made for each voice, which is beyond the scope of a simple "hello world" example for sound.