UNIT vocdecl; { see demo at end of document } INTERFACE function reset_dsp(base:word):boolean; procedure write_dac(level:byte); function read_dac:byte; function speaker_on:byte; function speaker_off:byte; procedure dma_pause; procedure dma_continue; procedure play_back(sound:pointer;size:word;frequency:word); procedure play_voc(filename:string;buf:pointer); function done_playing:boolean; function play_raw(filename:string;buf:pointer):word; IMPLEMENTATION uses crt; type iDsound=record dunno, rate, num_samples, dunno2:word; end; var dsp_reset:word; dsp_read_data:word; dsp_write_data:word; dsp_write_status:word; dsp_data_avail:word; since_midnight:longint absolute $40:$6C; playing_till:longint; function reset_dsp(base:word):boolean; begin base:=base*$10; dsp_reset:=base+$206; dsp_read_data:=base+$20a; dsp_write_data:=base+$20c; dsp_write_status:=base+$20c; dsp_data_avail:=base+$20e; port[dsp_reset]:=1; delay(10); port[dsp_reset]:=0; delay(10); reset_dsp:=(port[dsp_data_avail]and $80=$80)and(port[dsp_read_data]=$aa); end; procedure write_dsp(value:byte); begin while port[dsp_write_status] and $80<>0 do; port[dsp_write_data]:=value; end; function read_dsp:byte; begin while port[dsp_data_avail]and $80=0 do; read_dsp:=port[dsp_read_data]; end; procedure write_dac(level:byte); begin write_dsp($10); write_dsp(level); end; function read_dac:byte; begin write_dsp($20); read_dac:=read_dsp; end; function speaker_on:byte; begin write_dsp($d1); end; function speaker_off:byte; begin write_dsp($d3); end; procedure dma_continue; begin playing_till:=since_midnight+playing_till; write_dsp($d4); end; procedure dma_pause; begin playing_till:=playing_till-since_midnight; write_dsp($d0); end; procedure play_back(sound:pointer;size:word;frequency:word); var time_constant:word; page:word; offset:word; begin speaker_on; size:=size-1; { set up the dma chip } offset:=seg(sound^)shl 4+ofs(sound^); page:=(seg(sound^)+ofs(sound^)shr 4)shr 12; port[$0a]:=5; port[$0c]:=0; port[$0b]:=$49; port[$02]:=lo(offset); port[$02]:=hi(offset); port[$83]:=page; port[$03]:=lo(size); port[$03]:=hi(size); port[$0a]:=1; { set the playback frequency } time_constant:=256-1000000 div frequency; write_dsp($40); write_dsp(time_constant); { set the playback type (8-bit) } write_dsp($14); write_dsp(lo(size)); write_dsp(hi(size)); end; procedure play_voc(filename:string;buf:pointer); var f:file; s:word; freq:word; h:record signature:array[1..20]of char; data_start:word; version:integer; id:integer; end; d:record id:byte; len:array[1..3]of byte; sr:byte; pack:byte; end; begin {$i-} { if pos('.',filename)=0 then filename:=filename+'.voc';} assign(f,filename); reset(f,1); blockread(f,h,26); blockread(f,d,6); freq:=round(1000000/(256-d.sr)); s:=ord(d.len[3])+ord(d.len[2])*256+ord(d.len[1])*256*256; { writeln('-----------header----------'); writeln('signature: ', h.signature); writeln('data_start: ', h.data_start); writeln('version: ', hi(h.version), '.', lo(h.version)); writeln('id: ', h.id); writeln; writeln('------------data-----------'); writeln('id: ', d.id); writeln('len: ', s); writeln('sr: ', d.sr); writeln('freq: ', freq); writeln('pack: ', d.pack);} blockread(f,buf^,s); close(f); {$i-} if ioresult<>0 then begin writeln('Can''t find voc file "',filename,'".'); halt(1); end; playing_till:=since_midnight+round(s/freq*18.20648193); play_back(buf,s,freq); end; function done_playing:boolean; begin done_playing:=since_midnight>playing_till; end; function play_raw(filename:string;buf:pointer):word; var f:file; s:word; head:idSound; begin play_raw:=0; if pos('.',filename)=0 then filename:=filename+'.raw'; assign(f,filename); {$i-} reset(f,1); {$i+} if(ioresult<>0)then exit; blockread(f,head,sizeof(head)); if(maxavail