📄 d.txt
字号:
goto hitdone ;clean up and continue
upto3
movf offsetx,w ;it's 2/3/4. Figure out which...
sublw offset2_0 ;compare by subtracting
btfss status,z
goto upto4 ;if not a match on 2, it must be 3/4
itwas2
call set3 ;if it was 2, change range to 3
goto hitdone ;clean up and continue
upto4
call set4 ;if it was 3 go to 4.
;if it was already 4, stay at 4. (sticky button)
goto hitdone ;clean up and continue
;ahh, it wasn't the UP button. So check for DOWN or ZERO button...
isitdown
btfsc acopy,downkey ;non-inverted original in acopy
goto iszero ;if it wasn't DOWN, it was ZERO!
itwasdown
movf offsetx,w ;Down from *where*? 4/3/2/1
sublw offset4_0 ;compare by subtracting
btfss status,z
goto downto2 ;if it wasn't 4 it was 3/2/1
downto3
call set3 ;if it was 4, down range to 3
goto hitdone ;clean up and continue
downto2
movf offsetx,w ;maybe it is at 3?
sublw offset3_0
btfss status,z
goto downto1 ;if not it is 2/1
call set2 ;if it was 3, go down to 2
goto hitdone ;clean up and continue
downto1
call set1 ;2 goes down to 1. sticky button at 1
goto hitdone
iszero
call periodinit ;before we can perform a zeroing operation
; we must first acquire a clean reading!
call setzerox ;then we do the zero stuff
;and liesurely flow into the cleanup part below.
;clean up and continue
hitdone
comf porta,w ;copy inverted porta to w
andlw b'00011100' ;check three bits at once
btfss status,z
goto hitdone ;wait for key release!
movlw b'11111111'
movwf acopy ;"reset" acopy to indicate it is processed.
bsf autoflags,manual ;force manual mode
goto mainloop ;messes up stack, but who cares?
;this method allows quicker response
;exiting from a called subroutine by
;executing a goto is frowned upon by some,
;but in this case it is the simplest way
;to speed up the response. it effectively
;terminates the current loop and goes to the
;beginning of mainloop.
;following subroutine is used by initialization routine to auto-zero each range
setstuff
call xmillisecs
call periodinit
call setzerox
goto lcdclear2
;subroutines to set circuitry to handle a particular range. Range switching stuff.
set1
btfsc autoflags,manual ;normally in manual mode you don't auto-range.
return ; this is over-ridden if button is pushed.
movlw offset1_0 ;offsetx is loaded with appropriate pointer value
movwf offsetx
bsf shadowb,pselect ;ports are set to turn appropriate external
; circuitry on/off to select desired range
;some code is shared between set1 and set2
;strictly to save code space.
set1_2
movf shadowb,w
movwf portb
bcf porta,controla
bcf porta,controlb
return
set2
btfsc autoflags,manual
return
movlw offset2_0
movwf offsetx
bcf shadowb,pselect
goto set1_2
set3
btfsc autoflags,manual
return
bcf shadowb,pselect
movf shadowb,w
movwf portb
bsf porta,controla
bcf porta,controlb
movlw offset3_0
movwf offsetx
return
set4
btfsc autoflags,manual
return
bcf shadowb,pselect
movf shadowb,w
movwf portb
bsf porta,controla
bsf porta,controlb
movlw offset4_0
movwf offsetx
return
;subroutine to perform zero function by copying current contents of bin24 counter
; to local register set. Later the contents of the local set are subtracted from
; whatever the new current count is, and this effects the Zero or Comparison function.
setzerox
movf offsetx,w ;recover current offset group
movwf fsr ;use indirect addressing
movf bin24_0,w ;zero by copying bin24 to offset
movwf indf
incf fsr,f
movf bin24_1,w
movwf indf
incf fsr,f
movf bin24_2,w
movwf indf
return
;subroutine to subtract current offset from current bin24 count.
; allows Zeroing and Comparing.
;
;I do not claim that this implementation is minimal or fastest method to do this.
; I can only say that it works. (I need to get SOME sleep, guys!).
; writing code at 2 AM is not always conducive to achieving conciseness. ZZZZzzzzzz.
subtractoffset
movf offset_2,w
subwf bin24_2,w ;see which is biggest
btfsc status,z
goto equal_2 ;equal so far
notequal
btfsc status,c ;c=1 means bin24 bigger
goto bin24bigger
goto offsetbigger
equal_2
movf offset_1,w
subwf bin24_1,w ;see which is biggest
btfsc status,z
goto equal_1 ;equal so far
goto notequal ;carry bit tells all...
equal_1
movf offset_0,w
subwf bin24_0,w ;see which is biggest
btfsc status,z
goto equal_0 ;equal so far
goto notequal ;carry bit tells all...
equal_0
clrf bin24_0 ;so clear bin24
clrf bin24_1
clrf bin24_2
return
bin24bigger
bsf flags,plusminus ;bigger is +
bb0
movf offset_0,w
subwf bin24_0,f ;place result in bin24
btfsc status,z
goto bb1 ;if zero skip to next byte
btfsc status,c
goto bb1 ;if result was + skip to next byte
bb0neg
;handle negative
movlw 1 ;"borrow" one from next byte
subwf bin24_1,f
btfsc status,c ;if negative (no cy) we need another
; borrow from next byte.
goto bb1 ;if positive, do next byte
movlw 1 ;then "borrow" one from next byte
subwf bin24_2,f
bb1
movf offset_1,w ;subtract second byte set
subwf bin24_1,f ;place result in bin24
btfsc status,z
goto bb2 ;if zero skip to next byte
btfsc status,c
goto bb2 ;if result was + skip to next byte
bb1neg
;handle negative
decf bin24_2,f ;"borrow" one from next byte
;that was last byte, so no more borrows
bb2
movf offset_2,w ;subtract last byte set
subwf bin24_2,f ;place result in bin24
;this is msb so we is done
return ;result is in bin24 set
offsetbigger
;so subtract bin24 from offset
movf offset_0,w
;swap those buggers!
movwf temp0 ;use temp0
movf bin24_0,w
movwf offset_0
movf temp0,w
movwf bin24_0 ;swapped. tempset has offset.
movf offset_1,w
;swap those buggers!
movwf temp1 ;use temp1
movf bin24_1,w
movwf offset_1
movf temp1,w
movwf bin24_1 ;swapped. tempset has offset.
movf offset_2,w
;swap those buggers!
movwf temp2 ;use temp2
movf bin24_2,w
movwf offset_2
movf temp2,w
movwf bin24_2 ;swapped. temporary set has offset.
call bin24bigger ;re-use code!
bcf flags,plusminus ;except plusminus is different!
; (hey, it works!)
movf temp0,w ;recover offset set
movwf offset_0 ;0
movf temp1,w
movwf offset_1 ;1
movf temp2,w
movwf offset_2 ;2
call lcdhome1
movlw h'ff' ;flash the negative sign to attract attention
call lcdout
call xmillisecs ;just a little flash...
return
;subroutine to convert binary results into human readable format on lcd
convertit
copyzero ;set up indirect adressing to recover stuff
movf offsetx,w ;recover current offset group
movwf fsr ;use indirect addressing
movf indf,w ;get first element
movwf offset_0 ;copy it
incf fsr,f ;point to next element
movf indf,w ;get 2nd element
movwf offset_1 ;copy it
incf fsr,f ;point to next element
movf indf,w ;get 3rd element
movwf offset_2 ;copy it
call subtractoffset ;perform zero/compare
;bin2dec: converts bin24 to decimal in xlsb->xmsb registers.
;method I chose to use nibble bcd. to get speed up I use a hybrid
;approach to doing the conversions. I designed a decimal adder that
;allows me to add a decimal value by specifying its mantissa and
;exponent values. binary conversions proceed by converting binary
;bits to decimal mantissa/exponent form and then adding the
;mantissa/exponent pieces. I did not choose this method because it
;is elegant, optimal, or whatever. I chose it because it was something
;I had been playing around with as a mental exercise, and I decided
;to use the results of my investigations here in this project.
;so, if some of the code seems a bit strange to you, don't worry.
;it seems a bit strange to me, too! But, hey, it works, and I had
;some mental FUN trying this out.
bin2dec
byte0
movf bin24_0,w ;test for zero
btfsc status,z
goto byte1 ;if zero, skip & do next byte
movwf temp1 ;leave original alone
byte0loop ;first the onesies
call addtens10 ;mantissa is 1 exponent is 0. one.
decf temp1,f ;byte is finished when zero
btfss status,z
goto byte0loop
byte1 ;then groups of 256
movf bin24_1,w ;test for zero
btfsc status,z
goto byte2 ;if zero, skip & do next byte
movwf temp1 ;leave original alone
byte1loop
movlw 6
call addtensx0 ;exponent of 0 handled special
movlw 5
movwf mantissa
movlw 1
call addtensxx
movlw 2
movwf mantissa
movlw 2
call addtensxx
decf temp1,f ;byte is finished when zero
btfss status,z
goto byte1loop
byte2 ;then groups of 65,536
movf bin24_2,w ;test for zero
btfsc status,z
goto bin2decdone ;if zero, all done.
movwf temp1 ;leave original alone
byte2loop
movlw 6
call addtensx0
movlw 3
movwf mantissa
movlw 1
call addtensxx
movlw 5
movwf mantissa
movlw 2
call addtensxx
movlw 5
movwf mantissa
movlw 3
call addtensxx
movlw 6
movwf mantissa
movlw 4
call addtensxx
decf temp1,f ;byte is finished when zero
btfss status,z
goto byte2loop
;if zero, all done.
bin2decdone ;now we will take the resultant decimal number set
; and spread it out so we can add the commas and
; decimal points and other stuff.
movf offsetx,w ;determine range, because each range has a
sublw offset1_0 ; different layout for the digits.
btfss status,z
goto isit2
its1
call sd15x ;I use a shift left from here and drop
; method to get the pieces arranged and in place.
call sd12p ; for example, the sd15x routine will position
; us at digit position 15, shift all digits left
; one place, and then deposit an X at location 15
; Oh yeah, X has been replaced by an underscore instead.
; it simply looks neater.
;by the way, all this shift and drop stuff takes
;place within the bcd register set. once the register
;set is arranged as we want, then the whole set
;is read into the lcd display.
movlw d'8'
call sdxc
call sd4c
call lcdclear2
movlw '1'
call lcdout
call usual
movf bin24_2,w
sublw d'7'
btfsc status,c
goto commonstuff
call set4
goto commonstuffr
isit2
movf offsetx,w
sublw offset2_0
btfss status,z
goto isit3
its2
call sd15x
call sd15x
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -