Help with routine inc / dec in ASM 16 bit PIC16f877 - Page 1
Forum section: electronics / general

author: aless2056
author_rank: Contributor
timestamp: May 30, 2021, 01:51:09 am
content: Guys, I made this code in asm for a PIC 16F877 that decreases Value (high and low) to 0x00 and increases to 0x64. Does anyone see something wrong with this code, or do you think it could be improved?DECMOVF VALUE_HIGH,WSUBLW B'00000000'BTFSS STATUS,CGOTO DC_DECMOVF VALUE_LOW,WSUBLW B'00000000'BTFSC STATUS,CGOTO EXITDC_DECDECF VALUE_LOW,FMOVLW .255XORWF VALUE_LOW,WBTFSC STATUS,ZDECF VALUE_HIGH,FGOTO EXITINCMOVLW B'00000011'SUBWF VALUE_HIGH,WBTFSS STATUS,CGOTO DC_INCMOVLW B'11101000'SUBWF VALUE_LOW,WBTFSC STATUS,CGOTO EXITDC_INCINCF VALUE_LOW,FBTFSC STATUS,ZINCF VALUE_HIGH,FGOTO EXIT

author: Dabbot
author_rank: Regular Contributor
timestamp: May 30, 2021, 03:28:00 am
content: To clarify, you want subroutines that increment or decrement a 16 bit integer, with a lower limit of 0 and upper limit of 1000 (0x03E8)?Your test for zero can be improved by using the IORWF instruction to compare VALUE_HIGH with VALUE_LOW, and checking STATUS, ZThe decrement underflow can be improved by testing VALUE_LOW for zero first and decrementing VALUE_HIGH if STATUS, Z, then finally decrementing VALUE_LOW.

author: aless2056
author_rank: Contributor
timestamp: May 30, 2021, 01:50:42 pm
content: Quote from: Dabbot on May 30, 2021, 03:28:00 amBut then I would not be decreasing the value twice at the same time?I could rewrite the code to make it easier to visualize these changes

author: DavidAlfa
author_rank: Super Contributor
timestamp: May 30, 2021, 03:44:56 pm
content: The 18F series have much better instruction set, in special add/subtract/compare-and-jump ones, while still very easy to understand.Check a basic one like the 18F1220, very much like the 16F877. It will make your life easier!My asm is a bit rusty, but these PICS are really easy. I might have mistaken some BTFSS/BTFSC but the idea is there.Code:;--------------------------------------------------------------------------------------------------------; Start;--------------------------------------------------------------------------------------------------------STARTCALL INCR_16BIT ; Increase valueCALL DECR_16BIT ; Decrease valueDONEGOTO DONEINCR_16BITMOVLW 1ADDWF VALUE_LOW,F ; Increase Low byteBTFSS STATUS,C ; Is carry bit set?GOTO UPPER_LIMIT ; No, but we still need to check limits.ADDWF VALUE_HIGH,F ; Yes, increase high byteBTFSS STATUS,C ; Is carry bit set?GOTO UPPER_LIMIT ; No, but we still need to check limits.GOTO SET_MAX ; We got overflow! Apply limits;--------------------------------------------------------------------------------------------------------; Decrease 16 bit value;--------------------------------------------------------------------------------------------------------DECR_16BITMOVLW 1SUBWF VALUE_LOW,F ; Decrease Low byteBTFSC STATUS,C ; Is borrow bit set?RETURN ; Yes, we're doneSUBWF VALUE_HIGH,F ; No(Active), decrease high byteBTFSC STATUS,C ; Is borrow bit set?RETURN ; Yes, we're doneCLRF VALUE_HIGH ; No, we got underflow! Set min val(0)CLRF VALUE_LOW ;RETURN ;;--------------------------------------------------------------------------------------------------------; Check and clamp max value to 1000 (0x3E8);--------------------------------------------------------------------------------------------------------UPPER_LIMITMOVLW 0x03 ; Move 0x03 to WSUBWF VALUE_HIGH,W ; Subtract W to VALUE_HIGH, save to WBTFSS STATUS,C ; Check borrow bitRETURN ; Borrow not set, so VALUE_HIGH<0x03, nothing else to checkBTFSS STATUS,Z ; Borrow set, so VALUE_HIGH>=0x03. Read Z bitGOTO SET_MAX ; Z not set, so VALUE_HIGH>0x03, apply limitsMOVLW 0xE8 ; Z was set, so VALUE_HIGH=0x03, check lower byte. Move 0xE8 to W.SUBWF VALUE_LOW,W ; Subtract W to VALUE_LOW, store in WBTFSS STATUS,C ; Borrow bit set?RETURN ; Borrow not set, so VALUE_LOW<0xE8, nothing else to checkGOTO SET_MAX ; Borrow set, apply max valuesSET_MAXMOVLW 0x03 ; Set max value(0x03E8)MOVWF VALUE_HIGH ;MOVLW 0xE8 ;MOVWF VALUE_LOW ;RETURN ;Or did you mean to store it as 0-99 lower byte, 0-99 higher byte? So when lower byte goes>99, you increase higher byte?That's requires more checks but is not hard. Explain better...

author: Dabbot
author_rank: Regular Contributor
timestamp: May 30, 2021, 04:02:32 pm
content: Quote from: aless2056 on May 30, 2021, 01:50:42 pmTry this:Code:; Do nothing if zeroDEC16MOVF VALUE_LOW, WIORWF VALUE_HIGH, WBTFSC STATUS, ZRETURN; DecrementMOVF VALUE_LOW, WBTFSC STATUS, ZDECF VALUE_HIGH, FDECF VALUE_LOW, FRETURNQuote from: DavidAlfa on May 30, 2021, 03:44:56 pmThe INCF / DECF instructions only update the ZERO flag, not the CARRY flag.

author: DavidAlfa
author_rank: Super Contributor
timestamp: May 30, 2021, 04:09:37 pm
content: Quote from: Dabbot on May 30, 2021, 04:02:32 pmOoops, yes, these cheap ass PIC16! In PIC18 it does...Fixed. Made a quick simulation here:http://www.onlinepiccompiler.com/compiler16f84av1ENG.phpNice memories from years ago. I really liked PIC asm back in the day!.