2 ; SCCSID = @(#)tprintf.asm 4.3 85/07/02
3 ; SCCSID = @(#)tprintf.asm 4.3 85/07/02
4 TITLE COMMAND Transient Printf routine
6 ;****************************************************************
8 ;* ROUTINE: STD_PRINTF/STD_EPRINTF
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.
15 ;* INPUT: Msg_Disp_Class - set to message class
16 ;* Msg_Cont_Flag - set to control flags
17 ;* DS points to transient segment
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
27 ;* AX set to message number
31 ;****************************************************************
35 INCLUDE comsw
.asm
;AC000;
38 INCLUDE comequ
.asm
;AN000;
39 INCLUDE SYSMSG
.INC ;AN000;
43 datares
segment public
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
56 TRANSPACE
SEGMENT PUBLIC BYTE ;AC000;
57 EXTRN msg_flag
:byte ;AN022;
58 EXTRN print_err_flag
:word ;AN000;
60 EXTRN String_ptr_2
:word ;AC000;
61 EXTRN Subst_buffer
:byte ;AN061;
62 ;AD061; EXTRN String_ptr_2_sb:word ;AN000;
64 ; include data area for message services
66 MSG_UTILNAME
<COMMAND
> ;AN000; define utility name
68 MSG_SERVICES
<MSGDATA
> ;AN000;
70 PRINTF_HANDLE
DW ?
;AC000;
72 TRANSPACE ENDS
;AC000;
74 TRANCODE
SEGMENT PUBLIC BYTE ;AC000;
78 EXTRN tcommand
:near ;AN026;
80 ASSUME
CS:TRANGROUP
,DS:TRANGROUP
,ES:NOTHING
,SS:NOTHING
;AC000;
82 PUBLIC SETSTDINOFF
;AN026;
83 PUBLIC SETSTDINON
;AN026;
84 PUBLIC SETSTDOUTOFF
;AN026;
85 PUBLIC SETSTDOUTON
;AN026;
86 PUBLIC TSYSGETMSG
;AN000;
87 PUBLIC TSYSLOADMSG
;AN000;
103 mov Printf_Handle
,2 ;AC000;Print to STDERR
104 jmp short NEW_PRINTF
;AC000;
107 mov Printf_Handle
,1 ;AC000;Print to STDOUT
110 push ax ;AN000;save registers
113 push es ;AN000;get local ES
119 assume
es:trangroup
;AN000;
120 ;AD061; mov string_ptr_2_sb,0 ;AN000;initialize
121 mov print_err_flag
,0 ;AN000;
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
134 ;AD061; add dx,Ptr_Seg_Pos ;AN000;Point to position of first segment
135 ;AD061; push cx ;AN000;save substitution count
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
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;
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
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
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;
172 MOVE_SUBST_CONT: ;AN061;
173 pop cx ;AN061;get number of subst back
174 loop move_subst
;AN061;move cx sublists
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
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
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
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
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
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
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;
227 call SYSDISPMSG
;AN000;call Rod
229 pop es ;AN026; restore registers
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;
237 jnc Print_success
;AN000; everything went okay
238 mov print_err_flag
,ax ;AN000;
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
250 ;AD061; pop dx ;AN000;restore dx
251 ;AD061; cmp cx,0 ;AN000;Any substitutions?
252 ;AD061; jz NO_FIXUP ;AN000;No - leave
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
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
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
272 pop es ;AN000;restore registers
276 cmp print_err_flag
,0 ;AN000; if an error occurred - handle it
277 jnz print_err
;AN000;
284 cmp Printf_Handle
,2 ;AN026;Print to STDERR?
285 jnz not_stderr
;AN026;no - continue
286 jmp tcommand
;AN026;Yes - hopless - just exit
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.
295 mov dx,offset trangroup
:pipeemes_ptr
296 jmp print_err_exit
;AC000;
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
303 PRINT_ERR_EXIT: ;AC000;
308 ;****************************************************************
310 ;* ROUTINE: TSYSLOADMSG
312 ;* FUNCTION: Interface to call SYSLOADMSG to avoid duplicate
313 ;* names since these routines are also used in the
316 ;* INPUT: Inputs to SYSLOADMSG
318 ;* OUTPUT: Outputs from SYSLOADMSG
320 ;****************************************************************
323 TSYSLOADMSG PROC
NEAR ;AN000;
326 call sysloadmsg
;AN000; call routine
330 TSYSLOADMSG ENDP
;AN000;
332 ;****************************************************************
334 ;* ROUTINE: TSYSGETMSG
336 ;* FUNCTION: Interface to call SYSGETMSG to avoid duplicate
337 ;* names since these routines are also used in the
340 ;* INPUT: Inputs to SYSGETMSG
342 ;* OUTPUT: Outputs from SYSGETMSG
344 ;****************************************************************
347 TSYSGETMSG PROC
NEAR ;AN000;
350 call sysgetmsg
;AN000; call routine
354 TSYSGETMSG ENDP
;AN000;
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
359 PRINTF_LAST
LABEL WORD