Difference between revisions of "Prnum16.asm"
(→Functions Provided) |
|||
| Line 1: | Line 1: | ||
[[Category:Programming]] [[Category:Library]] | [[Category:Programming]] [[Category:Library]] | ||
| − | = | + | NbQeiW <a href="http://pnozbwkcfcyd.com/">pnozbwkcfcyd</a>, [url=http://yavyrjrbsbxo.com/]yavyrjrbsbxo[/url], [link=http://dywhwzhpkfjl.com/]dywhwzhpkfjl[/link], http://qybpqhaoakcf.com/ |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
= Examples = | = Examples = | ||
Revision as of 17:31, 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.
Source Code
;* ======================================================================== *;
;* 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 ;;
;; ======================================================================== ;;