{___________________________________________________________________________ ISPEC.ASM This routine takes joystick input through the ADCs to create a fourier spectra (real and imaginary), does an inverse FFT on it, and puts out the results on the left and right audio channels. ____________________________________________________________________________} #include "demo.h" .EXTERN irfft2; .EXTERN exponential; .SEGMENT/DM dm_sram; .VAR fullbuf; .EXTERN real; .EXTERN odreal; .EXTERN refft; {this better be on a boundry!} .EXTERN imfft; .EXTERN adacbuf; .EXTERN bdacbuf; .EXTERN aadc_dat; .EXTERN badc_dat; .EXTERN curbuffer; .EXTERN nextbuffer; .EXTERN curbin; .EXTERN orgvalue; .ENDSEG; .GLOBAL fullbuf; .GLOBAL ispec; .SEGMENT/PM pm_sram; ispec: do (pc,3) until not flag0_in; {wait for flag0 depressed} nop; nop; nop; ustat1=CNFG_ISPEC; {setup ustat1 for this routine} r0=0xe0; {initialization for cursor routine} i0=adacbuf; l0=0; i1=bdacbuf; l1=0; i7=adacbuf+8; dm(curbuffer)=i0; dm(nextbuffer)=i1; dm(curbin)=i7; dm(orgvalue)=r0; lcntr=PNTS/2+1, do (pc,2) until lce; {clear the buffers} dm(i0,1)=r0; dm(i1,1)=r0; again: r0=1; do waitloop until forever; {wait for output buffer to be outputed} bit tst ustat1 OUTBH; if tf jump (pc,3) (la), r0=r0-1; bit tst ustat1 OUTBF; waitloop: if tf jump (pc,1) (la), r0=pass r0; cont: dm(fullbuf)=r0; {save whether its a half or full buffer pass} bit tst ustat1 FLIRQ; {exit routine if flag0 and IRQ at same time} if tf rts; bit set astat FLG1; {turn-on analog load meter} {prepare fft data being displayed for an inverse fft} call unlog_ft; {do the inverse fft} call irfft2; {move data to audio output buffers} r0=dm(fullbuf); {signal which half of buffer to put data in} call audio_out; bit clr astat FLG1; {turn-off analog load meter} jump again; nop; nop; {___________________________________________________________________________ unlog_ft: This routine takes the fft data in *adacbuf* and *bdacbuf*, floats it, unlogs it, unscales it and puts in into *refft* and *imfft*. ____________________________________________________________________________} unlog_ft: {unlog and scale data in *adacbuf* and place it in *refft*} b0=adacbuf; l0=0; b1=refft; l1=0; m1=1; l3=0; {This is for the exponential routine} f5=LGOFF*0.69314718056; {ln(2) = 0.69314718056} f6=(DRNG/(256.0*6.0))*0.69314718056; {ln(2) = 0.69314718056} {coeff to convert from db to a loge} r9=dm(i0,m1); lcntr=PNTS/2+1, do unlog_re until lce; r4=lshift r9 by -24; {shift data down for calcs} f1=float r4; {convert to float} call exponential (db); {calc exp(f1) } f1=f1*f6; {translate to from db to loge} f0=f1-f5, r9=dm(i0,m1); {nullify log offset, fetch next data} unlog_re: dm(i1,m1)=f0; {store it} {unlog and scale data in *bdacbuf* and place it in *imfft*} b0=bdacbuf; b8=imfft; l8=0; m8=1; f0=0.0; {first imaginary sample is always zero} r4=dm(i0,m1), pm(i8,m8)=f0; {store it, do dummy read} r9=dm(i0,m1); lcntr=PNTS/2-1, do unlog_im until lce; r4=lshift r9 by -24; {shift data down for calcs} f1=float r4; {convert to float} call exponential (db); {calc exp(f1) } f1=f1*f6; {translate to from db to loge} f0=f1-f5, r9=dm(i0,m1); {nullify log offset, fetch next data} unlog_im: pm(i8,m8)=f0; {store it} f0=0.0; {last imaginary sample is always zero} pm(i8,m8)=f0; {store it} rts; nop; nop; {___________________________________________________________________________ audio_out: This routine takes the data in *real* and *odreal*, converts it to scaled fix point and writes it to the buffers *outleft* and *outright*. Calling info: r0 = 0 write to first half of buffer r0 <> 0 write to second half of buffer ____________________________________________________________________________} audio_out: {move the real data into output buffers} b0=outleft; l0=2*PNTS; b1=outright; l1=2*PNTS; b4=real; l4=0; b8=odreal; l8=0; m0=1; m1=PNTS; m8=1; r0=pass r0; if ne modify(i0,m1); {if fullbuffer, start inputing data mid-buffer} if ne modify(i1,m1); r15=AOSCL; {Float to fix scaling factor} lcntr=PNTS/2, do put_data until lce; f0=dm(i4,m0), f8=pm(i8,m8); r1=fix f0 by r15; r9=fix f8 by r15, dm(i0,m0)=r1; dm(i0,m0)=r9; dm(i1,m0)=r1; put_data: dm(i1,m0)=r9; rts; nop; nop; .ENDSEG;