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
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
| ;-----------------------------------------------------------------------
; This routine prints the marked text. If printer fails, it is cancelled.
;-----------------------------------------------------------------------
PRINT PROC NEAR
CMP MARK_MODE,0 ;is mark mode on?
JE PRINT_RET ;if not, nothing to print
MOV CX,MARK_END ;end of marked region
MOV SI,MARK_START ;start of marked region
SUB CX,SI ;number of bytes selected
JCXZ PRINT_DONE ;if nothing to print, return
DO_FF_CHAR:
XOR DX,DX ;select printer 0
MOV AH,2
INT 17H ;get printer status
TEST AH,10000000B ;is busy bit set?
JZ PRINT_DONE
TEST AH,00100000B ;is printer out of paper?
JNZ PRINT_DONE
PRINT_LOOP:
LODSB
XOR AH,AH
INT 17H ;print the character
ROR AH,1 ;check the time out bit
JC PRINT_DONE ;if set, quit printing
LOOP PRINT_LOOP
MOV AL,CR
;------ [typographical error in article]
;**nop! XOR AH,0 ;[would be No-Operation]
XOR AH,AH
;------
INT 17H ;finish with a CR
PRINT_DONE:
CALL MARK ;turn off the mark status
PRINT_RET:
RET
PRINT ENDP
;=======================================================================
; CHARACTER STRING SEARCH and SEARCH AGAIN services; HELP screen
;=======================================================================
; from TEDPLUS
; This routine is used to search or search again for a character string.
;-----------------------------------------------------------------------
FIND_STR PROC NEAR
PUSH DS
MOV BX,CS
MOV DS,BX
ASSUME DS:CSEG
;---------------------------------------
;** now ShftF6 CMP AH,66H ;Is it shift F9
CMP AH,89 ;Is it shift-F6 (JEG)
;---------------------------------------
JE RPT_FIND
MOV DH,ROWS
INC DH ;Last row on the screen
XOR DL,DL ;First column
MOV SI,OFFSET SRCH_PROMPT
CALL TTY_STRING ;Display search prompt
MOV DX, OFFSET SRCH_MAX
MOV AH,0AH
INT 21H ;Read input string
RPT_FIND:
XOR DX,DX
MOV DL,BYTE PTR SRCH_SIZ
ADD DX,OFFSET SRCH_STR
MOV DI,DX
DEC DI
MOV SRCH_END,DI
XOR DX,DX
MOV SI,CURSOR
INC SI
MOV SRCH_BASE,SI
S_REDO:
MOV DI,OFFSET SRCH_STR
MOV BX,SRCH_BASE
S_CYCLE: MOV AL,[DI]
MOV AH,AL ;CONVERT AL TO OPPOSITE AND PUT IN AH
CMP AL,'A'
JB S_CMP
CMP AL,'Z'
JA TSTLO
XOR AH,20H ;toggle letter case
JMP SHORT S_CMP
TSTLO: CMP AL,'a'
JB S_CMP
CMP AL,'z'
JA S_CMP
XOR AH,20H ;toggle letter case
S_CMP: CMP BX,LAST_CHAR
JA END_MCH
CMP AL,ES:[BX]
JE S_MCH
CMP AH,ES:[BX]
JE S_MCH
CMP DI,OFFSET SRCH_STR
JNE S_REDO
INC BX
CMP WORD PTR ES:[BX-1],CRLF ;test for EOL marker
JNE S_BX1
INC DL
S_BX1: JMP SHORT S_CMP
S_MCH: INC BX
CMP DI,OFFSET SRCH_STR
JNE NO_BSE
MOV SRCH_BASE,BX
NO_BSE: ADD DH,DL
XOR DL,DL
CMP DI,SRCH_END
JE YEA_MCH
INC DI
JMP SHORT S_CYCLE
YEA_MCH:
MOV SRCH_FLG,1
MOV SI,SRCH_BASE
DEC SI
MOV SRCH_BASE,SI
MOV CURSOR,SI
XOR BX,BX
MOV BL,BYTE PTR SRCH_SIZ
ADD BX,SI
MOV SRCH_END,BX
XOR DL,DL
ADD DX,CURS_POSN
CMP DH,ROWS
JBE NEW_S
XOR DX,DX
NEW_S:
POP DS ;ASSUME is no longer valid
CALL LOCATE
JMP SHORT END_MCH2
END_MCH:
POP DS
END_MCH2:
CALL REDO_PROMPT ;redraw the prompt and the screen
RET
FIND_STR ENDP
;=======================================================================
; This routine displays a user help screen
;-----------------------------------------------------------------------
HELP PROC NEAR
PUSH DS
PUSH CS
POP DS
ASSUME DS:CSEG ;for func-9, display message
CALL CLR_SCREEN
MOV DX,OFFSET HELP_SCREEN ;message is at DS:DX in CSEG
MOV AH,9 ;display message
INT 21H
HELP_WAIT_KEY:
MOV AH,1 ;wait for any key pressed
INT 16H
JZ HELP_WAIT_KEY
MOV AH,0
INT 16H
POP DS
ASSUME DS:NOTHING
JMP REDO_PROMPT ;redraw the prompt and the screen
;(CALL/RETurn)
HELP ENDP
;=======================================================================
; This routine prompts for a filename then writes the file. The original
; file is renamed to filename.BAK. If an invalid filename is entered, the
; speaker is beeped. If the file has not been altered, the edit file is
; abandoned and control is immediately returned to DOS.
;-----------------------------------------------------------------------
EXIT PROC NEAR
PUSH DS ;save in case ESC key
PUSH ES
MOV AX,CS
MOV DS,AX
MOV ES,AX
ASSUME DS:CSEG, ES:CSEG
TEST BYTE PTR DIRTY_FILE,0FFH ;is the file altered?
JNZ NEXT_LETTER ;(jump was out of range)
JMP FINISHED ;file has not been altered, no save.
;-----------------------
IS_BACKSPACE:
CMP DI,NAME_POINTER ;at first letter?
JLE NEXT_LETTER ;if yes, don't erase it
MOV BYTE PTR [DI-1],0
DEC NAME_END
NEXT_LETTER:
MOV DH,ROWS
INC DH ;last row on the screen
XOR DL,DL ;first column
MOV SI,OFFSET SAVE_MESS
PUSH DX
CALL TTY_STRING ;display a prompt
POP DX
ADD DL,9 ;move right 9 spaces
MOV SI,NAME_POINTER
CALL TTY_STRING ;display the filename
XOR AH,AH ;read the next key
INT 16H
MOV DI,NAME_END ;this points to the last letter
OR AL,AL ;is it a real character?
; JZ NEXT_LETTER ;ignore special keys
JZ IS_ESCAPE ;special keys return to edit mode
CMP AL,1BH ;is it ESCape?
JE IS_ESCAPE ;continue with exit procedure
CMP AL,CR ;is it CR?
JE GOT_NAME
CMP AL,08H ;is it a backspace?
JE IS_BACKSPACE
CMP DI,81H + 65 ;too many letters?
JG NEXT_LETTER ;if yes, ignore them
XOR AH,AH ;for new terminal 0 to string
STOSW ;store the new letter and 0
INC NAME_END ;name is one character longer
JMP NEXT_LETTER ;read another keystroke
;-----------------------
IS_ESCAPE:
POP ES ;get back file segment
POP DS
JMP REDO_PROMPT ;redraw the prompt and the screen
;(CALL/RETurn) ;return to edit mode
;-----------------------
GOT_NAME:
MOV DX,NAME_POINTER ;point to the filename
MOV AX,4300H ;get the file attribute
INT 21H ;DOS call
JNC NAME_OK ;if no error, filename is OK
CMP AX,3 ;was it "path not found" error?
JE BAD_NAME ;if yes, filename was bad
NAME_OK:
MOV SI,OFFSET DOT_$$$ ;point to the ".$$$"
MOV DI,OFFSET NAME_DOT_$$$
CALL CHG_EXTENSION ;add the new extension
MOV DX,OFFSET NAME_DOT_$$$ ;point to temp filename
MOV CX,0020H ;attribute for new file
MOV AH,3CH ;function to create file
INT 21H ;DOS call
JNC NAME_WAS_OK ;continue if name was OK
BAD_NAME:
MOV AX,0E07H ;write a bell character
INT 10H ;BIOS TTY service
JMP NEXT_LETTER ;get another letter
;-----------------------
WRITE_ERROR:
MOV AH,3EH ;close the file
INT 21H ;DOS call
JMP BAD_NAME ;filename must be bad
;-----------------------
NAME_WAS_OK:
XOR DX,DX ;this is the file buffer
MOV CX,LAST_CHAR ;number of chars in file
MOV BX,AX ;this is the handle
MOV AH,40H ;write to the file
POP DS ;recover the buffer segment
INT 21H ;write the buffer contents
POP DS
JC WRITE_ERROR ;exit on a write error
CMP AX,CX ;was entire file written?
JNE WRITE_ERROR ;if not, exit
PUSH CS
POP DS ;get the code segment
MOV AH,3EH ;close the temp file
INT 21H ;DOS call
MOV SI,OFFSET DOT_BAK ;point to the ".BAK"
MOV DI,OFFSET NAME_DOT_BAK
CALL CHG_EXTENSION ;make the backup filename
MOV DX,OFFSET NAME_DOT_BAK ;point to the backup name
MOV AH,41H ;delete existing backup file
INT 21H ;DOS call
MOV DI,OFFSET NAME_DOT_BAK
MOV DX,NAME_POINTER
MOV AH,56H
INT 21H ;DOS call
MOV DI,NAME_POINTER ;point to new filename
MOV DX,OFFSET NAME_DOT_$$$ ;point to temporary file
MOV AH,56H ;rename temp to new file
INT 21H ;DOS call, rename
POP AX ;restore the stack
POP AX
JMP SHORT FINISHED
;(To return to DOS)
EXIT ENDP
;-----------------------------------------------------------------------
; This routine prompts for a verify keystroke then exits without saving
; the file. If the file has not been altered, the edit file is abandoned
; and control is immediately returned to DOS.
;-----------------------------------------------------------------------
ABORT PROC NEAR
PUSH CS
POP DS
ASSUME DS:CSEG
TEST BYTE PTR DIRTY_FILE,0FFH ;is the file altered?
JZ FINISHED ;file has not been altered.
MOV DH,ROWS ;last row on display
INC DH ;bottom row on screen
XOR DL,DL ;first column
MOV SI,OFFSET VERIFY_MESS
CALL TTY_STRING ;display verify message
XOR AH,AH ;read the next key
INT 16H ;BIOS read key routine
CMP AL,CR ;is it CR?
JE FINISHED
OR AL,20H ;convert to lower case
CMP AL,"y" ;was answer Yes?
JE FINISHED ;if yes, then we're finished
CALL REDO_PROMPT ;redraw the prompt and the screen
PUSH ES
POP DS ;set DS back to file segment
RET ;return to edit mode
;-----------------------
FINISHED:
MOV DX,OFFSET COPYRIGHT
;-----------------------
EXIT_TO_DOS: ;External entry point (DX, message)
PUSH CS
POP DS ;point to code segment
ASSUME DS:CSEG
CALL CLR_SCREEN ;clear the screen (passes DX through)
MOV AH,9 ;display error/exit message DS:DX
INT 21H ;DOS call
MOV AX,EXIT_CODE ;Exit to DOS with exit code
INT 21H ;DOS call
ABORT ENDP
;=======================================================================
; This routine copies the input filename to CS:DI and changes the extension.
;-----------------------------------------------------------------------
CHG_EXTENSION PROC NEAR
ASSUME DS:CSEG, ES:CSEG
PUSH SI
MOV SI,NAME_POINTER
CHG_LOOP:
LODSB
CMP AL,"." ;look for the extension
JE FOUND_DOT
OR AL,AL
JZ FOUND_DOT
STOSB ;copy a character
JMP CHG_LOOP
;-----------------------
FOUND_DOT:
MOV CX,5 ;five characters in extension
POP SI
REP MOVSB ;move new extension in
RET
CHG_EXTENSION ENDP
;=======================================================================
; This routine displays the string at CS:SI at the location in DX. The
; remainder of the row is erased. Cursor is put at the end of the line.
;-----------------------------------------------------------------------
TTY_STRING PROC NEAR
ASSUME DS:CSEG
PUSH DX
CALL POSITION ;compute offset into video
POP DX
TTY_LOOP:
LODSB ;load DS:SI to AL
OR AL,AL ;at end of string yet?
JZ TTY_DONE
INC DL
PUSH DX
CALL WRITE_INVERSE ;write in inverse video
POP DX
JMP TTY_LOOP
;-----------------------
TTY_DONE:
CALL SET_CURSOR ;move cursor to end of string
JMP ERASE_EOL ;erase the rest of the line
;(CALL/RETurn)
TTY_STRING ENDP
;=======================================================================
; This routine clears the screen, leaves registers unaltered.
;-----------------------------------------------------------------------
CLR_SCREEN PROC NEAR
ASSUME DS:NOTHING
PUSH AX ;save registers (for INT-24)
PUSH BX
PUSH CX
PUSH DX ;save DX for message address
MOV DL,79 ;DL = right column
MOV DH,CS:ROWS ;DH = lower row
INC DH ;to clear the last line on the screen
MOV CX,0 ;CH = upper row, CL = left column
MOV BH,CS:NORMAL ;BH is blank line attribute, 07 = normal video
MOV AX,0600H ;scroll the cursor up (blank line)
INT 10H
XOR DX,DX ;set cursor to top left of screen
CALL SET_CURSOR
POP DX
POP CX
POP BX
POP AX
RET
CLR_SCREEN ENDP
;=======================================================================
; This is the control break handler for MS-DOS. It ignores the break.
; TED then responds by entering a <Ctrl-C> in the file.
;-----------------------------------------------------------------------
NEWINT23 PROC FAR
ASSUME DS:NOTHING, ES:NOTHING
MOV CS:DIRTY_BITS,1 ;to redraw the screen
CLC ;tell DOS to ignore break
IRET
NEWINT23 ENDP
;=======================================================================
; This is the severe error handler. It homes the cursor before
; processing the error.
;-----------------------------------------------------------------------
NEWINT24 PROC FAR
ASSUME DS:NOTHING, ES:NOTHING
PUSHF
CALL CLR_SCREEN ;clear the screen and home the cursor
POPF
JMP CS:OLDINT24
;(chain to old INT 24 handler)
NEWINT24 ENDP
;=======================================================================
; This is the location of the character string search buffer. It occupies
; the last three bytes in the program file. The following 64-bytes are used
; for the buffer area. The third byte is also used as the program code
; check-sum compensation byte.
;-----------------------------------------------------------------------
EVEN
SRCH_MAX DB 66 ;42H, maximum size of buffer
SRCH_SIZ DB 0 ;number of char's actually in buffer
SRCH_STR DB 0 ;start of buffer block
;This is the correction byte for the check-sum test
CHEK_SUM_BYT DB 0103
;=======================================================================
NAME_DOT_$$$ EQU $ +64 ;128 bytes
NAME_DOT_BAK EQU $+80H +64 ;128 bytes
UNDO_BUFFER EQU $+100H +64 ;256 bytes, Del key buffer
LINE_BUFFER EQU $+200H +64 ;256 bytes, Delete line, EOL
END_BUFFER EQU $+300H +64 +15 ;end of buffers, file segment follows
; +15 is for paragraph rounding
CSEG ENDS
;-----------------------------------------------------------------------
FILE_SEG SEGMENT
FILE_SEG ENDS
END START |