I have lots of servos and would happily test your code but unfortunately don't have a 16F1823 (BTW, according to **broken link removed** it doesn't exist!.
I don't see why RMW will be a problem due to the chip having latch registers. I'm assuming (I know, dangerous) that the PWM module will override a zero in the latch register otherwise this would cause a problem in all PWM code.
Edit, just placed an order for this chip and 12F1822 as both look like very interesting chips.
;******************************************************************
; Ow.rwByte, send byte in WREG (send 0xFF to read a byte with *
; the read result in 'OwByte'). *
; author: Mike McLaren, K8LH *
radix dec ;**********************************
Ow.rdByte
movlw 0xFF ; for read operation
Ow.rwByte
movwf OwByte ;
movlw 8 ;
movwf BitCtr ;
rwloop rrf OwByte,W ; put bit 0 in Carry
call Ow.rwBit ; send bit in Carry
rrf OwByte,F ;
decfsz BitCtr,F ; done (all 8 bits)?
goto rwloop ; no, loop, else
movf OwByte,W ; return "OwByte" in WREG
return ; exit
;
;
;******************************************************************
; Ow.rwBit (4..32 MHz clock), send bit in Carry (use carry = 1 *
; to read bit into carry). *
; author: Mike McLaren, K8LH *
radix dec ;**********************************
Ow.rdBit
setc ; set C to read a bit
Ow.rwBit
movlw DataLo ; start 60 us rw slot
tris PORTA ; falling edge 0 us
goto $+1 ;
goto $+1 ;
skpnc ; skip if bit = '0', else
movlw DataHi ; mask to release buss
tris PORTA ; low pulse is 1..8 us
inDlyCy(14*usecs-8) ; 14 us minus 8 cycles
btfss PORTA,owpin ; sample owpin at exactly 14 us
clrc ; clear Carry if '0'
inDlyCy(47*usecs-3) ; balance of 60 us slot
movlw DataHi ; mask to release buss
tris PORTA ; read/write slot ends at 61 us
return ; for search rom routine
;
;
;
radix dec
clock equ 16 ; 4, 8, 12, 16, 20,.. 32 MHz clock
usecs equ clock/4 ; cycles/microsecond multiplier
inDlyCy macro delay ; 0..1027 cycle range
local loop
if delay >= 4
movlw delay/4 ;
loop movwf temp ; a 4 cycle loop
decfsz temp,W ;
goto loop ;
endif
if delay%4 >= 2 ; delay%4 == 2 or delay%4 == 3
goto $+1 ; delay 2 additional cycles
endif
if delay&1 ; delay%4 == 1 or delay%4 == 3
nop ; delay 1 additional cycle
endif
endm
;-----------------------------------------------------------
; Subroutines for PIC10F322
; Author: Terry Hitt
; Last change: Feb 2, 2012
;-----------------------------------------------------------
; NOTE: !!! Routines are timed for 16MHz clock !!!
;-----------------------------------------------------------
; Routines Provided:
; Delay_uSec_W - Delays "W" microseconds (min = 3)
; Delay_mSec_W - Delays "W" milliseconds
; Delay_mSec - Delays "delay" milliseconds. Destroys "delay"
; Delay_10mSec_W - Delays "W" x 10 milliseconds
; Delay_10mSec - Delays "delay" x 10 milliseconds. Destroys "delay"
;
; Serial_In - Receives a byte, stores it in "serialData"
; You must define SERINPIN in your code before include.
; Default baud rate is 9600. Define InBaud to change.
;
; Serial_Out_W - Sends byte value in "W" to serial out pin as character
; You must define SEROUTPIN in your code before include.
; Default baud rate is 9600. Define OutBaud to change.
; Serial_Out - Sends byte value in "serialData" to serial out pin as character. Destroys "serialData"
; You must define SEROUTPIN in your code before include.
; Default baud rate is 9600. Define OutBaud to change.
; Print_Byte_W - Sends byte value in "W" to serial out pin as ASCII
; You must define SEROUTPIN in your code before include.
; Default baud rate is 9600. Define OutBaud to change.
; Print_Byte - Sends byte value in "printValue" to serial out pin as ASCII. Destroys "printValue"
; You must define SEROUTPIN in your code before include.
; Default baud rate is 9600. Define OutBaud to change.
; Print_Word - Sends word value in "printValue_LSB" "printValue_MSB" to the serial out pin.
; Destroys "printValue_LSB", "printValue_MSB"
; You must define SEROUTPIN in your code before include.
; Default baud rate is 9600. Define OutBaud to change.
;
; OW_Reset - Resets the 1-Wire bus
; You must define OWPIN in your code before include.
; OW_Read - Read a byte from the 1-wire bus. Value returned "W" and "owData"
; You must define OWPIN in your code before include.
; OW_Write_W - Write value in "W" to the 1-wire bus
; You must define OWPIN in your code before include.
; OW_Write - Write the value in "owData" to the 1-wire bus
; You must define OWPIN in your code before include.
;
; I2C_Start - Creates I2C start condition
; I2C_Stop - Creates I2C stop condition
; I2C_Read - Reads a byte from the I2C bus. Value in W and i2cData
; I2C_Write_W - Writes "w" to the I2C bus
; I2C_Write - Writes value in "i2cData" to I2C bus
;-----------------------------------------------------------
; You may save code space by omitting code by defining these:
; #DEFINE No_Delay_mSec
; #DEFINE No_Delay_10mSec
; #DEFINE No_Print_Byte
; #DEFINE No_Print_Word
; #DEFINE No_I2C_Read
;-----------------------------------------------------------
; Serial pin is high when at idle
; Default baud rate is 9600
; Set baud rate by defineing OutBaud and InBaud (Range 19200 to 4800)
; For Example:
; #DEFINE OutBaud d'19200'
;-----------------------------------------------------------
; YOU MUST DEFINE THE PINS IN YOUR CODE
; If a pin is not defined, the routines that use that pin are not included
;
;SEROUTPIN EQU d'0'
;SERINPIN EQU d'1'
;SCLPIN EQU d'0'
;SDAPIN EQU d'1'
;OWPIN EQU d'2'
radix dec
; Subroutine variables. Uses RAM from 0x74 to 0x7f
delayuSec EQU 0x74
delay EQU 0x75 ; mSec value for delay_mSec routine
delayTemp EQU 0x76 ; Temp for delay_mSec routine
printValue EQU 0x77 ; Value to be printed (destroyed by subroutine)
printValue_LSB EQU 0x78 ; LSB of 16-bit value to be printed
printValue_MSB EQU 0x79 ; MSB of 16-bit value to be printed
printChar EQU 0x7a ; Char (digit) to be printed
tempW_LSB EQU 0x7b ; LSB of temporary variable
tempW_MSB EQU 0x7c ; MSB of temporary variable
serialData EQU 0x7d ; Data for Serial_Out routine
bitCnt EQU 0x7e ; Bit count for Serial_Out routine
owData EQU 0x7f ; Data for 1-wire device
; --------------------------------------------------------------
; Delay microSeconds
; CALL Delay_uSec_W ; value is in "W" min=3
; "W" is preserved; all flags are preserved
; --------------------------------------------------------------
Delay_uSec_W:
movwf delayuSec ; Save value
decfsz delayuSec,f ; Adjust for movlw,call,return overhead without affecting flags
decfsz delayuSec,f
nop
nop
decfsz delayuSec,f
goto $-2
return
#IFNDEF No_Delay_mSec
; --------------------------------------------------------------
; Delay milliSeconds
; CALL Delay_mSec_W ; value is in "W" 0 = 256mSec
; CALL Delay_mSec ; value to send is in "delay" 0 = 256mSec
; Destroys value in "delay"
; --------------------------------------------------------------
Delay_mSec_W: ; Delay "W" milliseconds
movwf delay ; Set delay variable
Delay_mSec:
movlw 4 ; (1)
movwf delayTemp ; (1)
movlw 249 ; (1)
call Delay_uSec_W
decfsz delayTemp,F ; (1)
goto $-3 ; (2)
decfsz delay,F ; Wait another millisecond ?
goto Delay_mSec ; Yes, go back again
retlw 0x00 ; No, Done
#ENDIF ; #IFNDEF No_Delay_mSec
; --------------------------------------------------------------
; Delay 10 milliSeconds
; CALL Delay_10mSec_W ; value is in "W" 0 = 2560mSec
; CALL Delay_10mSec ; value to send is in "delay" 0 = 2560mSec
; Destroys value in "delay"
; --------------------------------------------------------------
#IFNDEF No_Delay_10mSec
Delay_10mSec_W: ; Delay "W" milliseconds
movwf delay ; Set delay variable
Delay_10mSec:
movlw 40 ; (1)
movwf delayTemp ; (1)
movlw 249 ; (1)
call Delay_uSec_W
decfsz delayTemp,F ; (1)
goto $-3 ; (2)
decfsz delay,F ; Wait another millisecond ?
goto Delay_10mSec ; Yes, go back again
retlw 0x00 ; No, Done
#ENDIF ; #IFNDEF No_Delay_10mSec
#IFDEF SEROUTPIN
#IFNDEF No_Print_Word
; -----------------------------------------------------
; Send word value as ASCII to Serial_Out routine
; Does not print leading zeros
; CALL Print_Word ; value to be printed in "printValue"
; Destroys value in "printValue"
; Uses subroutine Serial_Out_W
; -----------------------------------------------------
Print_Word:
clrf printChar ; Set char to zero
; Do 10,000's digit
movlw 39 ; Set value to subtract to 10,000 for 10,000's digit
movwf tempW_MSB
movlw 16
movwf tempW_LSB
call WDigit ; Returns with "W" set to 48d
andwf printChar,F ; Zero the char, but keep the 32&16 bits.
; Do 1,000's digit
movlw 3 ; Set value to subtract to 1,000 for 1,000's digit
movwf tempW_MSB
movlw 232
movwf tempW_LSB
call WDigit ; Returns with "W" set to 48d
andwf printChar,F ; Zero the char, but keep the 32&16 bits
; Do 100's digit
clrf tempW_MSB ; Set value to subtract to 100 for 100's digit
movlw 100
movwf tempW_LSB
call WDigit ; Returns with "W" set to 48d
andwf printChar,F ; Zero the char, but keep the 32&16 bits
; Do 10's digit
movlw 10 ; Set value to subtract to 10 for 10's digit
movwf tempW_LSB
call WDigit ; Returns with "W" set to 48d
andwf printChar,F ; Zero the char, but keep the 32&16 bits
; Do 1's digit
addwf printValue_LSB,W ; 1's digit always prints, just add 48 to value left
goto Serial_Out_W ; Print digit and return
WDigit:
incf printChar,F ; Increment print char
movf tempW_LSB,W ; Prepare to subtract LSB values
subwf printValue_LSB,F ; Subtract LSB values
movf tempW_MSB,W ; Prepare to subtract MSB values (no borrow on LSB)
btfss STATUS,C ; If LSB caused a underflow,
incf tempW_MSB,W ; subtract 1 more from MSB
subwf printValue_MSB,F ; Subtract MSB of digit value from value to be printed
btfsc STATUS,C ; Did we underflow ?
goto WDigit ; No, then repeat
addwf printValue_MSB,F ; Yes, then add MSB digit value back to value to be printed
movf tempW_LSB,W ; and LSB as well
addwf printValue_LSB,F
decf printChar,W ; Print char will be 1 higher than value, dec it
btfsc STATUS,Z ; If print char is zero, then don't print it
retlw 48 ; Digit was leading zero, don't print it, just return
iorlw 48 ; Make char ASCI by setting 32 & 16 bits
movwf printChar ; Save value so next digit knows this wasn't a leading zero
goto Serial_Out_W ; Falls into Serial_Out_W
#ENDIF ; #IFNDEF No_Print_Word
#IFNDEF No_Print_Byte
; -----------------------------------------------------
; Send byte value as ASCII to Serial_Out routine
; Does not print leading zeros
; CALL Print_W ; value to be printed in "W"
; CALL Print ; value to be printed in "printValue"
; Destroys value in "printValue"
; Uses subroutine Serial_Out_W
; -----------------------------------------------------
Print_Byte_W:
movwf printValue ; Save value to print
Print_Byte:
clrf printChar ; Set char to zero
movlw 100 ; Set value to subtract to 100 for 100's digit
call BDigit ; Returns with "W" set to 48d
andwf printChar,F ; Zero the char, but keep the 32&16 bits then we can tell that
; the 100's character WASN'T a zero if they are set
movlw 10 ; Set value to subtract to 10 for 10's digit
call BDigit ; Returns with "W" set to 48d
addwf printValue,W ; 1's digit always prints, just add 48 to value left
goto Serial_Out_W ; Print digit and return
BDigit:
incf printChar,F ; Increment print char
subwf printValue,F ; Subtract digit value from value to be printed
btfsc STATUS,C ; Did we underflow ?
goto BDigit ; No, then repeat
addwf printValue,F ; Yes, then add digit value back to value to be printed
decf printChar,W ; Print char will be 1 higher than value, dec it
btfsc STATUS,Z ; If print char is zero, then don't print it
retlw 48 ; Digit was leading zero, don't print it, just return
iorlw 48 ; Make char ASCI by setting 32 & 16 bits
movwf printChar ; Save value so next digit knows this wasn't a leading zero
; Falls into Serial_Out_W
#ENDIF ; #IFNDEF No_Print_Byte
; -----------------------------------------------------
; Sends a character to "SEROUTPIN" as serial data
; If clock is 4MHz baud rate is 19200
; CALL Serial_Out_W ; value to send is in "W"
; CALL Serial_Out ; value to send is in "serialData"
; Destroys "serialData" & "bitCnt"
; -----------------------------------------------------
#IFNDEF OutBaud
#DEFINE OutBaud 9600
#ENDIF
Serial_Out_W: ; Sends value in "W" on pin "SEROUTPIN"
movwf serialData
Serial_Out:
movlw 10 ; Send 10 bits (including start bit and stop bit)
movwf bitCnt
bcf LATA,SEROUTPIN ; Set pin to start bit state (same as data 0 bit state)
SerOut_NextBit:
movlw (960000 / OutBaud) ; Delay for each bit
call Delay_uSec_W
btfsc serialData,0 ; set pin to data bit state
bsf LATA,SEROUTPIN
btfss serialData,0
bcf LATA,SEROUTPIN
bsf STATUS,C ; rotate data bits and shift in stop bit value (1 bit)
rrf serialData,F
decfsz bitCnt,F ; loop until all bits are done
goto SerOut_NextBit
retlw 48 ; Support "Print" subroutine by setting "W" to 48d on return
#ENDIF ; IFDEF SEROUTPIN
; -----------------------------------------------------
; Receives a character from "SERPIN" as serial data
; If clock is 16MHz baud rate is 19200
; CALL Serial_In ; value received is in "serialData"
; -----------------------------------------------------
#IFDEF SERINPIN
#IFNDEF InBaud
#DEFINE InBaud 9600
#ENDIF
Serial_In:
clrf serialData
btfss PORTA,SERINPIN ; Wait for idle (HIGH)
goto $-1
btfsc PORTA,SERINPIN ; Wait for start bit (LOW)
goto $-1
movlw (1440000 / InBaud) ; Wait 1.5 bit times
call Delay_uSec_W
movlw 8 ; Receive 8 bits
movwf bitCnt
SerIn_NextBit:
bcf STATUS,C ; Make carry match pin state
btfsc PORTA,SERINPIN
bsf STATUS,C
rrf serialData,F ; Shift in received bit
movlw (960000 / InBaud) ; Wait 1 bit time
call Delay_uSec_W
decfsz bitCnt,F
goto SerIn_NextBit
movf serialData,w
return
#ENDIF ; IFDEF SERINPIN
; -----------------------------------------------------
; Reset 1-Wire device
; CALL OW_Reset ; Resets 1-wire device
; -----------------------------------------------------
#IFDEF OWPIN
OW_Reset:
bcf LATA,OWPIN ; Make pin low
bcf TRISA,OWPIN
movlw 250 ; Delay 500uSec
call Delay_uSec_W
movlw 250
call Delay_uSec_W
bsf TRISA,OWPIN ; Make pin input
movlw 250 ; Delay 500uSec
call Delay_uSec_W
movlw 250
call Delay_uSec_W
return
; -----------------------------------------------------
; Read a byte from 1-Wire device
; CALL OW_Read ; Read byte from 1-wire device, value in owData
; -----------------------------------------------------
OW_Read:
movlw 0xff
; -----------------------------------------------------
; Write a byte to 1-Wire device
; CALL OW_Write ; Write byte to 1-wire device
; -----------------------------------------------------
OW_Write_W:
movwf owData
OW_Write:
; 0 = Low for 60uSec; input for 10uSec
; 1 = Low for 5uSec; input for 15uSec, sample, input for 55uSec
movlw 8
movwf bitCnt
OW_Write_Next
rrf owData,f
bcf TRISA,OWPIN ; Make pin low
movlw 5
call Delay_uSec_W
btfsc STATUS,C ; If C=1 make pin input
bsf TRISA,OWPIN
movlw 10
call Delay_uSec_W
btfss PORTA,OWPIN ; If pin is low
bcf STATUS,C ; then clear carry
movlw 45
call Delay_uSec_W
bsf TRISA,OWPIN ; Make pin input
movlw 10
call Delay_uSec_W
decfsz bitCnt,f ; Do all bits
goto OW_Write_Next
rrf owData,f ; Get last bit from carry
movf owData,w ; Return with value read in "W"
return
#ENDIF ; IFDEF OWPIN
#IFDEF SCLPIN
#IFDEF SDAPIN
I2C_Start:
return
I2C_Stop:
return
#IFNDEF No_I2C_Read
I2C_Read:
return
#ENDIF ; #IFNDEF No_I2C_Read
I2C_Write_W:
movwf i2cData
I2C_Write:
return
#ENDIF ; #IFDEF SDAPIN
#ENDIF ; #IFDEF SCLPIN
; Read DS18B20 on pin RA.2 (needs 4.7K pull-up)
; Display on Serial LCD (Parallax) on pin RA.0
#include "p10f322.inc"
radix dec
__CONFIG _CP_OFF & _FOSC_INTOSC & _WDTE_OFF & _MCLRE_OFF & _LVP_OFF
; Pins
SEROUTPIN equ 0
OWPIN equ 2
; Variables (start at 0x40)
strPtr equ 0x40
tempLSB equ 0x41
tempMSB equ 0x42
; Startup code
ORG 0x0
movlw 0x70 ; Setup for 16MHz clock
movwf OSCCON
goto Start ; Jump to start of code
; Interrupt code
ORG 0x4
retfie
#DEFINE No_Print_Word
#DEFINE No_Delay_mSec
#include "10f322_routines_16MHz.inc"
radix dec
; --------------------------------------------------
; PrintStr is used to retrieve strings from program memory
; --------------------------------------------------
GetChar:
movf strPtr,w
addwf PCL,f
TableStart:
InitStr:
DT d'22', d'17', "PIC10F322", d'13', "LCD Demo", 0
TempStr:
DT d'128', "Temp=", 0
PrintStr:
addlw (d'256'-TableStart) ; Adjust for table offset
movwf strPtr
PrintStrNext:
call GetChar
addlw 0 ; Check if W is zero
btfsc STATUS,Z
return ; If W is zero, then return
call Serial_Out_W
incf strPtr,f
goto PrintStrNext
; --------------------------------------------------
Start:
; Setup serial output pin
bcf TRISA,SEROUTPIN
bcf ANSELA,SEROUTPIN
bsf LATA,SEROUTPIN
; Setup 1-wire pin
bsf TRISA,OWPIN
bcf ANSELA,OWPIN
bcf LATA,OWPIN
movlw d'10' ; Wait for LCD to startup
call Delay_10mSec_W
call ClearScreen
movlw InitStr
call PrintStr
movlw d'200'
call Delay_10mSec_W
call ClearScreen
Main:
movlw TempStr
call PrintStr
; Start temperature measurement
call OW_Reset
movlw 0xCC ; SkipROM command
call OW_Write_W
movlw 0x44 ; Convert command
call OW_Write_W
movlw d'80'
call Delay_10mSec ; Conversion takes 750mSec
; Read temperature
call OW_Reset
movlw 0xCC ; Send "SkipROM" command
call OW_Write_W
movlw 0xBE ; Send "Read scratchpad" command
call OW_Write_W
call OW_Read
movwf tempLSB
call OW_Read
movwf tempMSB
; Convert value to degrees
btfss tempMSB,7 ; Check if negative
goto Positive
movlw "-" ; print a "-" sign
call Serial_Out_W
comf tempMSB,f ; negate value
comf tempLSB,f
incf tempLSB,f
btfsc STATUS,Z
incf tempMSB,f
Positive:
; Rearrange bits so MSB hold whole value and LSB holds fractional value
movf tempLSB,w ; Get LSB bits
andlw 0xf0 ; only want high nibble
iorwf tempMSB,f ; put high nibble in MSB high nibble
swapf tempMSB,f ; exchange MSB high/low nibble
movlw 0x0f ; only want low nibble of LSB
andwf tempLSB,f
; Print whole temperature value (MSB)
movf tempMSB,w
call Print_Byte_W
; Print decimal point
movlw "."
call Serial_Out_W
; Print 1 digit of fractional temperature value (LSB)
; digit=(LSB*10)/16
bcf STATUS,C ; Clear carry for shift
rlf tempLSB,w ; w=LSB * 2
swapf tempLSB,f ; LSB=LSB * 16
bcf STATUS,C ; Clear carry for shift
rrf tempLSB,f ; LSB=LSB * 8 (* 16 / 2)
addwf tempLSB,f ; LSB = LSB * 10 (* 8 + * 2)
swapf tempLSB,w ; W = LSB / 16
andlw 0x0f ; Only use lower nibble of W
call Print_Byte_W ; Print digit
; Print "C" plus two spaces to overwrite old digits
movlw "C"
call Serial_Out_W
movlw " "
call Serial_Out_W
movlw " "
call Serial_Out_W
goto Main
ClearScreen:
movlw d'12' ; Clear Screen
call Serial_Out_W
movlw d'1' ; Must wait at least 5mSec after clear screen command
call Delay_10mSec_W
return
END
;==================================================================
; Pommie's brilliant DS18B20 Celsius to Fahrenheit algorithm
;
; 10F = 18C + 320 = 16C + 2C + 320 = 16C + (16C+4)/8 + 320
;
; TempH:L Neg Output Display
; =========================================
; 125.0000°C h'07D0' 0 2570 257.0°F
; 100.0000°C h'0640' 0 2120 212.0°F
; 77.0000°C h'04D0' 0 1706 170.6°F
; 25.0000°C h'0190' 0 0770 77.0°F
; 22.0000°C h'0160' 0 0716 71.6°F
; 0.5000°C h'0008' 0 0329 32.9°F
; 0.0625°C h'0001' 0 0321 32.1°F
; 0.0000°C h'0000' 0 0320 32.0°F
; - 0.0625°C h'FFFF' 0 0319 31.9°F
; - 0.1250°C h'FFFE' 0 0318 31.8°F
; - 5.0000°C h'FFB0' 0 0230 23.0°F
; -10.0000°C h'FF60' 0 0140 14.0°F
; -17.0625°C h'FEEF' 0 0013 1.3°F
; -17.6875°C h'FEE5' 0 0002 0.2°F
; -17.7500°C h'FEE4' 0 0001 0.1°F
; -17.8125°C h'FEE3' 1 0001 - 0.1°F
; -25.0000°C h'FE70' 1 0130 -13.0°F
; -55.0000°C h'FC90' 1 0670 -67.0°F
;
radix dec
c_to_f
;
; binh:binl = (TempH:TempL + 4) / 8
;
rlf TempH,W ; preserve sign bit (b15)
rrf TempH,W ;
movwf binh ;
rrf TempL,W ;
addlw 2 ; rounding
movwf binl ;
skpnc ;
incf binh,F ;
rlf binh,W ; preserve sign bit (b15)
rrf binh,F ;
rrf binl,F ;
rlf binh,W ; preserve sign bit (b15)
rrf binh,F ;
rrf binl,F ;
;
; binh:binl = binh:binl + TempH:TempL
;
movf TempL,W ;
addwf binl,F ;
movf TempH,W ;
skpnc ;
incf TempH,W ;
addwf binh,F ;
;
; binh:binl = binh:binl + 320
;
movlw low(320) ;
addwf binl,F ;
movlw high(320) ;
skpnc ;
addlw 1 ;
addwf binh,F ;
;
; get absolute value, set NegFlag
;
bcf NegFlag ;
btfss binh,7 ; negative? yes, skip, else
goto bin2dec ; branch
bsf NegFlag ;
comf binl,F ; twos complement result
comf binh,F ;
incf binl,F ;
skpnz ;
incf binh,F ;
;
; bin-to-bcd (13 bits -> 0000..9999)
;
bin2dec
clrf thou ;
movlw -10 ; wreg = -10
resHuns movwf huns ; set huns = -10
resTens movwf tens ; set tens = -10
div10z addwf binl,F ; binl = binl - 10, borrow?
skpc ; no, skip, else
decf binh,F ; decrement hi byte
btfsc binh,7 ; negative? no, skip, else
goto b2dwrap ; wrap up (underflow)
incfsz tens,F ; tens overflow? yes, skip, else
goto div10z ; loop
incfsz huns,F ; huns overflow? yes, skip, else
goto resTens ; reset 'tens' & loop
incf thou,F ; bump 'thou'
goto resHuns ; reset 'huns' & 'tens' & loop
b2dwrap subwf huns,F ; fix huns
subwf tens,F ; fix tens
subwf binl,W ; fix ones
movwf ones ;
;
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?