ZX Forum #04
19 ноября 1997 |
|
world of sound Spectrum - Chapter 4: Programming sound in assembler.
4. Programming audio codes The simplest example of the sound signal in the codes was given in the previous chapter. In principle, this is the only spsob get sound, but to design it There are many ways. For example, as a universal routine: 1415. 10 DI; ban interrupt 20 BEEP LD A, B; A = Border color 1930 SET 4, A; bit D4 = 1 40 OUT (254), A; output to port A 254 1950 PUSH HL; conservation HL 60 LOOP1 DEC HL; HL = HL-1 70 LD A, H; HL = 80 OR L; 0? 90 JR NZ, LOOP1; if not, then the cycle 100 POP HL; recovery HL 110 LD A, C; A = color effect 120 OUT (254), A; output to port A 254 130 PUSH HL; conservation HL 140 LOOP2 DEC HL; HL = HL-1 150 LD A, H; HL = 160 OR L; 0? 170 JR NZ, LOOP2; if not, then the cycle 180 POP HL; recovery HL 190 DEC DE; DE = DE-1 200 LD A, D; DE = 210 OR E; 0? 220 JR NZ, BEEP; if not, then the cycle 230 EI; permission to interrupt 240 RET; return to BASIC 2 Before calling this subroutine must be recorded in the register-pair frequency of HL in DE - duration, in B - Border color, and C - the color of the effect (if you want see curb uniform, then the value of C must be equal to B). In addition, if the Register to add B 8 (set bit D3), then together with the speaker signal is fed into a tape recorder. You can make the program more universal in another sense: 1415. 10 DI; ban interrupt 20 LD A, (23624); A = 1930 SRL A; color 1940 SRL A; Bor 1950 SRL A; Duras 60 BEEP XOR 16; inverting bits D4 70 OUT (254), A; output to port A 254 80 LD C, A; preservation A 1990 PUSH HL; conservation HL 100 PAUSE DEC HL; HL = HL-1 110 LD A, H; HL = 120 OR L; 0? 130 JR NZ, PAUSE; if not, then the cycle 140 POP HL; recovery HL 150 DEC DE; DE = DE-1 160 LD A, D; DE = 170 OR E; 0? 180 LD A, C; A recovery 190 JR NZ, BEEP; if DE <> 0 then loop 200 EI; permission to interrupt 210 RET; return to BASIC 2 This routine should be transferred only frequency in the HL register and the length of DE, and the color of border remains one that was when you call it (unless it was set by the operator OUT). Approximately the same routine is in ROM ZX-Spectrum. It is located at address 949 (# 03B5). Parameters as before, passed in registers HL and DE. Their values can be calculated as follows: HL = INT (437500/f-30.125 + .5) DE = INT (f * t + .5) where f - frequency in Hz and t - time in seconds. Frequency of the music for the fifth octave can be taken from Table 2. To raise a note or lower octave, its frequency should be respectively, multiplied or divided by 2. Moreover, by dividing the value obtained slightly more precise than multiplication. In the generation of sound in all ways the above, it is necessary to take into account that the higher the tone, the shorter the duration. If you want the programming sound code to use the usual parameters of the operator BEEP, then you can use subroutine ROM, located at 1016 (# 03F8). However, with it is associated with some difficulties. The fact that the parameters passed to it through the stack of the calculator and put in the fractional or negative number is not so simple. To circumvent this inconvenience, there is three main ways. The first - to keep the required values in the standard pyatibaytovoy form and place them in a stack using special routines ROM. Second - store these values in symbolic form and place them in a stack with other special routines ROM. And the third - a little to change the system settings and do calculations. The first method is not suitable because it is too large amount of memory consumed. Second - for the same reason, plus his work is too slow. That leaves the third way. It is quite suitable and can be easily accomplished. Let the duration specified in hundredths of seconds, and the Pitch, as before, in semitones above or below before the first octave. Such a system allows the parameters to get the notes for up to 2.55 seconds frequencies in the range from -60 to 69 (as in BASIC). The duration of the notes will be set in register C, and height - in the case B. That routine, carrying out all described above: 1412. 1910 PUSH BC; preservation BC 20 LD A, C; A = C (duration) 30 CALL 11560; A place in the stack calculator 40 LD A, 100; A = 100 50 CALL 11560; A place in the stack calculator 60 RST 40; call calculator 70 DEFB 5,56; division duration at 100 1980 POP BC; restore BC 90 LD A, B; A = B (frequency) 100 BIT 7, A; A - negative? 110 JR NZ, MINUS; if yes, go to MINUS 120 CALL 11560; otherwise put A in the stack calcium kulyatora 130 JP 1016; subroutine call playback Denia 140 MINUS NEG; in A - absolute value 150 CALL 11560; A place in the stack calculator 160 RST 40; call calculator 170 DEFB 27,56; change of sign 180 JP 1016; subroutine call playback Denia If your assembler does not "digest" negative numbers (there are such "things"), these values can be calculated using the following formula: n = 256-x, where x - absolute values and n - result.
Other articles:
Similar articles:
В этот день... 21 November