📄 ds1820.asm
字号:
tx_byte_loop_3 decfsz indf,f goto tx_byte_loop_3 movlw d'3' ; drop stack (timer, bit count, byte) addwf fsr,f retlw 0 ;;;;;; tx_header, transmit packet header, single byte followed by space;;; ;;; input: none;;; output: none;;; stack: calls others that do not call;;; data stack: ( byte -- ) [total 1];;; tx_header call tx_byte;;;;;; tx_space, send a single space;;; ;;; input: none;;; output: none;;; stack: calls others that do not call;;; data stack: ( -- ) [total 1];;; tx_space pushl 0x20 goto tx_byte;;;;;; tx_crlf, transmit carriage return line feed;;; ;;; input: none;;; output: none;;; stack: calls others that do not call;;; data stack: ( -- ) [total 1];;; tx_crlf pushl 0x0a call tx_byte pushl 0x0d goto tx_byte;;;;;; tx_put, macro for tx_byte_hex;;;;;; input: address of byte to send;;; output: none;;; stack: mainline macro;;; tx_put macro m_byte pushf m_byte bank0 call tx_byte_hex endm;;;;;; arithmetic vector table;;; (12c509 can't call into upper page of bank 0, 0x100 to 0x1ff);;;sb_bcd goto sb_bcd_sb_bcd_fix goto sb_bcd_fix_sb_add goto sb_add_sb_subtract goto sb_subtract_sb_abs goto sb_abs_sb_negate goto sb_negate_sb_nip goto sb_nip_sb_over goto sb_over_sb_multiply goto sb_multiply_sb_divide goto sb_divide_last0 equ sb_divide ; define the last call entry in page 0 ;;;;;; sb_bcd, convert accumulator to binary coded decimal for output;;;;;; data stack: ( lsb msb -- d0 d1 d2 ) [total 5];;; stack: calls others that do not call;;;sb_bcd_ ;; ( lsb msb ) popf r_ephemeral ; msb popf r_temporary ; lsb movlw 0 pushw ; d0 (lsd) pushw ; d1 pushw ; d2 (msd) pushf r_temporary ; lsb pushf r_ephemeral ; msb pushl d'16' ; count ;; ( d0 d1 d2 msb lsb count ) bcf status,csb_bcd_loop incf fsr,f ; ( d0 d1 d2 lsb msb ^ count ) incf fsr,f ; ( d0 d1 d2 lsb ^ msb count ) rlf indf,f ; lsb decf fsr,f ; ( d0 d1 d2 lsb msb ^ count ) rlf indf,f ; msb incf fsr,f incf fsr,f incf fsr,f incf fsr,f ; ( d0 ^ d1 d2 lsb msb count ) rlf indf,f ; d0 (lsd) decf fsr,f ; ( d0 d1 ^ d2 lsb msb count ) rlf indf,f ; d1 decf fsr,f ; ( d0 d1 d2 ^ lsb msb count ) rlf indf,f ; d2 (msd) movlw d'3' subwf fsr,f ; ( d0 d1 d2 lsb msb count ) decfsz indf,f ; count goto sb_bcd_adjust movlw d'3' addwf fsr,f ; drop drop drop ;; ( d0 d1 d2 ) retlw 0sb_bcd_adjust ;; ( d0 d1 d2 lsb msb count ) movlw d'3' addwf fsr,f ; ( d0 d1 d2 ^ lsb msb count ) call sb_bcd_fix ; d2 call sb_bcd_fix ; d1 call sb_bcd_fix ; d0 ; ( ^ d0 d1 d2 lsb msb count ) movlw d'6' subwf fsr,f ; ( d0 d1 d2 lsb msb count ) goto sb_bcd_loop sb_bcd_fix_ movlw 3 addwf indf,w ; add 3 to low nibble movwf r_ephemeral ; test bits btfsc r_ephemeral,3 ; if bit three is set movwf indf ; store the adjusted value movlw 0x30 addwf indf,w ; add 3 to high nibble movwf r_ephemeral ; test bits btfsc r_ephemeral,7 ; if bit seven is set movwf indf ; store the adjusted value incf fsr,f ; move to next digit pair retlw 0;;;;;; sb_*, sixteen bit math functions;;;;;;;;; sb_add, sixteen bit addition;;;;;; data stack: ( a b -- a+b ) [total 4];;; stack: none;;;sb_add_ ; ( lsb1 msb1 lsb2 msb2 -- lsb3 msb3 ) movf indf,w ; msb2 incf fsr,f ; ( lsb1 msb1 lsb2 ^ msb2 ) incf fsr,f ; ( lsb1 msb1 ^ lsb2 msb2 ) addwf indf,f ; msb3 = msb1 + msb2 decf fsr,f ; ( lsb1 msb3 lsb2 ^ msb2 ) movf indf,w ; lsb2 incf fsr,f ; ( lsb1 msb3 ^ lsb2 msb2 ) incf fsr,f ; ( lsb1 ^ msb3 lsb2 msb2 ) addwf indf,f ; lsb3 = lsb1 + lsb2 decf fsr,f ; ( lsb3 msb3 ^ lsb2 msb2 ) btfsc status,c ; carry? incf indf,f ; msb3 retlw 0 ; ( lsb3 msb3 );;;;;; sb_subtract, sixteen bit subtraction;;;;;; data stack: ( a b -- a-b ) [total 4];;; stack: none;;;sb_subtract_ ; ( lsb1 msb1 lsb2 msb2 -- lsb3 msb3 ) movf indf,w ; msb2 incf fsr,f ; ( lsb1 msb1 lsb2 ^ msb2 ) incf fsr,f ; ( lsb1 msb1 ^ lsb2 msb2 ) subwf indf,f ; msb3 = msb1 - msb2 decf fsr,f ; ( lsb1 msb3 lsb2 ^ msb2 ) movf indf,w ; lsb2 incf fsr,f ; ( lsb1 msb3 ^ lsb2 msb2 ) incf fsr,f ; ( lsb1 ^ msb3 lsb2 msb2 ) subwf indf,f ; lsb3 = lsb1 - lsb2 decf fsr,f ; ( lsb3 msb3 ^ lsb2 msb2 ) btfss status,c ; underflow? decf indf,f ; msb3 retlw 0;;;;;; sb_abs, sixteen bit absolute value;;;;;; data stack: ( a -- |a| ) [total 2];;; stack: none;;;sb_abs_ btfss indf,7 ; is it negative? retlw 0 ; no, so return ; fall through to negate ;;;;;; sb_negate, sixteen bit negate;;;;;; data stack: ( a -- 0-a ) [total 2];;; stack: none;;;sb_negate_ ; ( lsb msb -- lsb msb ) incf fsr,f ; ( lsb ^ msb ) comf indf,f ; lsb incf indf,f ; lsb decfsz fsr,f ; ( lsb msb ^ ) nop ; [decrement without losing z] btfsc status,z decf indf,f ; msb comf indf,f ; msb retlw 0 ; ( lsb msb );;;;;; sb_nip, sixteen bit nip, remove item under current item;;;;;; data stack: ( a b -- b ) [total 4];;; stack: none;;;sb_nip_ ; ( a b c d -- c d ) movf indf,w ; d @ incf fsr,f ; ->c incf fsr,f ; ->b movwf indf ; b ! decf fsr,f ; ->c movf indf,w ; c @ incf fsr,f ; ->b incf fsr,f ; ->a movwf indf ; a ! decf fsr,f ; ->b retlw 0;;;;;; sb_over, sixteen bit over, copy item under current item;;;;;; data stack: ( a b -- a b a ) [total 6];;; stack: none;;;sb_over_ ; ( a b c d -- a b c d a b ) incf fsr,f ; ( a b c ^ d ) incf fsr,f ; ( a b ^ c d ) incf fsr,f ; ( a ^ b c d ) movf indf,w ; a decf fsr,f ; ( a b ^ c d ) decf fsr,f ; ( a b c ^ d ) decf fsr,f ; ( a b c d ^ ) decf fsr,f ; ( a b c d ? ^ ) movwf indf ; a incf fsr,f ; ( a b c d ^ a ) incf fsr,f ; ( a b c ^ d a ) incf fsr,f ; ( a b ^ c d a ) movf indf,w ; b decf fsr,f ; ( a b c ^ d a ) decf fsr,f ; ( a b c d ^ a ) decf fsr,f ; ( a b c d a ^ ) decf fsr,f ; ( a b c d a ? ^ ) movwf indf ; b retlw 0 ;;;;;; sb_multiply, sixteen bit multiply;;;;;; data stack: ( multiplicand multiplier -- product ) [total 7];;; stack: calls others that do not call;;;sb_multiply_ ; ( al ah bl bh -- cl ch ) pushl16 d'0' ; clear product ;; ( al ah bl bh cl ch ) pushl d'16' ; count of bits to process ;; ( al ah bl bh cl ch count )sb_multiply_loop ; for each bit ;; ( al ah bl bh cl ch count ) ;; shift multiplier down by one movlw 5 addwf fsr,f ; ->ah rrf indf,f incf fsr,f ; ->al rrf indf,f decf fsr,f ; ->ah decf fsr,f ; ->bl ;; ( al ah bl ^ bh cl ch count ) ;; if the bit is set ... btfss status,c goto sb_multiply_skip ;; add the multiplicand to the product decf fsr,f ; ->bh movf indf,w decf fsr,f ; ->cl decf fsr,f ; ->ch addwf indf,f movlw 3 addwf fsr,f ; ->bl movf indf,w decf fsr,f ; ->bh decf fsr,f ; ->cl addwf indf,f decf fsr,f ; ->ch btfsc status,c incf indf,f movlw 3 addwf fsr,f ; ->blsb_multiply_skip ;; ( al ah bl ^ bh cl ch count ) ;; shift up multiplicand bcf status,c rlf indf,f decf fsr,f ; ->bh rlf indf,f ;; ( al ah bl bh ^ cl ch count ) ;; and loop for remainder of bits movlw 3 subwf fsr,f ; ->count decfsz indf,f goto sb_multiply_loop ;; ( al ah bl bh cl ch count ) popl ; count call sb_nip ; bl bh goto sb_nip ; al ah;;;;;; sb_divide, sixteen bit divide;;;;;; data stack: ( numerator denominator -- remainder quotient ) [total 10];;; stack: calls others that do not call;;;sb_divide_ ; ;; ( nl nh dl dh -- rl rh ql qh ) ;; prepare stack for results ;; ( nl nh dl dh ) call sb_over ;; ( nl nh dl dh nl nh ) call sb_over ;; ( nl nh dl dh nl nh dl dh ) ;; ( rl rh ql qh nl nh dl dh ) movlw d'4' addwf fsr,f ; ->qh clrf indf ; qh incf fsr,f ; ->ql clrf indf ; ql incf fsr,f ; ->rh clrf indf ; rh incf fsr,f ; ->rl clrf indf ; rl movlw d'7' subwf fsr,f ; ->dh ;; ( rl rh ql qh nl nh dl dh ) ;; save effective sign difference ;; sign = xor(nh,dh) ;; ( nl nh dl dh ) movf indf,w ; dh incf fsr,f ; incf fsr,f ; ->nh xorwf indf,w ; nh decf fsr,f ; decf fsr,f ; ->dh pushw ;; ( nl nh dl dh sign ) ;; force arguments to positive ;; n = abs (n) ;; ( nl nh dl dh sign ) movlw d'3' addwf fsr,f ; ->nh call sb_abs decf fsr,f ; ->dl decf fsr,f ; ->dh ;; d = abs (d) ;; ( nl nh dl dh ^ sign ) call sb_abs decf fsr,f ; ->sign ;; set the bit counter pushl d'16' ; for 16 shifts ;; ( nl nh dl dh sign count ) ;; ( rl rh ql qh nl nh dl dh sign count ) sb_divide_loop ;; ( rl rh ql qh nl nh dl dh sign count ) ;; shift bits left from numerator to remainder movlw d'5' addwf fsr,f ; ->nl bcf status,c ; clear status.c rlf indf,f ; nl decf fsr,f ; ->nh rlf indf,f ; nh incf fsr,f ; (must keep status.c) incf fsr,f ; incf fsr,f ; incf fsr,f ; incf fsr,f ; ->rl rlf indf,f ; rl decf fsr,f ; ->rh rlf indf,f ; rh ;; ( rl rh ^ ql qh nl nh dl dh sign count ) ;; check if remainder is greater than denominator movlw d'6' subwf fsr,f ; ->dh movf indf,w ; dh movwf r_ephemeral movlw d'6' addwf fsr,f ; ->rh movf r_ephemeral,w subwf indf,w ; rh btfss status,z goto sb_divide_skip_1 ;; ( rl rh ^ ql qh nl nh dl dh sign count ) ;; msb equal, so check lsb movlw d'5' subwf fsr,f ; ->dl movf indf,w ; dl movwf r_ephemeral movlw d'6' addwf fsr,f ; ->rl movf r_ephemeral,w subwf indf,w ; rl decf fsr,f ; ->rh ;; ( rl rh ^ ql qh nl nh dl dh sign count ) sb_divide_skip_1 btfss status,c goto sb_divide_skip_2 ; remainder is less ;; ( rl rh ^ ql qh nl nh dl dh sign count ) ;; carry set, remainder is greater than denominator ;; subtract denominator from remainder and save in remainder movlw d'5' subwf fsr,f ; ->dl movf indf,w ; dl movwf r_ephemeral movlw d'6' addwf fsr,f ; ->rl movf r_ephemeral,w subwf indf,f ; rl decf fsr,f ; ->rh btfss status,c decf indf,f ; rh movlw d'6' subwf fsr,f ; ->dh movf indf,w ; dh movwf r_ephemeral movlw d'6' addwf fsr,f ; ->rh movf r_ephemeral,w subwf indf,f ; rh
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -