PIC Division (multiplication of inverse)

Discussion in 'Embedded Systems and Microcontrollers' started by Pencil, Dec 22, 2011.

  1. Pencil

    Thread Starter Active Member

    Dec 8, 2009
    271
    38
    Hello all,

    I haven't been experimenting with microcontrollers very long (<1 year).

    I have attached a snippet of code (assembly) for dividing a 16 bit number
    by an 8 bit number. Details are in the comments.

    I would appreciate it greatly if anyone, more experienced, would look/test for errors.

    All comments (good and bad) welcome.

    Thanks.

    Code ( (Unknown Language)):
    1. ;**********************************************************************
    2. ;TEST FOR PIC16F690                                                   *
    3. ;DIVISION ROUTINE (MULTIPLICATION OF INVERSE OF DIVISOR)              *
    4. ;                                                                     *
    5. ;16 BIT DIVIDEND (XXXXXXXX XXXXXXXX)                                  *
    6. ;8 BIT INVERSE OF DIVISOR (1/DIVISOR)(.XXXXXXXX)                      *
    7. ;                                                                     *
    8. ;RESULT IS 16 BITS TO THE LEFT OF DECIMAL POINT, 8 BITS TO RIGHT      *
    9. ;OF THE DECIMAL POINT                                                 *
    10. ;                                                                     *
    11. ;RESULT FORMAT XXXXXXXX   XXXXXXXX   .XXXXXXXX                        *
    12. ;             HIGH BYTE   LOW BYTE   DECIMAL BYTE                     *
    13. ;                                                                     *
    14. ;INPUTS:                                                              *
    15. ;DVDHI=HIGH BYTE OF DIVIDEND                                          *
    16. ;DVDLO=LOW BYTE OF DIVIDEND                                           *
    17. ;DVSR=1/DIVISOR                                                       *
    18. ;                                                                     *
    19. ;OUTPUTS:                                                             *
    20. ;HIRSLT=HIGH BYTE OF RESULT                                           *
    21. ;LORSLT=LOW BYTE OF RESULT                                            *
    22. ;HIDEC=DECIMAL HIGH BYTE OF RESULT                                    *
    23. ;                                                                     *
    24. ;PRESERVES ORIGINAL VALUES OF DIVIDEND AND DIVISOR                    *
    25. ;                                                                     *
    26. ;                                                                     *
    27. ;                                                                     *
    28. ;**********************************************************************
    29. ;                                                                     *
    30. ;    Filename:        xxx.asm                                         *
    31. ;    Date:                                                            *
    32. ;    File Version:                                                    *
    33. ;                                                                     *
    34. ;    Author:                                                          *
    35. ;    Company:                                                         *
    36. ;                                                                     *
    37. ;                                                                     *
    38. ;**********************************************************************
    39. ;                                                                     *
    40. ;    Files Required: P16F690.INC                                      *
    41. ;                                                                     *
    42. ;**********************************************************************
    43. ;                                                                     *
    44. ;    Notes:                                                           *
    45. ;                                                                     *
    46. ;**********************************************************************
    47.  
    48.  
    49.     list        p=16f690        ; list directive to define processor
    50.     #include    <P16F690.inc>        ; processor specific variable definitions
    51.    
    52.     __CONFIG    _CP_OFF & _CPD_OFF & _BOR_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _FCMEN_OFF & _IESO_OFF
    53.  
    54.  
    55. ; '__CONFIG' directive is used to embed configuration data within .asm file.
    56. ; The labels following the directive are located in the respective .inc file.
    57. ; See respective data sheet for additional information on configuration word.
    58.  
    59.  
    60.  
    61. main
    62.  
    63.  
    64.     ;GENERAL PURPOSE VARIABLE ADDRESSES
    65. ;*************DIVISION ROUTINE VARIABLES*************
    66. CNTR1   EQU   0x34    ;GENERAL PURPOSE COUNTER
    67. CNTR2   EQU   0x35    ;GENERAL PURPOSE COUNTER
    68. DVDHI   EQU   0x41    ;DIVIDEND HIGH BYTE XXXXXXXX xxxxxxxx
    69. DVDLO   EQU   0x42    ;DIVIDEND LOW BYTE  xxxxxxxx XXXXXXXX
    70. DVSR    EQU   0x43    ;DIVISOR (1/DIVISOR) .XXXXXXXX
    71. HIRSLT  EQU   0x44    ;RESULT HIGH BYTE   XXXXXXXX xxxxxxxx
    72. LORSLT  EQU   0x45    ;RESULT LOW BYTE    xxxxxxxx XXXXXXXX
    73. HIDEC   EQU   0x46    ;RESULT DECIMAL PORTION xxxxxxxx xxxxxxxx.XXXXXXXX
    74. HITEMP  EQU   0x47    ;TEMP HIGH BYTE     XXXXXXXX xxxxxxxx
    75. LOTEMP  EQU   0x48    ;TEMP LOW BYTE      xxxxxxxx XXXXXXXX
    76. DVRTMP  EQU   0x49    ;TEMP DIVISOR .XXXXXXXX
    77. HDECTMP EQU   0x50    ;TEMP DECIMAL PORTION xxxxxxxx xxxxxxxx.XXXX
    78. ;***************************************************
    79.    ;****INITIALIZE DIVISION ROUTINE VARIABLES****
    80.     CLRF   CNTR1      ;0000 0000 INITIALIZE CNTR1
    81.     CLRF   CNTR2      ;0000 0000 INITIALIZE CNTR2
    82.     CLRF   DVDHI      ;0000 0000 INITIALIZE DVDHI
    83.     CLRF   DVDLO      ;0000 0000 INITIALIZE DVDLO
    84.     CLRF   HIRSLT     ;0000 0000 INITIALIZE HIRSLT
    85.     CLRF   LORSLT     ;0000 0000 INITIALIZE LORSLT
    86.     CLRF   HITEMP     ;0000 0000 INITIALIZE HITEMP
    87.     CLRF   LOTEMP     ;0000 0000 INITIALIZE LOTEMP
    88.     CLRF   HIDEC      ;0000 0000 INITIALIZE HIDEC
    89.     CLRF   DVSR       ;0000 0000 INITIALIZE DVSR
    90.     CLRF   DVRTMP     ;0000 0000 INITIALIZE DVRTEMP
    91.     CLRF   HDECTMP    ;0000 0000 INITIALIZE HDECTMP
    92. ;***************************************************
    93.  
    94.  
    95. ;***********DIVISION ROUTINE***********
    96.  
    97.    ;***ENTER DIVIDEND AND 1/DIVISOR BELOW HERE***
    98.    ;***ENTER DIVIDEND AND 1/DIVISOR BELOW HERE***
    99.     MOVLW   0xFF      ;DIVIDEND HIGH BYTE XXXX XXXX
    100.     MOVWF   DVDHI     ;DVDHI=XXXX XXXX
    101.  
    102.     MOVLW   0xFF      ;DIVIDEND LOW BYTE XXXX XXXX
    103.     MOVWF   DVDLO     ;DVDLO=XXXX XXXX
    104.  
    105.     MOVLW   0x01      ;1/DIVISOR .XXXX XXXX
    106.     MOVWF   DVSR      ;DVSR=.XXXX XXXX
    107.    ;***ENTER DIVIDEND AND 1/DIVISOR ABOVE HERE***
    108.    ;***ENTER DIVIDEND AND 1/DIVISOR ABOVE HERE***
    109.  
    110. ;*****BEGINNING OF DIVISION ROUTINE****
    111.     MOVF    DVDHI,W   ;DVDHI TO W
    112.     MOVWF   HITEMP    ;HITEMP=DVDHI
    113.     MOVF    DVDLO,W   ;DVDHI TO W
    114.     MOVWF   LOTEMP    ;LOTEMP=DVDLO
    115.     MOVF    DVSR,W    ;DVSR TO W
    116.     MOVWF   DVRTMP    ;DVRTMP=DVSR
    117.     MOVLW   0x00      ;0000 0000
    118.     MOVWF   HDECTMP   ;HDECTMP=0
    119.     MOVLW   0x08      ;0000 1000 (8)
    120.     MOVWF   CNTR1     ;CNTR1=8
    121.     MOVLW   0x00      ;0000 0000
    122.     MOVWF   CNTR2     ;CNTR2=0
    123.  
    124.   ;TEST BIT 7 OF DVRTMP
    125.     BCF     STATUS,C
    126.     INCF    CNTR2,F   ;BIT TEST COUNTER
    127.     BTFSS   DVRTMP,7  ;TEST BIT 7 OF DVRTEMP
    128.     GOTO    DIVIDECNTR
    129.     GOTO    DIVIDE1
    130.  
    131.    ;SHIFT AND ADD DIVIDEND
    132. DIVIDE1
    133.     BCF     STATUS,C
    134.     RRF     HITEMP,F   ;ROTATE RIGHT HITEMP
    135.     RRF     LOTEMP,F   ;ROTATE RIGHT LOTEMP
    136.     RRF     HDECTMP,F  ;ROTATE RIGHT HDECTMP
    137.     BCF     STATUS,C
    138.     DECF    CNTR2,F    ;BIT TEST COUNTER -1
    139.     MOVF    CNTR2,F    ;TESTING COUNTER FOR =0
    140.     BTFSS   STATUS,Z   ;IF INCREMENTAL SHIFTS NOT =O
    141.     GOTO    DIVIDE1    ;ROTATE AGAIN
    142.     MOVF    HDECTMP,W  ;HIDECTMP SAVED TO W
    143.     ADDWF   HIDEC,F    ;ADD HDECTMP TO HIDEC
    144.     BTFSS   STATUS,C   ;TEST FOR CARRY OF HIDEC
    145.     GOTO    $+5        ;IF NO CARRY
    146.     MOVLW   0x01
    147.     ADDWF   LORSLT,F   ;IF HIDEC CARRIED ADD 1 TO LORSLT
    148.     BTFSC   STATUS,C   ;TEST FOR CARRY OF LORSLT
    149.     INCF    HIRSLT,F   ;IF LORSLT CARRIED ADD 1 TO HIRSLT
    150.     MOVF    LOTEMP,W  
    151.     ADDWF   LORSLT,F   ;ADD LOTEMP TO LORSLT
    152.     BTFSC   STATUS,C   ;TEST FOR CARRY OF LORSLT
    153.     INCF    HIRSLT,F   ;IF LORSLT CARRIED ADD 1 TO HIRSLT  
    154.     MOVF    HITEMP,W
    155.     ADDWF   HIRSLT,F   ;ADD HITEMP TO HIRSLT
    156.     CLRF    CNTR2      ;CLEAR CNTR2
    157.     GOTO    DIVIDECNTR ;SHIFT AND TEST DIVISOR AGAIN
    158.  
    159.    ;MANAGE COUNTERS, SHIFT DIVISOR, TEST DIVISOR BITS
    160. DIVIDECNTR
    161.     BCF     STATUS,C
    162.     BCF     STATUS,Z
    163.     DECF    CNTR1,F   ;-1 TOTAL SHIFTS COUNTER
    164.     MOVF    CNTR1,F   ;TESTING COUNTER FOR =0  
    165.     BTFSC   STATUS,Z  ;CHECK FOR 8 TOTAL SHIFTS
    166.     GOTO    $+6       ;IF ALL BITS OF DIVISOR HAVE BEEN TESTED THEN EXIT
    167.     RLF     DVRTMP,F  ;ROTATE LEFT FOR TESTING NEXT BIT
    168.     INCF    CNTR2,F   ;+1 BIT TEST COUNTER
    169.     BTFSS   DVRTMP,7  ;TEST BIT 7 OF DVRTEMP
    170.     GOTO    $-7       ;IF BIT 7 IS 0 SHIFT AND TEST AGAIN
    171.     GOTO    DIVIDE1   ;IF BIT 7 IS 1 SHIFT AND ADD DIVIDEND
    172.  
    173.     NOP               ;TEMPORARY EXIT POINT
    174.     GOTO    $-1       ;ENDLESS LOOP
    175. ;*******END OF DIVISION ROUTINE*******
    176.  
    177. ;********************************
    178. BOTTOM
    179.     ORG    0x2100                ; data EEPROM location
    180.     DE    1,2,3,4                ; define first four EEPROM locations as 1, 2, 3, and 4
    181.     END                       ; directive 'end of program'
    182.  
     
  2. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    Sorry I haven't checked your code, but I wanted to suggest that you look at the microchip appnotes. They have a number of appnotes full of math examples in PIC assembler, that you can just cut and paste into your code. 16bit/8bit and 16bit/16bit division are very standard.
     
  3. Pencil

    Thread Starter Active Member

    Dec 8, 2009
    271
    38
    Thanks for replying.

    I am aware of the appnotes and other examples on the internet. I am trying
    to get a better understanding of the basics for myself. At this point I feel
    I should develop some basic routines "from the ground up". If I get into
    the habit of copying and pasting this early in my learning I won't progress
    as I feel I should. I am also afraid that if I am learning on my own, isolated
    from outside input, I may teach myself some some bad habits or faulty logic.
     
  4. MrChips

    Moderator

    Oct 2, 2009
    12,449
    3,365
    I agree with you. You would do yourself a big favor if you refrained from copying other people's code. Personally I think your code looks a mess. But then I think PIC MCU design sucks - just my opinion. I could not make out a single thing about your code but this is not your fault, just the design of PIC asm. I could solve the same problem in HC11, HC08 or AVR with a lot simpler code. (If you want to learn good asm design, my advice would be to switch away from PIC - but I am sure a whole bunch of AAC members are going to jump on me for this - so spare me the agony, please.)

    Before you attempt to tackle a problem like 16x8 or 16x16 multiply or divide and posting the code you should (or must) write out your algorithm. You can do this using a flowchart or pseudo code. I would suggest you begin here and I will guide you along the way.
    Pseudo code should be MCU independent and should not refer to any hardware aspects (such as registers) of the MCU. Use plain algebra.

    (I would also suggest going through this exercise first with 8x8 multiply, 16x8 multiply and 16x16 multiply just to get the hang of it.)
     
    Last edited: Dec 23, 2011
  5. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,394
    1,607
    It is always a good thing to write your own code for well defined problems such as this as it is a good learning tool. (It's also good to write code for new applications, they both teach you good things).

    1. I have no clear idea what you mean by:

    Code ( (Unknown Language)):
    1.     DVSR    EQU   0x43    ;DIVISOR (1/DIVISOR)         .XXXXXXXX
    Is this the "traditional" divisor or it's inverse? I suspect you mean the former but I hate to guess.

    2. Using code such as:

    Code ( (Unknown Language)):
    1.     GOTO    $+5        ;IF NO CARRY
    seems a willful act to purposely obfuscate the code. Use a label if you intend to have other people read the code.
     
  6. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
  7. Pencil

    Thread Starter Active Member

    Dec 8, 2009
    271
    38
    I realize how hard it is to read other peoples code. This is why it took
    me a long time before getting brave enough to post. This is also the
    reason I asked so I could learn how to get help.

    Before writing the code I always work out the routine and work examples,
    step by step, on paper. I will have to make something to post. My normal
    notes to myself only make sense to me, as you can probably see in my
    code. Learning to communicate ideas is something I'm working on.

    Edit: That is assigning the variable DVSR to the register address 0x43.
    Maybe you meant to copy from elsewhere in the program? I think I get
    the point about not knowing what to enter for the value of DVSR that
    would be from here:
    Code ( (Unknown Language)):
    1.    ;***ENTER DIVIDEND AND 1/DIVISOR BELOW HERE***
    2.    ;***ENTER DIVIDEND AND 1/DIVISOR BELOW HERE***
    3.     MOVLW   0xFF      ;DIVIDEND HIGH BYTE XXXX XXXX
    4.     MOVWF   DVDHI     ;DVDHI=XXXX XXXX
    5.  
    6.     MOVLW   0xFF      ;DIVIDEND LOW BYTE XXXX XXXX
    7.     MOVWF   DVDLO     ;DVDLO=XXXX XXXX
    8.  
    9.     MOVLW   0x01      ;1/DIVISOR .XXXX XXXX
    10.     MOVWF   DVSR      ;DVSR=.XXXX XXXX
    11.    ;***ENTER DIVIDEND AND 1/DIVISOR ABOVE HERE***
    12.    ;***ENTER DIVIDEND AND 1/DIVISOR ABOVE HERE***
    13.  
    The inverse of the divisor should be used. I was converting
    the inverse of the divisor to fractional binary on paper then substituting
    that value on the "MOVLW" line above the "MOVWF DVSR" line.
    The code I posted was for testing purposes, the real usage of the code
    will carry the value of DVSR to the subroutine for the calculation.

    I assure you it is not my intent to confuse. It is just poor coding. I
    believe I understand the use of labels, I will use labels instead of the
    "GOTO $±x" whenever possible. Thanks for the tip.

    Yes. I know of many references. Studying examples is all I have used
    so far. I intend to get a book at some point. Keep the references
    coming, there may be some I haven't seen.

    Thanks for the help so far. I'll re-post another try with the advice given.
     
    Last edited: Dec 23, 2011
  8. atferrari

    AAC Fanatic!

    Jan 6, 2004
    2,648
    764
    Reading others' code is a hard thing to do, at least for me. I feel much more inclined to look at your flow diagram than trying to understand your code.

    Since my start, many years ago, I got used to write a flow diagram of what I want to do, so, later, I can code simply by following it.
     
  9. Pencil

    Thread Starter Active Member

    Dec 8, 2009
    271
    38
    Please re-read Post#7.

    I misunderstood a comment and corrected the response.
     
  10. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    I respect that attitude totally. But I would liek to say that the Microchip math routines appnotes are not really "pasting someone else's code" they are an official tool that has been refined by the Microchip professionals, and contain not just the code but good commenting, and text notes with analysis of what is happening.

    As a learning tool they are VERY much worth looking at.
    A quick google brought up AN526 and AN617, both have division routines that should act as good examples. :)

    http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en011000
    http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en010962
     
  11. Pencil

    Thread Starter Active Member

    Dec 8, 2009
    271
    38
  12. Pencil

    Thread Starter Active Member

    Dec 8, 2009
    271
    38
    I'm really struggling with getting something in words/symbols
    for a flow diagram/algorithm.

    The best I can do for now is post an example showing how I initially
    mapped out the routine in order to see the logic.

    I'm still working on some sort of flow diagram.

    Can the logic behind the code be seen in this example?
    Is the logic sound?

    Code ( (Unknown Language)):
    1. Example of process used for multiplication
    2. of whole number and decimal in binary
    3.  
    4.  
    5. Example:  5*.59375
    6.  
    7. Multiplicand=5
    8. Multiplier=.59375
    9.  
    10. Convert multiplicand to binary format:    5=101
    11. Convert multiplier to binary format :   .59375=.10011
    12.  
    13. Expanded representation of multiplier:  .10011=.1+.0001+.00001
    14.  
    15. Distributive property of multiplication and substitution makes the following true:
    16.          101*.10011=(101*.1)+(101*.0001)+(101*.00001)
    17.  
    18. Equalities using bit shifting right technique:
    19.          (101*.1)=101 shifted right 1 time =10.1
    20.          (101*.0001)=101 shifted right 4 times =.0101
    21.          (101*.00001)=101 shifted right 5 times =.00101
    22.  
    23. Substituting values from bit shifting yields:
    24.          101*.10011=10.1+.0101+.00101
    25.  
    26. Solution of right hand side of equation:
    27.          10.1+.0101+.00101=10.11111   (in base 10:  2.5+.3125+.15625=2.96875)
    28.  
    29. Conclusion by substitution:
    30.          101*.1011=10.11111   (in base 10:  5*.59375=2.96875)
    31.  
    Does this help at all?
    I feel like a caveman trying to communicate with a mathematician.:eek:
     
  13. MrChips

    Moderator

    Oct 2, 2009
    12,449
    3,365
    Here is how I would explain multiplication.

    Let us see how this is done in decimal.
    Suppose you wish to multiply 1234 x 789
    There are two approaches:

    A)

    We could start with the least significant digit of the multiplier, 1234 x 9, save this result.
    Then we take 1234 and shift left one place, multiply by 8 and add to previous result.
    Then we take 12340 and shift left one place, multiply by 7 and add to previous result.

    B)

    We start with 1234, multiply by 7, and shift left by one place.
    We multiply 1234 by 8, add to result and shift left by one place.
    We multiply 1234 by 9, and add to previous result.

    For a binary multiplication, we may choose either approach. Let us choose (B).

    1. Begin with result = 0.
    2. Take the multiplicand and multiply with the MSB of the multiplier. Add to result.
    3. Is this the last bit of the multiplier? If yes, done.
    4. Shift the result one bit to the left. Shift the multiplier one bit to the left.
    5. Go to Step 2.
     
  14. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    I haven't looked at how the code functions, but here are a few tips:
    You will probably find declaring variables easier using the cblock method (google it). It saves typing and avoids accidentally declaring 2 files as the same register or leaving gaps in the registers (like 0x36-0x40 and 0x49-0x50).
    Using a loop and the FSR to clear variables saves a little code space - example code is in the datasheet in the indirect addressing section. Clearing them directly is faster.
    Use clrf foo instead of movlw 0x00, movwf foo.
    There are a few times where bcf STATUS, C is not needed.
    There is no need to do decf foo, F, movf foo, F because decf already changes the zero flag.
    They are pretty small changes, but it all adds up.
     
  15. Eric007

    Senior Member

    Aug 5, 2011
    1,044
    33
    I totaly disagree with you!!! But I respect your opinion...
    It all about coming up with a good algorithm to solve this kind of problem then the implementation can be done with PIC, AVR, wateva...

    Hahahahah...lolol you already know...
    Totally agree!!
     
  16. Pencil

    Thread Starter Active Member

    Dec 8, 2009
    271
    38
    Thanks for the examples, I am working my my way toward a
    thorough explanation. I realize the importance of this step.

    I am aware of c-block method, I need to start using it, it would help
    to "clean things up a little".
    I'll look for an example.
    When I'm not sure I tend to err on side of caution.
    I thought i had trouble with the counters. During debugging I tried
    "testing for zero" a different way to make sure I understood. I should
    have changed back (eliminated the movf foo,F) but didn't.
    The real problem turned out to be "inc foo,F" doesn't affect Status C.
    Great dialog (all posters) . Any advice helps me by making me rethink
    the way I approach the problem.
     
    Last edited: Dec 24, 2011
  17. MrChips

    Moderator

    Oct 2, 2009
    12,449
    3,365
    Just remember that I have not shown you how to do division as yet.
     
  18. Pencil

    Thread Starter Active Member

    Dec 8, 2009
    271
    38
    And I have not posted a program flow/summation yet.
     
  19. Pencil

    Thread Starter Active Member

    Dec 8, 2009
    271
    38
    This still is not really the algorithm, but more of a
    "program summation in words". Can anybody see
    faulty logic/process yet? I am working my way through this
    whole process backwards:D.

    Remember the original questions were,
    "Is this a valid, error free routine?"
    and "Will it produce accurate results throughout the
    entire range for which it was intended?"

    Note: This is intended to be used as a guide for
    checking the code (way back in post 1). Any errors
    may be in either place or both. (As a way of checking
    myself I tried to write this independant of the program
    and compare the two. I wanted to see it as anyone
    else would.)
    Code ( (Unknown Language)):
    1. Program flow for division routine
    2.  
    3. Purpose:  To calculate division of a 16 bit whole number dividend by an 8 bit
    4.                   divisor.
    5.  
    6. Limitations: Variable registers are 8 bits wide.
    7.  
    8. Inputs:  16 bit dividend is entered into 2 registers as a "high byte" and a "low byte".
    9.               Divisor is inverted (1/Divisor) and converted to "decimal binary" (.XXXXXXXX)
    10.               and entered into a single register.
    11.  
    12. Outputs: 16 bit result is stored in 3 registers as a "high byte" and a "low byte" and
    13.                 1 register as a "decimal byte".
    14.  
    15. Routine begins below here.
    16.                  
    17. 1. Enter dividend (whole number) in registers Dividend high byte and Dividend Low byte
    18. 2. Enter inverse of divisor (1/divisor) in register Divisor
    19.  
    20. 3.  Set Result high byte to 0
    21. 4.  Set Result low byte to 0
    22. 5.  Set Result decimal byte to 0
    23. 6.  Set Temporary decimal byte to 0
    24.  
    25. 7.  Set total bit test counter to 8
    26. 8.  Set interim bit test counter to 0
    27.  
    28.  (***Test Bit 7 Of Divisor***)
    29.  
    30. 9.    Decrement total bit test counter (-1)
    31. 10.  Is bit 7 of Divisor =1?
    32.             NO...goto step 22.
    33.             Yes...continue.
    34.  
    35.  (***Shift and add dividend***)
    36.  
    37. 11. Shift Dividend high byte to right (through Carry bit).
    38. 12. Shift Dividend low byte to right (through Carry bit).
    39. 13. Shift Temporary decimal byte to right.
    40. 14. Decrement interim bit test counter (-1).
    41. 15.  Is interim bit test counter=0?
    42.             NO...goto step 11.
    43.             Yes...continue.
    44. 16. Add Temporary decimal byte to Result  decimal byte.
    45. 17. Did Result decimal byte carry?
    46.             Yes...add 1 to Result low byte then goto step 19.
    47.              No...goto step19.
    48. 18. Did Result low byte carry?
    49.             Yes...add 1 to Result high byte then goto step 19.
    50.              No...continue.
    51. 19. Add Dividend low byte to Result low byte.
    52. 20. Did Result low byte carry?
    53.             Yes...add 1 to Result high byte then goto step 21.
    54.              No...continue.
    55. 21. Add Dividend high byte to Result high byte.
    56.  
    57.  (***Mange Counters, Shift Divisor, Test Divisor Bits***)
    58.  
    59. 22. Decrement total bit test counter (-1).
    60. 23. Is total bit test counter =0.
    61.              Yes...goto step 27 (computation complete).
    62.               No...continue.
    63. 24. Shift Divisor byte to left.
    64. 25. Increment interim bit test counter (+1).
    65. 26. Is bit 7 of Multiplier =1?
    66.              No...goto step 22.
    67.              Yes...goto step 11.
    68. 27.  End
    69.  
    As always thanks.
     
    Last edited: Dec 25, 2011
  20. MrChips

    Moderator

    Oct 2, 2009
    12,449
    3,365
    I have not read your post but something you must be aware of: Hardware design such as block diagrams and timing diagrams must not be drawn after the design has been completed.

    Similarly, software algorithms must not be written out after the code has been written. This is putting the carriage before the horse. Algorithms must dictate how the code is to be written. Not the other way around. If the algorithm does not make sense to begin with, the code would be a hopeless failure.

    (I'll look at the post once the eggnog wears off.)

    In the exercises, we begin with 8x8 multiply and divide, keeping things as simple as possible.
    When we extend this to 16-bit operations we have to accept that things become more complex because we have to deal with multiple-byte operations.
    In order to keep the algorithm simple to follow, we assume that multiple-byte operations are single operations. This way we treat high-byte and low-byte as a single entity. This reduces the number of steps in the algorithm and makes it easier to follow.

    There is another reason for doing it this way. The 8-bit limitation is specific to that type of MCU. When we move to 16-bit and 32-bit processors the algorithm can remain the same.
     
    Last edited: Dec 26, 2011
    Eric007 likes this.
Loading...