]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/CMD/COMMAND/TPRINTF.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / CMD / COMMAND / TPRINTF.ASM
1 page 80,132
2 ; SCCSID = @(#)tprintf.asm 4.3 85/07/02
3 ; SCCSID = @(#)tprintf.asm 4.3 85/07/02
4 TITLE 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
43 datares segment public
44 extrn pipeflag:byte
45 datares ends
46
47 TRANDATA 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
54 TRANDATA ENDS
55
56 TRANSPACE 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
70 PRINTF_HANDLE DW ? ;AC000;
71
72 TRANSPACE ENDS ;AC000;
73
74 TRANCODE SEGMENT PUBLIC BYTE ;AC000;
75
76 EXTRN cerror:near
77 EXTRN crlf2:near
78 EXTRN tcommand:near ;AN026;
79
80 ASSUME 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
89 PUBLIC Printf_Init
90 printf_init proc far
91 call std_printf
92 ret
93 printf_init endp
94
95 Public Printf_Crlf
96 PRINTF_CRLF:
97 CALL STD_PRINTF
98 CALL CRLF2
99 RET
100
101 PUBLIC Std_EPrintf
102 STD_EPRINTF:
103 mov Printf_Handle,2 ;AC000;Print to STDERR
104 jmp short NEW_PRINTF ;AC000;
105 PUBLIC Std_Printf
106 STD_PRINTF:
107 mov Printf_Handle,1 ;AC000;Print to STDOUT
108
109 NEW_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
123 UTILITY_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
162 MOVE_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
172 MOVE_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
186 CHECK_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
193 SET_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
200 SUBST_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
211 READY_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
240 print_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
281 print_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
288 not_stderr:
289 mov ax,print_err_flag ;AN026;get extended error number back
290 mov es,[resseg] ; No, set up for error, load the
291 assume 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
298 go_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
303 PRINT_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
323 TSYSLOADMSG PROC NEAR ;AN000;
324
325 push bx ;AN000;
326 call sysloadmsg ;AN000; call routine
327 pop bx ;AN000;
328 ret ;AN000; exit
329
330 TSYSLOADMSG 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
347 TSYSGETMSG PROC NEAR ;AN000;
348
349 push cx ;AN000;
350 call sysgetmsg ;AN000; call routine
351 pop cx ;AN000;
352 ret ;AN000; exit
353
354 TSYSGETMSG ENDP ;AN000;
355
356 MSG_SERVICES <COMT,NOVERCHECKmsg,NEARmsg,LOADmsg,NOCHECKSTDIN,NOCHECKSTDOUT,GETmsg> ;AC026; The message services
357 MSG_SERVICES <COMT,NEARmsg,SETSTDIO,DISPLAYmsg,CHARmsg,NUMmsg,TIMEmsg,DATEmsg> ;AC026; The message services
358
359 PRINTF_LAST LABEL WORD
360
361 include msgdcl.inc
362
363
364 TRANCODE ENDS
365 END