4.1. Programming Sound Effects
In fact, programming effects
code differs little from similar classes in Basic, but you get
a significant advantage at the expense of speed. Therefore,
other than pure tones in assembler, you can create and noise.
4.1.1. Tone
We begin with the effects based on the generation of tones.
What are they? Roughly the same as the effects in Basic:
the sound of smoothly varying frequency. For
complete similarity can even use
the same routine from ROM: 1415.
10 LD B, 30; B = number of notes
20 LD HL, 100; HL = start frequency
30 LOOP LD DE, 2; DE = duration
1940 PUSH HL; conservation HL
1950 PUSH BC; preservation BC
60 CALL 949, call ROM routines
1970 POP BC; restore BC
1980 POP HL; recovery HL
90 LD DE, 25; DE = step frequency changes
100 ADD HL, DE; increase in HL
110 DJNZ LOOP; cycle
120 RET; return to BASIC
2
Most likely, you've noticed that in this
effect does not prohibit termination, and signal quality no
worse (see chapter "How is sound"). The fact is
that routine is called to do everything myself.
If you have already managed to recruit and run
this fragment, it probably felt the difference in the sound,
not in favor of BASIC.
Modify somewhat the effect
possible by changing the frequency is not the whole but only its
Low byte:
1415.
10 LD B, 60; B = number of notes
20 LD C, 50; C = step frequency changes
30 LD HL, 300; HL = start frequency
40 LOOP LD DE, 10; DE = duration
1950 PUSH HL; conservation HL
1960 PUSH BC; preservation BC
70 CALL 949, call ROM routines
1980 POP BC; restore BC
1990 POP HL; recovery HL
100 LD A, L; uveli110 ADD C; chenie
120 LD L, A; L
130 DJNZ LOOP; cycle
140 RET; return to BASIC
2
The use of sub-ROMs proceed to creating your own. The sound
of the previous examples can be made smoother and more
prolonged: 1415.
10 DI; ban interrupt
20 XOR A; A = border color (0)
30 LD B, 255; B = initial frequency
40 LD C, 255; C = duration
50 BEEP XOR 16; inverting bits D4
60 OUT (254), A; output to port A 254
1970 PUSH BC; preservation BC
1980 LOOP DJNZ LOOP; delay
1990 POP BC; restore BC
100 DEC B; decrease in B
110 DEC C; C = C-1
120 JR NZ, BEEP; if C <> 0 then loop
130 EI; permission to interrupt
140 RET; return to BASIC
2
The possibilities of this effect can be easily increased to:
1415.
10 DI; ban interrupt
20 XOR A; A = border color (0)
30 LD B, 255; B = number of notes
40 LD C, 1; C = initial frequency
50 LOOP1 PUSH BC; preservation BC
60 LD B, 5; B = length
70 LOOP2 XOR 16; inverting bits D4
80 OUT (254), A; output to port A 254
1990 PUSH BC; preservation BC
100 LD B, C; B = C
110 LOOP3 DJNZ LOOP3; delay
120 POP BC; restore BC
130 DJNZ LOOP2; cycle
140 POP BC; restore BC
150 INC C; increase in C
160 DJNZ LOOP1; second cycle
170 EI; permission to interrupt
180 RET; return to BASIC
2
Most likely, you've noticed that in the first
variant delay is reduced, and the second
increases. Nothing prevents you to change
direction of change. It only
should choose DEC (decrease) or
INC (increase). You can also configure and
duration, start frequency, etc.
You can change the pitch of the frequency shift:
1415.
10 DI; ban interrupt
20 XOR A; A = border color (0)
30 LD B, 255; B = initial frequency
40 LD C, 255; C = duration
50 BEEP XOR 16; inverting bits D4
60 OUT (254), A; output to port A 254
1970 PUSH BC; preservation BC
1980 LOOP DJNZ LOOP; delay
1990 POP BC; restore BC
100 EX AF, AF '; shift registers A and F on
Alternative
110 LD A, B; A = B
120 SUB 3; A = A-3
130 LD B, A; B = A
140 EX AF, AF '; feedback shift registers
150 DEC C; C = C-1
160 JR NZ, BEEP; if C <> 0 then loop
170 EI; permission to interrupt
180 RET; return to BASIC
2
Now we use the freedom of action,
which we provide programming
in the codes. We write the non-standard procedure
Runtime:
1415.
10 DI; ban interrupt
20 LD D, 10; D = delay 1
30 LD E, 100; E = Delay 2
40 LD C, 255; C = duration
50 XOR A; A = border color (0)
60 LOOP1 XOR 16; inverting bits D4
70 OUT (254), A; output to port A 254
80 LD B, D; B = D
90 LOOP2 DJNZ LOOP2; delay
100 XOR 16; inverting bits D4
110 OUT (254), A; output to port A 254
120 LD B, E; B = E
130 LOOP3 DJNZ LOOP3; delay
140 INC D; increase in D
150 INC E; increase in E
160 DEC C; C = C-1
170 JR NZ, LOOP1; if C <> 0 then loop
180 EI; permission to interrupt
190 RET; return to BASIC
2
Here, too, can be long and carefully
vary the parameters (see Appendix 1 -
Flowing 2).
Quite an interesting effect is obtained by using the
register R, value under seven bits of which increases
after the next machine cycle. This effect can be described as
"polushumom.
Here is an example of such an effect:
1415.
10 DI; ban interrupt
20 LD C, 53; C = delay 1
30 LD B, 207; B = Delay 2
40 LD E, 203; E = duration
50 LD D, 0; D = Border color
60 LD A, 128; A = temp (0 / 128)
70 LD R, A; R = A
80 BEGIN LD A, R; A = R
90 PAUS1 DEC A; A = A-1
100 JR NZ, PAUS1; if A <> 0 then loop
110 LD A, D; A = D
120 OR 16; setting bit D4
130 OUT (254), A; output to port A 254
140 LD A, C; A = C
150 PAUS2 DEC A; A = A-1
160 JR NZ, PAUS2; if A <> 0 then loop
170 LD A, D; A = D
180 OUT (254), A; output to port A 254
190 LD A, B; A = B
200 PAUS3 DEC A; A = A-1
210 JR NZ, PAUS3; if A <> 0 then loop
220 INC C; C = C +1
230 INC B; B = B +1
240 DEC E; E = E-1
250 JR NZ, BEGIN; if E <> 0 then loop
260 EI; permission to interrupt
270 RET; Returns
2
Values in lines 20 and 30 define
delay between the differences of level, in line
40 - duration of effect, in line 50 -
Border color, and line 60 - the tempo. In
line 60 makes sense to use only
values 0 and 128, since all other
will be similar to this. In lines 220 and 230
You can set the law of variation of both
delay (command INC, DEC and NOP with the registers B and C in
any combination).
If you do not get caught in all these examples, then move on
to the generation of noise. If are you still did not
understand, I advise you to test these effects and their
poizmenyat parameters.
4.1.2. Noise
What is the fuss? This sequence of pulses of random
duration. Therefore, in order to create us need random data.
Where their get it? The only suitable source -
ROM, which contains the BASIC interpreter. ROM located at
address 0 to 16383 (# 3FFF). It is true that these values
will not completely random, or rather not random, but they
gave us.
Create noise in two different ways. They differ slightly in
sound. The first consists in the withdrawal of the port values
read from the ROM. The second - to use these values as
delay.
In the generation of noise in any of these methods do not
necessarily prohibit the interruption, as a crackling noise
heard will not.
When you use the first method of
each byte can retrieve data on eight passes cycle of
reproduction, but it is not beneficial to the software point of
view. Therefore, most of the effects of bytes
takes one value. For example:
1415.
10 LD HL, 0; HL = address of ROM
20 LD BC, 1000; BC = length
30 BEGIN PUSH BC; preservation BC
40 LD A, (HL); A = cell contents ROM
50 AND 240; reset bits curb
60 OUT (254), A; output to port A 254
70 LD B, 50; B = frequency
1980 LOOP DJNZ LOOP; delay
90 INC HL; HL = HL +1
100 POP BC; restore BC
110 DEC BC; BC = BC-1
120 LD A, B; BC =
130 OR C; 0?
140 JR NZ, BEGIN; cycle
150 RET; return to BASIC
2
An example of the second method:
1415.
10 LD HL, 0; HL = address of ROM
20 LD BC, 1000; BC = length
30 XOR A; A = border color (0)
40 BEGIN PUSH BC; preservation BC
50 XOR 16; inverting bits D4
60 OUT (254), A; output to port A 254
70 LD B, (HL); B = cell contents ROM
80 LOOP1 DJNZ LOOP1; delay
90 LD B, 40; B = frequency
100 LOOP2 DJNZ LOOP2; delay
110 INC HL; HL = HL +1
120 POP BC; restore BC
130 DEC BC; BC = BC-1
140 LD D, A; preservation A
150 LD A, B; BC =
160 OR C; 0?
170 LD A, D; A recovery
180 JR NZ, BEGIN; cycle
190 RET; return to BASIC
2 If these effects team replaced INC HL INC L, then they will
sound like to galloping. This is due to the fact
that the data are taken not from the entire set
of ROM, as part of its 256
bytes. And, when this part ends
reading continues from the beginning.
Try poizmenyat other options.
The next step - the noise with varying frequency. It will
look like this: 1415.
10 LD HL, 0; HL = address of ROM
20 LD B, 100; B = length of effect
30 LD C, 10; C = initial frequency
40 LOOP1 PUSH BC; preservation BC
50 LD B, 20; B = length
60 LOOP2 LD A, (HL); A = cell contents ROM
70 AND 240; reset bits curb
80 OUT (254), A; output to port A 254
1990 PUSH BC; preservation BC
100 LD B, C; B = C
110 LOOP3 DJNZ LOOP3; delay
120 INC HL; HL = HL +1
130 POP BC; restore BC
1415.140 DJNZ LOOP2; cycle
150 POP BC; restore BC
160 INC C; increase delay
170 DJNZ LOOP1; cycle
180 RET; return to BASIC
2
This effect can be changed beyond recognition: Change the
length, frequency, duration, pitch shift in the frequency,
direction, frequency offset (command INC C or DEC C), type of
noise (or command INC HL INC L).
Another version of Sound Effect:
1415.
10 LD HL, 0; HL = address of ROM
20 LD D, 100; D = delay 1
30 LD E, 10; E = Delay 2
40 LD C, 255; C = duration
50 XOR A; A = border color (0)
60 BEGIN XOR 16; inverting bits D4
70 OUT (254), A; output to port A 254
80 LD B, (HL); B = cell contents ROM
90 LOOP1 DJNZ LOOP1; delay 1
100 LD B, D; B = D
110 LOOP2 DJNZ LOOP2; Delay 2
120 XOR 16; inverting bits D4
130 OUT (254), A; output to port A 254
140 LD B, (HL); B = cell contents ROM
150 LOOP3 DJNZ LOOP3; delay 3
160 LD B, E; B = E
170 LOOP4 DJNZ LOOP4; delay 4
180 INC HL; HL = HL +1
190 INC D; increase in D
200 INC E; increase in E
210 DEC C; C = C-1
220 JR NZ, BEGIN; if C <> 0 then loop
230 RET; return to BASIC
2
On this example can be fun because
as long as over all the previous ones.
All the effects presented in this chapter can be regarded as
a blank. To get the final version, you
may have to work hard. As already
it was said, they all have a huge number of options. In
addition, you can combine multiple effects together, or cause
them to run in a loop, etc. All the basic principles of
combination effects are listed in chapter 2.1.
All effects were written so that you can
could change the maximum number of parameters. In cases of a
particular application they can be greatly simplified. Here's
an example combined and simplified the effect:
1415.
10 DI; ban interrupt
20 LD E, 100; E = cycle time
30 LD C, 0; C = color of the border
40 LD B, 4; B = number of cycles
50 LD L, 1; L = frequency offset
60 LD H, 30; H = initial frequency
70 LOOP1 LD D, E; D = E
80 LOOP2 LD A, C; A = C
90 XOR 16; inverting bits D4
100 OUT (254), A; output to port A 254
110 LD C, A; C = A
120 LD A, H; A = H
130 ADD A, L; add L to the A
140 LD H, A; H = A
150 LOOP3 DEC A; A = A-1
160 JR NZ, LOOP3; if A <> 0 then loop
170 DEC D; D = D-1
180 JR NZ, LOOP2; if D <> 0 then loop
190 LD A, L; A = L
200 NEG; the sign of the register A
210 LD L, A; L = A
220 DJNZ LOOP1; cycle
230 EI; permission to interrupt
240 RET; Returns
2
All of the above effects can
customize your own needs. For example,
change the color of the border or make it so
except that the signal dynamics when the SIM
tape recorder (for this team all XOR 16
must be replaced by XOR 24 and AND 240 AND
248).
4.1.3. Complexes effects
Usually in games (and in any other
programs) is not used one or two
sound effects, and much more. Therefore, the effects
conveniently grouped (Complexes) and call them on the
a subroutine, passing it as parameter number effect.
If the effects are varied and play various sub-programs, the
table of effects is best stored addresses these routines. In
this case, to reproduce the effects you can use this
subroutine: 1415.
10 ADD A, A; A = A * 2
20 LD E, A; DE
30 LD D, 0; = A
40 LD HL, TABLE; HL = address of table
50 ADD HL, DE; HL = HL + DE
60 LD E, (HL); DE =
70 INC HL; address
80 LD D, (HL); routines
90 EX DE, HL; exchange values HL and DE
100 JP (HL); subroutine call effect
110 TABLE DEFW ... , Address table
2
Before calling this subroutine in the register A has to
enter number effect. Do not forget to fill in the table
addresses effects. Naturally, the effects themselves must be
located at the address. No in no case should indicate the
number of effect greater than the number listed in the table
routines, otherwise the computer will freeze or "reset". Note
also that this subprogram can work a maximum of
127 effects.
If the effects are similar and reproduce the same routine,
then Table of effects parameters can be stored
This subroutine. Here's an example that uses this method:
1415.
10 LD E, A; A
20 ADD A, A; =
30 ADD A, E; A * 3
40 LD E, A; DE
50 LD D, 0; = A
60 LD HL, TABLE; HL = address of table
70 ADD HL, DE; HL = HL + DE
80 LD C, (HL); C = duration
90 INC HL; HL = HL +1
100 LD E, (HL); E = rate
110 INC HL; HL = HL +1
120 LD A, (HL); A = change in frequency
130 LD (CHNG), A; setting frequency
140 DI; ban interrupt
150 XOR A; A = color of the border (0)
160 BEGIN XOR 16; inverting bits D4
170 OUT (254), A; output to port A 254
180 LD B, E; B = E
190 PAUSE DJNZ PAUSE; delay
200 CHNG NOP; reserve for frequency
210 DEC C; C = C-1
220 JR NZ, BEGIN; if C <> 0 then loop
230 EI; permission to interrupt
240 RET; Returns
250 TABLE DEFB 0,0,28; table
260 DEFB 0,0,29;
270 DEFB 0,128,28; effects
280 DEFB 0,128,29;
2
Before calling this subroutine in the register A has to
enter number effect. In the above program has already created
four effects, but you can change them or increase their number.
When you call the effect, the number which is greater than the
number described routines can also happen that some awful.
In this example, the description of the effect given to
three bytes. The first byte - the duration of effect, the
second - the initial frequency, and the third - a way to change
the frequency. Third byte can be 0, 28 and 29. What does it
mean, respectively, maintaining, increasing and decreasing
frequency. Enter any other value in this byte is not worth it,
because it may cause to unpredictable consequences.
The above program is only
example. You can configure it to work with absolutely any
effect.
This routine can handle a maximum of 85 effects.
In both of the above routines effects numbering starts with
zero.