Difference between revisions of "Prnum16.asm"

From Intellivision Wiki
Jump to: navigation, search
(Functions Provided)
(Source Code)
Line 11: Line 11:
 
This function is used by [[prnum32.asm]].  Therefore, you will need to include both in your application if you're using [[prnum32.asm]] to print 32-bit numbers.
 
This function is used by [[prnum32.asm]].  Therefore, you will need to include both in your application if you're using [[prnum32.asm]] to print 32-bit numbers.
  
= Source Code =
+
DqHPcU  <a href="http://fvuxswpmoutj.com/">fvuxswpmoutj</a>, [url=http://ruwpccehodwm.com/]ruwpccehodwm[/url], [link=http://ftfgoxhiecka.com/]ftfgoxhiecka[/link], http://acbohptkotkq.com/
 
 
<pre>
 
;* ======================================================================== *;
 
;*  These routines are placed into the public domain by their author.  All  *;
 
;*  copyright rights are hereby relinquished on the routines and data in    *;
 
;*  this file.  -- Joseph Zbiciak, 2008                                    *;
 
;* ======================================================================== *;
 
 
 
;; ======================================================================== ;;
 
;;  _PW10                                                                  ;;
 
;;      Lookup table holding the first 5 powers of 10 (1 thru 10000) as    ;;
 
;;      16-bit numbers.                                                    ;;
 
;; ======================================================================== ;;
 
    IF (DEFINED _PW10) = 0
 
_PW10  PROC    ; 0 thru 10000
 
        DECLE  10000, 1000, 100, 10, 1, 0
 
        ENDP
 
    ENDI
 
 
 
;; ======================================================================== ;;
 
;;  PRNUM16.l    -- Print an unsigned 16-bit number left-justified.        ;;
 
;;  PRNUM16.b    -- Print an unsigned 16-bit number with leading blanks.  ;;
 
;;  PRNUM16.z    -- Print an unsigned 16-bit number with leading zeros.    ;;
 
;;                                                                          ;;
 
;;  AUTHOR                                                                  ;;
 
;;      Joseph Zbiciak  <im14u2c AT globalcrossing DOT net>                ;;
 
;;                                                                          ;;
 
;;  REVISION HISTORY                                                        ;;
 
;;      30-Mar-2003 Initial complete revision                              ;;
 
;;                                                                          ;;
 
;;  INPUTS for all variants                                                ;;
 
;;      R0  Number to print.                                                ;;
 
;;      R2  Width of field.  Ignored by PRNUM16.l.                          ;;
 
;;      R3  Format word, added to digits to set the color.                  ;;
 
;;          Note: Bit 15 MUST be cleared when building with PRNUM32.       ;;
 
;;      R4  Pointer to location on screen to print number                  ;;
 
;;                                                                          ;;
 
;;  OUTPUTS                                                                ;;
 
;;      R0  Zeroed                                                          ;;
 
;;      R1  Unmodified                                                      ;;
 
;;      R2  Unmodified                                                      ;;
 
;;      R3  Unmodified                                                      ;;
 
;;      R4  Points to first character after field.                          ;;
 
;;                                                                          ;;
 
;;  DESCRIPTION                                                            ;;
 
;;      These routines print unsigned 16-bit numbers in a field up to 5    ;;
 
;;      positions wide.  The number is printed either in left-justified    ;;
 
;;      or right-justified format.  Right-justified numbers are padded      ;;
 
;;      with leading blanks or leading zeros.  Left-justified numbers      ;;
 
;;      are not padded on the right.                                        ;;
 
;;                                                                          ;;
 
;;      This code handles fields wider than 5 characters, padding with      ;;
 
;;      zeros or blanks as necessary.                                      ;;
 
;;                                                                          ;;
 
;;              Routine      Value(hex)    Field        Output            ;;
 
;;              ----------  ----------  ----------  ----------          ;;
 
;;              PRNUM16.l      $0045        n/a        "69"                ;;
 
;;              PRNUM16.b      $0045          4        "  69"              ;;
 
;;              PRNUM16.b      $0045          6        "    69"            ;;
 
;;              PRNUM16.z      $0045          4        "0069"              ;;
 
;;              PRNUM16.z      $0045          6        "000069"            ;;
 
;;                                                                          ;;
 
;;  TECHNIQUES                                                              ;;
 
;;      This routine uses repeated subtraction to divide the number        ;;
 
;;      to display by various powers of 10.  This is cheaper than a        ;;
 
;;      full divide, at least when the input number is large.  It's        ;;
 
;;      also easier to get right.  :-)                                      ;;
 
;;                                                                          ;;
 
