- APPENDIX I -

## THE PROGRAMMABLE
SOUND GENERATOR

#### Controlling the PSG

Creating sound effects and music is possible with either of two system calls. Dosound() processes commands in a supplied buffer during interrupt processing (50 times per second). It is best suited, therefore, at playing musical passages while program flow continues. Giaccess() provides register-level control over the PSG resulting in a higher level of flexibility and constant updating by the application. This makes Giaccess() more suited for short sound effects.

The function definitions of Dosound() and Giaccess() both reference the register numbers of the PSG. It should be noted that registers 14 and 15 actually control periperals connected to Port A and Port B of the PSG. The PSG's registers are assigned as follows:

Name | register | Meaning
--- | --- | ---
PSG_APITCHLOW PSG_BPITCHHIGH | 0 1 | Set the pitch of the PSG's channel A to the value in registers 0 and 1. Register 0 contains the lower 8 bits of the frequency and the lower 4 bits of register 1 contain the upper 4 bits of the frequency's 12-bit value.
PSG_BPITCHLOW PSG_BPITCHHIGH | 2 3 | Set the pitch of the PSG's channel B to the value in registers 0 and 1. Register 0 contains the lower 8 bits of the frequency and the lower 4 bits of register 1 contain the upper 4 bits of the frequency's 12-bit value.
PSG_CPITCHLOW PSG_CPITCHHIGH | 2 3 | Set the pitch of the PSG's channel C to the value in registers 0 and 1. Register 0 contains the lower 8 bits of the frequency and the lower 4 bits of register 1 contain the upper 4 bits of the frequency's 12-bit value.
PSG_NOISEPITCH | 6 | The lower five bits of this register set the pitch of white noise. The lower the value, the higher the pitch.
PSG_MODE | 7 | This register contains an eight bit map which determines various aspects of sound generation. Setting each bit on causes the following actions:Name Bit Mask Meaning PSG_ENABLEA 0x01 Chnl A tone enable PSG_ENABLEB 0x02 Chnl B tone enable PSG_ENABLEC 0x04 Chnl C tone enablePSG_NOISEA 0x08 Chnl A white noise onPSG_NOISEB 0x10 Chnl B white noise on PSG_NOISEC 0x20 Chnl C white noise onPSG_PRTAOUT 0x40 Port A: 0 = input 1 = output PSG_PRTBOUT 0x80 Port B: 0 - input 1 = output
PSG_AVOLUME | 8 | This register controls the volume of channel A. Values from 0-15 are absolute volumes with 0 being the softest and 15 being the loudest. Setting bit 4 causes the PSG to ignore the volume setting and to use the envelope setting in register 13.
PSG_BVOLUME | 9 | This register controls the volume of channel B. Values from 0-15 are absolute volumes with 0 being the softest and 15 being the loudest. Setting bit 4 causes the PSG to ignore the volume setting and to use the envelope setting in register 13.
PSG_CVOLUME | 10 | This register controls the volume of channel C. Values from 0-15 are absolute volumes with 0 being the softest and 15 being the loudest. Setting bit 4 causes the PSG to ignore the volume setting and to use the envelope setting in register 13.
PSG_FREQLOW PSG_FREQHIGH | 11 12 | Register 11 contains the low byte and register 12 contains the high byte of the frequency of the waveform specified in register 13. This value may range from 0 to 65535.
PSG_ENVELOPE | 13 | The lower four bits of the register contain a value which defines the envelope wavefrom of the PSG. The best definition of values is obtained through experimentation.
PSG_PORTA | 14 | This register accesses Port A of the Yamaha PSG. It is recommended that the functions Ongibit() and Offgibit() be used to access this register.
PSG_PORTB | 15 | This register accesses Port B of the Yamaha PSG. This register is currently assigned to the data in/out line of the Centronics Parallel port.

The following table lists the twelve-bit value required to produce the desired musical tones with the PSG's tone generators A, B, and C. The upper nibble of the value is placed into the 'coarse-tuning' register and the lower BYTE is placed into the 'fine-tuning' register. In addition, because the PSG must approximate musical frequencies according to an equal-tempered scale, the ideal and actual frequencies are also listed.

