divert(-1) # SynDEx generic executive kernel for the Microchip PIC18F2680 microcontroller ifdef(`syndex.m4x_already_included',,`errprint( __file__:__line__: m4: syndex.m4x must be included before __file__! )m4exit(1)') ifdef( __file__`_already_included',`error_(`already included')m4exit(1)', `define(__file__`_already_included')') # ----------------------------------------------------------------------------- # L A N G U A G E # ----------------------------------------------------------------------------- define(`lang_',`PIC18F2680') # ----------------------------------------------------------------------------- # C O M M E N T S # ----------------------------------------------------------------------------- # comment{}comment MPLAB-style multi-line comments: define(`comment_',`changequote({,})patsubst({{$1}},{^},{; })changequote') # _(codeline) define(`_',` ifdef(`NOindent',`undefine(`NOindent')',`indentString')$@')dnl define(`indentString')dnl define(`indent_',`ifelse( $1,+,`pushdef(`indentString', indentString` ')', $1,-,`popdef(`indentString')ifdef(`indentString',,`define(`indentString')'dnl `error_(`more `indent_(-)' than `indent_(+)'')')', `error_(`expected `+' or `-' as argument for `indent_'')')') # ----------------------------------------------------------------------------- # D I R E C T I V E S # ----------------------------------------------------------------------------- define(`define_',``#'define') define(`include_',``#'include') # beginLoop_(reg,size) define(`beginLoop_',`dnl pushdef(`LOOPSIZE_',$2)dnl ifelse($2,1,,`dnl ifelse(eval($2<256),1,`dnl pushdef(`LOOPREG_',`$1')dnl _(`movlw .$2')dnl _(`movwf $1')')dnl pushtag(`op')dnl define(`NOindent')_(tag_`:')')') # endLoop_(FSR, label) define(`endLoop_', `dnl ifelse(LOOPSIZE_,1,,`dnl ifelse(eval(LOOPSIZE_<256),1,`dnl _(`decfsz 'LOOPREG_)dnl _(`bra 'tag_)dnl popdef(`LOOPREG_')',`dnl _(`movlw high($2+.'LOOPSIZE_`)')dnl _(`cpfseq $1H')dnl _(`bra 'tag_)dnl _(`movlw low($2+.'LOOPSIZE_`)')dnl _(`cpfseq $1L')dnl _(`bra 'tag_)')dnl poptag(`op')')dnl popdef(`LOOPSIZE_')') # ----------------------------------------------------------------------------- # D A T A T Y P E S # ----------------------------------------------------------------------------- typedef_(`bool', 1) typedef_(`char', 1) typedef_(`short', 2) typedef_(`int', 4) # ----------------------------------------------------------------------------- # M E M O R Y A L L O C A T I O N # ----------------------------------------------------------------------------- # basicAlloc_(label, memoryBank) define(`acount_',0) define(`basicAlloc_',`dnl define(NOindent)_(`$1 equ .'acount_)dnl ifelse(eval(acount_>=3328),1,`error_(`memory overflow!')')dnl define(`$1_base_',acount_)dnl define(`acount_',eval(acount_+$1_size_*$1_type_()_size_))') # basicAlias_(newLabel,oldLabel[,offset=0]) # Makes an equivalence between newLabel and oldLabel+charOffset define(`basicAlias_',`define(`NOindent')dnl _(define_` $1 'ifelse($3,,`$2',`$2+$3*$2_type_()_size_()'))') # ----------------------------------------------------------------------------- # M E M O R Y I N I T I A L I Z A T I O N # ----------------------------------------------------------------------------- # zero_(destLabel) def(`zero_',`defined_($1)dnl _(`lfsr FSR0,$1')dnl beginLoop_(TABLAT,eval($1_size_*type_($1)_size_))dnl _(`clrf POSTINC0')dnl endLoop_(FSR0,$1)') # ----------------------------------------------------------------------------- # M E M O R Y T R A N S F E R S # ----------------------------------------------------------------------------- # basicCopy_(destLabel,srceLabel,size) define(`basicCopy_',`dnl _(`lfsr FSR0,$2')dnl _(`lfsr FSR1,$1')dnl beginLoop_(TABLAT,eval($3*$2_type_()_size_))dnl _(`movff POSTINC0,POSTINC1')dnl endLoop_(FSR0,$2)') # ----------------------------------------------------------------------------- # S Y N C H R O N I Z E R S # ----------------------------------------------------------------------------- define(`fsem_',`.eval(sem__base_+($1_sem_>>3))') define(`bsem_',`fsem_($1),.eval($1_sem_&7)') # semaphores_(...) def(`semaphores_',`dnl alloc_(char,sem_,eval(($#+7&~7)>>3))dnl define(`semaphores_init_',`zero_(sem_)')number_($*)')dnl define(`number_',`ifelse($1,,, `define(`$1_sem_',decr($#))dnl define(`NOindent')_(`; $1: ('bsem_($1)`)')dnl number_(shift($*))')') # Pre0_(s) def(`Pre0_',`dnl _(banksel fsem_($1))dnl _(bsf bsem_($1),1)') # Suc0_(s) def(`Suc0_',`dnl _(banksel fsem_($1))dnl _(btfss bsem_($1),1)dnl _(bra `$-2')dnl _(bcf bsem_($1),1)') # Pre1_(s) def(`Pre1_',`dnl ifdef(`inLoop_',`_(bcf INTCON,GIE)')dnl _(`call suc1_'$1_sem_)dnl ifdef(`inLoop_',`_(bsf INTCON,GIE)')') # Suc1_(s) def(`Suc1_',`dnl define(`NOindent')_(`suc1_'$1_sem_:)dnl _(banksel fsem_($1))dnl _(btg bsem_($1),1)dnl _(btfsc bsem_($1),1)dnl _(return)') # ----------------------------------------------------------------------------- # C O N T R O L S T R U C T U R E S # ----------------------------------------------------------------------------- # basicIf_(bool, tagforElseOrEndif) define(`basicIf_',`dnl _(clrf WREG)dnl _(banksel $1)dnl _(cpfsgt $1)dnl _(goto $2)') # basicIfnot_(bool, tagForElseOrEndif) define(`basicIfnot_',`dnl _(clrf WREG)dnl _(banksel $1)dnl _(cpfseq $1)dnl _(goto $2)') # basicElse_(tagFromIf, tagForEndif) define(`basicElse_',` _(bra $2)dnl define(`NOindent')_($1:)') # basicEndif_(tagFromIfOrElse) define(`basicEndif_',`dnl define(`NOindent')_($1:)') # basicSwitch_(buffer, tagforElseOrEndif) define(`basicSwitch_',`pushdef(`swbuf_',$1)') # basicCase_(value, tagforElseOrEndif) define(`basicCase_',`proto_(type_(swbuf_)[1]?swbuf_)dnl _(lfsr FSR0,swbuf_)dnl _(movlw 0x`'eval($1&255,16))dnl _(cpfseq POSTINC0)dnl _(goto $2)dnl ifelse(type_(swbuf_),char,,`dnl _(movlw 0x`'eval(($1>>8)&255,16))dnl _(cpfseq POSTINC0)dnl _(goto $2)')dnl ifelse(type_(swbuf_),int,`dnl _(movlw 0x`'eval(($1>>16)&255,16))dnl _(cpfseq POSTINC0)dnl _(goto $2)dnl _(movlw 0x`'eval(($1>>24)&255,16))dnl _(cpfseq POSTINC0)dnl _(goto $2)')') # basicEndCase_(tagforElseOrEndif) define(`basicEndCase_',`define(`NOindent')_($1:)') # basicEndSwitch_(tag_) define(`basicEndSwitch_',`popdef(`swbuf_')') # basicLoop_(tagForEndloop) define(`basicLoop_',`dnl ifdef(`inMain',`dnl _(`bsf INTCON,PEIE ; enables all unmasked peripheral interrupts')dnl _(`bsf INTCON,GIE ; enables all unmasked interrupts')')dnl ifdef(`NBITERATIONS',`alloc_(char,i_$1,1)dnl ifelse(NBITERATIONS,0,`define(`NBITERATIONS',1)')dnl ifelse(eval(NBITERATIONS>255),1,`error_(`only 255 loop iterations allowed')dnl define(`NBITERATIONS',255)')dnl _(movlw .NBITERATIONS+.1)dnl _(banksel i_$1)dnl _(movwf i_$1,1)dnl _(goto f_$1)')dnl define(`NOindent')_(b_$1:)dnl pushdef(`inLoop_')') # basicEndloop_(tagFromLoop) define(`basicEndloop_',`dnl popdef(`inLoop_')dnl ifdef(`NBITERATIONS', `dnl define(`NOindent')_(f_$1:)dnl _(banksel i_$1)dnl _(decfsz i_$1,1,1)')dnl _(goto b_$1)') # ----------------------------------------------------------------------------- # M A I N S E Q U E N C E # ----------------------------------------------------------------------------- divert(1)dnl _(include_` p18f2680.inc')dnl indent_(+)dnl _(`processor 18f2680')dnl _(`config OSC = HS')dnl _(`config PBADEN = OFF')dnl _(`config WDT = OFF')dnl _(`config LVP = OFF')dnl _(`org 0x800')dnl _(`goto start')dnl _(`org 0x808')dnl _(`goto ithandler')dnl indent_(-)dnl divert(-1) # basicMain_() define(`basicMain_', `dnl define(NOindent)_(start:)dnl pushdef(`inMain')') # basicEndmain_() define(`basicEndmain_', `popdef(`inMain')dnl indent_(+)dnl _(`bcf INTCON,PEIE ; disables all unmasked peripheral interrupts')dnl _(`bcf INTCON,GIE ; disables all unmasked interrupts')dnl _(`goto 0 ; return to bootloader')dnl define(NOindent)_(`ithandler:')dnl alloc_(char,itregs_,4)dnl _(`movff FSR0L,itregs_ ; save processor context')dnl _(`movff FSR0H,itregs_+1')dnl _(`movff FSR1L,itregs_+2')dnl _(`movff FSR1H,itregs_+3')dnl undivert(1)dnl define(NOindent)_(`ithandler_end:')dnl _(`movff itregs_,FSR0L ; restore processor context')dnl _(`movff itregs_+1,FSR0H')dnl _(`movff itregs_+2,FSR1L')dnl _(`movff itregs_+3,FSR1H')dnl _(`retfie 1')dnl _(`END')dnl indent_(-)') # spawn_thread_(mediaName) ; spawn the pseudo-parallel execution of a com.seq. def(`spawn_thread_', `dnl ifdef(`semaphores_init_',`semaphores_init_()undefine(`semaphores_init_')')dnl _(call thread_$1)') # basicThread_(mediaName) define(`basicThread_', `dnl define(`NOindent')_(thread_$1:)') # basicEndthread_(mediaName) define(`basicEndthread_', `dnl indent_(+)dnl Pre0_(Semaphore_Thread_$1)dnl _(return)dnl indent_(-)') # wait_endthread_(mediaName) ; wait for com.seq. thread to terminate def(`wait_endthread_', `dnl Suc0_($1)') # ----------------------------------------------------------------------------- # L O G I C / A R I T H M E T I C # ----------------------------------------------------------------------------- define(`genLogic',`bool char short int') define(`genArith',`char short int') define(`genTypes',`bool char short int') define(`ifmulti_', `ifelse(eval($1<$2),1, `patsubst(`$3',`\?',`$1')ifmulti_(incr($1), $2, `$3')')') # generic unary operations for standard scalar and array types: define(`genUnary_', `ifelse($#,4,,`error_(`Expected 2 arguments.')')dnl mustBe(type_($4),`$2')proto_(pType_($4)?$3,pType_($4)!$4)dnl _(lfsr FSR0,$3)dnl _(lfsr FSR1,$4)dnl beginLoop_(TABLAT,eval($4_size_*type_($4)_size_))dnl _(movff POSTINC0,INDF1)dnl _($1 POSTINC1)dnl endLoop_(FSR1,$4)') def(`gnot', `genUnary_(`comf',genLogic,$*)') def(`gneg', `ifelse($#,2,,`error_(`Expected 2 arguments.')')dnl mustBe(type_($2),genArith)proto_(pType_($2)?$1,pType_($2)!$2)dnl _(lfsr FSR0,$1)dnl _(lfsr FSR1,$2)dnl beginLoop_(TABLAT,$2_size_)dnl _(movff POSTINC0,INDF1)dnl _(negf POSTINC1)dnl ifmulti_(1,type_($2)_size_,`dnl _(comf POSTINC0,0)dnl _(clrf INDF1)dnl _(addwfc POSTINC1)')dnl endLoop_(FSR1,$2)') # generic binary operations for standard scalar and array types: define(`genBinary_', `ifelse($#,6,,`error_(`Expected 3 arguments.')')dnl mustBe(type_($6),`$3')proto_(pType_($6)?$4,pType_($6)?$5,pType_($6)!$6)dnl _(lfsr FSR0,$4)dnl _(lfsr FSR1,$5)dnl _(lfsr FSR2,$6)dnl beginLoop_(TABLAT,$6_size_)dnl _(movff POSTINC0,INDF2)dnl _(movf POSTINC1,0)dnl _($1 POSTINC2)dnl ifmulti_(1,type_($6)_size_,`dnl _(movff POSTINC0,INDF2)dnl _(movf POSTINC1,0)dnl _($2 POSTINC2)')dnl endLoop_(FSR2, $6)') def(`gand', `genBinary_(`andwf', `andwf', genArith, $*)') def(`gor', `genBinary_(`iorwf', `iorwf', genArith, $*)') def(`gxor', `genBinary_(`xorwf', `xorwf', genArith, $*)') def(`gadd', `genBinary_(`addwf', `addwfc', genArith, $*)') def(`gsub', `genBinary_(`subwf', `subwfb', genArith, $*)') def(`gmul', `ifelse($#,3,,`error_(`Expected 3 arguments.')')dnl ifelse( type_($3),ushort,`dnl proto_(uchar[$3_size_]?$1,uchar[$3_size_]?$2,ushort[$3_size_]!$3)dnl gmul8($*)', type_($3),short,`dnl proto_(char[$3_size_]?$1,char[$3_size_]?$2,short[$3_size_]!$3)dnl gmul8($*)', type_($3),uint,`dnl proto_(ushort[$3_size_]?$1,ushort[$3_size_]?$2,uint[$3_size_]!$3)dnl gmul16($*)', type_($3),int,`dnl proto_(short[$3_size_]?$1,short[$3_size_]?$2,int[$3_size_]!$3)dnl gmul16($*)',`dnl error_(type_($1)`*'type_($2)`->'type_($3)` is not supported.')')') define(`gmul8',`dnl _(lfsr FSR0,$1)dnl _(lfsr FSR1,$2)dnl _(lfsr FSR2,$3)dnl beginLoop_(TABLAT,$3_size_)dnl ifelse(type_($3),short,`dnl _(movf INDF0,0)dnl _(mulwf INDF1)dnl _(btfsc INDF1,7)dnl _(subwf PRODH,1)dnl _(movf POSTINC1,0)dnl _(btfsc POSTINC0,7)dnl _(subwf PRODH,1)', `dnl _(movf POSTINC0,0)dnl _(mulwf POSTINC1)')dnl _(movff PRODL,POSTINC2)dnl _(movff PRODH,POSTINC2)dnl endLoop_(FSR2,$3)') define(`gmul16',`dnl _(lfsr FSR0,$1)dnl _(lfsr FSR1,$2)dnl _(lfsr FSR2,$3)dnl beginLoop_(TABLAT,$3_size_)dnl _(movf POSTINC0,0)dnl _(mulwf POSTINC1)dnl _(movff PRODL,POSTINC2)dnl _(movff PRODH,POSTINC2)dnl _(movf POSTDEC0,0)dnl _(mulwf INDF1)dnl _(movff PRODL,POSTINC2)dnl _(movff PRODH,POSTDEC2)dnl _(movf POSTDEC2)dnl _(movf POSTINC0,0)dnl _(mulwf POSTDEC1)dnl _(movf PRODL,0)dnl _(addwf POSTINC2)dnl _(movf PRODH,0)dnl _(addwfc POSTINC2)dnl _(clrf WREG)dnl _(addwfc POSTDEC2)dnl _(movf POSTDEC2)dnl _(movf ifelse(type_($1),short,`INDF',`POSTINC')0,0)dnl _(mulwf POSTINC1)dnl _(movf PRODL,0)dnl _(addwf POSTINC2)dnl _(movf PRODH,0)dnl _(addwfc POSTINC2)dnl _(clrf WREG)dnl _(addwfc ifelse(type_($2),short,`INDF',`POSTINC')2)dnl ifelse(type_($1),short,`dnl _(btfss INDF1,7)dnl pushtag(`op')_(bra tag_)dnl _(movf POSTDEC0)dnl _(movf POSTDEC2)dnl _(movf POSTINC0,0)dnl _(subwf POSTINC2)dnl _(movf INDF0,0)dnl _(subwfb INDF2)dnl define(`NOindent')_(tag_:)poptag(`op')dnl _(btfss POSTINC0,7)dnl pushtag(`op')_(bra tag_)dnl _(movf POSTDEC1)dnl _(movf POSTDEC2)dnl _(movf POSTINC1,0)dnl _(subwf POSTINC2)dnl _(movf INDF1,0)dnl _(subwfb INDF2)dnl define(`NOindent')_(tag_:)poptag(`op')')dnl ifelse($3_size_,1,,`dnl ifelse(type_($1),short,`dnl _(movf POSTINC2)')dnl _(movf POSTINC1)')dnl endLoop_(FSR2, $3)') def(`gdiv',`ifelse($#,5,,`error_(`Expected 5 arguments.')')dnl proto_(char[$3_size_]?$1,char[$3_size_]?$2,char[$3_size_]!$3,char[$3_size_]!$4,bool[1]!$5)dnl gdiv8($*)') define(`gdiv8',`dnl copy_($3,$1)dnl copy_($4,$2)dnl pushtag(`op')dnl pushdef(`size_',eval($3_size_))dnl _(`lfsr FSR0,$3')dnl _(`lfsr FSR1,$4')dnl _(`banksel $5')dnl _(`clrf $5,1')dnl define(`NOindent')_(tag_`:')dnl _(`clrf PRODH ; sign')dnl _(`clrf FSR2L ; remainder')dnl _(`movf INDF0,0')dnl _(`btfsc STATUS,Z')dnl _(`bra 'tag_`_E')dnl _(`xorwf INDF1,0')dnl _(`btfsc WREG,7')dnl _(`comf PRODH')dnl _(`clrf PRODL ; clear exception flag')dnl _(`btfsc INDF1,7 ; if MSB set, negate BARG')dnl _(`negf INDF1')dnl _(`btfsc INDF0,7 ; if MSB set, negate AARG')dnl _(`negf INDF0')dnl _(`movf INDF0,0')dnl _(`iorwf INDF1,0')dnl _(`btfsc WREG,7')dnl _(`bra 'tag_`_X1')dnl define(`NOindent')_(tag_`_S:')dnl _(`movf INDF1,0')dnl _(`subwf FSR2L')dnl _(`rlcf INDF0')dnl _(`rlcf INDF0,0')dnl _(`rlcf FSR2L')dnl _(`movf INDF1,0')dnl _(`addwf FSR2L')dnl _(`rlcf INDF0')dnl _(`movlw 6')dnl _(`movwf TABLAT')dnl define(`NOindent')_(tag_`_L:')dnl _(`rlcf INDF0,0')dnl _(`rlcf FSR2L')dnl _(`movf INDF1,0')dnl _(`btfsc INDF0,0')dnl _(`subwf FSR2L')dnl _(`btfss INDF0,0')dnl _(`addwf FSR2L')dnl _(`rlcf INDF0')dnl _(`decfsz TABLAT')dnl _(`bra 'tag_`_L')dnl _(`btfss INDF0,0')dnl _(`addwf FSR2L')dnl _(`btfsc PRODL,0 ; test exception flag')dnl _(`bra 'tag_`_X4')dnl define(`NOindent')_(tag_`_OK:')dnl _(`btfss PRODH,7')dnl _(`bra 'tag_`_E')dnl _(`negf INDF0')dnl _(`negf FSR2L')dnl _(`bra 'tag_`_E')dnl define(`NOindent')_(tag_`_X1:')dnl _(`btfss INDF1,7 ; test BARG exception')dnl _(`bra 'tag_`_X3')dnl _(`btfsc INDF0,7 ; test AARG exception')dnl _(`bra 'tag_`_X2')dnl _(`movf INDF0,0 ; quotient = 0, remainder = AARG')dnl _(`movwf FSR2L')dnl _(`clrf INDF0')dnl _(`bra 'tag_`_OK')dnl define(`NOindent')_(tag_`_X2:')dnl _(`clrf INDF0 ; quotient = 1, remainder = 0')dnl _(`incf INDF0')dnl _(`bra 'tag_`_E')dnl define(`NOindent')_(tag_`_X3:')dnl _(`comf INDF0 ; numerator = 0x7F + 1')dnl _(`incf PRODL')dnl _(`bra 'tag_`_S')dnl define(`NOindent')_(tag_`_X4:')dnl _(`incf FSR2L ; increment remainder and test for')dnl _(`movf INDF1,0 ; overflow')dnl _(`subwf FSR2L,0')dnl _(`btfss STATUS,Z')dnl _(`bra 'tag_`_OK')dnl _(`clrf FSR2L ; if remainder overflow, clear')dnl _(`incf INDF0 ; remainder, increment quotient and')dnl _(`btfss INDF0,7 ; test for overflow exception')dnl _(`bra 'tag_`_OK')dnl _(`setf $5,1')dnl define(`NOindent')_(tag_`_E:')dnl _(`movff FSR2L,POSTINC1')dnl ifelse(size_,1,,`dnl _(`movf POSTINC0')dnl _(`movlw high($3+'size_`)')dnl _(`cpfseq FSR0H')dnl _(`bra 'tag_)dnl _(`movlw low($3+'size_`)')dnl _(`cpfseq FSR0L')dnl _(`bra 'tag_)')dnl poptag(`op')dnl popdef(`size_')') # generic relational operations for standard scalar types: def(`gEQ', `genRelat_(`EQ_',genTypes,$*)')dnl $3=$1==$2; def(`gNE', `genRelat_(`NE_',genTypes,$*)')dnl $3=$1!=$2; def(`gLT', `genRelat_(`LT_',genArith,$*)')dnl $3=$1<$2; def(`gNL', `genRelat_(`NL_',genArith,$*)')dnl $3=$1>=$2; def(`gGT', `genRelat_(`GT_',genArith,$*)')dnl $3=$1>$2; def(`gNG', `genRelat_(`NG_',genArith,$*)')dnl $3=$1<=$2; define(`gequal', `gEQ($*)') define(`gnotequal',`gNE($*)') define(`gless', `gLT($*)') define(`gnotless', `gNL($*)') define(`genRelat_',`dnl mustBe(type_($3),`$2')proto_(type_($3)?$3,type_($3)?$4,bool!$5)dnl pushdef(`size_', eval(type_($3)_size_-1))dnl _(lfsr FSR0,$3+size_)dnl _(lfsr FSR1,$4+size_)dnl _(lfsr FSR2,$5)dnl define(`size_',incr(size_))$1($3,$4)`'dnl popdef(`size_')') define(`EQ_',`dnl _(setf INDF2)dnl ifmulti_(0,size_,`dnl _(movf POSTDEC0,0)dnl _(subwf POSTDEC1,0)dnl _(bz $+4)dnl _(clrf INDF2)')') define(`NE_',`dnl _(clrf INDF2)dnl ifmulti_(0,size_,`dnl _(movf POSTDEC0,0)dnl _(subwf POSTDEC1,0)dnl _(bz $+4)dnl _(setf INDF2)')') define(`GT_',`pushtag(`op')dnl _(`setf INDF2')dnl _(`movf INDF0,0')dnl _(`xorwf INDF1,0')dnl _(`bnn $+.6')dnl _(`rlcf INDF1,0')dnl _(`bra 'tag_)dnl _(`lfsr FSR0,$1')dnl _(`lfsr FSR1,$2')dnl ifmulti_(0,size_,`dnl _(`movf POSTINC1,0')dnl _(`subwfb POSTINC0,0')')dnl define(`NOindent')_(tag_`:')poptag(`op')dnl _(`btfss STATUS,C')dnl _(`clrf INDF2')') define(`NG_',`pushtag(`op')dnl _(`setf INDF2')dnl _(`movf INDF0,0')dnl _(`xorwf INDF1,0')dnl _(`bnn $+.6')dnl _(`rlcf INDF1,0')dnl _(`bra 'tag_)dnl _(`lfsr FSR0,$1')dnl _(`lfsr FSR1,$2')dnl ifmulti_(0,size_,`dnl _(`movf POSTINC1,0')dnl _(`subwfb POSTINC0,0')')dnl define(`NOindent')_(tag_`:')poptag(`op')dnl _(`btfsc STATUS,C')dnl _(`clrf INDF2')') define(`LT_',`pushtag(`op')dnl _(`setf INDF2')dnl _(`movf INDF0,0')dnl _(`xorwf INDF1,0')dnl _(`bnn $+.6')dnl _(`rlcf INDF0,0')dnl _(`bra 'tag_)dnl _(`lfsr FSR0,$1')dnl _(`lfsr FSR1,$2')dnl ifmulti_(0,size_,`dnl _(`movf POSTINC0,0')dnl _(`subwfb POSTINC1,0')')dnl define(`NOindent')_(tag_`:')poptag(`op')dnl _(`btfss STATUS,C')dnl _(`clrf INDF2')') define(`NL_',`pushtag(`op')dnl _(`setf INDF2')dnl _(`movf INDF0,0')dnl _(`xorwf INDF1,0')dnl _(`bnn $+.6')dnl _(`rlcf INDF0,0')dnl _(`bra 'tag_)dnl _(`lfsr FSR0,$1')dnl _(`lfsr FSR1,$2')dnl ifmulti_(0,size_,`dnl _(`movf POSTINC0,0')dnl _(`subwfb POSTINC1,0')')dnl define(`NOindent')_(tag_`:')poptag(`op')dnl _(`btfsc STATUS,C')dnl _(`clrf INDF2')') # ----------------------------------------------------------------------------- # C H R O N O S # ----------------------------------------------------------------------------- # Chronos_(size) ; size=number of (label,date) records def(`Chronos_',`ifelse($#,1,,`error_(`Expected 1 argument.')')dnl define(`Chronos_once_')dnl ifdef(`CHRONOS_NBITERATIONS',,`define(`CHRONOS_NBITERATIONS',3)')dnl alloc_(char,Chrono_base,eval($1*6*CHRONOS_NBITERATIONS+1))dnl alloc_(short,Chrono_msb,1)dnl alloc_(char,Chrono_freeze,1)dnl alloc_(short,Chrono_current,1)dnl _(`Chrono_lap_:')dnl indent_(+)dnl _(`movwf POSTINC0')dnl _(`bcf INTCON,GIE')dnl _(`movff TMR0L,POSTINC0')dnl _(`movff TMR0H,POSTINC0')dnl _(`movff Chrono_msb,POSTINC0')dnl _(`movff Chrono_msb+1,POSTINC0')dnl _(`bsf INTCON,GIE')dnl _(`movlw high(Chrono_base+.'decr(Chrono_base_size_)`)')dnl _(`cpfseq FSR0H')dnl _(`bra Chrono_lap_update_')dnl _(`movlw low(Chrono_base+.'decr(Chrono_base_size_)`)')dnl _(`cpfseq FSR0L')dnl _(`bra Chrono_lap_update_+.4')dnl _(`movlw low Chrono_base')dnl _(`banksel Chrono_current')dnl _(`movwf Chrono_current,1')dnl _(`movlw high Chrono_base')dnl _(`banksel Chrono_current+1')dnl _(`movwf Chrono_current+1,1')dnl _(`return')dnl define(`NOindent')_(`Chrono_lap_update_:')dnl _(`bra $+2')dnl _(`nop')dnl _(`nop')dnl _(`movff FSR0L,Chrono_current')dnl _(`movff FSR0H,Chrono_current+1')dnl _(`return')dnl indent_(-)dnl divert(1)dnl switch to interrupt handler indent_(+)dnl define(`NOindent')_(`TMR0_it: ; timer0 interrupt main handler')dnl _(`btfss INTCON,TMR0IF')dnl _(`bra TMR0_it_end')dnl _(`bcf INTCON,TMR0IF')dnl _(`lfsr FSR0,Chrono_msb')dnl _(`incf POSTINC0 ; Chrono_msb')dnl _(`clrf WREG')dnl _(`addwfc POSTINC0 ; Chrono_msb+1')dnl _(`btfsc INDF0,0 ; Chrono_freeze')dnl _(`goto ithandler_end')dnl define(`NOindent')_(`TMR0_it_end:')dnl indent_(-)dnl divert(0)') # Chrono_ini_() def(`Chrono_ini_',`dnl zero_(Chrono_base)dnl _(`clrf POSTINC0 ; Chrono_msb')dnl _(`clrf POSTINC0')dnl _(`clrf POSTINC0 ; Chrono_freeze')dnl _(`movlw low Chrono_base')dnl _(`movwf POSTINC0 ; Chrono_current')dnl _(`movlw high Chrono_base')dnl _(`movwf POSTINC0 ; Chrono_current+1')dnl _(`clrf TMR0H')dnl _(`clrf TMR0L')dnl _(`movlw 0x8f ; 16-bits clock cycle counter')dnl _(`movwf T0CON ; timer0')dnl _(`bcf INTCON,TMR0IF')dnl _(`bsf INTCON,TMR0IE')') # Chrono_lap_(label) ; record label with current date def(`Chrono_lap_',`dnl _(`movff Chrono_current,FSR0L')dnl _(`movff Chrono_current+1,FSR0H')dnl _(`movlw 0x'eval($1&255,16))dnl _(`movwf POSTINC0')dnl _(`movlw 0x'eval($1>>8&255,16))dnl _(`call Chrono_lap_')') # Chrono_end_() def(`Chrono_end_',`dnl ifdef(`BackwardSaver_once_',`_(`call BackwardSaver')')dnl _(`bcf INTCON,TMR0IE')') divert`'dnl---------------------- end of file ----------------------