home *** CD-ROM | disk | FTP | other *** search
-
- program dacsound;
-
- { Generates different tones through the DAC.
- These are sine waves, but you can generate different types of
- waves to see what they sound like. Turbo generates an array of
- points which are passed to an assembly language program for quick,
- consistent output.
- Passing byte values to the assembly routine worked fine, but I
- had a lot of trouble passing anything else, so I declared "time"
- and "wve_adr" at absolute addresses so I could just pluck the
- values out directly with assembly language. To determine where
- to put the absolute addresses, I looked at the Turbo compiler
- message which said "free."
- Note the length of the tone is controlled by the "time" variable
- (which MUST be reloaded before each waveout call) AND the length
- of the wave itself, so wave2 with a time of 8 has twice the duration
- of wave1 with a time of 8.
- Next time I'll be using a PC. }
-
- const
- A_CONTROL: byte = $22; {PIO address for KAYPRO 84s }
- A_DATA: byte = $20; {See issue #34 }
- MODE : byte = $0f; {0000 1111 mode 0 = output}
- INT : byte = $07; {0000 0111 ints disabled}
-
- count1 : byte = 50; { These are arbitrary; they don't }
- count2 : byte = 100; { represent any particular tones. }
- count3 : byte = 200; { (All those piano lessons wasted!)}
- type
- wave = array[0..255] of byte;
- var
- wave1,wave2,wave3 : wave;
- time : byte absolute $D000;
- wve_adr : integer absolute $D010;
- count : byte;
-
- procedure make_waves(var wavex : wave; count: byte);
- {fills the array wavex with a sine wave which is count
- bytes long}
- var
- radians : real;
- curve,i : integer;
- begin
- writeln('making waves ~~~~~~~~~~~');
- radians := 0;
- for i:= 0 to count do
- begin
- curve := 127 + round(127 * cos(radians));
- { 0 volts at the 8-bit DAC occurs with a byte value
- of 127, so the wave needs peak values of 127 with an
- offset of 127. }
- if curve > 255 then curve := 255;
- if curve < 0 then curve := 0;
- wavex[i] := byte(curve);
- radians := radians + (2 * 3.14159)/count;
- end;
- end; {make_waves}
-
- procedure waveout(COUNT: byte; PRT: byte);
- {Outputs bytes starting from memory location WVE_ADR to
- WVE_ADR + COUNT to port PRT. Repeats process TIME cycles.
- The value in DE is the number of cycles for each count in
- TIME. The OTIR instruction does the outputs. }
-
- {$A+}
- begin
- inline(
- $3A/PRT/ { LD A,(PRT) }
- $4F/ { LD C,A }
- $DD/$21/$00/$D0/{ LD IX,TIME }
- $11/$FF/$00/ { LOOP1:LD DE,00FFH }
- $2A/$10/$D0/ { LOOP2:LD HL,(WVE_ADR) }
- $3A/COUNT/ { LD A,(COUNT) }
- $47/ { LD B,A }
- $ED/$B3/ { OTIR }
- $1B/ { DEC DE }
- $7A/ { LD A,D }
- $FE/$00/ { CP 0 }
- $20/$F1/ { JR NZ,LOOP2 }
- $7B/ { LD A,E }
- $FE/$00/ { CP 0 }
- $20/$EC/ { JR NZ,LOOP2 }
- $DD/$35/$00/ { DEC (IX) }
- $20/$E4 { JR NZ,LOOP1 }
- );
- end; {Waveout}
-
- procedure tone(var wavex : wave; _time : byte; count: byte; pause: integer);
- begin
- { set global variables }
- wve_adr := addr(wavex[0]);
- time := _time;
-
- waveout(count,A_DATA);
- delay(pause);
- end; { tone }
-
- begin
- port[A_CONTROL]:= MODE; {initialize the pio}
- port[A_CONTROL]:= INT;
-
- make_waves(wave1,count1);
- make_waves(wave2,count2);
- make_waves(wave3,count3);
-
- while not keypressed do
- begin
- tone(wave1,8,count1,1000);
- tone(wave2,4,count2,1000);
- tone(wave3,2,count3,1000);
- end;
- end. { "The Star-Spangled Banner" is left as an excercise. }
-