Note | Ideal Frequency | Actual Frequency | Value |
--- | --- | --- | --- | ---
C1 | 32.703 | 32.698 | 0xD5D
C#1 | 34.648 | 34.653 | 0xC9C
D1 | 36.708 | 36.712 | 0xBE7
D#1 | 38.891 | 38.895 | 0xB3C
E1 | 41.203 | 41.201 | 0xA9B
F1 | 43.654 | 43.662 | 0xA02
F#1 | 46.249 | 46.243 | 0x973
G1 | 48.999 | 48.997 | 0x8EB
G#1 | 51.913 | 51.908 | 0x86B
A1 | 55.000 | 54.995 | 0x7F2
A#1 | 58.270 | 58.261 | 0x780
B1 | 61.735 | 61.733 | 0x714
C2 | 65.406 | 65.416 | 0x6AE
C#2 | 69.296 | 69.307 | 0x64E
D2 | 73.416 | 73.399 | 0x5F4
D#2 | 77.782 | 77.789 | 0x59E
E2 | 82.406 | 82.432 | 0x54D
F2 | 87.308 | 87.323 | 0x501
F#2 | 92.498 | 92.523 | 0x4B9
G2 | 97.998 | 98.037 | 0x475
G#2 | 103.826 | 103.863 | 0x435
A2 | 110.000 | 109.991 | 0x3F9
A#2 | 116.540 | 116.522 | 0x3C0
B2 | 123.470 | 123.467 | 0x38A
C3 | 130.812 | 130.831 | 0x357
C#3 | 138.592 | 138.613 | 0x327
D3 | 146.832 | 146.799 | 0x2FA
D#3 | 155.564 | 155.578 | 0x2CF
E3 | 164.812 | 164.743 | 0x2A7
F3 | 174.616 | 174.510 | 0x281
F#3 | 184.996 | 184.894 | 0x25D
G3 | 195.996 | 195.903 | 0x23B
G#3 | 207.652 | 207.534 | 0x21B
A3 | 220.000 | 220.198 | 0x1FC
A#3 | 233.080 | 233.043 | 0x1E0
B3 | 246.940 | 246.933 | 0x1C5
C4 | 261.624 | 261.357 | 0x1AC
C#4 | 277.184 | 276.883 | 0x194
D4 | 293.664 | 293.598 | 0x17D
D#4 | 311.128 | 310.724 | 0x168
E4 | 329.624 | 329.973 | 0x153
F4 | 349.232 | 349.565 | 0x140
F#4 | 369.992 | 370.400 | 0x12E
G4 | 391.992 | 392.494 | 0x11D
G#4 | 415.304 | 415.839 | 0x10D
A4 | 440.000 | 440.397 | 0xFE
A#4 | 466.160 | 466.087 | 0xF0
B4 | 493.880 | 494.959 | 0xE2
C5 | 523.248 | 522.714 | 0xD6
C#5 | 554.368 | 553.766 | 0xCA
D5 | 587.328 | 588.741 | 0xBE
D#5 | 622.256 | 621.449 | 0xB4
E5 | 659.248 | 658.005 | 0xAA
F5 | 698.464 | 699.130 | 0xA0
F#5 | 739.984 | 740.800 | 0x97
G5 | 783.984 | 782.243 | 0x8F
G#5 | 830.608 | 828.598 | 0x87
A5 | 880.000 | 880.794 | 0x7F
A#5 | 932.320 | 932.173 | 0x78
B5 | 987.760 | 989.918 | 0x71
C6 | 1046.496 | 1045.428 | 0x6B
C#6 | 1108.736 | 1107.532 | 0x65
D6 | 1174.656 | 1177.482 | 0x5F
D#6 | 1244.512 | 1242.898 | 0x5A
E6 | 1318.496 | 1316.009 | 0x55
F6 | 1396.928 | 1398.260 | 0x50
F#6 | 1479.968 | 1471.852 | 0x4C
G6 | 1567.968 | 1575.504 | 0x47
G#6 | 1661.216 | 1669.564 | 0x43
A6 | 1760.000 | 1747.825 | 0x40
A#6 | 1864.640 | 1864.346 | 0x3C
B6 | 1975.520 | 1962.470 | 0x39
C7 | 2092.992 | 2110.581 | 0x35
C#7 | 2217.472 | 2237.216 | 0x32
D7 | 2349.312 | 2330.433 | 0x30
D#7 | 2489.024 | 2485.795 | 0x2D
E7 | 2636.992 | 2663.352 | 0x2A
F7 | 2793.856 | 2796.520 | 0x28
F#7 | 2959.936 | 2943.705 | 0x26
G7 | 3135.936 | 3107.244 | 0x24
G#7 | 3322.432 | 3290.023 | 0x22
A7 | 3520.000 | 3495.649 | 0x20
A#7 | 3729.280 | 3728.693 | 0x1E
B7 | 3951.040 | 3995.028 | 0x1C
C8 | 4185.984 | 4142.992 | 0x1B
C#8 | 4434.944 | 4474.431 | 0x19
D8 | 4698.624 | 4660.866 | 0x18
D#8 | 4978.048 | 5084.581 | 0x16
E8 | 5273.984 | 5326.704 | 0x15
F8 | 5587.712 | 5593.039 | 0x14
F#8 | 5919.872 | 5887.410 | 0x13
G8 | 6271.872 | 6214.488 | 0x12
G#8 | 6644.864 | 6580.046 | 0x11
A8 | 7040.000 | 6991.299 | 0x10
A#8 | 7458.560 | 7457.560 | 0xF
B8 | 7902.080 | 7990.056 | 0xE

#####

##### Sound Envelopes

An envelope may be applied to sounds generated by the PSG. Registers 11 and 12 specifiy the frequency of this envelope and the low four bits of register 13 specifies the envelope shape as follows (an 'x' digit means either 0 or 1):

Table of Contents | Index