http://www.edtn.com/embapps/emba035.htm
http://www.geocities.com/robert_lacoste
Steve Thackery says:
[Microchip Application Note AN542 doesn't work]*No* disrespect to the guys who wrote it, but it doesn't work.
Over the last several months I've been developing a product for my employer which uses a fast fourier transform as part of its functionality. The product is based upon a 17C44, by the way.
I was foolish enough to plan my timescales assuming that the Microchip FFT would be pretty well "plug and play". After all, I do tend to trust the stuff they publish. How wrong I was!
I won't bore you with the details, but Microchip's FFT is seriously defective. I can only guess that it didn't receive much testing. In fact, reading between the lines in AN542 it becomes clear that it was primarily written as a *benchmarking* exercise rather than a reliable FFT module for use in our projects.
Basically, if you test it with the waveform shown in the AN, it works perfectly. I should have been suspicous, even so. The waveform shown is of very low frequency, and has a whole number of cycles in the sampling window. Alter that frequency by even a small amount, so that there isn't a whole number of cycles in the window and the whole thing goes haywire! It generates artefacts in the FFT output all over the place, both above and below the "real" frequency. Similarly, test it at higher frequencies with sine or square waves, and you get a complete spectrum of rubbish at the output.
Incidentally, it wasn't made clear in the AN that permissible input range of values is between 0 and 3FFF. In other words, you need to DC-shift your sound sample so its centred around 1FFF, and adjust its gain. That caught us out for a couple of days!
We assumed it must be something we were doing wrong and spent ages poring over the AN to see if we were doing something stupid. We also tried working through the code itself, but it is almost inpenetrable. We tried everything, including using very small amplitude signals, but to no avail. The output is rubbish *except* with very low frequency square waves with a whole number of cycles in the window.
I can only imagine that there is a scaling problem somewhere in the maths. It looks like there is some sort of overflow or fold-back going on.
This cost me two months of development time and made me very unpopular with my employer and customer!
In the end we gave up and looked elsewhere. This is where Robert Lacoste comes into the picture. He developed his own FFT module from scratch and incorporated it into his PIC'Spectrum product. I contacted him and asked if he would be willing to let us use his FFT module - for prototyping and test purposes only - in our own product. He was willing and incredibly helpful, answering all our questions with clarity.
It took us two days to unplug the Microchip FFT module and plug in the Lacoste module. Here's what happened. It worked PERFECTLY! The output is classic, text-book perfect under all circumstances. Furthermore, it runs at least ten times as fast as the Microchip module.
Let me state publicly my most grateful thanks to Robert. If you need to include an FFT in any of your products, contact him on robert_lacoste@yahoo.fr He allowed us free use in our prototypes, and suggested a very reasonable royalty on our production models. I expect he might extend a similar deal to others.
In summary, then: BEWARE the Microchip FFT, and THANK YOU Robert Lacoste!
;============================================================================ ; PROJECT : PIC'SPECTRUM ; ; FILE : PICSPECT.ASM ; ; VERSION : 1.0 ; ; DESCRIPTION : ; ; PIC'SCOPE digital audio spectrum analyser - Main source file ; ; This project is a complete audio spectrum analyser with output on a ; standard VGA display, done entirely with a PIC17C756 microcontroler. ; ; The controler is in charge of : ; - ADC acquisition of the incoming signal ; - Fast Fourier Transform of the signal ; - Power calculation and if required logarithmic scaling ; - Video generation entirely in software ; of course in real time. ; ; Developped on MICROCHIP's MPLAB 3.31.0 ; To be embedded in a PIC17C756 (32MHz crystal) ; ;============================================================================ ; Developped & Copyrighted by Robert LACOSTE ;============================================================================ ;---------------------------------------------------------------------------- ; System definitions ;---------------------------------------------------------------------------- PROCESSOR 17C756 ; Assembler directives RADIX HEX ERRORLEVEL 0 ERRORLEVEL -302 ; no bank control warnings TITLE "PIC'SPECTRUM" SUBTITLE "(C) Robert Lacoste" #include "P17C756.INC" ; Processor dependant declarations ; config register : ; XT osc, no watchdog, brown-out reset active, microcontroler __CONFIG (_XT_OSC & _WDT_OFF & _BODEN_ON & _MC_MODE) ;---------------------------------------------------------------------------- ; Application constants ;---------------------------------------------------------------------------- MAXPIXVAL equ 127 ; maximum scaled pixel value INITTIM equ $FFFF-254+13+5 ; timer load value, ; 254 because 31.77µS=254*4/32MHz ; minus 13 for irq to reload delay ; minus 5 for timer to irq delay BKG_COLOR equ %00000100 ; background=Blue SLINE_COLOR equ %00000011 ; separation lines=Yellow SHORTS_COLOR equ %00000011 ; small scale indicator=Yellow LONGS_COLOR equ %00000011 ; long scale indicator=Yellow FREQ_COLOR equ %00000001 ; Frequency bars=Red BKGTITLE_COLOR equ %00000010 ; Background title=Green TITLE_COLOR equ %00000000 ; Title=Black HOLD_COLOR equ %00000001 ; Hold=Red ;---------------------------------------------------------------------------- ; Vectors ;---------------------------------------------------------------------------- reset_vector org $0000 jmp start ; Initialisation intpin_vector org $0008 jmp start ; should not occur timer0_vector org $0010 jmp it_timer ; horizontal sync interrupt t0cki_vector org $0018 jmp start ; should not occur periph_vector org $0020 jmp start ; should not occur start_appl org $0050 ; start of application area ;---------------------------------------------------------------------------- ; Inclusion of extern application files ;---------------------------------------------------------------------------- #include "vars.inc" ; Variables declarations #include "fixed.inc" ; Fixed point arithmetic #include "testsig.inc" ; Test signals generation #include "fft.inc" ; FFT calculation routines #include "powers.inc" ; power calculation & display access #include "irq.inc" ; interrupt routine & video generation ;---------------------------------------------------------------------------- ; Main starting point ;---------------------------------------------------------------------------- start nop BANKSEL zone_main ;--> Initialisation call initialize ; initialization of ports & variables call realfft ; do the first FFT (on the test signal) call init_timer ; launch timer0 interrupts mainloop nop ;--> Power spectrum calculation & scaling movlb 0 ; if RB7=0 (mode log), snb RB.7 jmp spectlin spectlog call powerlog ; calculate spectrum in log scale jmp main1 spectlin call powerlin ; else calculate spectrum in lin scale main1 nop ;--> Analog acquisition movlb 0 ; if RB6=1 (non hold mode), sb RB.6 ; do analog sample acquisition : jmp main2 movlb 1 ; RD1=1 (debug line : ADC going on) setb RD.1 BANKSEL num_sample ; sample number=0 clr num_sample call init_adc ; initialize analog acquisition BANKSEL acq_request mov W, #1 ; put acqrequest flag to 1 mov acq_request, W clr WREG ; and wait for it to be 0 acqwait cpfseq acq_request jmp acqwait movlb 1 ; RD1=0 (debug line : ADC going on) clrb RD.1 ;--> Do the FFT movlb 1 ; RD0=1 (debug line : FFT going on) setb RD.0 BANKSEL zone_main call realfft ; do the FFT movlb 1 ; RD0=0 (debug line : FFT going on) clrb RD.0 ;--> And loop ! main2 jmp mainloop ;---------------------------------------------------------------------------- ; Ports & variables initialization ;---------------------------------------------------------------------------- initialize nop ;--> Variables initialization BANKSEL acq_request ; reset adc control registers clr acq_request clr num_sample BANKSEL scan_line ; reset scan line number clr scan_line ; (will be incremented to 1 at the clr scan_line+1 ; first interrupt) BANKSEL displ0 ; reset displ0 buffer mov W, #low displ0 mov FSR0, W clrb ALUSTA.FS1 ; auto increment mode setb ALUSTA.FS0 clrb ALUSTA.C mov W, #low displ0+64 rstdispl0 clr INDF0 cpfseq FSR0 jmp rstdispl0 BANKSEL displ1 ; reset displ1 buffer mov W, #low displ1 mov FSR0, W clrb ALUSTA.FS1 ; auto increment mode setb ALUSTA.FS0 clrb ALUSTA.C mov W, #low displ0+64 rstdispl1 clr INDF0 cpfseq FSR0 jmp rstdispl1 setb ALUSTA.FS1 ; return to non-increment mode BANKSEL zone_main m_ldaconst H'2000' ; generate test square signal mov W, #16 call test_square ;--> Ports initialization mov W, #%11111000 ; RB0 to RB2 are outputs movlb 0 mov DDRB, W clr RB ; initialized to 0 mov W, #%10101111 ; RC4 and RC6 are outputs movlb 1 mov DDRC, W clrb RC.4 ; RC4=0 (Hsync) setb RC.6 ; RC6=1 (Vsync) mov W, #%11111000 ; RD0 to RD2 are outputs movlb 1 mov DDRD, W clr RD ; initialized to 0 mov W, #%01111111 ; RG7 is output movlb 5 mov DDRG, W clr RG ; initialized to 0 ret ;---------------------------------------------------------------------------- ; Initialization of timer0 ; ; Generate an interrupt every 31.77 micro-second (horizontal refresh ; rate for VGA display in 640x350 mode = 31.476KHz) ; ; Warning : interrupts will start immediatly after calling this routine ;---------------------------------------------------------------------------- init_timer nop setb CPUSTA.GLINTD ; disable global interrupts setb T0STA.T0CS ; select internal clock clrb T0STA.T0PS3 ; and prescale factor 1:1 clrb T0STA.T0PS2 clrb T0STA.T0PS1 clrb T0STA.T0PS0 BANKSEL tmpcpt mov W, #high INITTIM ; load timer mov tmpcpt, W mov W, #low INITTIM mov TMR0L, W movfp tmpcpt,TMR0H clrb INTSTA.PEIE ; disable PEI interrupts clrb INTSTA.T0CKIE ; disable external interrupts on RA1 clrb INTSTA.INTE ; disable external interrupts on RA0 setb INTSTA.T0IE ; enable timer0 interrupts clrb CPUSTA.GLINTD ; enable global interrupts ret ;---------------------------------------------------------------------------- ; Configuration of analog acquisition port ; ; Connect the analog source and configure the A/D sub-system. Acquisition ; will be done by the interrupt routine synchronously with video generation. ;---------------------------------------------------------------------------- init_adc movlb 5 mov W, #%10000000 ; clock=F/64 (2µS conversion), mov ADCON1, W ; left justified, ref 0/5V mov W, #%10000000 ; select chanel AD8 mov ADCON0, W setb ADCON0.ADON ; switch on ADC sub-system ret END ;============================================================================ ; - END OF FILE - ;============================================================================ ;============================================================================ ; PROJECT : UPS'SPECTRUM ; ; FILE : VARS.INC ; ; VERSION : 1.0 ; ; DESCRIPTION : ; ; Definition of all RAM variables, bank per bank. ; Usage of each variable (used by main program, by interrupt routine or ; both) is defined ; ;============================================================================ ; Developped & Copyrighted by Robert LACOSTE ;============================================================================ ;---------------------------------------------------------------------------- ; Unbanked RAM ;---------------------------------------------------------------------------- ; unbanked RAM $1A to $1A : private unbanked save location for interrupt ; routine. Other locations are in bank 0. cblock H'001A' sv_bsr ; BSR save location endc ; unbanked ram $1B to $1F : arithmetic working registers, to be used only ; by the main program cblock H'001B' ; arithmetic working registers ra:2 ; (format s-2-13) rb:2 ; (format s-2-13) rdiv:1 ; (8 bit unsigned int) endc ;---------------------------------------------------------------------------- ; Bank 0 ;---------------------------------------------------------------------------- ; $20 to $7F : private registers for the interrupt routine ; and exchange registers & flags between main pgr and interrupt cblock H'0020' zone_irq:0 endc cblock scan_line:2 ; scan line number, from 1 to 449, H-L frame_num:1 ; frame number (for blinkings) tmpcolor:1 ; temporary storage of color tmpi:2 ; temporary variable tmpi2:2 ; temporary variable endc cblock sv_alusta ; save location for registers sv_wreg ; during interrupt sv_fsr0 endc ; WARNING : only these 4 registers (with bsr, saved in ; non-banked ram) are automaticaly saved. Be carefull when ; using FSR1 or table read registers ! ; Exchange registers et flags between main pgr and interrupt cblock acq_request:1 ; Analog acquisition flag ; (0:finished, 1:sampling, 2:convert) num_sample:1 ; Analog sample number endc ; $80 to $FF : FFT data buffer 0...63 (2 bytes/value, big endian : H-L) cblock H'0080' data0:128 ; (format s-2-13) endc ;---------------------------------------------------------------------------- ; Bank 1 ;---------------------------------------------------------------------------- ; $20 to $7F : private registers for the main program cblock H'0120' zone_main:0 endc cblock ; temporary variables for FFT and ; powers wr:2 ; (format s-2-13) wpr:2 ; (format s-2-13) wi:2 ; (format s-2-13) wpi:2 ; (format s-2-13) theta:2 ; (format s-2-13) mmax:1 ; counter m:1 ; counter j:1 ; counter istep:1 ; counter i:1 ; counter i1:1 ; counter i2:1 ; counter i3:1 ; counter i4:1 ; counter endc cblock ; temporary arithm. variables h1r:2 ; (format s-2-13) h1i:2 ; (format s-2-13) h2r:2 ; (format s-2-13) h2i:2 ; (format s-2-13) wtemp:2 ; (format s-2-13) endc cblock ; generic counters cptm:2 ; (16 bit unsigned int) cpti:2 ; (16 bit unsigned int) cptj:2 ; (16 bit unsigned int) endc cblock ; temporary registers for math.inc mres3:1 ; for m_mult and m_divi mres2:1 mres1:1 mres0:1 msign:1 x0:2 ; for m_sin x1:2 x2:2 sin_saveb:2 scaletmp:2 ; for m_scalelin and m_scalelog logresult:2 ; for m_scalelog endc cblock ; temporary registers for testsig.inc test_halfp:1 test_step:2 test_cval:2 endc cblock tmpcpt:1 ; temporary register for inittimer endc ; $80 to $FF : FFT data buffer 64...127 (2 bytes/value, big endian : H-L) cblock H'0180' data1:128 ; (format s-2-13) endc ;---------------------------------------------------------------------------- ; Bank 2 ;---------------------------------------------------------------------------- ; $20 to $5F : Display buffer 0...63 cblock H'0220' displ0:64 ; (value 0..MAXPIXVAL) endc ; $60 to $7F : unused ; $80 to $FF : FFT data buffer 128...191 (2 bytes/value, big endian : H-L) cblock H'0280' data2:128 ; (format s-2-13) endc ;---------------------------------------------------------------------------- ; Bank 3 ;---------------------------------------------------------------------------- ; $20 to $5F : Display buffer 64...127 cblock H'0320' displ1:64 ; (value 0..MAXPIXVAL) endc ; $60 to $7F : unused ; $80 to $FF : FFT data buffer 192...255 (2 bytes/value, big endian : H-L) cblock H'0380' data3:128 ; (format s-2-13) endc ;============================================================================ ; - END OF FILE - ;============================================================================ ;============================================================================ ; PROJECT : PIC'SPECTRUM ; ; FILE : FIXED.INC ; ; VERSION : 1.0 ; ; DESCRIPTION : ; ; Fixed point math routines, using a s-2-13 format (sign bit in 2-complement, ; 2 bits for the integer part, 13 bits for the decimal part). ; ; So values ranging +/-3.99999, resolution 1/2 exp 13 = 0.000122 ; ; All functions and macros operate on registers ra,rb and rdiv. ; Storage could be in a generic "arithmetic" register (2 bytes) or in the ; FFT data storage table ("data") ; ; The FFT data table ("data") is a 4x64 word (2 bytes) array, each of the ; four blocks being at at fixed adress ($80 to $ff) in the 4 banks. ; ; WARNING : ra/rb/rdiv are supposed to be in unbanked memory. Bank selector ; must be zone_main on input (access to arithmetic tempory registers) and is ; garanteed to be zone_main on exit ; ; In general, WREG is scrambled ; ;============================================================================ ; Developped & Copyrighted by Robert LACOSTE ;============================================================================ ;---------------------------------------------------------------------------- ; m_lda : copy a given general register (2 bytes) in register A ;---------------------------------------------------------------------------- m_lda macro inreg movfp inreg,WREG mov ra, W movfp inreg+1,WREG mov ra+1, W endm ;---------------------------------------------------------------------------- ; m_ldai : get the data value pointed by reg and store it in A ;---------------------------------------------------------------------------- m_ldai macro indexreg movfp indexreg, WREG movlr 0 ; start with bank 0 snb WREG.7 ; select the good bank setb BSR.5 snb WREG.6 ; based on 2 first bits of WREG setb BSR.4 clrb ALUSTA.C ; multiply by 2 rlcf WREG,1 setb WREG.7 ; and set high bit (data start at $80) mov FSR0, W ; and use it as an index movpf INDF0,ra ; to get msb value inc FSR0 movpf INDF0,ra+1 ; and lsb value BANKSEL zone_main ; reset bank register endm ;---------------------------------------------------------------------------- ; m_ldb : copy a given general register (2 bytes) in register B ;---------------------------------------------------------------------------- m_ldb macro inreg movfp inreg,WREG mov rb, W movfp inreg+1,WREG mov rb+1, W endm ;---------------------------------------------------------------------------- ; m_ldbi : get the data value pointed by reg and store it in B ;---------------------------------------------------------------------------- m_ldbi macro indexreg movfp indexreg,WREG movlr 0 ; start with bank 0 snb WREG.7 ; select the good bank setb BSR.5 snb WREG.6 ; based on 2 first bits of WREG setb BSR.4 clrb ALUSTA.C ; multiply by 2 rlcf WREG,1 setb WREG.7 ; and set high bit (data start at $80) mov FSR0, W ; and use it as an index movpf INDF0,rb ; to get msb value inc FSR0 movpf INDF0,rb+1 ; and lsb value BANKSEL zone_main ; reset bank register endm ;---------------------------------------------------------------------------- ; m_lddiv : copy a given register (int, 1 byte) in register DIV ;---------------------------------------------------------------------------- m_lddiv macro inreg movfp inreg,WREG mov rdiv, W endm ;---------------------------------------------------------------------------- ; m_sta : store the value of A in a given general register (2 bytes) ;---------------------------------------------------------------------------- m_sta macro outreg movfp ra,WREG mov outreg, W movfp ra+1,WREG mov outreg+1, W endm ;---------------------------------------------------------------------------- ; m_stai : store the value of A in the data value pointed by reg ;---------------------------------------------------------------------------- m_stai macro indexreg movfp indexreg, WREG movlr 0 ; start with bank 0 snb WREG.7 ; select the good bank setb BSR.5 snb WREG.6 ; based on 2 first bits of WREG setb BSR.4 clrb ALUSTA.C ; multiply by 2 rlcf WREG,1 setb WREG.7 ; and set high bit (data start at $80) mov FSR0, W ; and use it as an index movfp ra,INDF0 ; to store msb value inc FSR0 movfp ra+1,INDF0 ; and lsb value BANKSEL zone_main ; reset bank register endm ;---------------------------------------------------------------------------- ; m_ldaconst : load an immediate value in A ;---------------------------------------------------------------------------- m_ldaconst macro immvalue mov W, #high immvalue mov ra, W mov W, #low immvalue mov ra+1, W endm ;---------------------------------------------------------------------------- ; m_mvba : copy B to A ;---------------------------------------------------------------------------- m_mvba macro movfp rb,WREG mov ra, W movfp rb+1,WREG mov ra+1, W endm ;---------------------------------------------------------------------------- ; m_mvab : copy A to B ;---------------------------------------------------------------------------- m_mvab macro movfp ra,WREG mov rb, W movfp ra+1,WREG mov rb+1, W endm ;---------------------------------------------------------------------------- ; m_add : add B to A (A=A+B) ;---------------------------------------------------------------------------- m_add macro movfp rb+1,WREG ; low byte first add ra+1, W movfp rb,WREG ; and high byte with carry addwfc ra,1 endm ;---------------------------------------------------------------------------- ; m_sub : substract B to A (A=A-B) ;---------------------------------------------------------------------------- m_sub macro movfp rb+1,WREG ; low byte first sub ra+1, W movfp rb,WREG ; and high byte with borrow subwfb ra,1 endm ;---------------------------------------------------------------------------- ; m_mult : multiply A to B (A=A*B) ; Warning : overflow not detected if result>4 ;---------------------------------------------------------------------------- m_mult movfp ra+1,WREG ; low byte x low byte mulwf rb+1 movpf PRODH,mres1 movpf PRODL,mres0 movfp ra,WREG ; high byte x high byte mulwf rb movpf PRODH,mres3 movpf PRODL,mres2 movfp ra+1,WREG ; low byte x high byte mulwf rb movfp PRODL,WREG add mres1, W movfp PRODH,WREG addwfc mres2,F clr WREG addwfc mres3,F movfp ra,WREG ; high byte x low byte mulwf rb+1 movfp PRODL,WREG add mres1, W movfp PRODH,WREG addwfc mres2,F clr WREG addwfc mres3,F sb rb.7 ; test if B<0 jmp sign_ra movfp ra+1,WREG ; if so, adjust value sub mres2, W movfp ra,WREG subwfb mres3,F sign_ra sb ra.7 ; test if A<0 jmp sign_end movfp rb+1,WREG ; if so, adjust value sub mres2, W movfp rb,WREG subwfb mres3,F sign_end rlcf mres1,F ; shift left one time rlcf mres2,F rlcf mres3,F rlcf mres1,F ; shift left one time rlcf mres2,F rlcf mres3,F rlcf mres1,F ; shift left one time rlcf mres2,F rlcf mres3,F movfp mres3, ra ; forget mres1 and store result movfp mres2, ra+1 ; in register A end_mult ret ;---------------------------------------------------------------------------- ; m_divi : divide A with rdiv (A=A/DIV), rdiv being a non signed integer ; value and not a fixed decimal value ; ; call routines provided in Microchip's application notes (see div.inc) ;---------------------------------------------------------------------------- ; Correspondances between AN617 variables and pic'spectrum's... #define AARGB0 (ra) #define AARGB1 (ra+1) #define ACCB0 (ra) #define ACCB1 (ra+1) #define BARGB0 (rdiv) #define REMB0 (mres0) #define TEMP (mres1) #include "div.inc" ; include 16/8 unsigned routine ; from microchip's application ; note AN617 m_divi clrb msign.0 sb ra.7 ; save sign of A jmp m_divdiv setb msign.0 not ra ; if A<0, A=-A not ra+1 mov W, #1 add ra+1, W mov W, #0 addwfc ra,F m_divdiv call FXD1608U ; do the division sb msign.0 ; if A was <0 jmp end_mdivi not ra ; A=-A not ra+1 mov W, #1 add ra+1, W mov W, #0 addwfc ra,F end_mdivi ret ;---------------------------------------------------------------------------- ; m_div2 : divide A with 2 (A=A/2) ;---------------------------------------------------------------------------- m_div2 macro clrb ALUSTA.C rrcf ra,1 ; divide high byte rrcf ra+1,1 ; and low byte snb ra.6 ; test old sign bit setb ra.7 ; if set, report it to msb endm ;---------------------------------------------------------------------------- ; m_sin : replace A with sin(A) ; ; Sinus calculated by interpolation of tables values got with the MSB of A ; (v_msb and v_msb+1 are the table values corresponding for msb A and the next ; one in the table, with rollover on 0) ; ; ra=(((v_msb+1)*lsb ra+(v_msb)*(1-lsb ra)); ; ;---------------------------------------------------------------------------- radix dec sintable dw 0 dw 255, 511, 766, 1021, 1274, 1527, 1777, 2026 dw 2273, 2518, 2760, 3000, 3237, 3470, 3700, 3927 dw 4150, 4368, 4583, 4793, 4998, 5198, 5393, 5583 dw 5768, 5947, 6120, 6287, 6448, 6603, 6751, 6893 dw 7028, 7156, 7277, 7391, 7498, 7597, 7689, 7774 dw 7850, 7920, 7981, 8035, 8081, 8119, 8149, 8171 dw 8185, 8191, 8189, 8179, 8162, 8136, 8102, 8060 dw 8011, 7953, 7888, 7815, 7735, 7647, 7551, 7448 dw 7338, 7221, 7097, 6965, 6827, 6682, 6531, 6373 dw 6210, 6040, 5864, 5682, 5495, 5303, 5105, 4902 dw 4695, 4483, 4266, 4046, 3821, 3593, 3361, 3126 dw 2888, 2647, 2404, 2158, 1910, 1660, 1408, 1156 dw 902, 647, 391, 135, -120, -375, -631, -886 dw -1140, -1393, -1644, -1894, -2142, -2388, -2632, -2873 dw -3111, -3347, -3579, -3807, -4032, -4253, -4469, -4682 dw -4889, -5092, -5290, -5483, -5671, -5853, -6029, 6199 dw 6029, 5853, 5671, 5483, 5290, 5092, 4889, 4682 dw 4469, 4253, 4032, 3807, 3579, 3347, 3111, 2873 dw 2632, 2388, 2142, 1894, 1644, 1393, 1140, 886 dw 631, 375, 120, -135, -391, -647, -902, -1156 dw -1408, -1660, -1910, -2158, -2404, -2647, -2888, -3126 dw -3361, -3593, -3821, -4046, -4266, -4483, -4695, -4902 dw -5105, -5303, -5495, -5682, -5864, -6040, -6210, -6373 dw -6531, -6682, -6827, -6965, -7097, -7221, -7338, -7448 dw -7551, -7647, -7735, -7815, -7888, -7953, -8011, -8060 dw -8102, -8136, -8162, -8179, -8189, -8191, -8185, -8171 dw -8149, -8119, -8081, -8035, -7981, -7920, -7850, -7774 dw -7689, -7597, -7498, -7391, -7277, -7156, -7028, -6893 dw -6751, -6603, -6448, -6287, -6120, -5947, -5768, -5583 dw -5393, -5198, -4998, -4793, -4583, -4368, -4150, -3927 dw -3700, -3470, -3237, -3000, -2760, -2518, -2273, -2026 dw -1777, -1527, -1274, -1021, -766, -511, -255 radix hex m_sin movpf rb,sin_saveb ; save B register movpf rb+1,sin_saveb+1 clr x0+1 mov W, #low (sintable) ; get table value corresponding add W, ra ; to the MSB of A -> x0 mov TBLPTRL, W mov W, #high (sintable) addwfc x0+1,W mov TBLPTRH, W tablrd 0,0,x0+1 ; dummy read, update TABLATH tlrd 1,x0 ; read high byte tablrd 0,1,x0+1 ; and low byte. clr x1+1 movfp ra,WREG ; get table value corresponding mov W, ++WREG ; to the MSB of A+1, with rollover at 0 ;*** WARNING: ADDLW was expanded in three instructions! Check if previous instruction is a skip instruction. ; addlw low (sintable) ; -> x1 mov Hack, W mov W, #low (sintable) ; -> x1 add W, Hack mov TBLPTRL, W mov W, #high (sintable) addwfc x1+1,W mov TBLPTRH, W tablrd 0,0,x1+1 ; dummy read, update TABLATH tlrd 1,x1 ; read high byte tablrd 0,1,x1+1 ; and low byte. movfp ra+1,WREG ; get LSB of A in B mov rb, W ; and convert it to a weight factor clr rb+1 clrb ALUSTA.C rrcf rb,F rrcf rb+1,F clrb ALUSTA.C rrcf rb,F rrcf rb+1,F clrb ALUSTA.C rrcf rb,F rrcf rb+1,F m_lda x1 ; multiply "next" table value by B call m_mult m_sta x2 ; and save it m_ldaconst H'2000' ; calculate 1-weight factor m_sub m_ldb x0 ; and multiply it by "previous" value call m_mult m_ldb x2 ; add the 2 values m_add end_sin m_ldb sin_saveb ; restore B ret ;---------------------------------------------------------------------------- ; m_scalelin : linear scaling of A, result in WREG (0 to MAXPIXVAL) ; and in rdiv ;---------------------------------------------------------------------------- m_scalelin movpf ra,scaletmp ; copy A to scaletmp reg movpf ra+1,scaletmp+1 clrb ALUSTA.C ; divide by 16 rrcf scaletmp,F ; 2 rrcf scaletmp+1,F clrb ALUSTA.C rrcf scaletmp,F ; 4 rrcf scaletmp+1,F clrb ALUSTA.C rrcf scaletmp,F ; 8 rrcf scaletmp+1,F clrb ALUSTA.C rrcf scaletmp,F ; 16 rrcf scaletmp+1,F tstfsz scaletmp ; if tmp>255, return MAXPIVXVAL jmp m_scaleover mov W, #MAXPIXVAL ; if tmp>MAXPIXVAL, return MAXPIXVAL cpfslt scaletmp+1 jmp m_scaleover movfp scaletmp+1,WREG jmp end_scalelin m_scaleover mov W, #MAXPIXVAL ; return MAXPIXVAL end_scalelin mov rdiv, W ret ;---------------------------------------------------------------------------- ; m_scalelog : logarithmic scaling of A, result in WREG (0 to 127) ; and in rdiv ;---------------------------------------------------------------------------- radix dec logtable dw -4652, -4599, -4548, -4496, -4445, -4394, -4344, -4294 dw -4245, -4196, -4147, -4098, -4050, -4002, -3955, -3908 dw -3861, -3815, -3769, -3723, -3677, -3632, -3587, -3543 dw -3498, -3454, -3410, -3367, -3324, -3281, -3238, -3196 dw -3154, -3112, -3071, -3029, -2988, -2947, -2907, -2867 dw -2826, -2787, -2747, -2708, -2669, -2630, -2591, -2553 dw -2514, -2476, -2438, -2401, -2363, -2326, -2289, -2253 dw -2216, -2180, -2143, -2107, -2072, -2036, -2001, -1965 dw -1930, -1895, -1861, -1826, -1792, -1758, -1724, -1690 dw -1656, -1623, -1590, -1556, -1523, -1491, -1458, -1425 dw -1393, -1361, -1329, -1297, -1265, -1234, -1202, -1171 dw -1140, -1109, -1078, -1047, -1017, -986, -956, -926 dw -896, -866, -836, -806, -777, -748, -718, -689 dw -660, -631, -603, -574, -545, -517, -489, -461 dw -433, -405, -377, -349, -322, -294, -267, -240 dw -213, -186, -159, -132, -105, -79, -52, -26 radix hex m_scalelog tstfsz ra ; if A<32, return 0 jmp log_testover mov W, #32 cpfslt ra+1 jmp log_testover mov W, #0 jmp end_scalelog log_testover mov W, #high (032*MAXPIXVAL) ; if A>32xMAXPIXVAL, cpfsgt ra ; return MAXPIXVAL jmp log_1 jmp log_scaleover log_1 cpfseq ra jmp log_ok mov W, #low (032*MAXPIXVAL) cpfslt ra+1 jmp log_scaleover log_ok clr logresult ; clear result register clr logresult+1 movpf ra,scaletmp ; copy A to scaletmp reg movpf ra+1,scaletmp+1 ; (A is between 32 and 32xMAXPIXVAL) clrb ALUSTA.C ; multiply tmp by 8 rlcf scaletmp+1,F ; 2 rlcf scaletmp,F clrb ALUSTA.C rlcf scaletmp+1,F ; 4 rlcf scaletmp,F clrb ALUSTA.C rlcf scaletmp+1,F ; 8 rlcf scaletmp,F ; (tmp is between 256 and 256xMAXPIXVAL) ; normalization phase, until tmp < 256 log_normalize tstfsz scaletmp jmp log_2 jmp log_endnorm log_2 mov W, #low 4652 ; add 256*ln(2)*MAXPIXVAL/ln(MAXPIXVAL) add logresult+1, W ; (=4652) to current evaluation mov W, #high 4652 addwfc logresult,F clrb ALUSTA.C rrcf scaletmp,F ; divide tmp by 2 rrcf scaletmp+1,F jmp log_normalize ; and loop log_endnorm mov W, #$7F ; tmp is now between 128 and 255 and W, scaletmp+1 ; substract 128 ;*** WARNING: ADDLW was expanded in three instructions! Check if previous instruction is a skip instruction. ; addlw low (logtable) ; and use it as index in logtable mov Hack, W mov W, #low (logtable) ; and use it as index in logtable add W, Hack mov TBLPTRL, W mov W, #high (logtable) addwfc scaletmp,W mov TBLPTRH, W tablrd 0,0,scaletmp+1 ; dummy read, update TABLATH tlrd 1,scaletmp ; read high byte tablrd 0,1,scaletmp+1 ; and low byte. movfp scaletmp+1,WREG add logresult+1, W ; add this value to result movfp scaletmp,WREG add logresult, W movfp logresult,WREG ; returned value is high byte jmp end_scalelog log_scaleover mov W, #MAXPIXVAL end_scalelog mov rdiv, W ret ;---------------------------------------------------------------------------- ; m_mathtest : Test utility for mathlib functions ; ; to be used for debug only ;---------------------------------------------------------------------------- m_mathtest m_ldaconst H'23EF' ; (1.123) m_mvab m_ldaconst H'B561' ; (-2.332) m_lddiv 0 nop ; expected : ; RA = -19103 $B561 -2.331909 RB = 9199 $23EF 1.122925 RDIV = 0 $00 call m_sin nop ; expected : ; RA = -5931 $E8D5 -0.723999 RB = 9199 $23EF 1.122925 RDIV = 0 $00 call m_mult nop ; expected : ; RA = -6660 $E5FC -0.812988 RB = 9199 $23EF 1.122925 RDIV = 0 $00 m_mvab m_ldaconst H'F88B' ; (-0.233) m_add nop ; expected : ; RA = -8568 $DE88 -1.045898 RB = -6660 $E5FC -0.812988 RDIV = 0 $00 mov W, #44 mov h1i, W m_stai h1i m_ldaconst 0 mov W, #44 mov h1i, W m_ldbi h1i m_mvba nop ; expected : ; RA = -8568 $DE88 -1.045898 RB = -8568 $DE88 -1.045898 RDIV = 0 $00 m_ldaconst H'F8DB' ; (-0.2233); m_sub nop ; expected : ; RA = 6739 $1A53 0.822632 RB = -8568 $DE88 -1.045898 RDIV = 0 $00 m_mvab m_ldaconst H'470A' ; (2.22) m_add nop ; expected : ; RA = 24925 $615D 3.042603 RB = 6739 $1A53 0.822632 RDIV = 0 $00 call m_sin m_mvab m_ldaconst H'F560' ; (-0.332) call m_mult nop ; expected : ; RA = -268 $FEF4 -0.032715 RB = 809 $0329 0.098755 RDIV = 0 $00 m_sta h1r mov W, #31 mov h2r, W m_lddiv h2r call m_divi nop ; expected : ; RA = -8 $FFF8 -0.000977 RB = 809 $0329 0.098755 RDIV = 31 $1F m_ldb h1r m_sub call m_mult nop ; expected : ; RA = -8 $FFF8 -0.000977 RB = -268 $FEF4 -0.032715 RDIV = 31 $1F m_mvab m_lda h1r call m_sin call m_mult nop ; expected : ; RA = 0 $0000 0.000000 RB = -8 $FFF8 -0.000977 RDIV = 31 $1F m_ldaconst H'18E2' ; (0.7776) call m_scalelin nop ; expected : ; RA = 6370 $18E2 0.777588 RB = -8 $FFF8 -0.000977 RDIV = 127 $7F m_ldaconst H'C15' ; (0.3776); call m_scalelin nop ; expected : ; RA = 3093 $0C15 0.377563 RB = -8 $FFF8 -0.000977 RDIV = 96 $60 m_ldaconst H'C15' ; (0.3776) m_div2 call m_scalelin nop ; expected : ; RA = 1546 $060A 0.188721 RB = -8 $FFF8 -0.000977 RDIV = 48 $30 m_ldaconst H'18E2' ; (0.7776); call m_scalelog nop ; expected : ; RA = 6370 $18E2 0.777588 RB = -8 $FFF8 -0.000977 RDIV = 127 $7F m_ldaconst H'C15' ; (0.3776) call m_scalelog nop ; expected : ; RA = 3093 $0C15 0.377563 RB = -8 $FFF8 -0.000977 RDIV = 119 $77 m_ldaconst H'C15' ; (0.3776) m_div2 call m_scalelog nop ; expected : ; RA = 1546 $060A 0.188721 RB = -8 $FFF8 -0.000977 RDIV = 101 $65 m_lda h1r m_div2 call m_sin m_mvab m_ldaconst H'438D' ; (2.111) call m_mult nop ; expected : ; RA = -280 $FEE8 -0.034180 RB = -133 $FF7B -0.016235 RDIV = 101 $65 call m_scalelog nop ; expected : ; RA = -280 $FEE8 -0.034180 RB = -133 $FF7B -0.016235 RDIV = 0 $00 ret ;============================================================================ ; - END OF FILE - ;============================================================================ ;============================================================================ ; PROJECT : PIC'SPECTRUM ; ; FILE : TESTSIG.INC ; ; VERSION : 1.0 ; ; DESCRIPTION : ; ; Test signals generation (for validation of the FFT routines) ; ; A square test signal is generated during ram initialization, and is ; displayed if the Pic'Spectrum is switched on in hold mode. ; ;============================================================================ ; Developped & Copyrighted by Robert LACOSTE ;============================================================================ ;---------------------------------------------------------------------------- ; test_square : Generate a square signal ; ; On input, amplitude is in math register A, half-period in WREG ;---------------------------------------------------------------------------- test_square clr cpti ; cpti=index to data clr cptj ; cptj=phase mov test_halfp, W ; test_halfp=halfperiod testsquare_b inc cptj ; increment phase movfp cptj,WREG cpfseq test_halfp ; equal to half-period ? jmp testsquare_norm clr cptj ; if yes, reset phase m_mvab m_ldaconst H'E000' ; and multiply phase by -1 call m_mult testsquare_norm m_stai cpti ; store current amplitude incsz cpti jmp testsquare_b ; and loop ret ;---------------------------------------------------------------------------- ; test_triangle : Generate a triangle signal ; ; On input, step is in math register A, half-period in WREG ;---------------------------------------------------------------------------- test_triangle clr cpti ; cpti=index to data mov test_halfp, W ; halfp=halfperiod clrb ALUSTA.C rrcf WREG,W mov cptj, W ; cptj=phase (initialised to 50%) m_sta test_step ; test_step=step m_ldaconst 0 m_sta test_cval ; test_cval=current value testtriangle_b inc cptj ; increment phase movfp cptj,WREG cpfseq test_halfp ; equal to half-period ? jmp testtriang_norm clr cptj ; if yes, reset phase m_lda test_step m_mvab m_ldaconst H'E000' ; and multiply step by -1 call m_mult m_sta test_step testtriang_norm m_lda test_cval ; increment value by step value m_mvab m_lda test_step m_add m_sta test_cval m_stai cpti ; store current amplitude incsz cpti jmp testtriangle_b ; and loop ret ;============================================================================ ; - END OF FILE - ;============================================================================ ;============================================================================ ; PROJECT : PIC'SPECTRUM ; ; FILE : FFT.INC ; ; VERSION : 1.0 ; ; DESCRIPTION : ; ; 256 points FFT routines, using s/2/13 format for numeric computations ; (through the fixed.inc library). All data are stored in the internal ; registers of the 17C756 (array DATA). ; ; Execution time on a PIC17C756/32MHz : around 50ms without concurrent ; video generation (resulting in a 90-100ms refresh time with spectrum ; power calculation, analog acquisition and video refresh) ; ;============================================================================ ; Developped & Copyrighted by Robert LACOSTE ;============================================================================ ;---------------------------------------------------------------------------- ; Complex FFT, radix-1, decimation in place, 128 points ; ; Algorithm from "Numerical recipes in C", manually compiled in assembler ; and adapted... ; ; Input : 128 complex values (each on 4 bytes), stored in data[0..511] ; For each data : byte 0 = MSB of real part ; byte 1 = LSB of real part ; byte 2 = MSB of complex part ; byte 3 = LSB of complex part ; ; Replace data[0..511] by its FFT (128 frequencies, complex values) ;---------------------------------------------------------------------------- fft nop ; Control point : Input FFT ; ------> initialisation clr j ; j=0 ; nn=128 (implicit), n=256 (implicit) ; ------> bit reversal clr i ; for(i=0;i<n-1;i+=2) { iloop1 nop if1 movfp i,WREG ; if (j>i) { cpfsgt j jmp endif1 m_ldai j ; m_ldai(j) m_ldbi i ; m_ldbi(i) m_stai i ; m_stai(i) m_mvba ; m_mvba() m_stai j ; m_stai(j); inc j inc i m_ldai j ; m_ldai(j+1) m_ldbi i ; m_ldbi(i+1) m_stai i ; m_stai(i+1) m_mvba ; m_mvba() m_stai j ; m_stai(j+1) dec j dec i endif1 nop ; } endif mov W, #128 ; m=n>>1 mov m, W while1 mov W, #2 ; while(m>=2 && j>=m) { cpfslt m jmp $+2 jmp wend1 movfp m,WREG cpfslt j jmp $+2 jmp wend1 movfp m,WREG ; j-=m sub j, W clrb ALUSTA.C ; m>>=1 rrcf m,F wloop1 jmp while1 ; } wend1 movfp m,WREG ; j+=m add j, W inext1 inc i ; } next i incsz i jmp iloop1 ; ------> FFT itself mov W, #2 ; mmax=2 mov mmax, W while2 tstfsz mmax ; while(n>mmax) { jmp $+2 jmp wend2 movfp mmax, WREG ; istep=mmax<<1 clrb ALUSTA.C rlcf WREG,F mov istep, W ; theta=2pi/mmax m_ldaconst H'6488' ; m_ldaconst(3.14159265459) m_lddiv mmax ; m_lddiv(mmax>>1) clrb ALUSTA.C rrcf rdiv,F call m_divi ; m_divi() m_sta theta ; m_sta(&theta) ; wpr=-2*sin(theta/2)^2 mov W, #2 ; m_lddiv(2) mov rdiv, W call m_divi ; m_divi() call m_sin ; m_sin() m_mvab ; m_mvab() call m_mult ; m_mult() m_mvab ; m_mvab() m_ldaconst H'C000' ; m_ldaconst(-2.0) call m_mult ; m_mult() m_sta wpr ; m_sta(&wpr) ; wpi=n_sin(theta) m_lda theta ; m_lda(theta) call m_sin ; m_sin() m_sta wpi ; m_sta(&wpi) ; wr=1, wi=0 m_ldaconst H'2000' ; m_ldaconst(1.0) m_sta wr ; m_sta(&wr) m_ldaconst H'0000' ; m_ldaconst(0.0) m_sta wi ; m_sta(&wi) ffttst1 nop clr m ; for(m=0;m<mmax-1;m+=2) { mloop1 movfp mmax,WREG mov W, --WREG cpfslt m jmp mend1 ffttst2 nop movfp m,WREG ; for(i=m;i<n;i+=istep) { mov i, W iloop2 nop movfp i,WREG ; j=i+mmax mov j, W movfp mmax,WREG add j, W ffttst3 nop ; h1r=wr*data[j]-wi*data[j+1] m_lda wi ; m_lda(wi) inc j ; m_ldbi(j+1) m_ldbi j dec j call m_mult ; m_mult() m_sta h1r ; m_sta(&h1r) m_lda wr ; m_lda(wr) m_ldbi j ; m_ldbi(j) call m_mult ; m_mult() m_ldb h1r ; m_ldb(h1r) m_sub ; m_sub() m_sta h1r ; m_sta(&h1r) ; h1i=wr*data[j+1]+wi*data[j] m_lda wi ; m_lda(wi) m_ldbi j ; m_ldbi(j) call m_mult ; m_mult() m_sta h1i ; m_sta(&h1i) m_lda wr ; m_lda(wr) inc j ; m_ldbi(j+1) m_ldbi j dec j call m_mult ; m_mult() m_ldb h1i ; m_ldb(h1i) m_add ; m_add() m_sta h1i ; m_sta(&h1i) ; butterfly update, with in-place scaling ; data[j]=(data[i]-h1r)/2 m_ldai i ; m_ldai(i) m_ldb h1r ; m_ldb(h1r) m_sub ; m_sub() m_div2 ; m_div2() m_stai j ; m_stai(j) ; data[j+1]=(data[i+1]-h1i)/2 inc i ; m_ldai(i+1) m_ldai i dec i m_ldb h1i ; m_ldb(h1i) m_sub ; m_sub() m_div2 ; m_div2() inc j ; m_stai(j+1) m_stai j dec j ; data[i]=(data[i]+h1r)/2 m_ldai i ; m_ldai(i) m_ldb h1r ; m_ldb(h1r) m_add ; m_add() m_div2 ; m_div2() m_stai i ; m_stai(i) ; data[i+1]=(data[i+1]+h1i)/2 inc i ; m_ldai(i+1) m_ldai i dec i m_ldb h1i ; m_ldb(h1i) m_add ; m_add() m_div2 ; m_div2() inc i ; m_stai(i+1) m_stai i dec i inext2 tstfsz istep ; } next i jmp $+2 jmp iend2 movfp istep,WREG add i, W sb ALUSTA.C jmp iloop2 ; wtemp=wr iend2 m_lda wr ; m_lda(wr) m_sta wtemp ; m_sta(&wtemp) ; wr=wr*wpr-wi*wpi+wr m_lda wi ; m_lda(wi) m_ldb wpi ; m_ldb(wpi) call m_mult ; m_mult() m_sta h1r ; m_sta(&h1r) m_lda wr ; m_lda(wr) m_ldb wpr ; m_ldb(wpr) call m_mult ; m_mult() m_ldb h1r ; m_ldb(h1r) m_sub ; m_sub() m_ldb wr ; m_ldb(wr) m_add ; m_add() m_sta wr ; m_sta(&wr) ; wi=wi*wpr+wtemp*wpi+wi m_lda wtemp ; m_lda(wtemp) m_ldb wpi ; m_ldb(wpi) call m_mult ; m_mult() m_sta h1i ; m_sta(&h1i) m_lda wi ; m_lda(wi) m_ldb wpr ; m_ldb(wpr) call m_mult ; m_mult() m_ldb h1i ; m_ldb(h1i) m_add ; m_add() m_ldb wi ; m_ldb(wi) m_add ; m_add() m_sta wi ; m_sta(&wi) mnext1 inc m ; } next m inc m jmp mloop1 mend1 nop movfp istep,WREG ; mmax=istep mov mmax, W wloop2 jmp while2 ; } end while wend2 ret ;---------------------------------------------------------------------------- ; Real FFT ; ; Algorithm from "Numerical recipes in C", manually compiled in assembler ; and adapted... ; ; Calculate FFT of a set of 256 real values stored in data[0..511] ; (2 bytes per value, MSB first). ; ; Replace these data by the positive frequency half of the FFT ; (128 frequencies, complex values). First and last frequencies (which are ; real) are in data[1] and data[2] respectively. ; ; Method : consider the 256 real values as interleaved real/imaginary parts ; of 128 complex values. Do a complex 128 points FFT, and find back the ; FFT of the real numbers from the output of the complex FFT... ; ; Nota : this method allow to do a real FFT with 30-40% less calculations ; and, more important, 50% less RAM requirement. ;---------------------------------------------------------------------------- realfft nop ; control point, N=256 (implicit) ; ------> do a complex FFT of half the number of points, odd real points ; as real data, even real points as imaginary data call fft ;-------> and find the good values from the result... ; theta=2pi/n m_ldaconst H'6488' ; m_ldaconst(3.14159265459) mov W, #128 ; m_lddiv(n>>1) mov rdiv, W call m_divi ; m_divi() m_sta theta ; m_sta(&theta) ; wpr=-2*sin(theta/2)^2 mov W, #2 ; m_lddiv(2) mov rdiv, W call m_divi ; m_divi() call m_sin ; m_sin() m_mvab ; m_mvab() call m_mult ; m_mult() m_mvab ; m_mvab() m_ldaconst H'C000' ; m_ldaconst(-2.0) call m_mult ; m_mult() m_sta wpr ; m_sta(&wpr) ; wpi=n_sin(theta) m_lda theta ; m_lda(theta) call m_sin ; m_sin() m_sta wpi ; m_sta(&wpi) ; wr=1+wpr, wi=wpi m_ldb wpr ; m_ldb(wpr) m_ldaconst H'2000' ; m_ldaconst(1.0) m_add ; m_add() m_sta wr ; m_sta(&wr) m_lda wpi ; m_lda(wpi) m_sta wi ; m_sta(&wi) mov W, #2 ; for(i=2;i<=(n>>2);i++) { mov i, W iloop3 mov W, #64 cpfsgt i jmp $+2 jmp iend3 movfp i,WREG ; i1=i+i-2 mov i1, W add i1, W mov W, #2 sub i1, W movfp i1,WREG ; i2=1+i1 mov i2, W inc i2 movfp i2,WREG ; i3=n-i2+1 mov W, /WREG mov W, ++WREG mov W, ++WREG mov i3, W mov W, ++WREG mov i4, W ; i4=1+i3 ; h1r=(data[i1]+data[i3])/2 m_ldai i1 ; m_ldai(i1) m_ldbi i3 ; m_ldbi(i3) m_add ; m_add() m_div2 ; m_div2() m_sta h1r ; m_sta(&h1r) ; h1i=(data[i2]-data[i4])/2 m_ldai i2 ; m_ldai(i2) m_ldbi i4 ; m_ldbi(i4) m_sub ; m_sub() m_div2 ; m_div2() m_sta h1i ; m_sta(&h1i) ; h2r=(data[i2]+data[i4])/2 m_ldai i2 ; m_ldai(i2) m_ldbi i4 ; m_ldbi(i4) m_add ; m_add() m_div2 ; m_div2() m_sta h2r ; m_sta(&h2r) ; h2i=-(data[i1]-data[i3])/2 m_ldai i3 ; m_ldai(i3) m_ldbi i1 ; m_ldbi(i1) m_sub ; m_sub() m_div2 ; m_div2() m_sta h2i ; m_sta(&h2i) ; data[i1]=h1r+wr*h2r-wi*h2i m_lda wi ; m_lda(wi) m_ldb h2i ; m_ldb(h2i) call m_mult ; m_mult() m_sta wtemp ; m_sta(&wtemp) m_lda wr ; m_lda(wr) m_ldb h2r ; m_ldb(h2r) call m_mult ; m_mult() m_ldb wtemp ; m_ldb(wtemp) m_sub ; m_sub() m_ldb h1r ; m_ldb(h1r) m_add ; m_add() m_stai i1 ; m_stai(i1) ; data[i2]=h1i+wr*h2i+wi*h2r m_lda wi ; m_lda(wi) m_ldb h2r ; m_ldb(h2r) call m_mult ; m_mult() m_sta wtemp ; m_sta(&wtemp) m_lda wr ; m_lda(wr) m_ldb h2i ; m_ldb(h2i) call m_mult ; m_mult() m_ldb wtemp ; m_ldb(wtemp) m_add ; m_add() m_ldb h1i ; m_ldb(h1i) m_add ; m_add() m_stai i2 ; m_stai(i2) ; data[i3]=h1r-wr*h2r+wi*h2i m_lda wr ; m_lda(wr) m_ldb h2r ; m_ldb(h2r) call m_mult ; m_mult() m_sta wtemp ; m_sta(&wtemp) m_lda wi ; m_lda(wi) m_ldb h2i ; m_ldb(h2i) call m_mult ; m_mult() m_ldb wtemp ; m_ldb(wtemp) m_sub ; m_sub() m_ldb h1r ; m_ldb(h1r) m_add ; m_add() m_stai i3 ; m_stai(i3) ; data[i4]=-h1i+wr*h2i+wi*h2r m_lda wr ; m_lda(wr) m_ldb h2i ; m_ldb(h2i) call m_mult ; m_mult() m_sta wtemp ; m_sta(&wtemp) m_lda wi ; m_lda(wi) m_ldb h2r ; m_ldb(h2r) call m_mult ; m_mult() m_ldb wtemp ; m_ldb(wtemp) m_add ; m_add() m_ldb h1i ; m_ldb(h1i) m_sub ; m_sub() m_stai i4 ; m_stai(i4) ; wtemp=wr m_lda wr ; m_lda(wr) m_sta wtemp ; m_sta(&wtemp) ; wr=wr*wpr-wi*wpi+wr m_lda wi ; m_lda(wi) m_ldb wpi ; m_ldb(wpi) call m_mult ; m_mult() m_sta h1r ; m_sta(&h1r) m_lda wr ; m_lda(wr) m_ldb wpr ; m_ldb(wpr) call m_mult ; m_mult() m_ldb h1r ; m_ldb(h1r) m_sub ; m_sub() m_ldb wr ; m_ldb(wr) m_add ; m_add() m_sta wr ; m_sta(&wr) ; wi=wi*wpr+wtemp*wpi+wi m_lda wi ; m_lda(wi) m_ldb wpr ; m_ldb(wpr) call m_mult ; m_mult() m_sta h1r ; m_sta(&h1r) m_lda wtemp ; m_lda(wtemp) m_ldb wpi ; m_ldb(wpi) call m_mult ; m_mult() m_ldb h1r ; m_ldb(h1r) m_add ; m_add() m_ldb wi ; m_ldb(wi) m_add ; m_add() m_sta wi ; m_sta(&wi) inext3 inc i ; } next i jmp iloop3 iend3 nop ; ------> special case of the 2 first data ; h1r=data[0] mov W, #0 ; m_ldai(0) mov i, W m_ldai i m_sta h1r ; m_sta(&h1r) ; data[0]=h1r+data[1] mov W, #1 ; m_ldbi(1) mov i, W m_ldbi i m_add ; m_add() mov W, #0 ; m_stai(0) mov i, W m_stai i ; data[1]=h1r-data[1] m_lda h1r ; m_lda(h1r) mov W, #1 ; m_ldbi(1) mov i, W m_ldbi i m_sub ; m_sub() mov W, #1 ; m_stai(1) mov i, W m_stai i endrft ret ;============================================================================ ; - END OF FILE - ;============================================================================ ;============================================================================ ; 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 snb WREG.6 ; select the good bank setb BSR.4 ; based on 6th bit of index and W, #%00111111 ; clear 2 MSB bits ;*** WARNING: ADDLW was expanded in three instructions! Check if previous instruction is a skip instruction. ; addlw H'20' ; add $20 (data start at $20) mov Hack, W mov W, #$20 ; add $20 (data start at $20) add W, Hack mov FSR0, W ; 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 snb WREG.6 ; select the good bank setb BSR.4 ; based on 6th bit of index and W, #%00111111 ; clear 2 MSB bits ;*** WARNING: ADDLW was expanded in three instructions! Check if previous instruction is a skip instruction. ; addlw H'20' ; add $20 (data start at $20) mov Hack, W mov W, #$20 ; add $20 (data start at $20) add W, Hack mov FSR0, W ; 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() ret ;---------------------------------------------------------------------------- ; 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() ret ;---------------------------------------------------------------------------- ; 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) clr rdiv m_ldai rdiv ; m_ldai(0) m_ldbi rdiv ; m_ldbi(0) call intpowerlin ; intpower() mov W, #0 dispbufwr ; dispbuf[0]=(unsigned char)rdiv ;--------------> General case clr i ; for (i=1;i<SLENGTH/2;i++) { inc i iloop4 nop movfp i,WREG ; i2=(i<<1) mov i2, W clrb ALUSTA.C rlcf i2,F m_ldai i2 ; m_ldai(i2) inc i2 ; m_ldbi(i2+1) m_ldbi i2 call intpowerlin ; intpower(); movfp i,WREG ; dispbuf[i]=(unsigned char)rdiv dispbufwr inext4 inc i ; } next i mov W, #128 cpfseq i jmp iloop4 ret ;---------------------------------------------------------------------------- ; powerlog : Calculate power spectrum for the complex spectrum stored ; in "data", scale it with a log scale (result from 0 ; to MAXPIXVAL) and store the result in "dispbuf" ;---------------------------------------------------------------------------- powerlog nop ;--------------> Special case of the first value (real) clr rdiv m_ldai rdiv ; m_ldai(0) m_ldbi rdiv ; m_ldbi(0) call intpowerlog ; intpower() mov W, #0 dispbufwr ; dispbuf[0]=(unsigned char)rdiv ;--------------> General case clr i ; for (i=1;i<SLENGTH/2;i++) { inc i iloop5 nop movfp i,WREG ; i2=(i<<1) mov i2, W clrb ALUSTA.C rlcf i2,F m_ldai i2 ; m_ldai(i2) inc i2 ; m_ldbi(i2+1) m_ldbi i2 call intpowerlog ; intpower(); movfp i,WREG ; dispbuf[i]=(unsigned char)rdiv dispbufwr inext5 inc i ; } next i mov W, #128 cpfseq i jmp iloop5 ret ;============================================================================ ; - END OF FILE - ;============================================================================ ;============================================================================ ; PROJECT : UPS'SPECTRUM ; ; FILE : IRQ.INC ; ; VERSION : 1.0 ; ; DESCRIPTION : ; ; Handler of the timer0 interrupt, in charge of all real time tasks, ; mainly analog signal acquisition and software video generation... ; ; WARNING : These routines are VERY time critical, in particular for the ; video generation. Do not change the duration of any routine (even by adding ; or deleting only one instruction) without a deep analysis. Effects can go ; from misaligned pixels to... loss of video synchronisation. ; The main time dependencies are indicated in the source (see "PT" checkpoints ; and "RT" comments) but I'm not sure that the list is complete ! ; ; Comment : Some of the routines may seems a little "bulk force" and ; excessively rom expensive, but think twice about the performances required ; before replacing everything by loop ! In fact, we only do manually what ; modern compilers do as part as their optimization phase... loop unrolling ! ; ;============================================================================ ; Developped & Copyrighted by Robert LACOSTE ;============================================================================ ;---------------------------------------------------------------------------- ; Management of analog acquisitions and generation of Hsync signal ; ; Check if an analog acquisition is requested by the main program. ; If so do the acquisition of 256 samples (one each 2 video scan lines, ; giving a sample rate of 31.5KHz/2=15.75KHz) ; ; Synchronisation with the main program is done through acq_request flag ; and num_sample register : ; ; Main program : ; - To launch a sampling, put acq_request=1 and reset num_sample ; - wait for acq_request to be back 0 ; ; This interrupt routine : ; - if acq_request=0 => Nothing to do ; - if acq_request=1 => Launch acquisition and put acq_request=2 ; - if acq_request=2 => Get result and store it in (num_sample) ; Increment num_sample ; If <256, put acq_request=1 (sampling period) ; else put acq_request=0 ; ; The HSync signal is generated within this routine, insuring that its length ; is constant (=30 clock cycles) and its position fixed. ; ; Warning : The duration of this routine must be CONSTANT, whatever tests ; results are ! (now, its 37 cycles) ; ; Warning : on input, bankselect should be on zone_irq ;---------------------------------------------------------------------------- manage_adc macro setb RC.4 ; set RC4 (HSync signal active) ;--> RT constraint !!! From PT1, delay >= 0.94µS=8 instr (pre-HSync blanking) ; and fixed (whatever test & branch are executed) ;--> RT checkpoint PT2 (start of HSync signal) ;--> RT checkpoint PT0A (start of ADC management) mov W, #2 ; acq_request = 2 ? cpfseq acq_request jmp adc_not2 ;--> Acq_request=2 ; save RA (because we must use a non banked memory) movpf ra, tmpi movpf ra+1, tmpi+1 ; scale ADC value (0 to 653536 -> -8192 to +8192) movlb 5 movpf ADRESL,ra+1 ; get ADC value movpf ADRESH,ra ; and scale it to our floating format clrb ALUSTA.C rrcf ra,F ; divide by 4 rrcf ra+1,F clrb ALUSTA.C rrcf ra,F rrcf ra+1,F mov W, #$20 ; substract H'2000' sub ra, W ; it's now from -1.0 to +1.0 ; store ADC value in data(num_sample) movlb 5 ; select register bank 5 movfp num_sample, WREG movlr 0 ; start with bank 0 snb WREG.7 ; select the good bank setb BSR.5 snb WREG.6 ; based on 2 first bits of WREG setb BSR.4 clrb ALUSTA.C ; multiply by 2 rlcf WREG,1 setb WREG.7 ; and set high bit (data start at $80) mov FSR0, W ; and use it as an index movfp ra,INDF0 ; to store msb value... movlb 1 clrb RC.4 ; clear RC4 (HSync signal inactive) ;--> RT constraint !!! From PT2, delay = 3.77µS=30 instr (HSync duration) ; and fixed (whatever test & branch are executed) ;--> RT checkpoint PT3 (end of HSync signal) inc FSR0 movfp ra+1,INDF0 ; ... and lsb value BANKSEL zone_irq ; reset bank register ; increment num_sample and update aca_request clr acq_request ; acq_request=0 mov W, #1 incsz num_sample ; increment num_sample mov acq_request, W ; if <>0, acq_request=1 ; restore RA movfp tmpi, ra movfp tmpi+1, ra+1 jmp end_manage_adc adc_not2 nop ; acq_request <> 2 nop nop nop nop nop nop ; delay nop's in order to be in nop ; synch with the switch case above nop nop nop nop mov W, #1 cpfseq acq_request ; acq_request=1 ? jmp adc_0 jmp adc_1 ;--> Acq_request=0 adc_0 nop ; acq=request is 0. Nothing to do nop ; except wait... nop nop nop nop nop nop movlb 1 clrb RC.4 ; clear RC4 (HSync signal inactive) ;--> RT constraint !!! From PT2, delay = 3.77µS=30 instr (HSync duration) ; and fixed (whatever test & branch are executed) ;--> RT checkpoint PT3 (end of HSync signal) nop nop nop nop nop nop nop nop nop jmp end_manage_adc ;--> Acq_request=1 adc_1 nop movlb 5 ; start ADC conversion setb ADCON0.GO mov W, #2 ; acq_request=2 mov acq_request, W nop nop movlb 1 clrb RC.4 ; clear RC4 (HSync signal inactive) ;--> RT constraint !!! From PT2, delay = 3.77µS=30 instr (HSync duration) ; and fixed (whatever test & branch are executed) ;--> RT checkpoint PT3 (end of HSync signal) nop nop nop nop nop nop nop nop nop nop nop ; and wait end_manage_adc nop endm ;--> RT constraint !!! From PT0A, delay FIXED (now 42 instructions cycles) ;---------------------------------------------------------------------------- ; Routine called on timer0 interrupt ; ; This routine is called at 31.5KHz (horizontal refresh rate for 640x350) ; and do the main real time tasks : ; ; - Registers saving ; - Analog acquisition ; - Video generation ; - Registers restoring ; ; Warning : Time from interrupt to video generation must be rigourously ; stable. ;---------------------------------------------------------------------------- it_timer movpf BSR,sv_bsr ; save BSR ;--> RT checkpoint PT0 (start of interrupt routine) BANKSEL zone_irq movpf ALUSTA,sv_alusta ; save ALUSTA mov sv_wreg, W ; save WREG movpf FSR0,sv_fsr0 ; save FSR0 movlb 0 clr RB ; switch video off ;--> RT checkpoint PT1 (start of horizontal blanking zone) movlb 1 setb RD.2 ; set RD2 (debug line : IRQ going on) mov W, #high INITTIM ; reload timer mov tmpi, W mov W, #low INITTIM mov TMR0L, W movfp tmpi,TMR0H manage_adc ; ADC management, 35 clock cycles mov W, #1 ; increment scan_line add scan_line+1, W ; (rollback to 0 done in the last's clr WREG ; line sub-routine) addwfc scan_line,F movlb 0 ; select registers bank 0 for video ; Based on scan_line value (from 1 to 449), calculate ; the address of the line management routine mov W, #low jump_table ; calculate jump address add W, scan_line+1 mov tmpi, W mov W, #high jump_table addwfc scan_line,W ;*** WARNING: PCLATH register bits are in STATUS PAx bits. Or use PAGE/IREAD if possible ; movwf PCLATH mov PCLATH, W ;--> RT constraint !!! From PT3 to first pixel display, ; delay > 1.89µS=15 instr (post HSync blanking) movfp tmpi, PCL ; and jump to it ! ; at the end of the scan line display, the called routine ; will jump back to resume_irq resume_irq movlb 1 clrb RD.2 ; clear RD2 (debug line : IRQ going on) BANKSEL zone_irq movfp sv_alusta,ALUSTA ; restore ALUSTA movfp sv_fsr0,FSR0 ; and FSR0 movfp sv_wreg,WREG ; and WREG movfp sv_bsr,BSR ; and BSR ;*** WARNING: SX saves/restores W, STATUS, and FSR automatically. ; retfie ; return from interrupt reti ; return from interrupt ;--> RT constraint !!! From PT0, delay < 30µS=240 instr (Timer0 irq period) ; it lets 240-71=169 instructions for the scan_x routines ;---------------------------------------------------------------------------- ; Jump address table ; ; For each scan line (1 to 449), calculated jump to the good management ; routine, depending on the scan line number ;---------------------------------------------------------------------------- jump_table jmp scan_blanking ; scan 000, should not occur jmp scan_vsynch_on ; scan 001, switch on VSynch jmp scan_blanking ; scan 002, vertical blanking jmp scan_vsynch_off ; scan 003, switch off VSynch jmp scan_blanking ; scan 004, vertical blanking jmp scan_blanking ; scan 005, vertical blanking jmp scan_blanking ; scan 006, vertical blanking jmp scan_blanking ; scan 007, vertical blanking jmp scan_blanking ; scan 008, vertical blanking jmp scan_blanking ; scan 009, vertical blanking jmp scan_blanking ; scan 010, vertical blanking jmp scan_blanking ; scan 011, vertical blanking jmp scan_blanking ; scan 012, vertical blanking jmp scan_blanking ; scan 013, vertical blanking jmp scan_blanking ; scan 014, vertical blanking jmp scan_blanking ; scan 015, vertical blanking jmp scan_blanking ; scan 016, vertical blanking jmp scan_blanking ; scan 017, vertical blanking jmp scan_blanking ; scan 018, vertical blanking jmp scan_blanking ; scan 019, vertical blanking jmp scan_blanking ; scan 020, vertical blanking jmp scan_blanking ; scan 021, vertical blanking jmp scan_blanking ; scan 022, vertical blanking jmp scan_blanking ; scan 023, vertical blanking jmp scan_blanking ; scan 024, vertical blanking jmp scan_blanking ; scan 025, vertical blanking jmp scan_blanking ; scan 026, vertical blanking jmp scan_blanking ; scan 027, vertical blanking jmp scan_blanking ; scan 028, vertical blanking jmp scan_blanking ; scan 029, vertical blanking jmp scan_blanking ; scan 030, vertical blanking jmp scan_blanking ; scan 031, vertical blanking jmp scan_blanking ; scan 032, vertical blanking jmp scan_blanking ; scan 033, vertical blanking jmp scan_blanking ; scan 034, vertical blanking jmp scan_blanking ; scan 035, vertical blanking jmp scan_blanking ; scan 036, vertical blanking jmp scan_blanking ; scan 037, vertical blanking jmp scan_blanking ; scan 038, vertical blanking jmp scan_blanking ; scan 039, vertical blanking jmp scan_blanking ; scan 040, vertical blanking jmp scan_blanking ; scan 041, vertical blanking jmp scan_blanking ; scan 042, vertical blanking jmp scan_blanking ; scan 043, vertical blanking jmp scan_blanking ; scan 044, vertical blanking jmp scan_blanking ; scan 045, vertical blanking jmp scan_blanking ; scan 046, vertical blanking jmp scan_blanking ; scan 047, vertical blanking jmp scan_blanking ; scan 048, vertical blanking jmp scan_blanking ; scan 049, vertical blanking jmp scan_blanking ; scan 050, vertical blanking jmp scan_blanking ; scan 051, vertical blanking jmp scan_blanking ; scan 052, vertical blanking jmp scan_blanking ; scan 053, vertical blanking jmp scan_blanking ; scan 054, vertical blanking jmp scan_blanking ; scan 055, vertical blanking jmp scan_blanking ; scan 056, vertical blanking jmp scan_blanking ; scan 057, vertical blanking jmp scan_blanking ; scan 058, vertical blanking jmp scan_blanking ; scan 059, vertical blanking jmp scan_blanking ; scan 060, vertical blanking jmp scan_blanking ; scan 061, vertical blanking jmp scan_empty ; scan 062 (sl 000), empty line jmp scan_empty ; scan 063 (sl 001), empty line jmp scan_empty ; scan 064 (sl 002), empty line jmp scan_empty ; scan 065 (sl 003), empty line jmp scan_empty ; scan 066 (sl 004), empty line jmp scan_empty ; scan 067 (sl 005), empty line jmp scan_empty ; scan 068 (sl 006), empty line jmp scan_empty ; scan 069 (sl 007), empty line jmp scan_empty ; scan 070 (sl 008), empty line jmp scan_empty ; scan 071 (sl 009), empty line jmp scan_empty ; scan 072 (sl 010), empty line jmp scan_empty ; scan 073 (sl 011), empty line jmp scan_empty ; scan 074 (sl 012), empty line jmp scan_empty ; scan 075 (sl 013), empty line jmp scan_empty ; scan 076 (sl 014), empty line jmp scan_empty ; scan 077 (sl 015), empty line jmp scan_empty ; scan 078 (sl 016), empty line jmp scan_empty ; scan 079 (sl 017), empty line jmp scan_empty ; scan 080 (sl 018), empty line jmp scan_empty ; scan 081 (sl 019), empty line jmp scan_empty ; scan 082 (sl 020), empty line jmp scan_empty ; scan 083 (sl 021), empty line jmp scan_empty ; scan 084 (sl 022), empty line jmp scan_hscalelong ; scan 085 (sl 023), h.scale long sep jmp scan_hscalelong ; scan 086 (sl 024), h.scale long sep jmp scan_hscalelong ; scan 087 (sl 025), h.scale long sep jmp scan_hscalelong ; scan 088 (sl 026), h.scale long sep jmp scan_hscalelong ; scan 089 (sl 027), h.scale long sep jmp scan_hscalelong ; scan 090 (sl 028), h.scale long sep jmp scan_hscalelong ; scan 091 (sl 029), h.scale long sep jmp scan_hscalelong ; scan 092 (sl 030), h.scale long sep jmp scan_hscaleshort ; scan 093 (sl 031), h.scale short sep jmp scan_hscaleshort ; scan 094 (sl 032), h.scale short sep jmp scan_hscaleshort ; scan 095 (sl 033), h.scale short sep jmp scan_hscaleshort ; scan 096 (sl 034), h.scale short sep jmp scan_hscaleshort ; scan 097 (sl 035), h.scale short sep jmp scan_hscaleshort ; scan 098 (sl 036), h.scale short sep jmp scan_hscaleshort ; scan 099 (sl 037), h.scale short sep jmp scan_empty ; scan 100 (sl 038), empty line jmp scan_empty ; scan 101 (sl 039), empty line jmp scan_empty ; scan 102 (sl 040), empty line jmp scan_hscaleline ; scan 103 (sl 041), h. plain line jmp scan_sepline ; scan 104 (sl 042), frequencies sep. jmp scan_freqline ; scan 105 (sl 043), freq 001 jmp scan_sepline ; scan 106 (sl 044), frequencies sep. jmp scan_freqline ; scan 107 (sl 045), freq 002 jmp scan_sepline ; scan 108 (sl 046), frequencies sep. jmp scan_freqline ; scan 109 (sl 047), freq 003 jmp scan_sepline ; scan 110 (sl 048), frequencies sep. jmp scan_freqline ; scan 111 (sl 049), freq 004 jmp scan_sepline ; scan 112 (sl 050), frequencies sep. jmp scan_freqline ; scan 113 (sl 051), freq 005 jmp scan_sepline ; scan 114 (sl 052), frequencies sep. jmp scan_freqline ; scan 115 (sl 053), freq 006 jmp scan_sepline ; scan 116 (sl 054), frequencies sep. jmp scan_freqline ; scan 117 (sl 055), freq 007 jmp scan_sepline ; scan 118 (sl 056), frequencies sep. jmp scan_freqline ; scan 119 (sl 057), freq 008 jmp scan_sepline ; scan 120 (sl 058), frequencies sep. jmp scan_freqline ; scan 121 (sl 059), freq 009 jmp scan_sepline ; scan 122 (sl 060), frequencies sep. jmp scan_freqline ; scan 123 (sl 061), freq 010 jmp scan_sepline ; scan 124 (sl 062), frequencies sep. jmp scan_freqline ; scan 125 (sl 063), freq 011 jmp scan_sepline ; scan 126 (sl 064), frequencies sep. jmp scan_freqline ; scan 127 (sl 065), freq 012 jmp scan_sepline ; scan 128 (sl 066), frequencies sep. jmp scan_freqline ; scan 129 (sl 067), freq 013 jmp scan_sepline ; scan 130 (sl 068), frequencies sep. jmp scan_freqline ; scan 131 (sl 069), freq 014 jmp scan_sepline ; scan 132 (sl 070), frequencies sep. jmp scan_freqline ; scan 133 (sl 071), freq 015 jmp scan_sepline ; scan 134 (sl 072), frequencies sep. jmp scan_freqline ; scan 135 (sl 073), freq 016 jmp scan_vscaleshort ; scan 136 (sl 074), v.scale short s. jmp scan_freqline ; scan 137 (sl 075), freq 017 jmp scan_sepline ; scan 138 (sl 076), frequencies sep. jmp scan_freqline ; scan 139 (sl 077), freq 018 jmp scan_sepline ; scan 140 (sl 078), frequencies sep. jmp scan_freqline ; scan 141 (sl 079), freq 019 jmp scan_sepline ; scan 142 (sl 080), frequencies sep. jmp scan_freqline ; scan 143 (sl 081), freq 020 jmp scan_sepline ; scan 144 (sl 082), frequencies sep. jmp scan_freqline ; scan 145 (sl 083), freq 021 jmp scan_sepline ; scan 146 (sl 084), frequencies sep. jmp scan_freqline ; scan 147 (sl 085), freq 022 jmp scan_sepline ; scan 148 (sl 086), frequencies sep. jmp scan_freqline ; scan 149 (sl 087), freq 023 jmp scan_sepline ; scan 150 (sl 088), frequencies sep. jmp scan_freqline ; scan 151 (sl 089), freq 024 jmp scan_sepline ; scan 152 (sl 090), frequencies sep. jmp scan_freqline ; scan 153 (sl 091), freq 025 jmp scan_sepline ; scan 154 (sl 092), frequencies sep. jmp scan_freqline ; scan 155 (sl 093), freq 026 jmp scan_sepline ; scan 156 (sl 094), frequencies sep. jmp scan_freqline ; scan 157 (sl 095), freq 027 jmp scan_sepline ; scan 158 (sl 096), frequencies sep. jmp scan_freqline ; scan 159 (sl 097), freq 028 jmp scan_sepline ; scan 160 (sl 098), frequencies sep. jmp scan_freqline ; scan 161 (sl 099), freq 029 jmp scan_sepline ; scan 162 (sl 100), frequencies sep. jmp scan_freqline ; scan 163 (sl 101), freq 030 jmp scan_sepline ; scan 164 (sl 102), frequencies sep. jmp scan_freqline ; scan 165 (sl 103), freq 031 jmp scan_sepline ; scan 166 (sl 104), frequencies sep. jmp scan_freqline ; scan 167 (sl 105), freq 032 jmp scan_vscaleshort ; scan 168 (sl 106), v.scale short s. jmp scan_freqline ; scan 169 (sl 107), freq 033 jmp scan_sepline ; scan 170 (sl 108), frequencies sep. jmp scan_freqline ; scan 171 (sl 109), freq 034 jmp scan_sepline ; scan 172 (sl 110), frequencies sep. jmp scan_freqline ; scan 173 (sl 111), freq 035 jmp scan_sepline ; scan 174 (sl 112), frequencies sep. jmp scan_freqline ; scan 175 (sl 113), freq 036 jmp scan_sepline ; scan 176 (sl 114), frequencies sep. jmp scan_freqline ; scan 177 (sl 115), freq 037 jmp scan_sepline ; scan 178 (sl 116), frequencies sep. jmp scan_freqline ; scan 179 (sl 117), freq 038 jmp scan_sepline ; scan 180 (sl 118), frequencies sep. jmp scan_freqline ; scan 181 (sl 119), freq 039 jmp scan_sepline ; scan 182 (sl 120), frequencies sep. jmp scan_freqline ; scan 183 (sl 121), freq 040 jmp scan_sepline ; scan 184 (sl 122), frequencies sep. jmp scan_freqline ; scan 185 (sl 123), freq 041 jmp scan_sepline ; scan 186 (sl 124), frequencies sep. jmp scan_freqline ; scan 187 (sl 125), freq 042 jmp scan_sepline ; scan 188 (sl 126), frequencies sep. jmp scan_freqline ; scan 189 (sl 127), freq 043 jmp scan_sepline ; scan 190 (sl 128), frequencies sep. jmp scan_freqline ; scan 191 (sl 129), freq 044 jmp scan_sepline ; scan 192 (sl 130), frequencies sep. jmp scan_freqline ; scan 193 (sl 131), freq 045 jmp scan_sepline ; scan 194 (sl 132), frequencies sep. jmp scan_freqline ; scan 195 (sl 133), freq 046 jmp scan_sepline ; scan 196 (sl 134), frequencies sep. jmp scan_freqline ; scan 197 (sl 135), freq 047 jmp scan_sepline ; scan 198 (sl 136), frequencies sep. jmp scan_freqline ; scan 199 (sl 137), freq 048 jmp scan_vscaleshort ; scan 200 (sl 138), v.scale short s. jmp scan_freqline ; scan 201 (sl 139), freq 049 jmp scan_sepline ; scan 202 (sl 140), frequencies sep. jmp scan_freqline ; scan 203 (sl 141), freq 050 jmp scan_sepline ; scan 204 (sl 142), frequencies sep. jmp scan_freqline ; scan 205 (sl 143), freq 051 jmp scan_sepline ; scan 206 (sl 144), frequencies sep. jmp scan_freqline ; scan 207 (sl 145), freq 052 jmp scan_sepline ; scan 208 (sl 146), frequencies sep. jmp scan_freqline ; scan 209 (sl 147), freq 053 jmp scan_sepline ; scan 210 (sl 148), frequencies sep. jmp scan_freqline ; scan 211 (sl 149), freq 054 jmp scan_sepline ; scan 212 (sl 150), frequencies sep. jmp scan_freqline ; scan 213 (sl 151), freq 055 jmp scan_sepline ; scan 214 (sl 152), frequencies sep. jmp scan_freqline ; scan 215 (sl 153), freq 056 jmp scan_sepline ; scan 216 (sl 154), frequencies sep. jmp scan_freqline ; scan 217 (sl 155), freq 057 jmp scan_sepline ; scan 218 (sl 156), frequencies sep. jmp scan_freqline ; scan 219 (sl 157), freq 058 jmp scan_sepline ; scan 220 (sl 158), frequencies sep. jmp scan_freqline ; scan 221 (sl 159), freq 059 jmp scan_sepline ; scan 222 (sl 160), frequencies sep. jmp scan_freqline ; scan 223 (sl 161), freq 060 jmp scan_sepline ; scan 224 (sl 162), frequencies sep. jmp scan_freqline ; scan 225 (sl 163), freq 061 jmp scan_sepline ; scan 226 (sl 164), frequencies sep. jmp scan_freqline ; scan 227 (sl 165), freq 062 jmp scan_sepline ; scan 228 (sl 166), frequencies sep. jmp scan_freqline ; scan 229 (sl 167), freq 063 jmp scan_sepline ; scan 230 (sl 168), frequencies sep. jmp scan_freqline ; scan 231 (sl 169), freq 064 jmp scan_vscaleshort ; scan 232 (sl 170), v.scale short s. jmp scan_freqline ; scan 233 (sl 171), freq 065 jmp scan_sepline ; scan 234 (sl 172), frequencies sep. jmp scan_freqline ; scan 235 (sl 173), freq 066 jmp scan_sepline ; scan 236 (sl 174), frequencies sep. jmp scan_freqline ; scan 237 (sl 175), freq 067 jmp scan_sepline ; scan 238 (sl 176), frequencies sep. jmp scan_freqline ; scan 239 (sl 177), freq 068 jmp scan_sepline ; scan 240 (sl 178), frequencies sep. jmp scan_freqline ; scan 241 (sl 179), freq 069 jmp scan_sepline ; scan 242 (sl 180), frequencies sep. jmp scan_freqline ; scan 243 (sl 181), freq 070 jmp scan_sepline ; scan 244 (sl 182), frequencies sep. jmp scan_freqline ; scan 245 (sl 183), freq 071 jmp scan_sepline ; scan 246 (sl 184), frequencies sep. jmp scan_freqline ; scan 247 (sl 185), freq 072 jmp scan_sepline ; scan 248 (sl 186), frequencies sep. jmp scan_freqline ; scan 249 (sl 187), freq 073 jmp scan_sepline ; scan 250 (sl 188), frequencies sep. jmp scan_freqline ; scan 251 (sl 189), freq 074 jmp scan_sepline ; scan 252 (sl 190), frequencies sep. jmp scan_freqline ; scan 253 (sl 191), freq 075 jmp scan_sepline ; scan 254 (sl 192), frequencies sep. jmp scan_freqline ; scan 255 (sl 193), freq 076 jmp scan_sepline ; scan 256 (sl 194), frequencies sep. jmp scan_freqline ; scan 257 (sl 195), freq 077 jmp scan_sepline ; scan 258 (sl 196), frequencies sep. jmp scan_freqline ; scan 259 (sl 197), freq 078 jmp scan_sepline ; scan 260 (sl 198), frequencies sep. jmp scan_freqline ; scan 261 (sl 199), freq 079 jmp scan_sepline ; scan 262 (sl 200), frequencies sep. jmp scan_freqline ; scan 263 (sl 201), freq 080 jmp scan_vscalelong ; scan 264 (sl 202), v.scale long s. jmp scan_freqline ; scan 265 (sl 203), freq 081 jmp scan_sepline ; scan 266 (sl 204), frequencies sep. jmp scan_freqline ; scan 267 (sl 205), freq 082 jmp scan_sepline ; scan 268 (sl 206), frequencies sep. jmp scan_freqline ; scan 269 (sl 207), freq 083 jmp scan_sepline ; scan 270 (sl 208), frequencies sep. jmp scan_freqline ; scan 271 (sl 209), freq 084 jmp scan_sepline ; scan 272 (sl 210), frequencies sep. jmp scan_freqline ; scan 273 (sl 211), freq 085 jmp scan_sepline ; scan 274 (sl 212), frequencies sep. jmp scan_freqline ; scan 275 (sl 213), freq 086 jmp scan_sepline ; scan 276 (sl 214), frequencies sep. jmp scan_freqline ; scan 277 (sl 215), freq 087 jmp scan_sepline ; scan 278 (sl 216), frequencies sep. jmp scan_freqline ; scan 279 (sl 217), freq 088 jmp scan_sepline ; scan 280 (sl 218), frequencies sep. jmp scan_freqline ; scan 281 (sl 219), freq 089 jmp scan_sepline ; scan 282 (sl 220), frequencies sep. jmp scan_freqline ; scan 283 (sl 221), freq 090 jmp scan_sepline ; scan 284 (sl 222), frequencies sep. jmp scan_freqline ; scan 285 (sl 223), freq 091 jmp scan_sepline ; scan 286 (sl 224), frequencies sep. jmp scan_freqline ; scan 287 (sl 225), freq 092 jmp scan_sepline ; scan 288 (sl 226), frequencies sep. jmp scan_freqline ; scan 289 (sl 227), freq 093 jmp scan_sepline ; scan 290 (sl 228), frequencies sep. jmp scan_freqline ; scan 291 (sl 229), freq 094 jmp scan_sepline ; scan 292 (sl 230), frequencies sep. jmp scan_freqline ; scan 293 (sl 231), freq 095 jmp scan_sepline ; scan 294 (sl 232), frequencies sep. jmp scan_freqline ; scan 295 (sl 233), freq 096 jmp scan_vscaleshort ; scan 296 (sl 234), v.scale short s. jmp scan_freqline ; scan 297 (sl 235), freq 097 jmp scan_sepline ; scan 298 (sl 236), frequencies sep. jmp scan_freqline ; scan 299 (sl 237), freq 098 jmp scan_sepline ; scan 300 (sl 238), frequencies sep. jmp scan_freqline ; scan 301 (sl 239), freq 099 jmp scan_sepline ; scan 302 (sl 240), frequencies sep. jmp scan_freqline ; scan 303 (sl 241), freq 100 jmp scan_sepline ; scan 304 (sl 242), frequencies sep. jmp scan_freqline ; scan 305 (sl 243), freq 101 jmp scan_sepline ; scan 306 (sl 244), frequencies sep. jmp scan_freqline ; scan 307 (sl 245), freq 102 jmp scan_sepline ; scan 308 (sl 246), frequencies sep. jmp scan_freqline ; scan 309 (sl 247), freq 103 jmp scan_sepline ; scan 310 (sl 248), frequencies sep. jmp scan_freqline ; scan 311 (sl 249), freq 104 jmp scan_sepline ; scan 312 (sl 250), frequencies sep. jmp scan_freqline ; scan 313 (sl 251), freq 105 jmp scan_sepline ; scan 314 (sl 252), frequencies sep. jmp scan_freqline ; scan 315 (sl 253), freq 106 jmp scan_sepline ; scan 316 (sl 254), frequencies sep. jmp scan_freqline ; scan 317 (sl 255), freq 107 jmp scan_sepline ; scan 318 (sl 256), frequencies sep. jmp scan_freqline ; scan 319 (sl 257), freq 108 jmp scan_sepline ; scan 320 (sl 258), frequencies sep. jmp scan_freqline ; scan 321 (sl 259), freq 109 jmp scan_sepline ; scan 322 (sl 260), frequencies sep. jmp scan_freqline ; scan 323 (sl 261), freq 110 jmp scan_sepline ; scan 324 (sl 262), frequencies sep. jmp scan_freqline ; scan 325 (sl 263), freq 111 jmp scan_sepline ; scan 326 (sl 264), frequencies sep. jmp scan_freqline ; scan 327 (sl 265), freq 112 jmp scan_vscaleshort ; scan 328 (sl 266), v.scale short s. jmp scan_freqline ; scan 329 (sl 267), freq 113 jmp scan_sepline ; scan 330 (sl 268), frequencies sep. jmp scan_freqline ; scan 331 (sl 269), freq 114 jmp scan_sepline ; scan 332 (sl 270), frequencies sep. jmp scan_freqline ; scan 333 (sl 271), freq 115 jmp scan_sepline ; scan 334 (sl 272), frequencies sep. jmp scan_freqline ; scan 335 (sl 273), freq 116 jmp scan_sepline ; scan 336 (sl 274), frequencies sep. jmp scan_freqline ; scan 337 (sl 275), freq 117 jmp scan_sepline ; scan 338 (sl 276), frequencies sep. jmp scan_freqline ; scan 339 (sl 277), freq 118 jmp scan_sepline ; scan 340 (sl 278), frequencies sep. jmp scan_freqline ; scan 341 (sl 279), freq 119 jmp scan_sepline ; scan 342 (sl 280), frequencies sep. jmp scan_freqline ; scan 343 (sl 281), freq 120 jmp scan_sepline ; scan 344 (sl 282), frequencies sep. jmp scan_freqline ; scan 345 (sl 283), freq 121 jmp scan_sepline ; scan 346 (sl 284), frequencies sep. jmp scan_freqline ; scan 347 (sl 285), freq 122 jmp scan_sepline ; scan 348 (sl 286), frequencies sep. jmp scan_freqline ; scan 349 (sl 287), freq 123 jmp scan_sepline ; scan 350 (sl 288), frequencies sep. jmp scan_freqline ; scan 351 (sl 289), freq 124 jmp scan_sepline ; scan 352 (sl 290), frequencies sep. jmp scan_freqline ; scan 353 (sl 291), freq 125 jmp scan_sepline ; scan 354 (sl 292), frequencies sep. jmp scan_freqline ; scan 355 (sl 293), freq 126 jmp scan_sepline ; scan 356 (sl 294), frequencies sep. jmp scan_freqline ; scan 357 (sl 295), freq 127 jmp scan_sepline ; scan 358 (sl 296), frequencies sep. jmp scan_empty ; scan 359 (sl 297), empty line jmp scan_empty ; scan 360 (sl 298), empty line jmp scan_empty ; scan 361 (sl 299), empty line jmp scan_empty ; scan 362 (sl 300), empty line jmp scan_empty ; scan 363 (sl 301), empty line jmp scan_empty ; scan 364 (sl 302), empty line jmp scan_empty ; scan 365 (sl 303), empty line jmp scan_empty ; scan 366 (sl 304), empty line jmp scan_empty ; scan 367 (sl 305), empty line jmp scan_empty ; scan 368 (sl 306), empty line jmp scan_empty ; scan 369 (sl 307), empty line jmp scan_empty ; scan 370 (sl 308), empty line jmp scan_empty ; scan 371 (sl 309), empty line jmp scan_empty ; scan 372 (sl 310), empty line jmp scan_empty ; scan 373 (sl 311), empty line jmp scan_empty ; scan 374 (sl 312), empty line jmp scan_empty ; scan 375 (sl 313), empty line jmp scan_empty ; scan 376 (sl 314), empty line jmp scan_empty ; scan 377 (sl 315), empty line jmp scan_empty ; scan 378 (sl 316), empty line jmp scan_empty ; scan 379 (sl 317), empty line jmp scan_empty ; scan 380 (sl 318), empty line jmp scan_empty ; scan 381 (sl 319), empty line jmp scan_empty ; scan 382 (sl 320), empty line jmp scan_empty ; scan 383 (sl 321), empty line jmp scan_empty ; scan 384 (sl 322), empty line jmp scan_empty ; scan 385 (sl 323), empty line jmp scan_empty ; scan 386 (sl 324), empty line jmp scan_titlempty ; scan 387 (sl 325), empty title jmp scan_titlempty ; scan 388 (sl 326), empty title jmp scan_titlempty ; scan 389 (sl 327), empty title jmp scan_titlempty ; scan 390 (sl 328), empty title jmp scan_titlempty ; scan 391 (sl 329), empty title jmp scan_titlempty ; scan 392 (sl 330), empty title jmp scan_title0 ; scan 393 (sl 331), title line 0 jmp scan_title0 ; scan 394 (sl 332), title line 0 jmp scan_title1 ; scan 395 (sl 333), title line 1 jmp scan_title1 ; scan 396 (sl 334), title line 1 jmp scan_title2 ; scan 397 (sl 335), title line 2 jmp scan_title2 ; scan 398 (sl 336), title line 2 jmp scan_title3 ; scan 399 (sl 337), title line 3 jmp scan_title3 ; scan 400 (sl 338), title line 3 jmp scan_title4 ; scan 401 (sl 339), title line 4 jmp scan_title4 ; scan 402 (sl 340), title line 4 jmp scan_title5 ; scan 403 (sl 341), title line 5 jmp scan_title5 ; scan 404 (sl 342), title line 5 jmp scan_title6 ; scan 405 (sl 343), title line 6 jmp scan_title6 ; scan 406 (sl 344), title line 6 jmp scan_titlempty ; scan 407 (sl 345), empty title jmp scan_titlempty ; scan 408 (sl 346), empty title jmp scan_titlempty ; scan 409 (sl 347), empty title jmp scan_titlempty ; scan 410 (sl 348), empty title jmp scan_titlempty ; scan 411 (sl 349), empty title jmp scan_blanking ; scan 412, vertical blanking jmp scan_blanking ; scan 413, vertical blanking jmp scan_blanking ; scan 414, vertical blanking jmp scan_blanking ; scan 415, vertical blanking jmp scan_blanking ; scan 416, vertical blanking jmp scan_blanking ; scan 417, vertical blanking jmp scan_blanking ; scan 418, vertical blanking jmp scan_blanking ; scan 419, vertical blanking jmp scan_blanking ; scan 420, vertical blanking jmp scan_blanking ; scan 421, vertical blanking jmp scan_blanking ; scan 422, vertical blanking jmp scan_blanking ; scan 423, vertical blanking jmp scan_blanking ; scan 424, vertical blanking jmp scan_blanking ; scan 425, vertical blanking jmp scan_blanking ; scan 426, vertical blanking jmp scan_blanking ; scan 427, vertical blanking jmp scan_blanking ; scan 428, vertical blanking jmp scan_blanking ; scan 429, vertical blanking jmp scan_blanking ; scan 430, vertical blanking jmp scan_blanking ; scan 431, vertical blanking jmp scan_blanking ; scan 432, vertical blanking jmp scan_blanking ; scan 433, vertical blanking jmp scan_blanking ; scan 434, vertical blanking jmp scan_blanking ; scan 435, vertical blanking jmp scan_blanking ; scan 436, vertical blanking jmp scan_blanking ; scan 437, vertical blanking jmp scan_blanking ; scan 438, vertical blanking jmp scan_blanking ; scan 439, vertical blanking jmp scan_blanking ; scan 440, vertical blanking jmp scan_blanking ; scan 441, vertical blanking jmp scan_blanking ; scan 442, vertical blanking jmp scan_blanking ; scan 443, vertical blanking jmp scan_blanking ; scan 444, vertical blanking jmp scan_blanking ; scan 445, vertical blanking jmp scan_blanking ; scan 446, vertical blanking jmp scan_blanking ; scan 447, vertical blanking jmp scan_blanking ; scan 448, vertical blanking jmp scan_rstscanl ; scan 449, reset scan_line ;---------------------------------------------------------------------------- ; Soft generation of a vertical blanking line ; ; Warning : all scan_X routines should execute in less than 169 instructions ;---------------------------------------------------------------------------- scan_blanking jmp resume_irq ; Nothing to do as video already off ! ;---------------------------------------------------------------------------- ; Soft generation of a vertical blanking line with switch on of Vsynch ; ; Warning : all scan_X routines should execute in less than 169 instructions ;---------------------------------------------------------------------------- scan_vsynch_on movlb 1 clrb RC.6 ; RC6=0 (Vsynch active) inc frame_num ; increment frame number jmp resume_irq ;---------------------------------------------------------------------------- ; Soft generation of a vertical blanking line with switch off of Vsynch ; ; Warning : all scan_X routines should execute in less than 169 instructions ;---------------------------------------------------------------------------- scan_vsynch_off movlb 1 setb RC.6 ; RC6=1 (Vsynch inactive) jmp resume_irq ;---------------------------------------------------------------------------- ; Soft generation of a blank screen line (background color) ; ; Warning : all scan_X routines should execute in less than 169 instructions ;---------------------------------------------------------------------------- scan_empty movlb 0 mov W, #BKG_COLOR mov RB, W ; set background color jmp resume_irq ;---------------------------------------------------------------------------- ; Soft generation of a frequency line ; ; Warning : all scan_X routines should execute in less than 169 instructions ;---------------------------------------------------------------------------- scan_freqline movlb 0 mov W, #BKG_COLOR mov RB, W ; set background color mov W, #103 ; calculate frequency number mov W, scan_line+1-w ; (=(scan_line-103)/2) mov tmpi, W clrb ALUSTA.C rrcf tmpi,W dispbufrd ; read display buffer value (8 cycles) and W, #%01111111 ; be sure it is <128 mov tmpi, W ; and store it in tmpi ;*** WARNING: Manual replacement required for "SUBLW k" instruction (w = k - w). Check if previous instruction is a skip instruction. sublw low endfreqline ; calculate jump address mov tmpi2+1, W ; (endfreqline-freq value) mov W, #high endfreqline ; store msb in PCLATH and lsb in tmpi2+1 mov tmpi2, W clr WREG subwfb tmpi2,F movfp tmpi2,PCLATH mov W, #BKG_COLOR mov tmpcolor, W mov W, #SLINE_COLOR mov RB, W ; draw vertical line movfp tmpcolor,PORTB ; and return to background color clr WREG cpfsgt tmpi ; if value 0 jmp resume_irq ; return mov W, #FREQ_COLOR ; else mov RB, W ; draw frequency line movfp tmpi2+1,PCL ; and jump to precalculated address nop nop start_wait128 nop nop ; 128 nop's nop ; in order to have a cycle per cycle nop ; delay, a jump is done to the nop ; precalculated nop in this list ! nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop endfreqline mov W, #BKG_COLOR mov RB, W ; and return to background color jmp resume_irq ;---------------------------------------------------------------------------- ; Soft generation of a separating line between 2 frequency lines ; ; Warning : all scan_X routines should execute in less than 169 instructions ;---------------------------------------------------------------------------- scan_sepline movlb 0 mov W, #BKG_COLOR mov RB, W ; set background color nop nop nop ; serie of nop's in order to nop ; be sure that the vertical nop ; line will be aligned with ; the one for frequency lines ! nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop mov W, #BKG_COLOR mov tmpcolor, W mov W, #SLINE_COLOR mov RB, W ; draw vertical line movfp tmpcolor,PORTB ; and return to background color jmp resume_irq ;---------------------------------------------------------------------------- ; Soft generation of a separating line with a "short" scale indicator ; ; Warning : all scan_X routines should execute in less than 169 instructions ;---------------------------------------------------------------------------- scan_vscaleshort movlb 0 mov W, #BKG_COLOR mov RB, W ; set background color nop nop nop ; serie of nop's in order to nop ; be sure that the vertical nop ; line will be aligned with ; the one for frequency lines ! nop nop nop nop nop nop nop nop nop nop nop nop nop mov W, #SHORTS_COLOR mov RB, W ; draw the small indicator nop mov W, #BKG_COLOR mov tmpcolor, W mov RB, W ; return to background color mov W, #SLINE_COLOR mov RB, W ; draw vertical line movfp tmpcolor,PORTB ; and return to background color jmp resume_irq ;---------------------------------------------------------------------------- ; Soft generation of a separating line with a "long" scale indicator ; ; Warning : all scan_X routines should execute in less than 169 instructions ;---------------------------------------------------------------------------- scan_vscalelong movlb 0 mov W, #BKG_COLOR mov RB, W ; set background color nop nop nop ; serie of nop's in order to nop ; be sure that the vertical nop ; line will be aligned with ; the one for frequency lines ! nop nop nop nop nop nop nop nop nop nop nop mov W, #LONGS_COLOR mov RB, W ; draw the long indicator nop nop nop mov W, #BKG_COLOR mov tmpcolor, W mov RB, W ; return to background color mov W, #SLINE_COLOR mov RB, W ; draw vertical line movfp tmpcolor,PORTB ; and return to background color jmp resume_irq ;---------------------------------------------------------------------------- ; Soft generation of the horizontal scale "long" steps ; ; Warning : all scan_X routines should execute in less than 169 instructions ;---------------------------------------------------------------------------- scan_hscalelong movlb 0 mov W, #BKG_COLOR mov RB, W ; set background color mov tmpi2, W ; save color for background mov W, #LONGS_COLOR mov tmpi, W ; save color for long steps drawing mov W, #BKG_COLOR mov tmpi+1, W ; save color for short steps drawing movlb 0 snb RB.7 ; log mode ? jmp scale_lin_m ; if not, draw lin scale jmp scale_log_m ; else draw log scale scale_lin_m nop ; time correction for btfsc scale_lin_m2 nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop movfp tmpi,PORTB ;col 0 -> long movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB ;col 10 movfp tmpi2,PORTB movfp tmpi+1,PORTB ;-> short movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB ;col20 movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi+1,PORTB ;->short movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB ;col30 movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi+1,PORTB ;->short movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB ;col 40 movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi+1,PORTB ;->short movfp tmpi2,PORTB movfp tmpi2,PORTB ;col 50 movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi,PORTB ;col 60->long movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB ;col 70 movfp tmpi2,PORTB movfp tmpi+1,PORTB ;->short movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB ;col 80 movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi+1,PORTB ;->short movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB ;col 90 movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi+1,PORTB ;->short movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB ;col 100 movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi+1,PORTB ;->short movfp tmpi2,PORTB movfp tmpi2,PORTB ;col 110 movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi,PORTB ;col 120->long movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB ;col 127 jmp resume_irq scale_log_m nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop movfp tmpi,PORTB ;col 0->long movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB ;col 10 movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi+1,PORTB ;->short movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB ;col20 movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi+1,PORTB ;->short movfp tmpi2,PORTB movfp tmpi2,PORTB ;col30 movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi+1,PORTB ;->short movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi,PORTB ;col 40->long movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB ;col 50 movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi+1,PORTB ;->short movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB ;col 60 movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi+1,PORTB ;->short movfp tmpi2,PORTB movfp tmpi2,PORTB ;col 70 movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi+1,PORTB ;->short movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi,PORTB ;col 80->long movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB ;col 90 movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi+1,PORTB ;->short movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB ;col 100 movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi+1,PORTB ;->short movfp tmpi2,PORTB movfp tmpi2,PORTB ;col 110 movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi+1,PORTB ;->short movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi,PORTB ;col 120->long movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB movfp tmpi2,PORTB ;col 127 jmp resume_irq ;---------------------------------------------------------------------------- ; Soft generation of the horizontal scale "short" steps ; ; Warning : all scan_X routines should execute in less than 169 instructions ;---------------------------------------------------------------------------- scan_hscaleshort movlb 0 mov W, #BKG_COLOR mov RB, W ; set background color mov tmpi2, W ; save color for background mov W, #LONGS_COLOR mov tmpi, W ; save color for long steps drawing mov W, #SHORTS_COLOR mov tmpi+1, W ; save color for short steps drawing movlb 0 snb RB.7 ; log mode ? jmp scale_lin_m ; if not, draw lin scale jmp scale_log_m ; else draw log scale ;---------------------------------------------------------------------------- ; Soft generation of the horizontal scale plain line ; ; Warning : all scan_X routines should execute in less than 169 instructions ;---------------------------------------------------------------------------- scan_hscaleline movlb 0 mov W, #BKG_COLOR mov RB, W ; set background color nop nop nop ; serie of nop's in order to nop ; be sure that the vertical nop ; line will be aligned with ; the one for frequency lines ! nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop mov W, #SLINE_COLOR mov RB, W ; draw vertical line jmp start_wait128 ; and wait for end of active line ;---------------------------------------------------------------------------- ; Soft generation of a blank screen line (background title color) ; ; Warning : all scan_X routines should execute in less than 169 instructions ;---------------------------------------------------------------------------- scan_titlempty movlb 0 mov W, #BKGTITLE_COLOR mov RB, W ; set background color jmp resume_irq ;---------------------------------------------------------------------------- ; Soft generation of the title lines ; ; Warning : all scan_X routines should execute in less than 169 instructions ;---------------------------------------------------------------------------- ; Title content : ; * **** ***** *** * *** ***** ***** *** ***** **** * * * * * ; *** * * * * * * * * * * * * * * * * * * ** ** *** ; ***** * * * * * * * * * * * * * * * * * ***** ; ******* **** * * *** ***** *** * * **** * * * * ******* ; ********* * * * * * * * * * * * * * * ********* ; *********** * * * * * * * * * * * * * * * * * *********** ; ************* * ***** *** *** * ***** *** * * * *** * * ************* ; ; Hold sign content : ; ; * * * * ; * * * * ; * ***** * ; * * * * ; * * * * ; ; The following routines display each line of the previous strings, scan line ; per scan line. No other way to do cycle per cycle video generation (of course ; it's possible to implement a character set map, but not useful in this case) ; ; Of course the following routines where generated automaticaly ! (seems like a ; compiler job, no ?) ; Generation of title0 scan_title0 movlb 0 mov W, #BKGTITLE_COLOR mov RB, W ;set background color mov W, #TITLE_COLOR ;store title color mov tmpi+1, W ;in tmpi+1 mov W, #BKGTITLE_COLOR ;and background color mov tmpi, W ;in tmpi movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB ;reset to background color jmp resume_irq ;and return ; Generation of title1 scan_title1 movlb 0 mov W, #BKGTITLE_COLOR mov RB, W ;set background color mov W, #TITLE_COLOR ;store title color mov tmpi+1, W ;in tmpi+1 mov W, #BKGTITLE_COLOR ;and background color mov tmpi, W ;in tmpi movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB ;reset to background color movlb 0 snb RB.6 ;mode hold ? jmp resume_irq ;if not, return snb frame_num.5 ;blinking test jmp resume_irq ;if off return mov W, #HOLD_COLOR ;store hold color mov tmpi+1, W ;in tmpi+1 movfp tmpi,PORTB ;and display "hold" sign movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB movfp tmpi,PORTB movfp tmpi,PORTB jmp resume_irq ;and return ; Generation of title2 scan_title2 movlb 0 mov W, #BKGTITLE_COLOR mov RB, W ;set background color mov W, #TITLE_COLOR ;store title color mov tmpi+1, W ;in tmpi+1 mov W, #BKGTITLE_COLOR ;and background color mov tmpi, W ;in tmpi movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB ;reset to background color movlb 0 snb RB.6 ;mode hold ? jmp resume_irq ;if not, return snb frame_num.5 ;blinking test jmp resume_irq ;if off return mov W, #HOLD_COLOR ;store hold color mov tmpi+1, W ;in tmpi+1 movfp tmpi,PORTB ;and display "hold" sign movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB movfp tmpi,PORTB jmp resume_irq ;and return ; Generation of title3 scan_title3 movlb 0 mov W, #BKGTITLE_COLOR mov RB, W ;set background color mov W, #TITLE_COLOR ;store title color mov tmpi+1, W ;in tmpi+1 mov W, #BKGTITLE_COLOR ;and background color mov tmpi, W ;in tmpi movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB ;reset to background color movlb 0 snb RB.6 ;mode hold ? jmp resume_irq ;if not, return snb frame_num.5 ;blinking test jmp resume_irq ;if off return mov W, #HOLD_COLOR ;store hold color mov tmpi+1, W ;in tmpi+1 movfp tmpi,PORTB ;and display "hold" sign movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB movfp tmpi+1,PORTB movfp tmpi+1,PORTB movfp tmpi+1,PORTB movfp tmpi+1,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB movfp tmpi,PORTB jmp resume_irq ;and return ; Generation of title4 scan_title4 movlb 0 mov W, #BKGTITLE_COLOR mov RB, W ;set background color mov W, #TITLE_COLOR ;store title color mov tmpi+1, W ;in tmpi+1 mov W, #BKGTITLE_COLOR ;and background color mov tmpi, W ;in tmpi movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB ;reset to background color movlb 0 snb RB.6 ;mode hold ? jmp resume_irq ;if not, return snb frame_num.5 ;blinking test jmp resume_irq ;if off return mov W, #HOLD_COLOR ;store hold color mov tmpi+1, W ;in tmpi+1 movfp tmpi,PORTB ;and display "hold" sign movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB movfp tmpi,PORTB jmp resume_irq ;and return ; Generation of title5 scan_title5 movlb 0 mov W, #BKGTITLE_COLOR mov RB, W ;set background color mov W, #TITLE_COLOR ;store title color mov tmpi+1, W ;in tmpi+1 mov W, #BKGTITLE_COLOR ;and background color mov tmpi, W ;in tmpi movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB ;reset to background color movlb 0 snb RB.6 ;mode hold ? jmp resume_irq ;if not, return snb frame_num.5 ;blinking test jmp resume_irq ;if off return mov W, #HOLD_COLOR ;store hold color mov tmpi+1, W ;in tmpi+1 movfp tmpi,PORTB ;and display "hold" sign movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB movfp tmpi,PORTB movfp tmpi,PORTB jmp resume_irq ;and return ; Generation of title6 scan_title6 movlb 0 mov W, #BKGTITLE_COLOR mov RB, W ;set background color mov W, #TITLE_COLOR ;store title color mov tmpi+1, W ;in tmpi+1 mov W, #BKGTITLE_COLOR ;and background color mov tmpi, W ;in tmpi movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi,PORTB movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi+1,PORTB ;Pixel on movfp tmpi,PORTB ;reset to background color jmp resume_irq ;and return ;---------------------------------------------------------------------------- ; Soft generation of a vertical blanking line with scan_line reset ; ; Warning : all scan_X routines should execute in less than 169 instructions ;---------------------------------------------------------------------------- scan_rstscanl clr scan_line ; reset scanline (will be incremented clr scan_line+1 ; to 1 at next interrupt) jmp resume_irq ;============================================================================ ; - END OF FILE - ;============================================================================