How good/effective is this code

Thread Starter

MisterFisk

Joined Jun 8, 2020
18
Good Day,

Would you mind having a look at my code and give me a rating of what you think of it? What the code does is it Takes a hexadecimal(0xAF) byte and then detects the Ascii characters used in this byte and outputs them separately.

The program works quite well from what I tested.

(I tried getting the comments in a nice column in the post, but I couldn't get it right)

Code:
;*************HexToAscii********************************************************
;Name:
;Student Number :
;Program Description :The program detects what Ascii characters would     
;              represent the Hexadecimal Values in Hexbyte and stores
;              them in two seperate registers. AsciiTens for the MSB and
;              AsciiUnits for the LSB.
;Registers Affected : w,FSR,INDF,STATUS,20h,21h,22h,23h
;Input registers : 20h
;Output registers : 21h,22h
;Process details : Seperate the 4 MSB and the 4 LSB and then detect the Ascii
;           character represented by these bits.
  
;**********Config**************************************************************

;PIC16F877A
  
;*************Equates***********************************************************

FSR        equ    04h
PCL        equ    02h
INDF      equ    00h
Status    equ    03h
Carry     equ    0
RamBank0    equ    20H

;*************Variables*********************************************************
  
    cblock  RamBank0
    HexByte       ;Reg for HexByte,Input        20h
    CharTens       ;Reg for CharTens,Output    21h
    CharUnits      ;Reg for CharUnits,Output   22h
    Counter         ;Reg for Loop Counter        23h
    endc

  
RES_VECT  CODE    0x0000            ; processor reset vector
    GOTO    START                   ; go to beginning of program

; TODO ADD INTERRUPTS HERE IF USED

MAIN_PROG CODE                     ; let linker place main program

START

;*************Initialization****************************************************
;Prepares and clears the nessesary registers for inputs,outputs and Loops

;Effected Registers
;CharTens   21h
;CharUnits  22h
;w reg
;Counter    23h
;FSR     

    clrf    CharTens            ;Clears Output  21h
    clrf    CharUnits           ;Clears Output    22h
    movlw   B'00000100'   ;Moves decimal 4 to w reg to put into Counter
    movwf   Counter         ;Moves w reg to Counter 23h
    movf    HexByte,0        ;Moves HexByte to w reg
    movwf   CharTens       ;Moves w reg to CharTens 21h
    movwf   CharUnits       ;Moves w reg to CharUnits 22h
    movlw   21h                 ;Moves Hexadecimal value 21h to w reg
    movwf   FSR                 ;Prepares the FSR to point at reg 21h which is
                                         ;CharTens and the first output register
  
;*************DetectAscii*******************************************************
;This is the main code. It will call the functions needed to rotate and detect
;the Ascii present in the HexByte and store them in the correct registers
;It first handels CharTens after which it increases the FSR to point to
;CharUnits.
              
;Effected Registers
;CharTens   21h
;CharUnits  22h
;w reg
;Counter    23h
;FSR                   
          
DetectAscii
    CALL    ShiftRight        ;Calls ShiftRight function to manipulate
                                        ;CharTens
    movf    INDF,0             ;Moves the manipulated CharTens to w reg
    CALL    AsciiChar         ;Calls AsciiChar to detect what Ascii character
                                        ;represents CharTens Value
    movwf   INDF             ;w reg (which contains the value returned from
                                        ;AsciiChar) to the output reg of CharTens 21h
    incf    FSR                    ;Increses FSR to point to CharUnits 22h
    CALL    ShiftLeft          ;Calls ShiftLeft function to manipulate
                                        ;Manipulate CharUnits
    CALL    ShiftRight       ;Calls ShiftRight funtion to manipulate
                                        ;CharUnits
    movf    INDF,0             ;Moves the manipulated CharUnits to w reg
    CALL    AsciiChar         ;Calls AsciiChar function to detect what Ascii
                                        ;characrer represents CharUnits Value
    movwf   INDF              ;w reg (which contains the value returned from
                                        ;AsciiChar) to the output reg of CharUnits 22h
  
    GOTO $                       ;loop forever/Program End
;*************ShiftRight********************************************************
;This funtion clears the fisrt bit of the register indicated by the INDF and
;then shifts this register to the right. This loop loops 4 times before it
;resets the counter and returns to the main code.
  
;This function is used to move the 4 MSB bits in the byte to the first 3 LSB
;bits (eg 10101111 -> 00001010)
  
;Effected Registers
;CharTens   21h
;CharUnits  22h
;w reg
;Counter    23h       
 
ShiftRight
    bcf        INDF,0        ;clears the fisrt bit of the reg indicated by the
                                    ;INDF
    rrf        INDF            ;Rotates the reg indicated by the INDF to the right
    decfsz  Counter       ;decreases counter and skips next instruction if the
                                    ;counter is zero
    GOTO    ShiftRight        ;loop ShiftRight
          
    movlw   B'00000100'       ;Resets the counter
    movwf   Counter
  
    return            ;Returns to main code DetectAscii

;*************ShiftLeft*********************************************************
;This function rotates the register left. This loop loops 4 times before
;resting the counter and returning to the main code

;This function is to prepares the INDF(CharUnits 22h) for the ShiftRight
;function that will sepereate the needed bits
  
;Effected Registers
;CharTens   21h
;CharUnits  22h
;w reg
;Counter    23h       
 
ShiftLeft
    rlf        INDF             ;Rotates the reg indicated by the INDF to the left
    decfsz  Counter        ;Decreases counter
    GOTO    ShiftLeft     ;loop ShiftLeft
  
    movlw   B'00000100'        ;Resets the counter
    movwf   Counter     
  
    Return            ;Returns to main code DetectAscii
  
;*************ReferenceTabl***************************************************** 
;This is the reference table that will detect the Ascii Character representing
;the hexadecimal vaule. It adds the w reg(which will be loaded with the
;manipulated CharTens and CharUnit values) to the PCL to indicate which one the
;function should return.
  
;Effected Registers
;w reg

AsciiChar
    addwf   PCL,1
    retlw   B'00110000'       ;Decode 0
    retlw   B'00110001'       ;Decode 1
    retlw   B'00110010'       ;Decode 2
    retlw   B'00110011'        ;Decode 3
    retlw   B'00110100'       ;Decode 4
    retlw   B'00110101'       ;Decode 5
    retlw   B'00110110'       ;Decode 6
    retlw   B'00110111'       ;Decode 7
    retlw   B'00111000'       ;Decode 8
    retlw   B'00111001'       ;Decode 9
    retlw   B'01000001'       ;Decode A
    retlw   B'01000010'        ;Decode B
    retlw   B'01000011'       ;Decode C
    retlw   B'01000100'       ;Decode D
    retlw   B'01000101'       ;Decode E
    retlw   B'01000110'       ;Decode F
  
    GOTO $                          ; loop forever

    END
 

jpanhalt

Joined Jan 18, 2008
11,087
I am taking a look at the code now. As for format, be sure to set "replace tabs with spaces." With MPLab 8.92, that is easy to do. Don't know how to do it with later IDE's. Once formatted properly, copy and paste here as you have done, Use code or plain tags like this: [code] <insert code>[/code]
 

Thread Starter

MisterFisk

Joined Jun 8, 2020
18
Netwide Assembler:
;*************HexToAscii********************************************************
;Name: Erasmus van Graan
;Student Number : 60595132
;Program Description :The program detects what Ascii characters would      
;        represent the Hexadecimal Values in Hexbyte and stores
;        them in two seperate registers. AsciiTens for the MSB and
;        AsciiUnits for the LSB.
;Registers Affected : w,FSR,INDF,STATUS,20h,21h,22h,23h
;Input registers : 20h
;Output registers : 21h,22h
;Process details : Seperate the 4 MSB and the 4 LSB and then detect the Ascii
;           character represented by these bits.
   
;**********Config**************************************************************

;PIC16F877A
   
;*************Equates***********************************************************

FSR        equ    04h
PCL        equ    02h
INDF        equ    00h
Status        equ    03h
Carry        equ    0
RamBank0    equ    20H

;*************Variables*********************************************************
   
    cblock  RamBank0
    HexByte        ;Reg for HexByte,Input        20h
    CharTens        ;Reg for CharTens,Output    21h
    CharUnits        ;Reg for CharUnits,Output   22h
    Counter        ;Reg for Loop Counter        23h
    endc

   
RES_VECT  CODE    0x0000            ; processor reset vector
    GOTO    START                   ; go to beginning of program

; TODO ADD INTERRUPTS HERE IF USED

MAIN_PROG CODE                      ; let linker place main program

START

;*************Initialization****************************************************
;Prepares and clears the nessesary registers for inputs,outputs and Loops

;Effected Registers
;CharTens   21h
;CharUnits  22h
;w reg
;Counter    23h
;FSR      

    clrf    CharTens        ;Clears Output  21h
    clrf    CharUnits        ;Clears Output    22h  
    movlw   B'00000100'        ;Moves decimal 4 to w reg to put into Counter
    movwf   Counter        ;Moves w reg to Counter 23h
    movf    HexByte,0        ;Moves HexByte to w reg
    movwf   CharTens        ;Moves w reg to CharTens 21h
    movwf   CharUnits        ;Moves w reg to CharUnits 22h
    movlw   21h            ;Moves Hexadecimal value 21h to w reg
    movwf   FSR            ;Prepares the FSR to point at reg 21h which is
                ;CharTens and the first output register
   
;*************DetectAscii*******************************************************
;This is the main code. It will call the functions needed to rotate and detect
;the Ascii present in the HexByte and store them in the correct registers
;It first handels CharTens after which it increases the FSR to point to
;CharUnits.
               
;Effected Registers
;CharTens   21h
;CharUnits  22h
;w reg
;Counter    23h
;FSR                    
           
DetectAscii
    CALL    ShiftRight        ;Calls ShiftRight function to manipulate
                ;CharTens
    movf    INDF,0        ;Moves the manipulated CharTens to w reg
    CALL    AsciiChar        ;Calls AsciiChar to detect what Ascii character
                ;represents CharTens Value
    movwf   INDF        ;w reg (which contains the value returned from
                ;AsciiChar) to the output reg of CharTens 21h
    incf    FSR            ;Increses FSR to point to CharUnits 22h
    CALL    ShiftLeft        ;Calls ShiftLeft function to manipulate
                ;Manipulate CharUnits
    CALL    ShiftRight        ;Calls ShiftRight funtion to manipulate
                ;CharUnits
    movf    INDF,0        ;Moves the manipulated CharUnits to w reg
    CALL    AsciiChar        ;Calls AsciiChar function to detect what Ascii
                ;characrer represents CharUnits Value
    movwf   INDF        ;w reg (which contains the value returned from
                ;AsciiChar) to the output reg of CharUnits 22h
   
    GOTO $            ;Loop forever/Program End
;*************ShiftRight********************************************************
;This funtion clears the fisrt bit of the register indicated by the INDF and
;then shifts this register to the right. This loop loops 4 times before it
;resets the counter and returns to the main code.
   
;This function is used to move the 4 MSB bits in the byte to the first 3 LSB
;bits (eg 10101111 -> 00001010)
   
;Effected Registers
;CharTens   21h
;CharUnits  22h
;w reg
;Counter    23h        
   
ShiftRight
    bcf        INDF,0        ;clears the fisrt bit of the reg indicated by the
                ;INDF
    rrf        INDF        ;Rotates the reg indicated by the INDF to the right
    decfsz  Counter        ;decreases counter and skips next instruction if the
                ;counter is zero
    GOTO    ShiftRight        ;loop ShiftRight
           
    movlw   B'00000100'        ;Resets the counter
    movwf   Counter
   
    return            ;Resturns to main code DetectAscii

;*************ShiftLeft*********************************************************
;This function rotates the register left. This loop loops 4 times before
;resting the counter and returning to the main code

;This function is to prepares the INDF(CharUnits 22h) for the ShiftRight
;function that will sepereate the needed bits
   
;Effected Registers
;CharTens   21h
;CharUnits  22h
;w reg
;Counter    23h        
   
ShiftLeft
    rlf        INDF        ;Rotates the reg indicated by the INDF to the left
    decfsz  Counter        ;Decreases counter
    GOTO    ShiftLeft        ;loop ShiftLeft
   
    movlw   B'00000100'        ;Resets the counter
    movwf   Counter      
   
    Return            ;Resturns to main code DetectAscii
   
;*************ReferenceTabl*****************************************************  
;This is the reference table that will detect the Ascii Character representing
;the hexadecimal vaule. It adds the w reg(which will be loaded with the
;manipulated CharTens and CharUnit values) to the PCL to indicate which one the
;function should return.
   
;Effected Registers
;w reg

AsciiChar
    addwf   PCL,1
    retlw   B'00110000'        ;Decode 0
    retlw   B'00110001'        ;Decode 1
    retlw   B'00110010'        ;Decode 2
    retlw   B'00110011'        ;Decode 3
    retlw   B'00110100'        ;Decode 4
    retlw   B'00110101'        ;Decode 5
    retlw   B'00110110'        ;Decode 6
    retlw   B'00110111'        ;Decode 7
    retlw   B'00111000'        ;Decode 8
    retlw   B'00111001'        ;Decode 9
    retlw   B'01000001'        ;Decode A
    retlw   B'01000010'        ;Decode B
    retlw   B'01000011'        ;Decode C
    retlw   B'01000100'        ;Decode D
    retlw   B'01000101'        ;Decode E
    retlw   B'01000110'        ;Decode F
   
    GOTO $                          ; loop forever

    END
 

jpanhalt

Joined Jan 18, 2008
11,087
The code assembles. I needed to change this:
Code:
RES_VECT  CODE    0x0000            ; processor reset vector
    GOTO    START                   ; go to beginning of program
to this:
Code:
     ORG       0x0000
    GOTO    START                   ; go to beginning of program
START
That is probably because I use absolute, not relocatable code.

There were some messages related to not showing a destination register for incf, rrf, rlf, and decfsz .
In several places, you use "effected registers" and probably mean "affected registers."

Aside from those minor nitpicks, you use a look-up table well to accomplish your purpose.

Just FYI, here is how I convert binary to ascii (Source; PicList.com, Scott Dattalo):
Code:
;Since char_hi is transmitted first, original code was
;modified to finish with char_hi in w.  Modified version is 13 cycles.
;Enter with binary in w.
;*******************************************************************************
BIN2ASCII
     movwf  char
     andlw  0x0f
     addlw  6
     btfsc  STATUS,1                
     addlw  0x07                  
     addlw  0x2A                  
     movwf  char_lo
     swapf  char,w
     andlw  0x0f
     addlw  6
     btfsc  STATUS,1              
     addlw  0x07                  
     addlw  0x2A                  
;    movwf  char_hi            ;optional so no worry about w on call/return     
     return
That works with this macro to print to an LCD when I want to see what's happening:
Code:
;*******************************************************************************  
;                          RegPrint Macro
;*******************************************************************************
RegPrint  macro     label
          movf      label,w
          call      bin2ascii
          call      Put232
          movf      char_lo,w
          call      Put232     
          endm
;*******************************************************************************
 

Thread Starter

MisterFisk

Joined Jun 8, 2020
18
The code assembles. I needed to change this:
Code:
RES_VECT  CODE    0x0000            ; processor reset vector
    GOTO    START                   ; go to beginning of program
to this:
Code:
     ORG       0x0000
    GOTO    START                   ; go to beginning of program
START
That is probably because I use absolute, not relocatable code.

There were some messages related to not showing a destination register for incf, rrf, rlf, and decfsz .
In several places, you use "effected registers" and probably mean "affected registers."

Aside from those minor nitpicks, you use a look-up table well to accomplish your purpose.

Just FYI, here is how I convert binary to ascii (Source; PicList.com, Scott Dattalo):
Code:
;Since char_hi is transmitted first, original code was
;modified to finish with char_hi in w.  Modified version is 13 cycles.
;Enter with binary in w.
;*******************************************************************************
BIN2ASCII
     movwf  char
     andlw  0x0f
     addlw  6
     btfsc  STATUS,1               
     addlw  0x07                 
     addlw  0x2A                 
     movwf  char_lo
     swapf  char,w
     andlw  0x0f
     addlw  6
     btfsc  STATUS,1             
     addlw  0x07                 
     addlw  0x2A                 
;    movwf  char_hi            ;optional so no worry about w on call/return    
     return
That works with this macro to print to an LCD when I want to see what's happening:
Code:
;******************************************************************************* 
;                          RegPrint Macro
;*******************************************************************************
RegPrint  macro     label
          movf      label,w
          call      bin2ascii
          call      Put232
          movf      char_lo,w
          call      Put232    
          endm
;*******************************************************************************
Thank you for your feedback. Your code is much more efficient than mine. I didn't think about using swapf.
 
Top