home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / microcrn / issue_36.arc / REAL36.FIG < prev    next >
Text File  |  1987-05-21  |  4KB  |  115 lines

  1.  
  2. program dacsound;
  3.  
  4. { Generates different tones through the DAC.
  5. These are sine waves, but you can generate different types of
  6. waves to see what they sound like. Turbo generates an array of
  7. points which are passed to an assembly language program for quick,
  8. consistent output.
  9.     Passing byte values to the assembly routine worked fine, but I
  10. had a lot of trouble passing anything else, so I declared "time"
  11. and "wve_adr" at absolute addresses so I could just pluck the
  12. values out directly with assembly language.  To determine where
  13. to put the absolute addresses, I looked at the Turbo compiler
  14. message which said "free."
  15.     Note the length of the tone is controlled by the "time" variable
  16. (which MUST be reloaded before each waveout call) AND the length
  17. of the wave itself, so wave2 with a time of 8 has twice the duration
  18. of wave1 with a time of 8.
  19.     Next time I'll be using a PC. }
  20.  
  21. const
  22.      A_CONTROL: byte = $22;     {PIO address for KAYPRO 84s }
  23.      A_DATA: byte = $20;        {See issue #34 }
  24.      MODE : byte = $0f;         {0000 1111  mode 0 = output}
  25.      INT : byte = $07;          {0000 0111 ints disabled}
  26.  
  27.      count1 : byte = 50;   { These are arbitrary; they don't  }
  28.      count2 : byte = 100;  { represent any particular tones.  }
  29.      count3 : byte = 200;  { (All those piano lessons wasted!)}
  30. type
  31.      wave = array[0..255] of byte;
  32. var
  33.      wave1,wave2,wave3 : wave;
  34.      time : byte absolute $D000;
  35.      wve_adr : integer absolute $D010;
  36.      count : byte;
  37.  
  38. procedure make_waves(var wavex : wave; count: byte);
  39. {fills the array wavex with a sine wave which is count
  40. bytes long}
  41. var
  42.    radians : real;
  43.    curve,i : integer;
  44. begin
  45. writeln('making waves ~~~~~~~~~~~');
  46. radians := 0;
  47. for i:= 0 to count do
  48.     begin
  49.          curve := 127 + round(127 * cos(radians));
  50.          { 0 volts at the 8-bit DAC occurs with a byte value
  51.          of 127, so the wave needs peak values of 127 with an
  52.          offset of 127. }
  53.          if curve > 255 then curve := 255;
  54.          if curve < 0 then curve := 0;
  55.          wavex[i] := byte(curve);
  56.          radians := radians + (2 * 3.14159)/count;
  57.     end;
  58. end; {make_waves}
  59.  
  60. procedure waveout(COUNT: byte; PRT: byte);
  61. {Outputs bytes starting from memory location WVE_ADR to
  62. WVE_ADR + COUNT to port PRT. Repeats process TIME cycles.
  63. The value in DE is the number of cycles for each count in
  64. TIME.  The OTIR instruction does the outputs. }
  65.  
  66. {$A+}
  67. begin
  68. inline(
  69. $3A/PRT/        {       LD    A,(PRT)       }
  70. $4F/            {       LD    C,A           }
  71. $DD/$21/$00/$D0/{       LD    IX,TIME       }
  72. $11/$FF/$00/    { LOOP1:LD    DE,00FFH      }
  73. $2A/$10/$D0/    { LOOP2:LD    HL,(WVE_ADR)  }
  74. $3A/COUNT/      {       LD    A,(COUNT)     }
  75. $47/            {       LD    B,A           }
  76. $ED/$B3/        {       OTIR                }
  77. $1B/            {       DEC    DE           }
  78. $7A/            {       LD    A,D           }
  79. $FE/$00/        {       CP    0             }
  80. $20/$F1/        {       JR    NZ,LOOP2      }
  81. $7B/            {       LD    A,E           }
  82. $FE/$00/        {       CP    0             }
  83. $20/$EC/        {       JR    NZ,LOOP2      }
  84. $DD/$35/$00/    {       DEC   (IX)          }
  85. $20/$E4         {       JR    NZ,LOOP1      }
  86. );
  87. end; {Waveout}
  88.  
  89. procedure tone(var wavex : wave; _time : byte; count: byte; pause: integer);
  90. begin
  91.      { set global variables }
  92.      wve_adr := addr(wavex[0]);
  93.      time := _time;
  94.  
  95.      waveout(count,A_DATA);
  96.      delay(pause);
  97. end; { tone }
  98.  
  99. begin
  100.      port[A_CONTROL]:= MODE;   {initialize the pio}
  101.      port[A_CONTROL]:= INT;
  102.  
  103.      make_waves(wave1,count1);
  104.      make_waves(wave2,count2);
  105.      make_waves(wave3,count3);
  106.  
  107. while not keypressed do
  108.      begin
  109.          tone(wave1,8,count1,1000);
  110.          tone(wave2,4,count2,1000);
  111.          tone(wave3,2,count3,1000);
  112.      end;
  113. end. { "The Star-Spangled Banner" is left as an excercise. }
  114.  
  115.