summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/COMMAND/TPRINTF.ASM
blob: c502f835f811e4f82c396a925cf981c61a1915fe (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
 page 80,132
;	SCCSID = @(#)tprintf.asm	4.3 85/07/02
;	SCCSID = @(#)tprintf.asm	4.3 85/07/02
TITLE	COMMAND Transient Printf routine

;****************************************************************
;*
;* ROUTINE:	STD_PRINTF/STD_EPRINTF
;*
;* FUNCTION:	Set up to print out a message using SYSDISPMSG.
;*		Set up substitutions if utility message.  Make
;*		sure any changes to message variables in TDATA
;*		are reset to avoid reloading the transient.
;*
;* INPUT:	Msg_Disp_Class	-  set to message class
;*		Msg_Cont_Flag	-  set to control flags
;*		DS	points to transient segment
;*
;*		if utility message:
;*		DX	points to a block with message number
;*			(word), number of substitutions (byte),
;*			followed by substitution list if there
;*			are substitutions.  If substitutions
;*			are not in transient segment they must
;*			be set.
;*		else
;*		AX	set to message number
;*
;* OUTPUT:	none
;*
;****************************************************************

.xlist
.xcref
	INCLUDE comsw.asm		;AC000;
	INCLUDE DOSSYM.INC
	INCLUDE comseg.asm
	INCLUDE comequ.asm		;AN000;
	INCLUDE SYSMSG.INC		;AN000;
.list
.cref

datares segment public
	extrn	pipeflag:byte
datares ends

TRANDATA	SEGMENT PUBLIC BYTE	;AC000;
	EXTRN	extend_buf_off:word	;AN000;
	EXTRN	Extend_Buf_ptr:word	;AN000;
	EXTRN	Extend_Buf_seg:word	;AN000;
	EXTRN	Msg_Cont_Flag:byte	;AN000;
	EXTRN	Msg_disp_Class:byte	;AN000;
	EXTRN	pipeemes_ptr:word
TRANDATA	ENDS

TRANSPACE	SEGMENT PUBLIC BYTE	;AC000;
	EXTRN	msg_flag:byte		;AN022;
	EXTRN	print_err_flag:word	;AN000;
	EXTRN	RESSEG:WORD
	EXTRN	String_ptr_2:word	;AC000;
	EXTRN	Subst_buffer:byte	;AN061;
;AD061; EXTRN	String_ptr_2_sb:word	;AN000;

	; include data area for message services

	MSG_UTILNAME <COMMAND>		;AN000; define utility name

	MSG_SERVICES <MSGDATA>		;AN000;

PRINTF_HANDLE	DW  ?			;AC000;

TRANSPACE	ENDS			;AC000;

TRANCODE	SEGMENT PUBLIC BYTE	;AC000;

	EXTRN	cerror:near
	EXTRN	crlf2:near
	EXTRN	tcommand:near		;AN026;

ASSUME	CS:TRANGROUP,DS:TRANGROUP,ES:NOTHING,SS:NOTHING ;AC000;

	PUBLIC	SETSTDINOFF		;AN026;
	PUBLIC	SETSTDINON		;AN026;
	PUBLIC	SETSTDOUTOFF		;AN026;
	PUBLIC	SETSTDOUTON		;AN026;
	PUBLIC	TSYSGETMSG		;AN000;
	PUBLIC	TSYSLOADMSG		;AN000;

PUBLIC Printf_Init
printf_init proc far
	call	std_printf
	ret
printf_init endp

Public	Printf_Crlf
PRINTF_CRLF:
	CALL	STD_PRINTF
	CALL	CRLF2
	RET

PUBLIC	Std_EPrintf
STD_EPRINTF:
	mov	Printf_Handle,2 		;AC000;Print to STDERR
	jmp	short NEW_PRINTF		;AC000;
PUBLIC	Std_Printf
STD_PRINTF:
	mov	Printf_Handle,1 		;AC000;Print to STDOUT

NEW_PRINTF:
	push	ax				;AN000;save registers
	push	bx				;AN000;
	push	cx				;AN000;
	push	es				;AN000;get local ES
	push	ds				;AN000;
	pop	es				;AN000;
	push	di				;AN000;
	push	si				;AN000;
	push	dx				;AN000;
	assume	es:trangroup			;AN000;
;AD061; mov	string_ptr_2_sb,0		;AN000;initialize
	mov	print_err_flag,0		;AN000;

UTILITY_SETUP:
	mov	si,dx				;AN000;Get offset of message number
	lodsw					;AN000;load message number
	push	ax				;AN000;save it
	lodsb					;AN000;get number of substitutions
	mov	cl,al				;AN000;set up CX as # of subst
	xor	ch,ch				;AN000;   SI now points to subst list
	pop	ax				;AN000;get message number back
	cmp	cx,0				;AN000;Any substitutions?
	jz	READY_TO_PRINT			;AN000;No - continue

;AD061;  add	 dx,Ptr_Seg_Pos 		 ;AN000;Point to position of first segment
;AD061;  push	 cx				 ;AN000;save substitution count

;AD061;SET_SUBST:
;AD061;  mov	 bx,dx				 ;AN000;get dx into base register
;AD061;  cmp	 word ptr [bx],0		 ;AN000;has segment been set?
;AD061;  jnz	 SUBST_SEG_SET			 ;AN000;if not 0, don't replace it
;AD061;  test	 word ptr [bx+3],date_type	 ;AN000;if date or time - don't set segment
;AD061;  jnz	 subst_seg_set			 ;AN000;yes - skip it
;AD061;  mov	 word ptr [bx],cs		 ;AN000;put segment of subst parm in list

;AD061;SUBST_SEG_SET:
;AD061;  add	 dx,Parm_Block_Size		 ;AN000;point to position of next segment
;AD061;  loop	 SET_SUBST			 ;AN000;keep replacing until complete
;AD061;  pop	 cx				 ;AN000;

;AD061;NO_REPLACEMENT:
;AD061;  mov	 bx,parm_off_pos [si]		 ;AN000;get subst offset
;AD061;  cmp	 bx,offset trangroup:string_ptr_2 ;AN000;this is used for double indirection
;AD061;  jnz	 ready_to_print 		 ;AN000;we already have address
;AD061;  mov	 dx,string_ptr_2		 ;AN000;get address in string_ptr_2
;AD061;  mov	 parm_off_pos [si],dx		 ;AN000;put proper address in table
;AD061;  mov	 string_ptr_2_sb,si		 ;AN000;save block changed

	mov	di,offset trangroup:subst_buffer;AN061; Get address of message subst buffer
	push	di				;AN061; save it
	push	cx				;AN061; save number of subst

MOVE_SUBST:
	push	cx				;AN061;save number of subst
	mov	bx,si				;AN061;save start of sublist
	mov	cx,parm_block_size		;AN061;get size of sublist
	rep	movsb				;AN061;move sublist
	test	byte ptr [bx.$M_S_FLAG],date_type ;AN061;are we doing date/time?
	jz	move_subst_cont 		;AN061;no - no need to reset
	mov	word ptr [bx.$M_S_VALUE],0	;AN061;reset original date or time to 0
	mov	word ptr [bx.$M_S_VALUE+2],0	;AN061;

MOVE_SUBST_CONT:				;AN061;
	pop	cx				;AN061;get number of subst back
	loop	move_subst			;AN061;move cx sublists

	pop	cx				;AN061;get number of subst
	push	ax				;AN061;save message number
	cmp	Msg_Disp_Class,Util_Msg_Class	;AN061;Is this a utility message
	jz	CHECK_FIX			;AN061;YES - go see if substitutions
	mov	msg_flag,ext_msg_class		;AN061;set message flag
	mov	di,offset trangroup:extend_buf_ptr ;AN061; Get address of extended message block
	xor	ax,ax				;AN061;clear ax register
	stosw					;AN061;clear out message number
	stosb					;AN061;clear out subst count

CHECK_FIX:					;AN061;
	pop	ax				;AN061;get message number back
	pop	di				;AN061;get start of sublists
	mov	si,di				;AN061;get into SI for msgserv
	mov	bx,si				;AN061;get into BX for addressing
	push	cx				;AN061;save number of subst

SET_SUBST:					;AN061;store the segment of the subst
	cmp	word ptr [bx.$M_S_VALUE+2],0	;AN061;was it set already?
	jnz	subst_seg_set			;AN061;if not 0, don't replace it
	test	byte ptr [bx.$M_S_FLAG],date_type ;AN061;don't replace if date or time
	jnz	subst_seg_set			;AN061;yes - skip it
	mov	word ptr [bx.$M_S_VALUE+2],cs	;AN061;set segment value

SUBST_SEG_SET:					;AN061;
	add	bx,parm_block_size		;AN061;go to next sublist
	loop	set_subst			;AN061;loop CX times
	pop	cx				;AN061;get number of subst back

	mov	bx,si				;AN061;get start of sublist to BX
	cmp	word ptr [bx.$M_S_VALUE],offset trangroup:string_ptr_2 ;AN061;are we using double indirection?
	jnz	ready_to_print			;AN061;no - we already have address
	mov	dx,string_ptr_2 		;AN061;get address in string_ptr_2
	mov	word ptr [bx.$M_S_VALUE],dx	;AN061;put it into the subst block

READY_TO_PRINT:
	mov	bx,Printf_Handle		;AN000;get print handle
	mov	dl,Msg_Cont_Flag		;AN000;set up control flag
	mov	dh,Msg_Disp_Class		;AN000;set up display class
	mov	Msg_Cont_Flag,No_Cont_Flag	;AN061;reset flags to avoid
	mov	Msg_Disp_Class,Util_Msg_Class	;AN061;   transient reload

;AD061; push	bx				;AN026; save registers
;AD061; push	cx				;AN026;
;AD061; push	dx				;AN026;
;AD061; push	si				;AN026;
;AD061; push	di				;AN026;
	push	ds				;AN026;
	push	es				;AN026;


	call	SYSDISPMSG			;AN000;call Rod

	pop	es				;AN026; restore registers
	pop	ds				;AN026;
;AD061; pop	di				;AN026;
;AD061; pop	si				;AN026;
;AD061; pop	dx				;AN026;
;AD061; pop	cx				;AN026;
;AD061; pop	bx				;AN026;

	jnc	Print_success			;AN000; everything went okay
	mov	print_err_flag,ax		;AN000;

print_success:
;AD061; cmp	Msg_Disp_Class,Util_Msg_Class	;AN000;Is this a utility message
;AD061; jz	CHECK_FIX			;AN000;YES - go see if substitutions
;AD061; mov	msg_flag,ext_msg_class		;AN022;set message flag
;AD061; mov	di,offset trangroup:extend_buf_ptr ;AN000; Get address of extended message block
;AD061; xor	ax,ax				;AN000;clear ax register
;AD061; stosw					;AN000;clear out message number
;AD061; stosb					;AN000;clear out subst count

;AD061;  CHECK_FIX:
;AD061;  pop	 dx				 ;AN000;restore dx
;AD061;  cmp	 cx,0				 ;AN000;Any substitutions?
;AD061;  jz	 NO_FIXUP			 ;AN000;No - leave

;AD061;  mov	 si,dx				 ;AN000;Reset changes so transient won't reload
;AD061;  add	 si,Ptr_Seg_Pos 		 ;AN000;Point to position of first segment

;AD061;FIX_SUBST:
;AD061;  mov	 word ptr [si],0		 ;AN000;reset segment to 0
;AD061;  add	 si,Parm_Block_Size		 ;AN000;point to position of next segment
;AD061;  loop	 FIX_SUBST			 ;AN000;keep replacing until complete
;AD061;  cmp	 string_ptr_2_sb,no_subst	 ;AN000;was double indirection used?
;AD061;  jz	 no_fixup			 ;AN000;no - we're finished
;AD061;  mov	 si,string_ptr_2_sb		 ;AN000;get offset changed
;AD061;  mov	 parm_off_pos [si],offset trangroup:string_ptr_2 ;AN000; set address back to string_ptr_2

;AD061;NO_FIXUP:
;AD061; mov	Msg_Cont_Flag,No_Cont_Flag	;AN000;reset flags to avoid
;AD061; mov	Msg_Disp_Class,Util_Msg_Class	;AN000;   transient reload
	pop	dx				;AN061;restore dx
	pop	si				;AN000;restore registers
	pop	di				;AN000;
	pop	es				;AN000;restore registers
	pop	cx				;AN000;
	pop	bx				;AN000;
	pop	ax				;AN000;
	cmp	print_err_flag,0		;AN000; if an error occurred - handle it
	jnz	print_err			;AN000;

	ret					;AC000;

print_err:
	push	cs
	pop	es
	cmp	Printf_Handle,2 		;AN026;Print to STDERR?
	jnz	not_stderr			;AN026;no - continue
	jmp	tcommand			;AN026;Yes - hopless - just exit

not_stderr:
	mov	ax,print_err_flag		;AN026;get extended error number back
	mov	es,[resseg]			; No, set up for error, load the
assume	es:resgroup				;  right error msg, and jmp to cerror.
	test	PipeFlag,-1
	jz	go_to_error
	invoke	PipeOff
	mov	dx,offset trangroup:pipeemes_ptr
	jmp	print_err_exit			;AC000;

go_to_error:
	mov	msg_disp_class,ext_msg_class	;AN000; set up extended error msg class
	mov	dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
	mov	Extend_Buf_ptr,ax		;AN000; get message number in control block

PRINT_ERR_EXIT: 				;AC000;
	push	cs
	pop	es
	JMP	CERROR

;****************************************************************
;*
;* ROUTINE:	TSYSLOADMSG
;*
;* FUNCTION:	Interface to call SYSLOADMSG to avoid duplicate
;*		names since these routines are also used in the
;*		resident.
;*
;* INPUT:	Inputs to SYSLOADMSG
;*
;* OUTPUT:	Outputs from SYSLOADMSG
;*
;****************************************************************


TSYSLOADMSG	PROC	NEAR			;AN000;

	push	bx				;AN000;
	call sysloadmsg 			;AN000; call routine
	pop	bx				;AN000;
	ret					;AN000; exit

TSYSLOADMSG	ENDP				;AN000;

;****************************************************************
;*
;* ROUTINE:	TSYSGETMSG
;*
;* FUNCTION:	Interface to call SYSGETMSG to avoid duplicate
;*		names since these routines are also used in the
;*		resident.
;*
;* INPUT:	Inputs to SYSGETMSG
;*
;* OUTPUT:	Outputs from SYSGETMSG
;*
;****************************************************************


TSYSGETMSG	PROC	NEAR			;AN000;

	push	cx				;AN000;
	call sysgetmsg				;AN000; call routine
	pop	cx				;AN000;
	ret					;AN000; exit

TSYSGETMSG	ENDP				;AN000;

MSG_SERVICES <COMT,NOVERCHECKmsg,NEARmsg,LOADmsg,NOCHECKSTDIN,NOCHECKSTDOUT,GETmsg> ;AC026; The message services
MSG_SERVICES <COMT,NEARmsg,SETSTDIO,DISPLAYmsg,CHARmsg,NUMmsg,TIMEmsg,DATEmsg>	    ;AC026; The message services

PRINTF_LAST LABEL   WORD

include msgdcl.inc


TRANCODE    ENDS
	    END