DIV in HCS08

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

DIV in HCS08

2,854 Views
Zohreh
Contributor I
Hello All,
 
I'm new to the field and to the forum.
 I'd like to divide a 16bit by 10 repeatedly (to display it in decimal).
As MC9S08AW60 supports 16 by 8 bit Division, and the quotient and Remainder are each one byte, I do not know how to manage that? I expect 2 bytes for Q!
 
Will you explain in an easy language as English is not my first language?
Thanks in advance
 
Zohreh
 
 
Labels (1)
0 Kudos
Reply
7 Replies

818 Views
tonyp
Senior Contributor II
And here's another version which is fully stack-based (re-entrant), suppresses leading zeros, and prints the result.  (Just point PutChar to the address of the routine which prints a single ASCII character in RegA.)

                    #ROM

;*******************************************************************************
; Purpose: Print a number as decimal ASCII string
; Input  : XA = 16-bit number to display as ASCII string (if entering from PrintWordXA)
;        : HX = 16-bit number to display as ASCII string (if entering from PrintWordHX)
; Output : None

PrintWordXA         txh                           ;H = dividend (MSB)
                    tax                           ;X = dividend (LSB)

PrintWordHX         clra
                    psha                          ;ASCIZ terminator

?PrintWord.Loop     pshhx                         ;save (current) dividend

                    ldhx      #10                 ;H = 0 (always), X = divisor (10)
                    pula
                    div
                    psha
                    lda       2,sp
                    div
                    sta       2,sp

                    tha                           ;A = remainder
                    add       #'0'                ;convert to ASCII
                    pulhx                         ;remove dividend from stack
                    psha                          ;save next result byte (right to left)
                    cphx      #0                  ;while dividend not zero...
                    bne       ?PrintWord.Loop     ;... keep going

?PrintWord.Print    pula                          ;get next ASCIZ char
                    cbeqa     #0,?PrintWord.Done  ;on terminator, exit
                    jsr       PutChar             ;else, print digit
                    bra       ?PrintWord.Print

?PrintWord.Done     rts



Message Edited by tonyp on 2008-11-03 03:06 PM
0 Kudos
Reply

818 Views
bigmac
Specialist III
Hello,
 
It is probably worth mentioning that TonyP's code uses a number of macros that have not been defined within the code snippet.  Substitute the following instruction sequences in place of each macro.
 
TXH macro is equivalent to:
   pshx
   pulh
 
THA macro is equivalent to:
   pshh
   pula
 
PSHHX macro is equivalent to:
   pshh
   pshx
 
PULHX macro is equivalent to:
   pulx
   pulh
 
Regards,
Mac
 
0 Kudos
Reply

818 Views
tonyp
Senior Contributor II
Oops! The order is actually reverse, to be consistent with big-endian.

PSHHX
  pshx
  pshh

PULHX
 pulh
 pulx

bigmac wrote:
PSHHX macro is equivalent to:
   pshh
   pshx
 
PULHX macro is equivalent to:
   pulx
   pulh




Message Edited by tonyp on 2008-11-03 07:20 PM
0 Kudos
Reply

818 Views
tonyp
Senior Contributor II
Thanks bigmac, I always forget to mention that.

It is also worth mentioning that since the leading zeros are suppressed, you can easily expand the routine for bytes, too.  Just add one more entry point and a few PUSH/PULL instructions to protect the registers from destruction.  Attached is the final version.



Message Edited by tonyp on 2008-11-03 06:48 PM
0 Kudos
Reply

818 Views
bigmac
Specialist III
Hello Zohreh, and welcome to the forum.
 
I assume that you are using assembly code.
 
Since the result of a division (by 10 decimal) may be 16-bits length,  the process becomes "long division" using the DIV instruction twice, once for each byte of the 16-bit value.  After the first division (starting with H = 0), the remainder within H becomes the most significant byte for the second division.
 
This is demonstrated in the following assembly code sub-routine.  Each decimal digit value is stored on the stack until four digits have been processed, and ACC contains the MS digit.  Each digit is then converted to ASCII, and stored in BUF.
 
;**************************************************************
; 16-BIT BINARY TO 5-DIGIT BCD CONVERSION
;**************************************************************
; On entry, first two bytes of BUF contain binary number.
; On exit, the six bytes of BUF contain null terminated numeric
; ASCII data string.
 
CONVERT:  LDX    #4             ; Number of divisions required
          STX    BUF+5
          LDX    #10            ; Divisor
CNV1:     BSR    DIVIDE
          PSHH                  ; Store remainder to stack
          DBNZ   BUF+5,CNV1     ; Loop for next digit
 
          ADD    #'0'           ; Convert to numeric ASCII
          STA    BUF            ; MS digit
          CLRX                  ; Buffer index
CNV2:     PULA                  ; Get value from stack
          ADD    #'0'           ; Convert to numeric ASCII
          STA    BUF+1,X
          INCX
          CPX    #4             ; Test for maximum digits
          BLO    CNV2           ; Loop if not
          RTS
 
DIVIDE:   CLRH
          LDA    BUF
          DIV
          STA    BUF
          LDA    BUF+1
          DIV
          STA    BUF+1
          RTS
 
Regards,
Mac
 


Message Edited by bigmac on 2008-11-03 02:53 PM
0 Kudos
Reply

818 Views
Zohreh
Contributor I
Thank you so much Mac.
You helped me a lot.
 
Zohreh
0 Kudos
Reply

818 Views
bigmac
Specialist III
Hello Zohreh,
 
I have just noticed that there is an error within my previous code.  Prior to the CNV2 label, an additional CLRH instruction will be necessary.  Otherwise the subsequent instruction  STA BUF+1,X will point to the incorrect memory location.
 
Regards,
Mac
 
0 Kudos
Reply