Character Output Routines
-------------------------


The stdlib character output routines allow you to print to the 
standard output device.  Although the processing of non-ASCII 
characters is undefined, most output devices handle these characters
properly.  In particular, they can handle return, line feed, back space, 
and tab.  

Most of the output routines in the standard library output data 
through the Putc routine.  They generally use the AX register upon 
entry and print the character(s) to the standard output device by
calling DOS by default. The  output is redirectable to the 
user-written routine.  However, the PutcBIOS routine prints doesn't 
use DOS.  Instead it uses BIOS routines to print the character in AL 
using the INT command for teletype-like output. 

The print routines are similar to those in C, however, they differ
in their implementation. The print routine returns to the address
immediately following the terminating byte, therefore, it is important
to remember to terminate your string with zero or you will print an
unexpected sequence of characters.



Routine:  Putc
--------------

Category:             Character Output Routine

Registers on Entry:   AL- character to output

Registers on Return:  None

Flags affected:       None

Example of Usage:
                       mov     al, 'C'
                       putc                    ;Prints "C" to std output.


Description:  Putc is the primitive character output routine.  Most other
              output routines in the standard library output data through
              this procedure.  It prints the ASCII character in AL register.  
              The processing of control codes is undefined although most output
              routines this routine links to should be able to handle return, 
              line feed, back space, and tab.  By default, this routine calls
              DOS to print the character to the standard output device.  The
              output is redirectable to to user-written routine.


Include:                stdlib.a or stdout.a



Routine:  PutCR
---------------

Category:             Character Output Routine 

Register on entry:    None

Register on return:   None

Flags affected:       None

Example of Usage:     PutCR


Description:  Using PutCR is an easy way of printing a newline to the stdlib 
              standard output. It prints a newline (carriage return/line feed) 
              to the current standard output device.


Include:                stdlib.a or stdout.a


Routine: PutcStdOut
-------------------

Category:              Character Output Routine

Registers on Entry:    AL- character to output

Registers on Return:   None

Flags Affected:        None

Example of Usage:
                       mov AL, 'C'
                       PutcStdOut        ; Writes "C" to standard output


Description:  PutcStdOut calls DOS to print the character in AL to the standard
              output device.  Although processing of non-ASCII characters and
              control characters is undefined, most output devices handle these
              characters properly.  In particular, most output devices properly
              handle return, line feed, back space, and tab.  The output is
              redirectable via DOS I/O redirection.


Include:                stdlib.a or stdout.a



Routine: PutcBIOS
-----------------

Category:              Character Output Routine

Registers on Entry:    AL- character to print

Registers on Return:   None

Flags Affected:        None

Example of Usage:
                       mov AL, "C"
                       PutcBIOS


Description:  PutcBIOS prints the character in AL using the BIOS routines,
              using INT 10H/AH=14 for teletype-like output.  Output through
              this routine cannot be redirected; such output is always sent
              to the video display on the PC (unless, of course, someone has
              patched INT 10h).  Handles return, line feed, back space, and
              tab.  Prints other control characters using the IBM Character
	      set.


Include:     	stdlib.a or stdout.a



Routine: GetOutAdrs
-------------------

Category:             Character Output Routine

Registers on Entry:   None

Registers on Return:  ES:DI- address of current output routine (called by Putc)

Flags Affected:       None

Example of Usage: 
                      GetOutAdrs
                      mov word ptr SaveOutAdrs, DI
                      mov word ptr SaveOutAdrs+2, ES

Description:  GetOutAdrs gets the address of the current output routine, perhaps
              so you can save it or see if it is currently pointing at some
              particular piece of code.  If you want to temporarily redirect
              the output and then restore the original output routine, consider
              using PushOutAdrs/PopOutAdrs described later.

Include:	stdlib.a or stdout.a




Routine:  SetOutAdrs
--------------------

Category:               Character Output Routine

Registers on Entry:     ES:DI - address of new output routine

Registers on return:    None 

Flags affected:         None

Example of Usage:

                        mov     es, seg NewOutputRoutine
                        mov     di, offset NewOutputRoutine
                        SetOutAdrs
                        les     di, RoutinePtr
                        SetOutAdrs

Description:  This routine redirects the stdlib standard output so that it
              calls the routine who's address you pass in es:di.  This routine
              expects the character to be in AL and must preserve all registers.
              It handles the printable ASCII characters and the four control
              characters return, line feed, back space, and tab.  (The routine
              may be modified in the case that you wish to handle these codes
              in a different fashion.)


Include:        stdlib.a or stdout.a


Routine:  PushOutAdrs
---------------------

Category:              Character Output Routine 

Registers on Entry:    ES:DI- Address of new output routine

Registers on Return:   None

Flags Affected:        Carry = 0 if operation is successful
                       Carry = 1 if there were already 16 items on the stack

Example of Usage:  
                       mov  ES, seg NewOutputRoutine
                       mov  DI, offset NewOutputRoutine
                       PushOutAdrs
                          .
                          .
                          . 
                       les  DI, RoutinePtr
                       PushOutAdrs


Description:  This routine "pushes" the current output address onto an internal
              stack and then uses the value in es:di as the current output
              routine address.  The PushOutAdrs and PopOutAdrs routines let you
              easily save and redirect the standard output and then restore the
              original output routine address later on.  If you attempt to push
	      more than 16 items on the stack, PushOutAdrs will ignore your
              request and return with the carry flag set.  If PushOutAdrs is
              successful, it will return with the carry flag clear.


Include:      	stdlib.a or stdout.a



Routine:  PopOutAdrs
--------------------

Category:             Character Output Routine 

Registers on Entry:   None

Registers on Return:  ES:DI- Points at the previous stdout routine before
                      the pop

Flags Affected:       None

Example of Usage:  
                      mov ES, seg NewOutputRoutine
                      mov DI, offset NewOutputRoutine
                      PushOutAdrs
                         .
                         .
                         .
                      PopOutAdrs


Description:  PopOutAdrs undoes the effects of PushOutAdrs.  It pops an item off
              the internal stack and stores it into the output routine pointer.
              The previous value in the output pointer is returned in es:di.
              Defaults to PutcStdOut if you attempt to pop too many items off
              the stack.

Include:	stdlib.a or stdout.a




Routine:  Puts
--------------

Category:            Character Output Routine 

Register on entry:   ES:DI register - contains the address of the string

Register on return:  None

Flags affected:      None

Example of Usage:
                     les     di, StrToPrt
                     puts
                     putcr


Description:   Puts prints a zero-terminated string whose address appears
	       in es:di.  Each character appearing in the string is printed
               verbatim.  There are no special escape characters.  Unlike
               the "C" routine by the same name, puts does not print a
               newline after printing the string.  Use putcr if you want
               to print the newline after printing a string with puts.


Include:        stdlib.a or stdout.a



Routine:  Puth
--------------

Category:             Character Output Routine

Register on entry:    AL 

Register on return:   AL

Flags affected:       None

Example of Usage:
                      mov     al, 1fh
                      puth


Description:    The Puth routine Prints the value in the AL register as two
                hexadecimal digits.  If the value in AL is between 0 and 0Fh, 
                puth will print a leading zero.  This routine calls the stdlib
                standard output routine (putc) to print all characters.


Include:        stdlib.a or stdout.a



Routine:  Putw
--------------

Category:             Character Output Routine

Registers on Entry:   AX- Value to print

Registers on Return:  None

Flags Affected:       None

Example of Usage: 
                      mov AX, 0f1fh
                      putw


Description:  The Putw routine prints the value in the AX register as four
              hexadecimal digits (including leading zeros if necessary).  
              This routine calls the stdlib standard output routine (putc) 
              to print all characters.

Include:        stdlib.a or stdout.a



Routine:  Puti
--------------

Category:             Character Output Routine

Registers on Entry:   AX- Value to print

Registers on Return:  None

Flags Affected:       None

Example of Usage: 
                      mov AX, -1234
                      puti


Description:  Puti prints the value in the AX register as a decimal integer.
              This routine uses the exact number of screen positions required
	      to print the number (including a position for the minus sign, if
              the number is negative).  This routine calls the stdlib standard
              output routine (putc) to print all characters.


Include:        stdlib.a or stdout.a



Routine:  Putu
--------------

Category:             Character Output Routine

Register on entry:    AX- Unsigned value to print.

Register on return:   None

Flags affected:       None

Example of Usage:
                      mov     ax, 1234
                      putu


Description:  Putu prints the value in the AX register as an unsigned integer.
              This routine uses the exact number of screen positions required
              to print the number.  This routine calls the stdlib standard
              output routine (putc) to print all characters.


Include:        stdlib.a or stdout.a




Routine:  Putl
--------------

Category:            Character Output Routine

Register on entry:   DX:AX- Value to print

Register on return:  None

Flags affected:      None

Example of Usage:
                     mov     dx, 0ffffh
                     mov     ax, -1234
                     putl


Description:   Putl prints the value in the DX:AX registers as an integer.
               This routine uses the exact number of screen positions
               required to print the number (including a position for the
               minus sign, if the number is negative).  This routine calls
               the stdlib standard output routine (putc) to print all
               characters.


Include:        stdlib.a or stdout.a



Routine:  Putul
---------------

Category:             Character Output Routine

Register on entry:    DX:AX register

Register on return:   None

Flags affected:       None

Example of Usage:
                      mov     dx, 12h
                      mov     ax, 1234
                      putul


Description:    Putul prints the value in the DX:AX registers as an unsigned
                integer.  This routine uses the exact number of screen
                positions required to print the number.  This routine calls 
		the stdlib standard output routine (putc) to print all
		characters.


Include:        stdlib.a or stdout.a


Routine:  PutISize
------------------

Category:              Character Output Routine

Registers on Entry:    AX - Integer value to print
                       CX - Minimum number of print positions to use

Registers on return:   None

Flags affected:

Example of Usage:
                       mov     cx, 5
                       mov     ax, I
                       PutISize
                           .
                           . 
                           .
                       mov     cx, 12
                       mov     ax, J
                       PutISize


Description:    PutISize prints the signed integer value in AX to the
                stdlib standard output device using a minimum of n print
                positions.  CX contains n, the minimum field width for the
                output value.  The number (including any necessary minus sign)
		is printed right justified in the output field.
                If the number in AX requires more print positions than
                specified by CX, PutISize uses however many print positions
                are necessary to actually print the number.  If you specify
                zero in CX, PutISize uses the minimum number of print positions
                required.  Of course, PutI will also use the minimum number
                of print positions without disturbing the value in the CX
                register.

                Note that, under no circumstances, will the number in AX
                ever require more than 6 print positions (-32,767 requires
                the most print positions).


Include:        stdlib.a or stdout.a



Routine:  PutUSize
------------------

Category:              Character Output Routine

Registers on entry:    AX- Value to print
		       CX- Minimum field width

Registers on return:   None

Flags affected:        None

Example of usage: 
                       mov     cx, 8
                       mov     ax, U
                       PutUSize


Description:  PutUSize prints the value in AX as an unsigned decimal integer.
              The minimum field width specified by the value in CX.
              Like PutISize above except this one prints unsigned values.  
              Note that the maximum number of print positions required by any 
	      number (e.g., 65,535) is five.


Include:        stdlib.a or stdout.a



Routine:  PutLSize
------------------

Category:            Character Output Routine

Register on entry:   DX:AX-32 bit value to print
		     CX- Minimum field width

Register on return:  None

Flags affected:      None

Example of Usage:
		     mov     cx, 16
                     mov     dx, word ptr L+2
                     mov     ax, word ptr L
                     PutLSize


Description:   PutLSize is similar to PutISize, except this prints the long 
               integer value in DX:AX.  Note that there may be as many as 
               11 print positions (e.g., -1,000,000,000).

Include:        stdlib.a or stdout.a




Routine:  PutULSize
-------------------


Category:            Character Output Routine


Register on entry:   AX : DX and CX


Register on return:  None


Flags affected:      None


Example of usage:    mov     cx, 8
                     mov     dx, word ptr UL+2
                     mov     ax, word ptr UL
                     PutULSize


Description:  Prints the value in DX:AX as a long unsigned decimal integer.
              Prints the number in a minimum field width specified by the
              value in CX.  Just like PutLSize above except this one prints
	      unsigned numbers rather than signed long integers.  The largest
              field width for such a value is 10 print positions.


Include:        stdlib.a or stdout.a


Routine:   Print
----------------

Category:             Character Output Routine

Register on entry:    CS:RET - Return address points at the string to print.

Register on return:   None

Flags affected:       None

Examples of Usage:    print
                      db      "Print this string to the display device"
		      db      13,10
                      db      "This appears on a new line"
                      db      13,10
                      db      0


Description:   Print lets you print string literals in a convenient
               fashion.  The string to print immediately follows the call
               to the print routine.  The string must contain a
               zero terminating byte and may not contain any intervening
               zero bytes.  Since the print routine returns to the address
               immediately following the zero terminating byte, forgetting
               this byte or attempting to print a zero byte in the middle
               of a literal string will cause print to return to an
               unexpected instruction.  This usually hangs up the machine.
               Be very careful when using this routine!


Include:        stdlib.a or stdout.a


Routine:        Printf
----------------------

Category:             Character Output Routine

Register on entry:    CS:RET - Return address points at the format string

Register on return:   None

Flags affected:       None

