summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/COMMAND/TPRINTF.ASM
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/CMD/COMMAND/TPRINTF.ASM
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0/src/CMD/COMMAND/TPRINTF.ASM')
-rw-r--r--v4.0/src/CMD/COMMAND/TPRINTF.ASM365
1 files changed, 365 insertions, 0 deletions
diff --git a/v4.0/src/CMD/COMMAND/TPRINTF.ASM b/v4.0/src/CMD/COMMAND/TPRINTF.ASM
new file mode 100644
index 0000000..c502f83
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/TPRINTF.ASM
@@ -0,0 +1,365 @@
1 page 80,132
2; SCCSID = @(#)tprintf.asm 4.3 85/07/02
3; SCCSID = @(#)tprintf.asm 4.3 85/07/02
4TITLE COMMAND Transient Printf routine
5
6;****************************************************************
7;*
8;* ROUTINE: STD_PRINTF/STD_EPRINTF
9;*
10;* FUNCTION: Set up to print out a message using SYSDISPMSG.
11;* Set up substitutions if utility message. Make
12;* sure any changes to message variables in TDATA
13;* are reset to avoid reloading the transient.
14;*
15;* INPUT: Msg_Disp_Class - set to message class
16;* Msg_Cont_Flag - set to control flags
17;* DS points to transient segment
18;*
19;* if utility message:
20;* DX points to a block with message number
21;* (word), number of substitutions (byte),
22;* followed by substitution list if there
23;* are substitutions. If substitutions
24;* are not in transient segment they must
25;* be set.
26;* else
27;* AX set to message number
28;*
29;* OUTPUT: none
30;*
31;****************************************************************
32
33.xlist
34.xcref
35 INCLUDE comsw.asm ;AC000;
36 INCLUDE DOSSYM.INC
37 INCLUDE comseg.asm
38 INCLUDE comequ.asm ;AN000;
39 INCLUDE SYSMSG.INC ;AN000;
40.list
41.cref
42
43datares segment public
44 extrn pipeflag:byte
45datares ends
46
47TRANDATA SEGMENT PUBLIC BYTE ;AC000;
48 EXTRN extend_buf_off:word ;AN000;
49 EXTRN Extend_Buf_ptr:word ;AN000;
50 EXTRN Extend_Buf_seg:word ;AN000;
51 EXTRN Msg_Cont_Flag:byte ;AN000;
52 EXTRN Msg_disp_Class:byte ;AN000;
53 EXTRN pipeemes_ptr:word
54TRANDATA ENDS
55
56TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
57 EXTRN msg_flag:byte ;AN022;
58 EXTRN print_err_flag:word ;AN000;
59 EXTRN RESSEG:WORD
60 EXTRN String_ptr_2:word ;AC000;
61 EXTRN Subst_buffer:byte ;AN061;
62;AD061; EXTRN String_ptr_2_sb:word ;AN000;
63
64 ; include data area for message services
65
66 MSG_UTILNAME <COMMAND> ;AN000; define utility name
67
68 MSG_SERVICES <MSGDATA> ;AN000;
69
70PRINTF_HANDLE DW ? ;AC000;
71
72TRANSPACE ENDS ;AC000;
73
74TRANCODE SEGMENT PUBLIC BYTE ;AC000;
75
76 EXTRN cerror:near
77 EXTRN crlf2:near
78 EXTRN tcommand:near ;AN026;
79
80ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:NOTHING,SS:NOTHING ;AC000;
81
82 PUBLIC SETSTDINOFF ;AN026;
83 PUBLIC SETSTDINON ;AN026;
84 PUBLIC SETSTDOUTOFF ;AN026;
85 PUBLIC SETSTDOUTON ;AN026;
86 PUBLIC TSYSGETMSG ;AN000;
87 PUBLIC TSYSLOADMSG ;AN000;
88
89PUBLIC Printf_Init
90printf_init proc far
91 call std_printf
92 ret
93printf_init endp
94
95Public Printf_Crlf
96PRINTF_CRLF:
97 CALL STD_PRINTF
98 CALL CRLF2
99 RET
100
101PUBLIC Std_EPrintf
102STD_EPRINTF:
103 mov Printf_Handle,2 ;AC000;Print to STDERR
104 jmp short NEW_PRINTF ;AC000;
105PUBLIC Std_Printf
106STD_PRINTF:
107 mov Printf_Handle,1 ;AC000;Print to STDOUT
108
109NEW_PRINTF:
110 push ax ;AN000;save registers
111 push bx ;AN000;
112 push cx ;AN000;
113 push es ;AN000;get local ES
114 push ds ;AN000;
115 pop es ;AN000;
116 push di ;AN000;
117 push si ;AN000;
118 push dx ;AN000;
119 assume es:trangroup ;AN000;
120;AD061; mov string_ptr_2_sb,0 ;AN000;initialize
121 mov print_err_flag,0 ;AN000;
122
123UTILITY_SETUP:
124 mov si,dx ;AN000;Get offset of message number
125 lodsw ;AN000;load message number
126 push ax ;AN000;save it
127 lodsb ;AN000;get number of substitutions
128 mov cl,al ;AN000;set up CX as # of subst
129 xor ch,ch ;AN000; SI now points to subst list
130 pop ax ;AN000;get message number back
131 cmp cx,0 ;AN000;Any substitutions?
132 jz READY_TO_PRINT ;AN000;No - continue
133
134;AD061; add dx,Ptr_Seg_Pos ;AN000;Point to position of first segment
135;AD061; push cx ;AN000;save substitution count
136
137;AD061;SET_SUBST:
138;AD061; mov bx,dx ;AN000;get dx into base register
139;AD061; cmp word ptr [bx],0 ;AN000;has segment been set?
140;AD061; jnz SUBST_SEG_SET ;AN000;if not 0, don't replace it
141;AD061; test word ptr [bx+3],date_type ;AN000;if date or time - don't set segment
142;AD061; jnz subst_seg_set ;AN000;yes - skip it
143;AD061; mov word ptr [bx],cs ;AN000;put segment of subst parm in list
144
145;AD061;SUBST_SEG_SET:
146;AD061; add dx,Parm_Block_Size ;AN000;point to position of next segment
147;AD061; loop SET_SUBST ;AN000;keep replacing until complete
148;AD061; pop cx ;AN000;
149
150;AD061;NO_REPLACEMENT:
151;AD061; mov bx,parm_off_pos [si] ;AN000;get subst offset
152;AD061; cmp bx,offset trangroup:string_ptr_2 ;AN000;this is used for double indirection
153;AD061; jnz ready_to_print ;AN000;we already have address
154;AD061; mov dx,string_ptr_2 ;AN000;get address in string_ptr_2
155;AD061; mov parm_off_pos [si],dx ;AN000;put proper address in table
156;AD061; mov string_ptr_2_sb,si ;AN000;save block changed
157
158 mov di,offset trangroup:subst_buffer;AN061; Get address of message subst buffer
159 push di ;AN061; save it
160 push cx ;AN061; save number of subst
161
162MOVE_SUBST:
163 push cx ;AN061;save number of subst
164 mov bx,si ;AN061;save start of sublist
165 mov cx,parm_block_size ;AN061;get size of sublist
166 rep movsb ;AN061;move sublist
167 test byte ptr [bx.$M_S_FLAG],date_type ;AN061;are we doing date/time?
168 jz move_subst_cont ;AN061;no - no need to reset
169 mov word ptr [bx.$M_S_VALUE],0 ;AN061;reset original date or time to 0
170 mov word ptr [bx.$M_S_VALUE+2],0 ;AN061;
171
172MOVE_SUBST_CONT: ;AN061;
173 pop cx ;AN061;get number of subst back
174 loop move_subst ;AN061;move cx sublists
175
176 pop cx ;AN061;get number of subst
177 push ax ;AN061;save message number
178 cmp Msg_Disp_Class,Util_Msg_Class ;AN061;Is this a utility message
179 jz CHECK_FIX ;AN061;YES - go see if substitutions
180 mov msg_flag,ext_msg_class ;AN061;set message flag
181 mov di,offset trangroup:extend_buf_ptr ;AN061; Get address of extended message block
182 xor ax,ax ;AN061;clear ax register
183 stosw ;AN061;clear out message number
184 stosb ;AN061;clear out subst count
185
186CHECK_FIX: ;AN061;
187 pop ax ;AN061;get message number back
188 pop di ;AN061;get start of sublists
189 mov si,di ;AN061;get into SI for msgserv
190 mov bx,si ;AN061;get into BX for addressing
191 push cx ;AN061;save number of subst
192
193SET_SUBST: ;AN061;store the segment of the subst
194 cmp word ptr [bx.$M_S_VALUE+2],0 ;AN061;was it set already?
195 jnz subst_seg_set ;AN061;if not 0, don't replace it
196 test byte ptr [bx.$M_S_FLAG],date_type ;AN061;don't replace if date or time
197 jnz subst_seg_set ;AN061;yes - skip it
198 mov word ptr [bx.$M_S_VALUE+2],cs ;AN061;set segment value
199
200SUBST_SEG_SET: ;AN061;
201 add bx,parm_block_size ;AN061;go to next sublist
202 loop set_subst ;AN061;loop CX times
203 pop cx ;AN061;get number of subst back
204
205 mov bx,si ;AN061;get start of sublist to BX
206 cmp word ptr [bx.$M_S_VALUE],offset trangroup:string_ptr_2 ;AN061;are we using double indirection?
207 jnz ready_to_print ;AN061;no - we already have address
208 mov dx,string_ptr_2 ;AN061;get address in string_ptr_2
209 mov word ptr [bx.$M_S_VALUE],dx ;AN061;put it into the subst block
210
211READY_TO_PRINT:
212 mov bx,Printf_Handle ;AN000;get print handle
213 mov dl,Msg_Cont_Flag ;AN000;set up control flag
214 mov dh,Msg_Disp_Class ;AN000;set up display class
215 mov Msg_Cont_Flag,No_Cont_Flag ;AN061;reset flags to avoid
216 mov Msg_Disp_Class,Util_Msg_Class ;AN061; transient reload
217
218;AD061; push bx ;AN026; save registers
219;AD061; push cx ;AN026;
220;AD061; push dx ;AN026;
221;AD061; push si ;AN026;
222;AD061; push di ;AN026;
223 push ds ;AN026;
224 push es ;AN026;
225
226
227 call SYSDISPMSG ;AN000;call Rod
228
229 pop es ;AN026; restore registers
230 pop ds ;AN026;
231;AD061; pop di ;AN026;
232;AD061; pop si ;AN026;
233;AD061; pop dx ;AN026;
234;AD061; pop cx ;AN026;
235;AD061; pop bx ;AN026;
236
237 jnc Print_success ;AN000; everything went okay
238 mov print_err_flag,ax ;AN000;
239
240print_success:
241;AD061; cmp Msg_Disp_Class,Util_Msg_Class ;AN000;Is this a utility message
242;AD061; jz CHECK_FIX ;AN000;YES - go see if substitutions
243;AD061; mov msg_flag,ext_msg_class ;AN022;set message flag
244;AD061; mov di,offset trangroup:extend_buf_ptr ;AN000; Get address of extended message block
245;AD061; xor ax,ax ;AN000;clear ax register
246;AD061; stosw ;AN000;clear out message number
247;AD061; stosb ;AN000;clear out subst count
248
249;AD061; CHECK_FIX:
250;AD061; pop dx ;AN000;restore dx
251;AD061; cmp cx,0 ;AN000;Any substitutions?
252;AD061; jz NO_FIXUP ;AN000;No - leave
253
254;AD061; mov si,dx ;AN000;Reset changes so transient won't reload
255;AD061; add si,Ptr_Seg_Pos ;AN000;Point to position of first segment
256
257;AD061;FIX_SUBST:
258;AD061; mov word ptr [si],0 ;AN000;reset segment to 0
259;AD061; add si,Parm_Block_Size ;AN000;point to position of next segment
260;AD061; loop FIX_SUBST ;AN000;keep replacing until complete
261;AD061; cmp string_ptr_2_sb,no_subst ;AN000;was double indirection used?
262;AD061; jz no_fixup ;AN000;no - we're finished
263;AD061; mov si,string_ptr_2_sb ;AN000;get offset changed
264;AD061; mov parm_off_pos [si],offset trangroup:string_ptr_2 ;AN000; set address back to string_ptr_2
265
266;AD061;NO_FIXUP:
267;AD061; mov Msg_Cont_Flag,No_Cont_Flag ;AN000;reset flags to avoid
268;AD061; mov Msg_Disp_Class,Util_Msg_Class ;AN000; transient reload
269 pop dx ;AN061;restore dx
270 pop si ;AN000;restore registers
271 pop di ;AN000;
272 pop es ;AN000;restore registers
273 pop cx ;AN000;
274 pop bx ;AN000;
275 pop ax ;AN000;
276 cmp print_err_flag,0 ;AN000; if an error occurred - handle it
277 jnz print_err ;AN000;
278
279 ret ;AC000;
280
281print_err:
282 push cs
283 pop es
284 cmp Printf_Handle,2 ;AN026;Print to STDERR?
285 jnz not_stderr ;AN026;no - continue
286 jmp tcommand ;AN026;Yes - hopless - just exit
287
288not_stderr:
289 mov ax,print_err_flag ;AN026;get extended error number back
290 mov es,[resseg] ; No, set up for error, load the
291assume es:resgroup ; right error msg, and jmp to cerror.
292 test PipeFlag,-1
293 jz go_to_error
294 invoke PipeOff
295 mov dx,offset trangroup:pipeemes_ptr
296 jmp print_err_exit ;AC000;
297
298go_to_error:
299 mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
300 mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
301 mov Extend_Buf_ptr,ax ;AN000; get message number in control block
302
303PRINT_ERR_EXIT: ;AC000;
304 push cs
305 pop es
306 JMP CERROR
307
308;****************************************************************
309;*
310;* ROUTINE: TSYSLOADMSG
311;*
312;* FUNCTION: Interface to call SYSLOADMSG to avoid duplicate
313;* names since these routines are also used in the
314;* resident.
315;*
316;* INPUT: Inputs to SYSLOADMSG
317;*
318;* OUTPUT: Outputs from SYSLOADMSG
319;*
320;****************************************************************
321
322
323TSYSLOADMSG PROC NEAR ;AN000;
324
325 push bx ;AN000;
326 call sysloadmsg ;AN000; call routine
327 pop bx ;AN000;
328 ret ;AN000; exit
329
330TSYSLOADMSG ENDP ;AN000;
331
332;****************************************************************
333;*
334;* ROUTINE: TSYSGETMSG
335;*
336;* FUNCTION: Interface to call SYSGETMSG to avoid duplicate
337;* names since these routines are also used in the
338;* resident.
339;*
340;* INPUT: Inputs to SYSGETMSG
341;*
342;* OUTPUT: Outputs from SYSGETMSG
343;*
344;****************************************************************
345
346
347TSYSGETMSG PROC NEAR ;AN000;
348
349 push cx ;AN000;
350 call sysgetmsg ;AN000; call routine
351 pop cx ;AN000;
352 ret ;AN000; exit
353
354TSYSGETMSG ENDP ;AN000;
355
356MSG_SERVICES <COMT,NOVERCHECKmsg,NEARmsg,LOADmsg,NOCHECKSTDIN,NOCHECKSTDOUT,GETmsg> ;AC026; The message services
357MSG_SERVICES <COMT,NEARmsg,SETSTDIO,DISPLAYmsg,CHARmsg,NUMmsg,TIMEmsg,DATEmsg> ;AC026; The message services
358
359PRINTF_LAST LABEL WORD
360
361include msgdcl.inc
362
363
364TRANCODE ENDS
365 END