_A WAVELET ANALYZER_ by Mac A. Cody [LISTING ONE] #include "dsp_type.h" #if DSP32 #include "dspregs.h" #endif .global DECOMP /* DECOMP perform recursive decomposition on non-terminating data sequence registers used: r1 r2 r3 r4 r5 r6 r11 r12 r13 r14 r15 r16 accumulators used: a0 a1 input: r1 - pointer to wavelet high-pass filter coefficients r2 - pointer to wavelet low-pass filter coefficients r6 - pointer to wavelet output data list r11 - jump address for proper filter length r12 - pointer to data pointer array r13 - pointer to stack r14 - return stack register, i.e. "TOP OF STACK" r15 - recursion counter r16 - filter coefficient pointer wrap back index */ DECOMP: r3e = *r12++; /* load pointer to approx. input array source */ r5e = *r12; /* load pointer to approx. output array destination */ goto r11; /* jump to appropriate filter processing for length */ r4e = r3 + 8; /* set pointer to approx. input array destination */ DT6: a0 = a0 + *r3++ * *r1++; /* pass data through high-pass wavelet */ a0 = a0 + *r3++ * *r1++; /* filter (a0 = 0.0 initially) */ DT4: a0 = a0 + *r3++ * *r1++; /* the destination of the jump depends */ a0 = a0 + *r3++ * *r1++; /* upon the length of the wavelet */ DT2: a0 = a0 + *r3++ * *r1++; /* filter */ goto r11 + 28; /* jump to appropriate filter processing for length */ *r6++ = a0 = a0 + *r3++r16 * *r1++r16; /* output is detail point */ AT6: a1 = a1 + (*r4++ = *r3++) * *r2++; /* pass data through low-pass */ a1 = a1 + (*r4++ = *r3++) * *r2++; /* filter (a1 = 0.0 initially) */ AT4: a1 = a1 + (*r4++ = *r3++) * *r2++; a1 = a1 + (*r4++ = *r3++) * *r2++; AT2: a1 = a1 + *r3++ * *r2++; a1 = a1 + *r3++ * *r2++r16; r15 = r15 - 1; /* check the recursion count */ if (eq) goto NO_RECUR; /* if true, recursion at bottom of tree */ r5e & 0x0004; /* check for even/odd status */ *r5-- = a1 = a1; /* save approx. data for next level */ if (ne) goto CLEAN_UP; /* if true, await another data point */ r4e = r5 + 8; /* wrap output pointer back */ *r12++ = r4e; /* save wrapped pointer to approx. O/P */ *r13-- = r14e; /* save return address to stack */ a0 = a0 - a0; /* clear the accumulators */ call DECOMP (r14); /* recurse down the tree */ a1 = a0; #if DSP32C r13e = r13 + 4; /* align stack pointer to return address */ #else r13 = r13 + 2; /* align stack pointer to return address */ #endif r14e = *r13; /* pop the return address */ nop; return (r14); nop; NO_RECUR: *r6 = a1 = a1; /* save approx. coeff. as next value */ CLEAN_UP: return (r14); *r12++ = r5e; /* save unwrapped pointer to approx. output */ /* END OF DECOMP */ [LISTING TWO] #include "dsp_type.h" #if DSP32 #include "dspregs.h" #endif .global DRAWIMAG /* DRAWIMAG -- draw image of supplied point and connect to previous point registers used: r1 r2 r3 r4 r5 r6 r7 r12 r13 r14 accumulators used: a0 a1 input: r12 - pointer to data pointer array r13 - pointer to stack r14 - return stack register, i.e. "TOP OF STACK" a0 - data point to draw */ DRAWIMAG: a0 = *r12++ - a0 * *r12++; /* multiply by scalling coefficient */ a1 = -a0 + *r12; /* determine if value above upper threshold */ a0 = ifalt(*r12++); /* if true, limit data to threshold */ a1 = a0 - *r12; /* determine if value below lower threshold */ a0 = ifalt(*r12++); /* if true, limit data to threshold */ *r12++ = a0 = int(a0); /* convert data to integer format */ nop; r6e = r12 - 2; /* point to temporary storage */ r1 = *r12++; /* load the row increment value */ r4 = *r12++; /* load the row baseline offset value */ r2 = *r12++; /* load the bit pointer */ r3e = *r12; /* load the byte column pointer */ r6 = *r6; /* read the new byte column pointer offset */ r2 - 0x80; /* check if first bit of new byte column */ if (ne) goto ADD_BAR; /* if true, add new bar to byte column */ nop; #if DSP32C r6 - 23; /* check if datum point is above baseline */ if (le) goto ABOVE_BL; /* if true, it is above the baseline */ nop; r4 = 25; /* top counter for clearing of pixel over bar */ r5 = r6 - 24; /* middle counter for draw of bar pixels */ goto DRAW_COL; /* go draw the column of pixels */ r6 = 48 - r6; /* bottom counter for clearing of pixel under bar */ ABOVE_BL: r4 = r6; /* top counter for clearing of pixel over bar */ r5 = r6; r5 = 24 - r5; /* middle counter for draw of bar pixels */ r6 = 25; /* bottom counter for clearing of pixel under bar */ DRAW_COL: r4 = r4 - 1; /* check if no top pixels are to be cleared */ if (lt) goto NO_TOP; /* if true, skip clearing bytes above bar */ r7 = r7 - r7; /* force the register to zero */ do 0, r4; /* repeat next instruntion r4+1 times */ *r3++r1 = r7l; /* zero the bytes above the bar */ NO_TOP: r5 = r5 - 1; /* check if no bar pixels are to be set */ if (lt) goto NO_MID; /* if true, skip setting bytes of bar */ nop; do 0, r5; /* repeat next instruntion r5+1 times */ *r3++r1 = r2l; /* MSB of byte is bar, others cleared */ NO_MID: r6 = r6 - 1; /* check if no bottom pixels are to be cleared */ if (lt) goto NO_BOT; /* if true, skip clearing bytes below bar */ nop; do 0, r6; /* repeat next instruntion r6+1 times */ *r3++r1 = r7l; /* zero the bytes below the bar */ NO_BOT: goto SHIFTBIT; /* go shift the bit pointer and clear up */ r3e = *r12; /* reload the byte pointer */ ADD_BAR: r6 - 24; /* check if datum below baseline */ if (gt) goto BELOW_BL; /* if true, datum is below baseline */ r6 = r6 - 24; /* calculate length of bar */ r6 = -r6; /* datum above baseline length was negative */ r1e = -r1; /* datum above baseline, increment is decrement */ BELOW_BL: r4e = r4 + r3; /* add baseline offset to byte column pointer */ r5e = r4 + r1; /* move pointer away from the baseline */ r7 = 0; /* zero initial storage value */ do 2, r6; /* repeat the next 3 instructions r6+1 times */ r6l = *r5++r1; /* load the byte */ *r4++r1 = r7l; /* store the byte and move the pointer */ r7 = r6 | r2; /* OR byte with bit pointer to set the bit */ #else r6 = r6 * 2; /* multiply offset by four to account for ... */ r6 = r6 * 2; /* four bytes per instruction in MEMSET */ r6 - 92; /* check if datum point is above baseline */ if (le) goto ABOVE_BL; /* if true, it is above the baseline */ r5 = -r6; /* middle counter for draw of bar pixels */ r4 = 0; /* top counter for clearing of pixel over bar */ r5 = r5 + 196; /* middle counter for draw of bar pixels */ goto DRAW_COL; /* go draw the column of pixels */ r6 = r6 - 92; /* bottom counter for clearing of pixel under bar */ ABOVE_BL: r4 = -r6; /* top counter for clearing of pixel over bar */ r4 = r4 + 100; /* top counter for clearing of pixel over bar */ r5 = r6 + 4; /* middle counter for draw of bar pixels */ r6 = 0; /* bottom counter for clearing of pixel under bar */ DRAW_COL: *r13-- = r14; /* save return address to the stack */ call r4+MEMSET (r14); /* zero the bytes above the bar */ r7 = r7 - r7; /* force the register to zero */ call r5+MEMSET (r14); /* set the bytes of the bar */ r7 = r2; /* MSB of byte is bar, others cleared */ call r6+MEMSET (r14); /* zero the bytes below the bar */ r7 = r7 - r7; /* force the register to zero */ r13 = r13 + 2; /* point to return address on the stack */ r14 = *r13; /* load the return address from the stack */ NO_BOT: goto SHIFTBIT; /* go shift the bit pointer and clear up */ r3 = *r12; /* reload the byte pointer */ ADD_BAR: r6 = r6 * 2; /* multiply offset by twelve to account for ... */ r6 = r6 * 2; /* four bytes per instruction and ... */ r7 = r6 * 2; /* three instructions per byte in MEM_OR */ r6 = r6 + r7; r6 - 288; /* check if datum below baseline */ if (gt) goto BELOW_BL; /* if true, datum is below baseline */ r6 = r6 - 288; /* calculate length of bar */ r6 = -r6; /* datum above baseline length was negative */ r1 = -r1; /* datum above baseline, increment is decrement */ BELOW_BL: r6 = 288 - r6 /* align the counter for proper call */ r4 = r4 + r3; /* add baseline offset to byte column pointer */ r5 = r4; r5 = r5 + r1; /* move pointer away from the baseline */ *r13-- = r14; /* save return address to the stack */ r7 = 0; /* zero initial storage value */ call r6+MEM_OR (r14); r6 = r7; r13 = r13 + 2; /* point to return address on the stack */ r14 = *r13; /* load the return address from the stack */ #endif SHIFTBIT: r2 = r2 >> 1; /* shift the pixel pointed to right */ if (ne) goto NO_WRAP; /* if true, don't wrap the pixel pointer */ r12e = r12 - 2; /* point to bit pointer storage */ r2 = 0x0080; /* new bit mask if pixel wraps */ r3e = r3 + 1; /* increment base to next byte upon wrap */ NO_WRAP: *r12++ = r2; /* save the next bit pointer */ return (r14); *r12++ = r3e; /* save the next byte pointer start value */ /* END OF DRAWIMAG */ #if DSP32 /* MEMSET -- set column of image bytes to a given value registers used: r1 r3 r7 r14 input: r1 - postincrement value r3 - byte column pointer r7 - storage value r14 - return stack register, i.e. "TOP OF STACK" */ MEMSET: *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; *r3++r1 = r7l; return (r14); nop; /* END OF MEMSET */ /* MEM_OR -- logical OR column of image bytes with a given value registers used: r1 r4 r5 r6 r7 r14 input: r1 - postincrement value r2 - 'OR' value r4 - lagging byte column pointer r5 - leading byte column pointer r14 - return stack register, i.e. "TOP OF STACK" */ MEM_OR: r6l = *r5++r1; /* load column byte */ *r4++r1 = r7l; /* save initial 'dummy' value */ r6 = r6 | r2; /* 'OR' column byte with byte value */ r7l = *r5++r1; /* load the next column byte */ *r4++r1 = r6l; /* save the new column byte value */ r7 = r7 | r2; /* 'OR' the next column byte with the byte value */ r6l = *r5++r1; *r4++r1 = r7l; r6 = r6 | r2; r7l = *r5++r1; *r4++r1 = r6l; r7 = r7 | r2; r6l = *r5++r1; *r4++r1 = r7l; r6 = r6 | r2; r7l = *r5++r1; *r4++r1 = r6l; r7 = r7 | r2; r6l = *r5++r1; *r4++r1 = r7l; r6 = r6 | r2; r7l = *r5++r1; *r4++r1 = r6l; r7 = r7 | r2; r6l = *r5++r1; *r4++r1 = r7l; r6 = r6 | r2; r7l = *r5++r1; *r4++r1 = r6l; r7 = r7 | r2; r6l = *r5++r1; *r4++r1 = r7l; r6 = r6 | r2; r7l = *r5++r1; *r4++r1 = r6l; r7 = r7 | r2; r6l = *r5++r1; *r4++r1 = r7l; r6 = r6 | r2; r7l = *r5++r1; *r4++r1 = r6l; r7 = r7 | r2; r6l = *r5++r1; *r4++r1 = r7l; r6 = r6 | r2; r7l = *r5++r1; *r4++r1 = r6l; r7 = r7 | r2; r6l = *r5++r1; *r4++r1 = r7l; r6 = r6 | r2; r7l = *r5++r1; *r4++r1 = r6l; r7 = r7 | r2; r6l = *r5++r1; *r4++r1 = r7l; r6 = r6 | r2; r7l = *r5++r1; *r4++r1 = r6l; r7 = r7 | r2; r6l = *r5++r1; *r4++r1 = r7l; r6 = r6 | r2; r7l = *r5++r1; *r4++r1 = r6l; r7 = r7 | r2; r6l = *r5++r1; *r4++r1 = r7l; r6 = r6 | r2; r7l = *r5++r1; *r4++r1 = r6l; r7 = r7 | r2; r6l = *r5++r1; *r4++r1 = r7l; return (r14); nop; /* END OF MEMSET */ #endif [LISTING THREE] #include "dsp_type.h" #if DSP32 #include "dspregs.h" #endif .extern DECOMP, DRAWIMAG .extern WAVEADRS, WAVELVLS, IMAGSHOW, LVLADDRS .extern SIG_DRAW, DRAW_CNT, H_FILTER, L_FILTER .extern RST_DATA, IM0_PTRS, IM1_PTRS, IMAGE_0 .extern STACKEND, SIGNALIN, DATA_OUT /* ANALYZER main control program for the wavelet analyzer registers used: r1 r2 r3 r4 r5 r6 r8 r9 r11 r12 r13 r14 r15 r16 r17 accumulators used: a0 a1 a2 a3 */ .rsect ".bank0" dauc = 0x0000; /* initialize DAU formats */ r1e = WAVELVLS; /* point to jump address for wavelet filter size */ r2e = SIGNALIN; /* point to approximation data storage */ r3 = *r1++; /* load number of levels in wavelet transform */ r4 = 8; /* load number of unit intervals per image */ r1e = r1 + 2; /* point to the unit interval count storage */ *r1++ = r4; /* store the unit interval count value */ r4 = r4 - r4; /* zero the register */ *r1++ = r4; /* set active image flag storage to 0 (IMAGE 0) */ a3 = a3 - a3; /* intial data value is zero */ #if DSP32C r3 = r3 - 1; /* number of levels in wavelet transform - 1 */ do 8, r3; /* repeat next nine instructions r5+1 times */ #else r3 = r3 - 2; /* number of levels in wavelet transform - 2 */ #endif INITAPPX: *r1++ = r2e; /* store base address of each approximation level */ *r2++ = a3 = a3; /* zero storage for approximation level */ *r2++ = a3 = a3; /* r2 ends up pointing to first location .... */ *r2++ = a3 = a3; /* in the next approximation level */ *r2++ = a3 = a3; *r2++ = a3 = a3; *r2++ = a3 = a3; #if DSP32C nop; *r1++ = r2e; /* store the next location */ ioc = 0x40987; /* initialize the serial I/O to the codec */ r1e = RST_DATA; /* point to reset pointer initialization storage */ r2e = SIG_DRAW; /* point to signal drawing data sets */ r3 = 26; /* integer pointer index, 4 bytes per pointer */ r2e = r2 + 22; /* point to bit pointer storage */ do 3, 7; /* perform next 4 instructions eight times */ r4e = *r1++; /* load initial bit pointer */ r5e = *r1++; /* load initial byte column pointer */ *r2++ = r4; /* store initial bit pointer */ *r2++r3 = r5e; /* store initial byte column pointer */ #else if (r3-- >=0) goto INITAPPX; /* repeat for all arrays */ *r1++ = r2e; /* store the next location */ ioc = 0x0987; /* initialize the serial I/O to the codec */ r1 = RST_DATA; /* point to reset pointer initialization storage */ r2 = SIG_DRAW; /* point to signal drawing data storage */ r3 = 26; /* integer pointer index, 2 bytes per pointer */ r2 = r2 + 22; /* point to bit pointer storage */ r4 = 6; /* initialize loop counter for eight loops */ INIT_PTR: r5 = *r1++; /* load initial bit pointer */ r6 = *r1++; /* load initial byte column pointer */ *r2++ = r5; /* store initial bit pointer */ if (r4-- >=0) goto INIT_PTR; /* repeat for all pointers */ *r2++r3 = r6; /* store initial byte column pointer */ #endif r12e = WAVEADRS; /* load pointer to filter jump address */ r13e = STACKEND; /* load pointer to top of stack memory */ r11e = *r12++; /* load jump address for filter size */ r16e = *r12++; /* load coefficient pointer wrap back index */ r17 = *r12++; /* load number of levels */ r15 = *r12; /* load image data space size / 4 */ r3e = IMAGE_0; /* point to the detail level float output */ #if DSP32C r15 = r15 - 1; /* number of data points minus one */ do 0, r15; /* repeat next instruction r15+1 times */ *r3++ = a3 = a3; /* clear four bytes in IMAGE_0 array */ #else r15 = r15 - 2; /* number of data points minus two */ CLR_IMAG: if (r15-- >=0) goto CLR_IMAG; /* repeat until all image cleared */ *r3++ = a3 = a3; /* clear four bytes in IMAGE_0 array */ #endif goto ENTRY_PT; /* jump to the entry point */ nop; MAINLOOP: r8 = DATA_OUT; /* point to output data array */ r12e = SIG_DRAW; /* point to signal drawing data sets */ r9e = DRAW_CNT; /* point to draw count array */ a0 = *r8++; /* load first signal data point */ r9e = r9 + r15; /* index into draw count array */ call DRAWIMAG (r14); /* draw the first input sample point */ r9l = *r9; /* load the draw loop counter */ r12e = SIG_DRAW; /* point to signal drawing data sets */ DRWLOOP1: if (ibf) goto SAMPL_IN; /* if true, next sample available */ nop; a0 = *r8++; /* load data point */ call DRAWIMAG (r14); /* draw data point */ nop; if (r9-- >= 0) goto DRWLOOP1; /* repeat for all levels of xfrm */ #if DSP32C nop; #else r12 = r12 + 2; /* point to data set for next level */ #endif WAITIBF1: if (ibe) goto WAITIBF1; /* wait until next data sample arrives */ nop; goto TEST_LVL; SAMPL_IN: a3 = float(ibuf); /* load the new signal sample */ DRWLOOP2: a0 = *r8++; /* load data point */ call DRAWIMAG (r14); /* draw data point */ nop; if (r9-- >= 0) goto DRWLOOP2; #if DSP32C nop; #else r12 = r12 + 2; /* point to data set for next level */ #endif TEST_LVL: r15 - 0; /* test for process of all levels */ if (ne) goto ENTRY_PT; /* if true, all levels have not been done */ r12e = IMAGSHOW; /* point to the unit interval count down */ nop; r3 = *r12++; /* load the unit interval count down */ r4 = *r12--; /* load the image draw flag */ r3 = r3 - 1; /* decrement the unit interval count */ if (ne) goto ENTRY_PT; /* if true, not done with new data set */ *r12++ = r3; /* save the new count */ r3 = 8; /* reset count to eight unit intervals */ r12 = r12 - 2; /* point to unit interval count storage */ *r12++ = r3; /* save the reset count */ pir = r4; /* interrupt host processor for new image */ r4 = r4; /* tickle CAU flags for image set */ if (ne) goto IM0_NEXT; /* if true, set up for drawing on IMAGE 0 */ nop; r4 = 1; /* next image displayed is IMAGE 1 */ goto PNTRINIT; /* go to image pointer initialization */ r2e = IM1_PTRS; /* set up for drawing on IMAGE 1 */ IM0_NEXT: r4 = 0; /* next image displayed is IMAGE 0 */ r2e = IM0_PTRS; /* set up for drawing on IMAGE 0 */ PNTRINIT: r1 = SIG_DRAW; /* point to signal drawing data sets */ *r12++ = r4; /* save the image draw flag */ r1e = r1 + 24; /* point to byte column pointer storage */ #if DSP32C r15e = 28; /* set up post increment value */ do 0, 7; /* perform next instruction eight times */ a0 = (*r1++r15 = *r2++) + a0; /* moves four bytes at once! */ #else r3 = 28; /* set up post increment value */ r4 = 6; /* set up loop counter for eight iterations */ REINIPTR: r5 = *r2++; /* load image array pointer */ if (r4-- >= 0) goto REINIPTR; /* repeat for all pointers */ *r1++r3 = r5; /* store image array pointer */ #endif WAIT_PIE: if (pif) goto WAIT_PIE; /* wait for pif flag to be cleared */ nop; ENTRY_PT: r3e = SIGNALIN; /* point to input signal storage array */ WAITIBF2: if (ibe) goto WAITIBF2; /* wait until next data sample arrives */ r15 = r17; /* inititialize the recursion counter */ *r3++ = a2 = float(ibuf); /* output second data sample first */ r6e = DATA_OUT; /* point to output data array */ *r3 = a3 = a3; /* output first data sample last */ *r6++ = a3 = a3; /* place first sample in data output array */ *r6++ = a2 = a2; /* place second sample in data output array */ r1e = H_FILTER; /* point to detail filter coefficients */ r2e = L_FILTER; /* point to approx. filter coefficients */ r12e = LVLADDRS; /* point to data level address pointers */ a0 = a0 - a0; /* zero the accumulators */ call DECOMP (r14); /* start the recursive decomposition */ a1 = a0; goto MAINLOOP; nop; [LISTING FOUR] /* WAVEDATA.S */ #include "dsp_type.h" #if DSP32 #include "dspregs.h" #endif .global WAVEADRS, WAVELVLS, IMAGSHOW, LVLADDRS .global SIG_DRAW, DRAW_CNT, H_FILTER, L_FILTER .global RST_DATA, IM0_PTRS, IM1_PTRS, IMAGE_0 .global STACKEND, SIGNalIN, DATA_OUT .align 4 WAVEADRS: int24 0; /* jump address for wavelet filter length */ WAVEINDX: int24 0; /* wrap back index for wavelet filter length */ WAVELVLS: int 6, 1625; /* number of levels, clear loop counter */ IMAGSHOW: int 8, 0; /* unit interval count, active image pointer */ LVLADDRS: int24 SIGNalIN, APPROX_5; /* data pointer storage for level 5 */ int24 APPROX_5, APPROX_4; /* data pointer storage for level 4 */ int24 APPROX_4, APPROX_3; /* data pointer storage for level 3 */ int24 APPROX_3, APPROX_2; /* data pointer storage for level 2 */ int24 APPROX_2, APPROX_1; /* data pointer storage for level 1 */ int24 APPROX_1, 0; /* data pointer storage for level 0 */ .align 4 SIG_DRAW: float 0.0, 24.0, 48.0, 0.0; /* scaling and offset coefficients */ int 0, 64; /* temp storage, row increment */ int 1536, 0; /* baseline value, bit pointer */ int24 0; /* byte column pointer */ .align 4 float 0.0, 24.0, 48.0, 0.0; int 0, 32; int 768, 0; int24 0; .align 4 float 0.0, 24.0, 48.0, 0.0; int 0, 16; int 384, 0; int24 0; .align 4 float 0.0, 24.0, 48.0, 0.0; int 0, 8; int 192, 0; int24 0; .align 4 float 0.0, 24.0, 48.0, 0.0; int 0, 4; int 96, 0; int24 0; .align 4 float 0.0, 24.0, 48.0, 0.0; int 0, 2; int 48, 0; int24 0; .align 4 float 0.0, 24.0, 48.0, 0.0; int 0, 2; int 48, 0; int24 0; .align 4 float 0.0, 24.0, 48.0, 0.0; int 0, 2; int 48, 0; int24 0; DRAW_CNT: byte 6, 4, 3, 2, 1, 0; .align 4 H_FILTER: 6*float 0.0; /* highpass wavelet filter storage allocation */ L_FILTER: 6*float 0.0; /* lowpass wavelet filter storage allocation */ /* image pointer reset initialization data */ RST_DATA: int24 0x02; /* position of first pixel in unit interval at reset */ int24 IM0INITS; /* 00 00 00 00 00 00 00 01 */ int24 0x01, IM0INIT5; /* 00 00 00 01 */ int24 0x01, IM0INIT4; /* 00 01 */ int24 0x01, IM0_LVL3; /* 01 */ int24 0x10, IM0_LVL2; /* 10 */ int24 0x40, IM0_LVL1; /* 40 */ int24 0x80, IM0_LVL0; /* 80 */ int24 0x80, IM0_LVLA; /* 80 */ /* image pointer switch initialization data */ IM0_PTRS: int24 IM0SIGNL, IM0_LVL5, IM0_LVL4, IM0_LVL3; int24 IM0_LVL2, IM0_LVL1, IM0_LVL0, IM0_LVLA; IM1_PTRS: int24 IM1SIGNL, IM1_LVL5, IM1_LVL4, IM1_LVL3; int24 IM1_LVL2, IM1_LVL1, IM1_LVL0, IM1_LVLA; /* IMAGE 0 storage allocation */ IMAGE_0: IM0SIGNL: 7*byte 0; IM0INITS: 3193*byte 0; IM0_LVL5: 3*byte 0; IM0INIT5: 1597*byte 0; IM0_LVL4: byte 0; IM0INIT4: 799*byte 0; IM0_LVL3: 400*byte 0; IM0_LVL2: 200*byte 0; IM0_LVL1: 100*byte 0; IM0_LVL0: 100*byte 0; IM0_LVLA: 100*byte 0; /* IMAGE 1 storage allocation */ IM1SIGNL: 3200*byte 0; IM1_LVL5: 1600*byte 0; IM1_LVL4: 800*byte 0; IM1_LVL3: 400*byte 0; IM1_LVL2: 200*byte 0; IM1_LVL1: 100*byte 0; IM1_LVL0: 100*byte 0; IM1_LVLA: 100*byte 0; .align 2 STACKBSE: 31*int24 0; /* subroutine stack storage allocation */ STACKEND: int24 0; .rsect ".hi_ram" SIGNalIN: 6*float 0.0; /* approximation data storage allocation */ APPROX_5: 6*float 0.0; APPROX_4: 6*float 0.0; APPROX_3: 6*float 0.0; APPROX_2: 6*float 0.0; APPROX_1: 6*float 0.0; DATA_OUT: 9*float 0.0; /* output data storage allocation */ [LISTING FIVE] DSP_REGS.H /* register file redefinition */ #define r1e r1 #define r2e r2 #define r3e r3 #define r4e r4 #define r5e r5 #define r6e r6 #define r7e r7 #define r8e r8 #define r9e r9 #define r10e r10 #define r11e r11 #define r12e r12 #define r13e r13 #define r14e r14 #define r15e r15 #define r16e r16 #define r17e r17 #define r18e r18 #define r19e r19 #define r20e r20 #define r21e r21 /* integer and float redefinition */ #define int24 int #define float24 float DSP_TYPE.32 #define DSP32 1 DSP_TYPE.32C #define DSP32C 1 MAKE32.BAT copy dsp_type.32 dsp_type.h d3make -M2 -N -l analyzer.s decomp.s drawimag.s wavedata.s -o anlyzr32.dsp MAKE32C.BAT copy dsp_type.32c dsp_type.h d3make -M6 -Q -O -l analyzer.s decomp.s drawimag.s wavedata.s -o anlyz32c.dsp [LISTING SIX] V592x480.h void Set592x480(void); void ShiftWaveTraces(unsigned int src, unsigned int dest); void GetDSPimage(unsigned int dest, unsigned int io_addr); V592x480.c /* Mode set routine for VGA 592x480 16-color mode. Tested with Borland C 2.0 */ #include #include unsigned char palette_set[17]={0,64,60,3,4,5,6,55,1,62,1,62,56,62,7,62,0}; void Set592x480(void) { union REGS regset; struct SREGS sregset; /* First, set to standard 640x480 mode (mode 12h) */ regset.x.ax = 0x0012; int86(0x10, ®set, ®set); /* Next, set up the new color palette */ regset.x.ax = 0x1002; regset.x.dx = (unsigned int) palette_set; sregset.es = _DS; int86x(0x10, ®set, ®set, &sregset); /* Now, tweak the registers needed to convert the horizontal character count from 80 to 74 characters (640 to 592 pixels) per line */ outportb(0x3D4, 0x11); /* allow access to CRTC registers 0 - 7 */ outportb(0x3D5, inportb(0x3D5) & 0x7f); outport(0x3D4, 0x4901); /* adjust the Horizontal Display Enable End register for 74 byte display area width */ outport(0x3D4, 0x2513); /* adjust the Offset register for 74 byte (37 word) display area width */ /* adjust Line Compare register to start display of non-flipping area at line 400 (row scan number 399 (0x18f) */ outportb(0x3D4, 9); /* clear tenth bit of Line Compare count */ outportb(0x3D5, inportb(0x3D5) & 0xbf); outportb(0x3D4, 7); /* set ninth bit of Line Compare count */ outportb(0x3D5, inportb(0x3D5) | 0x10); outport(0x3D4, 0x8f18); /* remaining eight bits of Line Compare */ /* adjust the Start Address High and Start Address Low registers to start screen display on page 0 */ outport(0x3D4, 0x170c); outport(0x3D4, 0x200d); outportb(0x3D4, 0x11); /* block access to CRTC registers 0 - 7 */ outportb(0x3D5, inportb(0x3D5) | 0x80); } #define CLD 0xfc #define PUSH_DS 0x1e #define PUSH_CX 0x51 #define POP_DS 0x1f #define POP_CX 0x59 #define REP 0xf3 #define MOVSB 0xa4 #define STOSB 0xaa #define INSW 0x6d #define DEC_AX 0X48 #define DEC_CX 0X49 #define DEC_DX 0X4a #define INC_DX 0X42 #define DEC_SI 0X4e #define JNE 0X75 #define OUT_DX_AL 0xee #define USE_ES 0x26 #define MOV_AL_DI 0x058a #define MOV_CX_AX 0xc88b #define MOV_CX_DX 0xca8b #define ADD_DI_BX 0xfb03 #define ADD_SI_BX 0xf303 #define ADD_SI_CX 0xf103 #define SUB_SI_CX 0xf12b unsigned char colorarray[74]; unsigned char leftedges[8]={0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01}; unsigned char rightedges[8]={0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; static unsigned int shift_blocks[7][2] = { {42, 32}, {26, 48}, {18, 56}, {14, 60}, {12, 62}, {11, 63}, {11, 63}}; void ShiftWaveTraces(unsigned int src, unsigned int dest) { int i; /* set the Mode Register Write Mode to 1 */ outportb(0x3ce, 5); outportb(0x3cf, (inportb(0x3cf) & 0xfc) | 0x01); /* set the Map Mask Register to enable writes to pixel planes 0, 1, and 3 and disable writes to pixel plane 2 */ outport(0x3c4, 0x0b02); _SI = src; _DI = dest + 10; _ES = 0xa000; __emit__(CLD); /* assure that MOVSB increments SI and DI */ for (i = 0; i < 7; i++) { _DX = shift_blocks[i][1]; /* load the length of each line for block */ _BX = shift_blocks[i][0]; /* init middle loop for wrap value for block */ __emit__(PUSH_DS); _DS = 0xa000; _AX = 50; /* init middle loop for number of lines in block */ __emit__(ADD_SI_BX, MOV_CX_DX, REP, MOVSB); __emit__(ADD_DI_BX, DEC_AX, JNE, 0xf5, POP_DS); } /* set the Mode Register Write Mode to 0 */ outportb(0x3ce, 5); outportb(0x3cf, inportb(0x3cf) & 0xfc); /* set the Map Mask Register to enable writes to all pixel planes */ outport(0x3c4, 0x0f02); } static unsigned int imag_blocks[6][2]={{10,32},{42,16},{58,8}, {66,4},{70,2},{72,1}}; void GetDSPimage(unsigned int dest, unsigned io_addr) { int i; /* Map Mask register - set pixel planes 1, 2, and 3 to "0", pixel plane 0 to "1" */ outport(0x3c4, 0x0102); _DX = io_addr; _DI = dest; _ES = 0xa000; __emit__(CLD); /* assure that INSW increments DI */ for (i = 0; i < 6; i++) { /* point to fill element offset */ _AX = imag_blocks[i][1]; /* load the length of each line for block */ _BX = imag_blocks[i][0]; /* init middle loop for wrap value for block */ _SI = 50; /* init middle loop for number of lines in image block */ __emit__(ADD_DI_BX); /* wrap destination pointer to next row of display */ __emit__(MOV_CX_AX, REP, INSW, DEC_SI, JNE, 0xf7); } _DI += 1; /* offset pointer by one */ _CX = imag_blocks[5][0]; /* init middle loop for wrap value for block */ _SI = 100; /* init middle loop for number of lines in image block */ __emit__(ADD_DI_BX, INSW, DEC_SI, JNE, 0xfa); /* Map Mask register - set pixel planes 0 - 3 to "1" */ outport(0x3c4, 0x0f02); }