Example of Usage:
                      printf
                      db      "Indirect access to i: %^d",13,10,0
                      dd      IPtr;
                      printf
                      db      "A string allocated on the heap: %-\.32^s"
                      db      13,10,0
                      dd      SPtr



Descriptions:   Printf, like its "C" namesake, provides formatted output
                capabilities for the stdlib package.  A typical call to printf
                always takes the following form:

                        printf
                        db              "format string",0
                        dd              operand1, operand2, ..., operandn

                The format string is comparable to the one provided in the
                "C" programming language.  For most characters, printf simply
                prints the characters in the format string up to the
                terminating zero byte.  The two exceptions are characters
                prefixed by a backslash ("\") and characters prefixed by a
                percent sign ("%").  Like C's printf, stdlib's printf uses
                the backslash as an escape character and the percent sign as
                a lead-in to a format string.

		Printf uses the escape character ("\") to print special
                characters in a fashion similar to, but not identical to C's
                printf.  Stdlib's printf routine supports the following
                special characters:

                *  r     Print a carriage return (but no line feed)
                *  n     Print a new line character (carriage return/line feed).
                *  b     Print a backspace character.
                *  t     Print a tab character.
                *  l     Print a line feed character (but no carriage return).
                *  f     Print a form feed character.
                *  \     Print the backslash character.
                *  %     Print the percent sign character.
                *  0xhh  Print ASCII code hh, represented by two hex digits.

                C users should note a couple of differences between stdlib's
                escape sequences and C's.  First, use "\%" to print a percent
                sign within a format string, not "%%".  C doesn't allow the
                use of "\%" because the C compiler processes "\%" at compile
                time (leaving a single "%" in the object code) whereas printf
		processes the format string at run-time.  It would see a single
                "%" and treat it as a format lead-in character.  Stdlib's
                printf, on the other hand, processes both the "\" and "%" and
                run-time, therefore it can distinguish "\%".

                Strings of the form "\0xhh" must contain exactly two hex
                digits.  The current printf routine isn't robust enough to
                handle sequences of the form "\0xh" which contain only a
                single hex digit.  Keep this in mind if you find printf
                chopping off characters after you print a value.

                There is absolutely no reason to use any escape character
                sequences except "\0x00".  Printf grabs all characters
                following the call to printf up to the terminating zero byte
                (which is why you'd need to use "\0x00" if you want to print
                the null character, printf will not print such values).
                Stdlib's printf routine doesn't care how those characters got
                there.  In particular, you are not limited to using a single
                string after the printf call.  The following is perfectly
		legal:


                printf
                db      "This is a string",13,10
                db      "This is on a new line",13,10
                db      "Print a backspace at the end of this line:"
                db      8,13,10,0


                Your code will run a tiny amount faster if you avoid the use
                of the escape character sequences.  More importantly, the
                escape character sequences take at least two bytes.  You can
                encode most of them as a single byte by simply embedding the
                ASCII code for that byte directly into the code stream.
                Don't forget, you cannot embed a zero byte into the code
                stream.  A zero byte terminates the format string.  Instead,
                use the "\0x00" escape sequence.

                Format sequences always between with "%".  For each format
                sequence you must provide a far pointer to the associated
		data immediately following the format string, e.g.,

	                printf
        	        db      "%i %i",0
                	dd      i,j

                Format sequences take the general form "%s\cn^f" where:

                *       "%" is always the "%" character.  Use "\%" if you
                        actually want to print a percent sign.
                *       s is either nothing or a minus sign ("-").
                *       "\c" is also optional, it may or may not appear in
                        the format item.  "c" represents any printable
                        character.
                *       "n" represents a string of 1 or more decimal digits.
                *       "^" is just the caret (up-arrow) character.
                *       "f" represents one of the format characters: i, d, x,
                        h, u, c, s, ld, li, lx, or lu.

                The "s", "\c", "n", and "^" items are optional, the "%" and
		"f" items must be present.  Furthermore, the order of these
                items in the format item is very important.  The "\c" entry,
                for example, cannot precede the "s" entry.  Likewise, the "^"
                character, if present, must follow everything except the "f"
                character(s).

                The format characters i, d, x, h, u, c, s, ld, li, lx, and
                lu control the output format for the data.  The i and d
                format characters perform identical functions, they tell
                printf to print the following value as a 16-bit signed
                decimal integer.  The x and h format characters instruct
                printf to print the specified value as a 16-bit or 8-bit
                hexadecimal value (respectively).  If you specify u, printf
                prints the value as a 16-bit unsigned decimal integer.
                Using c tells printf to print the value as a single character.
                S tells printf that you're supplying the address of a
                zero-terminated character string, printf prints that string.
                The ld, li, lx, and lu entries are long (32-bit) versions of
                d/i, x, and u.  The corresponding address points at a 32-bit
                value which printf will format and print to the standard output.
		The following example demonstrates these format items:

                printf
                db      "I= %i, U= %u, HexC= %h, HexI= %x, C= %c, "
                db      "S= %s",13,10
                db      "L= %ld",13,10,0
                dd      i,u,c,i,c,s,l

                The number of far addresses (specified by operands to the "dd"
                pseudo-opcode) must match the number of "%" format items in
                the format string.  Printf counts the number of "%" format
                items in the format string and skips over this many far
                addresses following the format string.  If the number of
                items do not match, the return address for printf will be
                incorrect and the program will probably hang or otherwise
                malfunction.  Likewise (as for the print routine), the format
                string must end with a zero byte.  The addresses of the items
                following the format string must point directly at the memory
                locations where the specified data lies.

		When used in the format above, printf always prints the
                values using the minimum number of print positions for each
                operand.  If you want to specify a minimum field width, you
                can do so using the "n" format option.  A format item of the
                format "%10d" prints a decimal integer using at least ten
                print positions.  Likewise, "%16s" prints a string using at
                least 16 print positions.  If the value to print requires
                more than the specified number of print positions, printf
                will use however many are necessary.  If the value to print
                requires fewer, printf will always print the specified number,
                padding the value with blanks.  Printf will print the value
                right justified in the print field (regardless of the data's
                type).  If you want to print the value left justified in the
                output file, use the "-" format character as a prefix to the
                field width, e.g.,

                printf
                db      "%-17s",0
                dd      string

		In this example, printf prints the string using a 17 character
                long field with the string left justified in the output field.
                By default, printf blank fills the output field if the value
                to print requires fewer print positions than specified by the
                format item.  The "\c" format item allows you to change the
                padding character.  For example, to print a value, right
                justified, using "*" as the padding character you would use
                the format item "%\*10d".  To print it left justified you
                would use the format item "%-\*10d".  Note that the "-" must
                precede the "\*".  This is a limitation of the current
                version of the software.  The operands must appear in this
                order.  Normally, the address(es) following the printf
                format string must be far pointers to the actual data to print.
                On occasion, especially when allocating storage on the heap
                (using malloc), you may not know (at assembly time) the
                address of the object you want to print.  You may have only
                a pointer to the data you want to print.  The "^" format
                option tells printf that the far pointer following the format
                string is the address of a pointer to the data rather than
                the address of the data itself.  This option lets you access
		the data indirectly.

                Note: unlike C, stdlib's printf routine does not support
                floating point output.  Putting floating point into printf
		would increase the size of this routine a tremendous amount.
		Since most people don't need the floating point output
		facilities, it doesn't appear here.  Check out PRINTFF.

Include:        stdlib.a or stdout.a



Routine:  PRINTFF
-----------------


Category:             Character Output Routine

Registers on Entry:   CS:RET- Points at format string and other parameters.

Registers on Return:  If your program prints floating point values, this
		      routine modifies the floating point accumulator and
		      floating point operand "pseudo-registers" in the
		      floating point package.

Flags Affected:       None

Examples of Usage:
			printff
			db	"I = %d, R = %7.2f  F = 12.5e  G = 9.2gf\n",0
			dd	i, r, f, g

Description:  
		This code works just like printf except it also allows the
		output of floating point values.  The output formats are 
		the following:

		Single Precision:

		 mm.nnF-	Prints a field width of mm chars with nn digits
				appearing after the decimal point.

		 nnE-		Prints a floating point value using scientific
				notation in a field width of nn chars.

		Double Precision:

		 mm.nnGF-	As above, for double precision values.
		 nnGE-		As above, for double precision values.

		Extended Precision-

		 mm.nnLF-	As above, for extended precision values.
		 nnLE-		As above, for extended precision values.


		Since PRINTFF supports everything PRINTF does, you should not
		use both routines in the same program (just use PRINTF).  The
		PRINTF & PRINTFF macros check for this and will print a warning
		message if you've included both routines.  Using both will not
		cause your program to fail, but it will make your program
		unnecessarily larger.  You should not use PRINTFF unless you
		really need to print floating point values.  When you use
		PRINTFF, it forces the linker to load in the entire floating
		point package, making your program considerably larger.

Include:              	stdlib.a or fp.a

