;============================================================================ ; PROJECT : PIC'SPECTRUM ; ; FILE : POWERS.INC ; ; VERSION : 1.0 ; ; DESCRIPTION : ; ; Power spectrum calculation starting with the result of the real FFT. ; Result power is scaled (lin or log) and stored in the display buffer ; area (dispbuf) : 1 byte per frequency (1 to 126) ; ; This file define also the routine used by the interrupt routine to ; access the display buffer (with is paged) ; ; The display buffer table ("dispbuf") is a 2x64 bytes array, each of the ; two blocks being at at fixed adress ($20 to $5F) in the banks 2 and 3. ; ; Nota : dispbuf(0) (DC frequency) is not displayed. ; ;============================================================================ ; Developped & Copyrighted by Robert LACOSTE ;============================================================================ ;---------------------------------------------------------------------------- ; dispbufwr : Write a value in the given display buffer cell ; On input : WREG = index (0 to 127) ; RDIV = value (0 to MAXPIXVAL) ; On output : bank selected = zone_main ;---------------------------------------------------------------------------- dispbufwr macro movlr 2 ; start with bank 2 btfsc WREG,6 ; select the good bank bsf BSR,4 ; based on 6th bit of index andlw B'00111111' ; clear 2 MSB bits addlw H'20' ; add $20 (data start at $20) movwf FSR0 ; and use it as an index movfp rdiv,INDF0 ; to store value BANKSEL zone_main ; reset bank register endm ;---------------------------------------------------------------------------- ; dispbufrd : Read a value from the given display buffer cell ; On input : WREG = index (0 to 127) ; On output : WREG = value (0 to MAXPIXVAL) ; bank selected = zone_irq ; ; WARNING : Time critical routine ! In particular, execution time should ; be always exactly the same (if not, pixels won't be aligned ; anymore...) ; ; DURATION : 8 cycles (1.00 microsecond at 32MHz) ;---------------------------------------------------------------------------- dispbufrd macro movlr 2 ; start with bank 2 btfsc WREG,6 ; select the good bank bsf BSR,4 ; based on 6th bit of index andlw B'00111111' ; clear 2 MSB bits addlw H'20' ; add $20 (data start at $20) movwf FSR0 ; and use it as an index movfp INDF0,WREG ; to read value BANKSEL zone_irq ; reset bank register endm ;---------------------------------------------------------------------------- ; intpowerlin : Calculate power spectrum for the complex value stored ; in RA and RB, scale it with a linear scale (result from 0 ; to MAXPIXVAL) and store the result in RDIV ;---------------------------------------------------------------------------- ; A=(A/2)^2+(B/2)^2 (divide by 2 to exclude overflow) intpowerlin m_sta h1r ; m_sta(&h1r) m_mvba ; m_mvba() m_div2 ; m_div2() m_mvab ; m_mvab() call m_mult ; m_mult() m_sta h2r ; m_sta(&h2r) m_lda h1r ; m_lda(h1r) m_div2 ; m_div2() m_mvab ; m_mvab() call m_mult ; m_mult() m_ldb h2r ; m_ldb(h2r) m_add ; m_add() call m_scalelin ; m_scalelin() return ;---------------------------------------------------------------------------- ; intpowerlog : Calculate power spectrum for the complex value stored ; in RA and RB, scale it with a log scale (result from 0 ; to MAXPIXVAL) and store the result in RDIV ;---------------------------------------------------------------------------- ; A=(A/2)^2+(B/2)^2 (divide by 2 to exclude overflow) intpowerlog m_sta h1r ; m_sta(&h1r) m_mvba ; m_mvba() m_div2 ; m_div2() m_mvab ; m_mvab() call m_mult ; m_mult() m_sta h2r ; m_sta(&h2r) m_lda h1r ; m_lda(h1r) m_div2 ; m_div2() m_mvab ; m_mvab() call m_mult ; m_mult() m_ldb h2r ; m_ldb(h2r) m_add ; m_add() call m_scalelog ; m_scalelog() return ;---------------------------------------------------------------------------- ; powerlin : Calculate power spectrum for the complex spectrum stored ; in "data", scale it with a linear scale (result from 0 ; to MAXPIXVAL) and store the result in "dispbuf" ; ; Nota : last frequency (number 128) is discarted ;---------------------------------------------------------------------------- powerlin nop ;--------------> Special case of the first value (real) clrf rdiv,F m_ldai rdiv ; m_ldai(0) m_ldbi rdiv ; m_ldbi(0) call intpowerlin ; intpower() movlw 0 dispbufwr ; dispbuf[0]=(unsigned char)rdiv ;--------------> General case clrf i,F ; for (i=1;i Special case of the first value (real) clrf rdiv,F m_ldai rdiv ; m_ldai(0) m_ldbi rdiv ; m_ldbi(0) call intpowerlog ; intpower() movlw 0 dispbufwr ; dispbuf[0]=(unsigned char)rdiv ;--------------> General case clrf i,F ; for (i=1;i