]>
wirehaze git hosting - MS-DOS.git/blob - v4.0/src/INC/PRINTF.ASM
1 TITLE PRINTF ROUITNE FOR
MS-DOS
3 ; PRINTF(Control String, arg1, arg2,...,argn-1,argn)
5 ; Characters are output to PFHandle according to the
6 ; specifications contained in the Control String.
8 ; The conversion characters are as follow:
10 ; %c - output the next argument as a character
11 ; %s - output the next argument as a string
12 ; %x - output the next argument as a hexidecimal number
14 ; %X - output the next argument as a hexidecimal number
16 ; %d - output the next argument as a decimal number
19 ; Other format specifiers that may precede the conversion character are:
21 ; - (minus sign) - causes the field to be left-adjusted
22 ; + (plus sign) - causes the field to be right-adjusted (default)
23 ; n - digit specifing the minimum field width (default to 1)
24 ; L - specifing a long integer
26 ; On entry to PRINTF the stack contains the return address and a pointer
27 ; to an argument list.
29 ; ____________________
31 ; --------------------
33 ; --------------------
35 ; And the argument list contains the following:
37 ; String_ptr (a pointer to the control string)
46 ; If the argument is a %s or %c the arg contains a pointer to the string
49 ; The arguments are used in one-to-one correspondence to % specifiers.
57 printf_CODE
SEGMENT public byte
58 ASSUME
CS:PRINTF_CODE
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
60 PUBLIC PRINTF
, PFHandle
73 PRINTF_TABLE
DB "0123456789ABCDEFabcdef"
99 PRINTF_BUF
DB BUFSIZ
DUP (?
)
100 db 0 ;This buffer is always nul terminated
101 BUFEND
DW $-PRINTF_BUF
104 PUSH BP ;Save the callers' registers
115 POP ES ;ES points to Printf segment
116 MOV DI,OFFSET PRINTF_BUF
;DI points to the output buffer
117 MOV BP,[BP.STRING
] ;BP points to the argument list
118 MOV SI,DS:[BP] ;SI points to the control string
119 XOR BX,BX ;BX is the index into the arg list
120 CALL Clear_flags
; initialize the world
122 LODSB ;Get a character
123 CMP AL,"%" ;Is it a conversion specifier?
124 JZ CONV_CHAR
;Yes - find out which one
125 OR AL,AL ;Is it the end of the control string?
126 JZ PRINTF_DONE
;Yes - then we're done
127 CALL OUTCHR
;Otherwise store the character
128 JMP SHORT GET_CHAR
;And go get another
141 POP CS:[RET_ADDR1
] ;Fix up the stack
155 ;Look for any format specifiers preceeding the conversion character
157 CMP AL,"%" ;Just print the %
159 CMP AL,"-" ;Right justify the field
161 CMP AL,"+" ;Left justify the field
163 CMP AL,"L" ;Is it a long integer
167 CMP AL,"0" ;Is it a precision specification
173 CMP CS:[PRINTF_WIDTH
],0
175 MOV CS:BYTE PTR [PAD_CHAR
],"0"
177 PUSH AX ;Adjust decimal place on precision
179 MUL CS:[PRINTF_WIDTH
]
180 MOV CS:[PRINTF_WIDTH
],AX
184 ADD CS:[PRINTF_WIDTH
],AX ;And save the total
185 JMP SHORT NXT_CONV_CHAR
187 ;Set the correct flags for the options in a conversion
190 INC CS:BYTE PTR[PRINTF_LEFT
]
191 JMP SHORT NXT_CONV_CHAR
194 INC CS:BYTE PTR[PRINTF_LONG
]
198 ;Look for a conversion character
204 ;Make all other conversion characters upper case
221 ;Didn't find any legal conversion character - IGNORE it
227 MOV CS:[TABLE_INDEX
],6 ;Will print lower case hex digits
229 MOV CS:[PRINTF_BASE
],16 ;Hex conversion
233 MOV CS:[PRINTF_BASE
],10 ;Decimal conversion
237 INC CS:[S_FLAG
] ;It's a string specifier
239 PUSH SI ;Save pointer to control string
242 MOV SI,ds:[BP+SI.ARG
] ;Point to the % string or character
243 CMP BYTE PTR CS:[S_FLAG
],0
248 CALL OUTCHR
;Put it into our buffer
252 mov cx,cs:[printf_width
]
255 cmp cs:byte ptr[printf_left
],0
263 LODSB ;Put them all in our buffer
270 cmp byte ptr[printf_left
],0
272 mov cx,cs:[printf_width
]
278 POP SI ;Restore control string pointer
279 JMP GET_CHAR
;Go get another character
298 PUSH SI ;Save pointer to control string
299 MOV SI,BX ;Get index into argument list
300 ADD BX,2 ;Increment the index
301 MOV AX,ds:[BP+SI.ARG
] ;Lo word of number in SI
302 CMP BYTE PTR CS:[PRINTF_LONG
],0 ;Is this is a short or long integer?
304 MOV SI,BX ;Copy index
305 ADD BX,2 ;Increment the index
306 MOV DX,ds:[BP+SI.ARG
] ;Hi word of number in BP
309 XOR DX,DX ;Hi word is zero
311 PUSH BX ;Save index into arguemnt list
312 MOV si,CS:[PRINTF_BASE
]
313 MOV cx,CS:[PRINTF_WIDTH
]
341 CMP CS:BYTE PTR[PRINTF_LEFT
],0
348 CMP CS:BYTE PTR [PRINTF_HEX
],0
350 ADD AL,CS:BYTE PTR [TABLE_INDEX
]
352 MOV BX,OFFSET PRINTF_TABLE
366 MOV AL,CS:BYTE PTR [PAD_CHAR
]
377 CMP DI,offset bufend
-1 ;Don't count the nul
386 MOV DX,OFFSET PRINTF_BUF
391 MOV DI,OFFSET PRINTF_BUF
395 CMP DI,OFFSET PRINTF_BUF
397 SUB DI,OFFSET PRINTF_BUF
404 MOV BYTE PTR CS:[PRINTF_LEFT
],al ;Reset justifing flag
405 MOV BYTE PTR CS:[PRINTF_LONG
],al ;Reset long flag
406 MOV BYTE PTR CS:[TABLE_INDEX
],al ;Reset hex table index
407 MOV CS:[PRINTF_WIDTH
],ax ;Reinitialize width to 0
408 MOV BYTE PTR CS:[PAD_CHAR
]," " ;Reset padding character
409 MOV BYTE PTR CS:[S_FLAG
],al ;Clear the string flag
412 PRINTF_LAST
LABEL WORD