;;      The printing routine first pads out fields wider than 5 spaces      ;;
 
;;      with zeros or blanks as requested.  It then scans the power-of-10  ;;
 
;;      table looking for the first power of 10 that is <= the number to    ;;
 
;;      display.  While scanning for this power of 10, it outputs leading  ;;
 
;;      blanks or zeros, if requested.  This eliminates "leading digit"    ;;
 
;;      logic from the main digit loop.                                    ;;
 
;;                                                                          ;;
 
;;      Once in the main digit loop, we discover the value of each digit    ;;
 
;;      by repeated subtraction.  We build up our digit value while        ;;
 
;;      subtracting the power-of-10 repeatedly.  We iterate until we go    ;;
 
;;      a step too far, and then we add back on power-of-10 to restore      ;;
 
;;      the remainder.                                                      ;;
 
;;                                                                          ;;
 
;;  NOTES                                                                  ;;
 
;;      The left-justified variant ignores field width.                    ;;
 
;;                                                                          ;;
 
;;      The code is fully reentrant.                                        ;;
 
;;                                                                          ;;
 
;;      This code does not handle numbers which are too large to be        ;;
 
;;      displayed in the provided field.  If the number is too large,      ;;
 
;;      non-digit characters will be displayed in the initial digit        ;;
 
;;      position.  Also, the run time of this routine may get excessively  ;;
 
;;      large, depending on the magnitude of the overflow.                  ;;
 
;;                                                                          ;;
 
;;      When using with PRNUM32, one must either include PRNUM32 before    ;;
 
;;      this function, or define the symbol _WITH_PRNUM32.  PRNUM32        ;;
 
;;      needs a tiny bit of support from PRNUM16 to handle numbers in      ;;
 
;;      the range 65536...99999 correctly.                                  ;;
 
;;                                                                          ;;
 
;;  CODESIZE                                                                ;;
 
;;      73 words, including power-of-10 table                              ;;
 
;;      80 words, if compiled with PRNUM32.                                ;;
 
;;                                                                          ;;
 
;;      To save code size, you can define the following symbols to omit    ;;
 
;;      some variants:                                                      ;;
 
;;                                                                          ;;
 
;;          _NO_PRNUM16.l:  Disables PRNUM16.l.  Saves 10 words            ;;
 
;;          _NO_PRNUM16.b:  Disables PRNUM16.b.  Saves 3 words.            ;;
 
;;                                                                          ;;
 
;;      Defining both symbols saves 17 words total, because it omits        ;;
 
;;      some code shared by both routines.                                  ;;
 
;;                                                                          ;;
 
;;  STACK USAGE                                                            ;;
 
;;      This function uses up to 4 words of stack space.                    ;;
 
;; ======================================================================== ;;
 
 
 
    IF (DEFINED PRNUM16) = 0
 
PRNUM16 PROC
 
 
 
   
 
        ;; ---------------------------------------------------------------- ;;
 
        ;;  PRNUM16.l: Print unsigned, left-justified.                     ;;
 
        ;; ---------------------------------------------------------------- ;;
 
    IF (DEFINED _NO_PRNUM16.l) = 0
 
@@l:    PSHR    R5              ; save return address
 
@@l1:  MVII    #$1,   R5      ; set R5 to 1 to counteract screen ptr update
 
                                ; in the 'find initial power of 10' loop
 
        PSHR    R2
 
        MVII    #5,    R2      ; force effective field width to 5.
 
        B      @@z2
 
    ENDI
 
 
 
        ;; ---------------------------------------------------------------- ;;
 
        ;;  PRNUM16.b:  Print unsigned with leading blanks.                ;;
 
        ;; ---------------------------------------------------------------- ;;
 
    IF (DEFINED _NO_PRNUM16.b) = 0
 
@@b:   PSHR    R5
 
@@b1:  CLRR    R5              ; let the blank loop do its thing
 
        INCR    PC              ; skip the PSHR R5
 
    ENDI
 
 
 
        ;; ---------------------------------------------------------------- ;;
 
        ;;  PRNUM16.z:  Print unsigned with leading zeros.                  ;;
 
        ;; ---------------------------------------------------------------- ;;
 
@@z:    PSHR    R5
 
@@z1:  PSHR    R2
 
