Relative addressing mode problem with HC05

Discussion in 'Embedded Systems and Microcontrollers' started by JohnnyD, Jul 6, 2007.

  1. JohnnyD

    Thread Starter Well-Known Member

    Aug 29, 2006
    79
    0
    Hi,

    I'm having a problem with a Branch instruction in a program i'm trying to write for a Freescale HC05 micro.

    Basically, in the HC05, when a branch instruction is executed, an 8-bit signed integer value is calculated and used to adjust the program counter (PC) forward or backwards so it continues execution at the correct location.

    As an example i've just written a simple bit of code which loops back to the label 'HERE' until the value of PORTA = zero:
    Code ( (Unknown Language)):
    1. HERE     LDA     PORTA
    2.          BNE     HERE
    so the relative offset is calculated by how much the PC needs to be adjusted by in order to continue at 'HERE'. So the offset in this case will be negative.

    My problem is that I have more than 127 bytes of code between 'HERE' and the branch instruction which is more than can be represented by an 8-bit signed integer which results in a compiler error.

    What can I do about this? I'm surprised at this limitation, and I wonder why Freescale didn't use a 16-bit signed integer value for relative addressing offsets instead.
     
  2. Papabravo

    Expert

    Feb 24, 2006
    10,138
    1,787
    The solution is
    Code ( (Unknown Language)):
    1.  
    2. HERE:
    3.           LDA   PORTA
    4.           .
    5.           .
    6.           .
    7.           BEQ  THERE
    8.           JMP   HERE
    9. THERE:
    10.  
    I don't know why you should be surprised, most processors have a limited relative branch range. It is an 8-bit ALU, why should every relative branch have to be three bytes long to accomodate a 16 bit offset. One other curious thing is those other instructions: won't they change the value of the accumulator btween the reading of PORTA and the branch - just wondering.
     
  3. JohnnyD

    Thread Starter Well-Known Member

    Aug 29, 2006
    79
    0
    Thanks for the answer, much appreciated!

    I was only surprised because there are other modes such as indexed addressing which support the use of 16-bit addresses so I assumed that branching would support it as well. I guess I'm used to high-level languages where you can jump to anywhere you want in the program. This is the first program I've ever written in assembly language see.

    BTW, the code I posted up was to illustrate my point, the actual code is completely different from that. Actually I might as well post up the whole code because I'm sure it could be simplified a lot using indexed addressing lookup-type instructions. I just don't know how lol.

    The program reads a set of switches on portB which are arranged so I can use them to represent a binary number. The program then takes that number and finds the number of hundreds, tens and units in order to display them on a 3-digit 7-segment LED display. I haven't gotten round to writing the code to display the values on the LEDs yet. I have it all worked out though, that's not the bit I need help with. The only way I could think to work out the number of hundreds, tens and units was this:
    Code ( (Unknown Language)):
    1.  
    2. ****************************************************************************
    3. * LEDOUT SUBROUTINE                                                        *
    4. *                                                                          *
    5. * USES VALUE OF X TO UPDATE A 3-DIGIT 7-SEGMENT DISPLAY.                   *
    6. * THE DISPLAY USES A BCD VALUE ON BITS 0-3 AND IS MULTIPLEXED USING BITS   *
    7. * 4 AND 5 TO TURN ON ONE DIGIT AT A TIME.                                  *
    8. ****************************************************************************
    9. LEDOUT  TXA                     ;TRANSFER CONTENTS OF X INTO A
    10.         CMP     #200            ;IS A >= 200?
    11.         BHS     HUND2
    12.         CMP     #100            ;IS A >= 100?
    13.         BHS     HUND1
    14.        
    15.         CLR     HUNDS           ;SET VALUE OF HUNDREDS TO 0
    16.         BRA     TENUNIT
    17.  
    18. HUND2   LDX     #2
    19.         STX     HUNDS           ;SET VALUE OF HUNDREDS TO 2
    20.         SUB     #200            ;SUBTRACT 200 FROM A
    21.         BRA     TENUNIT
    22.  
    23. HUND1   LDX     #1
    24.         STX     HUNDS           ;SET VALUE OF HUNDREDS TO 1
    25.         SUB     #100
    26.         BRA     TENUNIT
    27.  
    28.         LDX     #2              ;START COUNT AT 2. WHEN COUNT=2, DIGIT IS TENS
    29.         STX     COUNT           ;WHEN COUNT=1, DIGIT IS UNITS
    30.        
    31. TENUNIT CMP     #90             ;IS A >= 90?
    32.         BHS     DIGIT9
    33.         CMP     #80
    34.         BHS     DIGIT8
    35.         CMP     #70
    36.         BHS     DIGIT7
    37.         CMP     #60
    38.         BHS     DIGIT6
    39.         CMP     #50
    40.         BHS     DIGIT5
    41.         CMP     #40
    42.         BHS     DIGIT4
    43.         CMP     #30
    44.         BHS     DIGIT3
    45.         CMP     #20
    46.         BHS     DIGIT2
    47.         CMP     #10
    48.         BHS     DIGIT1
    49.  
    50.         CLR     DIGIT
    51.         BRA     XTENUNI
    52.  
    53. DIGIT9  LDX     #9
    54.         STX     DIGIT
    55.         SUB     #90
    56.         BRA     XTENUNI        
    57. DIGIT8  LDX     #8
    58.         STX     DIGIT
    59.         SUB     #80
    60.         BRA     XTENUNI
    61. DIGIT7  LDX     #7
    62.         STX     DIGIT
    63.         SUB     #70
    64.         BRA     XTENUNI
    65. DIGIT6  LDX     #6
    66.         STX     DIGIT
    67.         SUB     #60
    68.         BRA     XTENUNI
    69. DIGIT5  LDX     #5
    70.         STX     DIGIT
    71.         SUB     #50
    72.         BRA     XTENUNI
    73. DIGIT4  LDX     #4
    74.         STX     DIGIT
    75.         SUB     #40
    76.         BRA     XTENUNI
    77. DIGIT3  LDX     #3
    78.         STX     DIGIT
    79.         SUB     #30
    80.         BRA     XTENUNI
    81. DIGIT2  LDX     #2
    82.         STX     DIGIT
    83.         SUB     #20
    84.         BRA     XTENUNI
    85. DIGIT1  LDX     #1
    86.         STX     DIGIT
    87.         SUB     #10
    88.         BRA     XTENUNI
    89.        
    90. XTENUNI LDX     #2
    91.         CPX     COUNT
    92.         BEQ     TIMES10
    93.         LDX     DIGIT
    94.         STX     UNITS
    95.         BRA     XLOOP
    96.  
    97. TIMES10 LDX     #10             ;LOAD X WITH 10 TO BE MULTIPLIED WITH A
    98.         MUL                     ;LOWER BYTE OF RESULT WILL BE IN A
    99.         LDX     DIGIT
    100.         STX     TENS
    101.         BRA     XLOOP
    102.        
    103. XLOOP   DEC     COUNT
    104.         BNE     TENUNIT
    105.        
    106. XLED    RTS
    The problem occurs on the second-to-last line where it branches back up to 'TENUNIT'.
    I couldn't work out any other way of doing it, because the HC05 doesn't have a division instruction, it can only do addition, subtraction and multiplication.

    Sorry, I know it's a lot of code to look at. If you want me to explain it in words instead then let me know.

    Thanks a lot.
     
Loading...