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
|
procedure $STD_CON_STRING_INPUT,NEAR ;System call 10
ASSUME DS:NOTHING,ES:NOTHING
; Inputs:
; DS:DX Point to an input buffer
; Function:
; Fill buffer from console input until CR
; Returns:
; None
MOV AX,SS
MOV ES,AX
MOV SI,DX
XOR CH,CH
LODSW
OR AL,AL
retz ;Buffer is 0 length!!?
MOV BL,AH ;Init template counter
MOV BH,CH ;Init template counter
CMP AL,BL
JBE NOEDIT ;If length of buffer inconsistent with contents
CMP BYTE PTR [BX+SI],c_CR
JZ EDITON ;If CR correctly placed EDIT is OK
NOEDIT:
MOV BL,CH ;Reset buffer
EDITON:
MOV DL,AL
DEC DX ;DL is # of bytes we can put in the buffer
NEWLIN:
MOV AL,[CARPOS]
MOV [STARTPOS],AL ;Remember position in raw buffer
PUSH SI
MOV DI,OFFSET DOSGROUP:INBUF ;Build the new line here
MOV [INSMODE],CH ;Insert mode off
MOV BH,CH ;No chars from template yet
MOV DH,CH ;No chars to new line yet
invoke $STD_CON_INPUT_NO_ECHO ;Get first char
CMP AL,c_LF ;Linefeed
JNZ GOTCH ;Filter out LF so < works
entry GETCH
invoke $STD_CON_INPUT_NO_ECHO
GOTCH:
CMP AL,"F"-"@" ;Ignore ^F
JZ GETCH
CMP AL,[ESCCHAR]
JZ ESC
CMP AL,c_DEL
JZ BACKSPJ
CMP AL,c_BS
JZ BACKSPJ
CMP AL,c_CR
JZ ENDLIN
CMP AL,c_LF
JZ PHYCRLF
CMP AL,CANCEL
JZ KILNEW
SAVCH:
CMP DH,DL
JAE BUFFUL ;No room
STOSB
INC DH ;Got a char
invoke BUFOUT ;Print control chars nicely
CMP BYTE PTR [INSMODE],0
JNZ GETCH ;In insert mode, get more chars
CMP BH,BL
JAE GETCH ;We are out of chars in template
INC SI ;Skip to next char in template
INC BH
JMP SHORT GETCH
BACKSPJ: JMP SHORT BACKSP
BUFFUL:
MOV AL,7 ;Bell
invoke OUT
JMP SHORT GETCH
ESC:
transfer OEMFunctionKey
ENDLIN:
STOSB ;Put the CR in the buffer
invoke OUT ;Echo it
POP DI ;Get start of buffer
MOV [DI-1],DH ;Tell user how many bytes
INC DH ;DH is length including CR
COPYNEW:
MOV BP,ES ;XCHG ES,DS
MOV BX,DS
MOV ES,BX
MOV DS,BP
MOV SI,OFFSET DOSGROUP:INBUF
MOV CL,DH
REP MOVSB ;Copy final line to user buffer
return ;All done
;Output a CRLF
entry CRLF
MOV AL,c_CR
invoke OUT
MOV AL,c_LF
JMP OUT
;Output a CRLF which is not terminate buffer
PHYCRLF:
invoke CRLF
JMP GETCH
;Zap the line without zapping the template
entry KILNEW
MOV AL,"\"
invoke OUT ;Print the CANCEL indicator
POP SI ;Remember start of edit buffer
PUTNEW:
invoke CRLF ;Go to next line on screen
MOV AL,[STARTPOS]
invoke TAB ;Tab over
JMP NEWLIN ;Start over again
;Back up one char
entry BACKSP
OR DH,DH
JZ OLDBAK ;No chars in line, do nothing to line
CALL BACKUP ;Do the backup
MOV AL,ES:[DI] ;Get the deleted char
CMP AL," "
JAE OLDBAK ;Was a normal char
CMP AL,c_HT
JZ BAKTAB ;Was a tab, fix up users display
CALL BACKMES ;Was a control char, zap the '^'
OLDBAK:
CMP BYTE PTR [INSMODE],0
JNZ GETCH1 ;In insert mode, get more chars
OR BH,BH
JZ GETCH1 ;Not advanced in template, stay where we are
DEC BH ;Go back in template
DEC SI
GETCH1:
JMP GETCH
BAKTAB:
PUSH DI
DEC DI ;Back up one char
STD ;Go backward
MOV CL,DH ;Number of chars currently in line
MOV AL," "
PUSH BX
MOV BL,7 ;Max
JCXZ FIGTAB ;At start, do nothing
FNDPOS:
SCASB ;Look back
JNA CHKCNT
CMP BYTE PTR ES:[DI+1],9
JZ HAVTAB ;Found a tab
DEC BL ;Back one char if non tab control char
CHKCNT:
LOOP FNDPOS
FIGTAB:
SUB BL,[STARTPOS]
HAVTAB:
SUB BL,DH
ADD CL,BL
AND CL,7 ;CX has correct number to erase
CLD ;Back to normal
POP BX
POP DI
JZ OLDBAK ;Nothing to erase
TABBAK:
invoke BACKMES
LOOP TABBAK ;Erase correct number of chars
JMP SHORT OLDBAK
BACKUP:
DEC DH ;Back up in line
DEC DI
BACKMES:
MOV AL,c_BS ;Backspace
invoke OUT
MOV AL," " ;Erase
invoke OUT
MOV AL,c_BS ;Backspace
JMP OUT ;Done
;User really wants an ESC character in his line
entry TwoEsc
MOV AL,[ESCCHAR]
JMP SAVCH
;Copy the rest of the template
entry COPYLIN
MOV CL,BL ;Total size of template
SUB CL,BH ;Minus position in template, is number to move
JMP SHORT COPYEACH
entry CopyStr
invoke FINDOLD ;Find the char
JMP SHORT COPYEACH ;Copy up to it
;Copy one char from template to line
entry COPYONE
MOV CL,1
;Copy CX chars from template to line
COPYEACH:
MOV BYTE PTR [INSMODE],0 ;All copies turn off insert mode
CMP DH,DL
JZ GETCH2 ;At end of line, can't do anything
CMP BH,BL
JZ GETCH2 ;At end of template, can't do anything
LODSB
STOSB
invoke BUFOUT
INC BH ;Ahead in template
INC DH ;Ahead in line
LOOP COPYEACH
GETCH2:
JMP GETCH
;Skip one char in template
entry SKIPONE
CMP BH,BL
JZ GETCH2 ;At end of template
INC BH ;Ahead in template
INC SI
JMP GETCH
entry SKIPSTR
invoke FINDOLD ;Find out how far to go
ADD SI,CX ;Go there
ADD BH,CL
JMP GETCH
;Get the next user char, and look ahead in template for a match
;CX indicates how many chars to skip to get there on output
;NOTE: WARNING: If the operation cannot be done, the return
; address is popped off and a jump to GETCH is taken.
; Make sure nothing extra on stack when this routine
; is called!!! (no PUSHes before calling it).
FINDOLD:
invoke $STD_CON_INPUT_NO_ECHO
CMP AL,[ESCCHAR] ; did he type a function key?
JNZ FindSetup ; no, set up for scan
invoke $STD_CON_INPUT_NO_ECHO ; eat next char
JMP NotFnd ; go try again
FindSetup:
MOV CL,BL
SUB CL,BH ;CX is number of chars to end of template
JZ NOTFND ;At end of template
DEC CX ;Cannot point past end, limit search
JZ NOTFND ;If only one char in template, forget it
PUSH ES
PUSH DS
POP ES
PUSH DI
MOV DI,SI ;Template to ES:DI
INC DI
REPNE SCASB ;Look
POP DI
POP ES
JNZ NOTFND ;Didn't find the char
NOT CL ;Turn how far to go into how far we went
ADD CL,BL ;Add size of template
SUB CL,BH ;Subtract current pos, result distance to skip
return
NOTFND:
POP BP ;Chuck return address
JMP GETCH
entry REEDIT
MOV AL,"@" ;Output re-edit character
invoke OUT
POP DI
PUSH DI
PUSH ES
PUSH DS
invoke COPYNEW ;Copy current line into template
POP DS
POP ES
POP SI
MOV BL,DH ;Size of line is new size template
JMP PUTNEW ;Start over again
entry EXITINS
entry ENTERINS
NOT BYTE PTR [INSMODE]
JMP GETCH
;Put a real live ^Z in the buffer (embedded)
entry CTRLZ
MOV AL,"Z"-"@"
JMP SAVCH
$STD_CON_STRING_INPUT ENDP
|