summaryrefslogtreecommitdiff
path: root/v4.0/src/DOS/PRINT.ASM
blob: c2bbe55f723b2bc611680b2d9fd018e4a1d1a06e (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
;	SCCSID = @(#)print.asm	1.1 85/04/10
;
; PFMT - formatted output.  Calling sequence:
;   PUSH    BP
;   PUSH    fmtstr
;   MOV     BP,SP
;   PUSH    args
;   CALL    PFMT
;   ADD     SP,n
;   POP     BP
;
; The format string contains format directives and normal output characters
; much like the PRINTF for C.  We utilize NO format widths.  Special chars
; and strings are:
;
;       $x      output a hex number
;       $s      output an offset string
;       $c      output a character
;       $S      output a segmented string
;       $p      output userid/processid
;       \t      output a tab
;       \n      output a CRLF
;
; The format string must be addressable via CS
;

Procedure PFMT,NEAR
	SaveReg <AX,BX,DS,SI>
	MOV     AX,8007h
	INT     2Ah
	PUSH    CS
	POP     DS
	SUB     BP,2
	Call    FMTGetArg
	MOV     SI,AX
FmtLoop:
	LODSB
	OR      AL,AL
	JZ      FmtDone
	CMP     AL,'$'
	JZ      FmtOpt
	CMP     AL,'\'
	JZ      FmtChr
FmtOut:
	CALL    Out
	JMP     FmtLoop
Out:
	SaveReg <SI,DI,BP>
	INT     29h
	RestoreReg  <BP,DI,SI>
	return
FmtDone:
	MOV     AX,8107h
	INT     2Ah
	RestoreReg  <SI,DS,BX,AX>
	RET
;
; \ leads in a special character. See what the next char is.
;
FmtChr: LODSB
	OR      AL,AL                   ; end of string
	JZ      fmtDone
	CMP     AL,'n'                  ; newline
	JZ      FmtCRLF
	CMP     AL,'t'                  ; tab
	JNZ     FmtOut
	MOV     AL,9
	JMP     FmtOut
FmtCRLF:MOV     AL,13
	CALL    Out
	MOV     AL,10
	JMP     FmtOut
;
; $ leads in a format specifier.
;
FmtOpt: LODSB
	CMP     AL,'x'                  ; hex number
	JZ      FmtX
	CMP     AL,'c'                  ; single character
	JZ      FmtC
	CMP     AL,'s'                  ; offset string
	JZ      FmtSoff
	CMP     AL,'S'                  ; segmented string
	JZ      FmtSseg
	CMP     AL,'p'
	JZ      FmtUPID
	JMP     FmtOut
FmtX:
	Call    FMTGetArg
	MOV     BX,AX
	CALL    MNUM
	JMP     FmtLoop
FmtC:
	Call    FmtGetArg
	CALL    Out
	JMP     FmtLoop
FmtSoff:
	SaveReg <SI>
	Call    FmtGetArg
	MOV     SI,AX
	CALL    fmtsout
	RestoreReg  <SI>
	JMP     FmtLoop
FmtSSeg:
	SaveReg <DS,SI>
	CALL    FMTGetArg
	MOV     DS,AX
	CALL    FMTGetArg
	MOV     SI,AX
	CALL    fmtsout
	RestoreReg  <SI,DS>
	JMP     FmtLoop
FmtUPID:
	SaveReg <DS>
	MOV     BX,0
	MOV     DS,BX
	MOV     DS,DS:[82h]
	ASSUME  DS:DOSGroup
	MOV     BX,User_ID
	CALL    MNUM
	MOV     AL,':'
	CALL    OUT
	MOV     BX,Proc_ID
	CALL    MNUM
	RestoreReg  <DS>
	Assume  DS:NOTHING
	JMP     FmtLoop
EndProc PFMT

Procedure   FMTGetArg,NEAR
	MOV     AX,[BP]
	SUB     BP,2
	return
EndProc FMTGetArg

Procedure   FmtSOut,NEAR
	LODSB
	OR      AL,AL
	retz
	CALL    OUT
	JMP     FmtSOut
EndProc FMTSout

;
;   MOut - output a message via INT 29h
;   Inputs:     BX points to bytes to output relative to CS
;   Outputs:    message
;   Registers modified: BX
Procedure   MOut,Near
	ASSUME  DS:NOTHING,SS:NOTHING,ES:NOTHING
	PUSHF
	SaveReg <DS,SI,AX>
	PUSH    CS
	POP     DS
	MOV     SI,BX
	Call    FMTSout
	RestoreReg  <AX,SI,DS>
	POPF
	return
EndProc MOut

;   MNum - output a number in BX
;   Inputs:     BX contains a number
;   Outputs:    number in hex appears on screen
;   Registers modified: BX

Procedure   MNum,NEAR
	ASSUME  DS:NOTHING,ES:NOTHING,SS:NOTHING
	PUSHF
	SaveReg <ES,DI,AX,BX,CX,SI,DS>
	PUSH    SS
	POP     ES
	SUB     SP,6
	MOV     DI,SP                   ;   p = MNumBuf;
	SaveReg <DI>
	MOV     CX,4                    ;   for (i=0; i < 4; i++)
DLoop:  SaveReg <CX>
	MOV     CX,4                    ;       rotate(n, 4);
	ROL     BX,CL
	RestoreReg  <CX>
	MOV     AL,BL
	AND     AL,0Fh
	ADD     AL,'0'
	CMP     AL,'9'
	JBE     Nok
	ADD     AL,'A'-'0'-10
Nok:    STOSB                           ;       *p++ = "0123456789ABCDEF"[n];
	LOOP    DLoop
	XOR     AL,AL
	STOSB                           ;   *p++ = 0;
	RestoreReg  <SI>
	PUSH    ES
	POP     DS
	CALL    FMTSOUT                 ;   mout (mNumBuf);
	ADD     SP,6
	RestoreReg  <DS,SI,CX,BX,AX,DI,ES>
	POPF
	return
EndProc MNum