OK, this post is a bit old... but
Since a few, I am working about sound effects with Oric, the way they are generated by PING, EXPLODE or SHOOT (Not zap, because, it does not works the same way).
According to Theoric (Special issue, August 1985, page 36/37) , it works as it :
You have a table of 14 bytes at some address.
for PING, it is located at #FAA7( 64167) : 24,0,0,0,0,0,0,62,16,0,0,0,15,0
for SHOOT, at #FABD( 64189) : 0,0,0,0,0,0,15,7,16,16,16,0,8,0
for EXPLODE, at #FAD3( 64211) : 0,0,0,0,0,0,31,7,16,16,16,0,24,0
Whenever you call PING, SHOOT or EXPLODE :
1 ) Register X is loaded with lower order byte of the table starting address
2 ) Register Y is loaded with higher order byte of the table starting address
3) an Oric routine is called, playing the sound with this table.
Calling SHOOT, calls this piece of code
(JSR #FA6C for Oric1)
by trying and guess, luck I discovered a few interesting sound effects :
Electricity : 0,4,0,184,0,3,120,190,12,0,0,0,167,194
Helicopter : 168,191,0,3,184,191,14,0,0,0,167,194,76,176
Engine : 1,5,193,7,7,8,7,8,53,151,47,151,0,152
Inside the cockpit of a plane : 150,0,152,46,4,255,255,112,7,80,0,102,5,65
A plane (turboprop) : 32,2,140,0,5,132,14,136,132,12,140,0,69,173
Helicopter (far away) : 14,136,132,12,140,0,69,173,0,5,208,4,169,192
Forge hammer hitting an anvil : 32,134,250,96,0,0,0,0,0,0,31,7,16,16
all of these have to be a bit cleaned up (it's a non sense to have some data for channel A for instance, but with channel A non-activated)
found on the web,
here (another helicopter) :
206,108,231,36,137,112,70,182,170,239,83,246,12,165
Found in the Theoric magazine :
PONG : EE 02 00 00 00 00 00 3E 10 00 00 D0 07 00
PCHH: 00 00 00 00 00 00 01 37 10 00 00 D6 0B 00
Now, what is the meaning of each byte of the table ?
Simply, they correspond to the AY-3-8912 registers :
- 0 and 1 : tone (pitch) on channel A (n between 0 and 4096) (12 bits)
- 2 et 3 : tone (pitch) on channel B (between 0 and 4096) (12 bits)
- 4 et 5 : tone (pitch) on channel C (between 0 and 4096) (12 bits)
note:n=real_period/16/T0 (TO=1µS for Oric) or in short Frequency=1MHz/16/n (n=0 acts as n=1)
Possible frequencies are in range from 62500Hz (n=1) down to approx. 15.26Hz (n=4095)
6 : period of the noise generator (between 0 and 31) note: only bits 0 to 4 are used, Frequency=1MHz/16/n (n=0 acts as n=1)
7: Channels activation
bit 0: channel A
bit 1: channel B
bit 2: channel C
bit 3,4 et 5 mixing of the noise into the three primary channels
becarefull: bit=0 means "activated" bit=1 means NOT activated, for the 6 bits
(note: bit 6 is the port A direction and bit 7 the port B direction, not used for sound generation)
8,9,10 --> volume A,B,C (0 to 16)
more precisely :
- bits 0 to 3 (amplitude): maximum amplitude or volume (0 to 15)
- bit 4 (modulation) : 0 -->fixed amplitude 1-->amplitude controlled by B0-B3 and the envelop generator
Note : The volume is non-linear. The "real world" amplitude can be computed like this :
Code: Select all
real_world_amplitude = max / sqrt(2)^(15-n),
This amplitude corresponds to the voltage output to a speaker. (15 --> max/1, 14 --> max/1.414, 13 --> max/2, etc...)
11 and 12 --> Envelope step frequency - sound duration - (0 to 65535) note:Frequency=1MHz/16/n (n=0 acts as n=1)
Depending on the envelope shape, the volume is incremented from 0 to 15, or decremented from 15 to 0. In either case it takes 16 steps to complete, the completion time for 16 steps is therefore:
Code: Select all
T = n*256 / 1MHz ;with n in range 1..65535 (256µs .. 16.7 seconds)
13 --> envelop (0 to 15) note:only bits 0 to 3 are used.
According to wikipedia (french) : bits 0 to 3 permit to control the sound envelop but only 10 are available because only B2 is taken into account when B3 is equal to zero :
Code: Select all
B3 - Continue
B2 - Attack
B1 - Alternate
B0 - Hold
Code: Select all
Binary Hex Shape
00XX 00h-03h \_________ (same as 09h)
01XX 04h-07h /_________ (same as 0Fh)
1000 08h \\\\\\\\\\
1001 09h \_________ (volume remains quiet)
1010 0Ah \/\/\/\/\/
1011 0Bh \""""""""" (volume remains high)
1100 0Ch //////////
1101 0Dh /""""""""" (volume remains high)
1110 0Eh /\/\/\/\/\
1111 0Fh /_________ (volume remains quiet)
Registers+envelops :
http://download.abandonware.org/magazin ... e%2021.jpg
Pong sample for OSDK :
main.c
Code: Select all
#include <lib.h>
void Pong();
void main()
{
setflags(SCREEN+NOKEYCLICK);
while(get()!='Q') Pong();
}
pongsound.s
Code: Select all
Pongtable
.byt 238,2,0,0,0,0,0,62,16,0,0,208,7,0
_Pong
ldx #<Pongtable
ldy #>Pongtable
jsr $FA86
rts
There's a lot to dig in with this, because it is rather simple to put in practice, it does not consume a lot of memory.
Moreover (I would like to study that closely), it may be interesting to look out around with what can exist for the cpc464, for instance, or other microcomputer, for instance :
https://cpcrulez.fr/coding_basic-le_son_sur_AMSTRAD.htm
https://cpcrulez.fr/coding_src-list-sou ... mstrad.htm