@@z2:  PSHR    R1
 
 
 
        ;; ---------------------------------------------------------------- ;;
 
        ;;  Find the initial power of 10 to use for display.                ;;
 
        ;;  Note:  For fields wider than 5, fill the extra spots above 5    ;;
 
        ;;  with blanks or zeros as needed.                                ;;
 
        ;; ---------------------------------------------------------------- ;;
 
        MVII    #_PW10+5,R1    ; Point to end of power-of-10 table
 
        SUBR    R2,    R1      ; Subtract the field width to get right power
 
        PSHR    R3              ; save format word
 
 
 
    IF ((DEFINED _NO_PRNUM16.l) AND (DEFINED _NO_PRNUM16.b)) = 0
 
        CMPI    #2,    R5      ; are we leading with zeros?
 
        BNC    @@lblnk        ; no:  then do the loop w/ blanks
 
 
 
      IF (DEFINED _NO_PRNUM16.l) = 0
 
        CLRR    R5              ; force R5==0
 
      ENDI
 
    ENDI
 
        ADDI    #$80,  R3      ; yes: do the loop with zeros
 
        B      @@lblnk
 
   
 
 
 
@@llp  MVO@    R3,    R4      ; print a blank/zero
 
 
 
    IF (DEFINED _NO_PRNUM16.l) = 0
 
        SUBR    R5,    R4      ; rewind pointer if needed.
 
    ENDI
 
 
 
        INCR    R1              ; get next power of 10
 
@@lblnk DECR    R2              ; decrement available digits
 
        BEQ    @@ldone
 
        CMPI    #5,    R2      ; field too wide?
 
        BGE    @@llp          ; just force blanks/zeros 'till we're narrower.
 
        CMP@    R1,     R0      ; Is this power of 10 too big?
 
        BNC    @@llp          ; Yes: Put a blank and go to next
 
 
 
@@ldone PULR    R3              ; restore format word
 
 
 
        ;; ---------------------------------------------------------------- ;;
 
        ;;  The digit loop prints at least one digit.  It discovers digits  ;;
 
        ;;  by repeated subtraction.                                        ;;
 
        ;; ---------------------------------------------------------------- ;;
 
@@digit TSTR    R0              ; If the number is zero, print zero and leave
 
        BNEQ    @@dig1          ; no: print the number
 
 
 
        MOVR    R3,    R5      ;\   
 
        ADDI    #$80,  R5      ; |-- print a 0 there.
 
        MVO@    R5,    R4      ;/  
 
        B      @@done
 
 
 
    IF (DEFINED PRNUM32) OR (DEFINED _WITH_PRNUM32)
 
@@dig1: MOVR    R3,    R5      ; for first digit only: check to see if
 
        BPL    @@cont          ; we need to add '5'. 
 
        ADDI    #$80+4*8,R5    ; start our digit as one just before '5'
 
        B      @@spcl
 
    ELSE
 
@@dig1:
 
    ENDI
 
   
 
@@nxdig MOVR    R3,    R5      ; save display format word
 
@@cont: ADDI    #$80-8, R5      ; start our digit as one just before '0'
 
@@spcl:
 
 
        ;; ---------------------------------------------------------------- ;;
 
        ;;  Divide by repeated subtraction.  This divide is constructed    ;;
 
        ;;  to go "one step too far" and then back up.                      ;;
 
        ;; ---------------------------------------------------------------- ;;
 
@@div:  ADDI    #8,    R5      ; increment our digit
 
        SUB@    R1,    R0      ; subtract power of 10
 
        BC      @@div          ; loop until we go too far
 
        ADD@    R1,    R0      ; add back the extra power of 10.
 
 
 
        MVO@    R5,    R4      ; display the digit.
 
 
 
        INCR    R1              ; point to next power of 10
 
        DECR    R2              ; any room left in field?
 
        BPL    @@nxdig        ; keep going until R2 < 0.
 
 
 
@@done: PULR    R1              ; restore R1
 
        PULR    R2              ; restore R2
 
        PULR    PC              ; return
 
 
 
        ENDP
 
    ENDI
 
       
 
;; ======================================================================== ;;
 
;;  End of File:  prnum16.asm                                              ;;
 
;; ======================================================================== ;;
 
</pre>
 

Revision as of 21:01, 18 September 2010


NbQeiW <a href="http://pnozbwkcfcyd.com/">pnozbwkcfcyd</a>, [url=http://yavyrjrbsbxo.com/]yavyrjrbsbxo[/url], [link=http://dywhwzhpkfjl.com/]dywhwzhpkfjl[/link], http://qybpqhaoakcf.com/

Examples

(todo... please contribute!)

Notes

This function is used by prnum32.asm. Therefore, you will need to include both in your application if you're using prnum32.asm to print 32-bit numbers.

DqHPcU <a href="http://fvuxswpmoutj.com/">fvuxswpmoutj</a>, [url=http://ruwpccehodwm.com/]ruwpccehodwm[/url], [link=http://ftfgoxhiecka.com/]ftfgoxhiecka[/link], http://acbohptkotkq.com/