summaryrefslogtreecommitdiff
path: root/v2.0/source/EDLIN.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v2.0/source/EDLIN.ASM')
-rw-r--r--v2.0/source/EDLIN.ASM1846
1 files changed, 1846 insertions, 0 deletions
diff --git a/v2.0/source/EDLIN.ASM b/v2.0/source/EDLIN.ASM
new file mode 100644
index 0000000..f795ac4
--- /dev/null
+++ b/v2.0/source/EDLIN.ASM
@@ -0,0 +1,1846 @@
1 title EDLIN for MSDOS 2.0
2
3;-----------------------------------------------------------------------;
4; REVISION HISTORY: ;
5; ;
6; V1.02 ;
7; ;
8; V2.00 9/13/82 M.A. Ulloa ;
9; Modified to use Pathnames in command line file ;
10; specification, modified REPLACE to use an empty ;
11; string intead of the old replace string when this ;
12; is missing, and search and replace now start from ;
13; first line of buffer (like old version of EDLIN) ;
14; instead than current+1 line. Also added the U and ;
15; V commands that search (replace) starting from the ;
16; current+1 line. ;
17; ;
18; 9/15/82 M.A. Ulloa ;
19; Added the quote character (^V). ;
20; ;
21; 9/16/82 M.A. Ulloa ;
22; Corrected bug about use of quote char when going ;
23; into default insert mode. Also corrected the problem ;
24; with ^Z being the end of file marker. End of file is ;
25; reached when an attempt to read returns less chars ;
26; than requested. ;
27; ;
28; 9/17/82 M.A. Ulloa ;
29; Corrected bug about boundaries for Copy ;
30; ;
31; 10/4/82 Rev. 1 M.A. Ulloa ;
32; The IBM version now does NOT have the U and V ;
33; commands. The MSDOS version HAS the U and V commands. ;
34; Added the B switch, and modified the effect of ;
35; the quote char. ;
36; ;
37; 10/7/82 Rev. 2 M.A. Ulloa ;
38; Changed the S and R commands to start from the ;
39; current line+1 (as U and V did). Took away U and V in ;
40; all versions. ;
41; ;
42; 10/13/82 Rev. 3 M.A. Ulloa ;
43; Now if parameter1 < 1 then parameter1 = 1 ;
44; ;
45; 10/15/82 Rev. 4 M.A. Ulloa ;
46; Param4 if specified must be an absolute number that ;
47; reprecents the count. ;
48; ;
49; 10/18/82 Rev. 5 M.A. Ulloa ;
50; Fixed problem with trying to edit files with the ;
51; same name as directories. Also, if the end of file is ;
52; reached it checks that a LF is the last character, ;
53; otherwise it inserts a CRLF pair at the end. ;
54; ;
55; 10/20/82 Rev. 6 M.A.Ulloa ;
56; Changed the text of some error messages for IBM and ;
57; rewrite PAGE. ;
58; ;
59; 10/25/82 Rev. 7 M.A.Ulloa ;
60; Made all messages as in the IBM vers. ;
61; ;
62; 10/28/82 Rev. 8 M.A.Ulloa ;
63; Corrected problem with parsing for options. ;
64; ;
65; Rev. 9 Aaron Reynolds ;
66; Made error messages external. ;
67; ;
68; 12/08/82 Rev. 10 M.A. Ulloa ;
69; Corrected problem arising with having to restore ;
70; the old directory in case of a file name error. ;
71; ;
72; 12/17/82 Rev. 11 M.A. Ulloa ;
73; Added the ROPROT equate for R/O file protection. ;
74; It causes only certain operations (L,P,S,W,A, and Q) ;
75; to be allowed on read only files. ;
76; ;
77; 12/29/82 Rev. 12 M.A. Ulloa :
78; Added the creation error message. ;
79; ;
80; 4/14/83 Rev. 13 N.Panners ;
81; Fixed bug in Merge which lost char if not ^Z. ;
82; Fixed bug in Copy to correctly check ;
83; for full buffers. ;
84; ;
85; ;
86; 7/23/83 Rev. 14 N.Panners ;
87; Split EDLIN into two seperate modules to ;
88; allow assembly of sources on an IBM PC ;
89; EDLIN and EDLPROC ;
90; ;
91;-----------------------------------------------------------------------;
92
93
94FALSE EQU 0
95TRUE EQU NOT FALSE
96
97KANJI EQU FALSE
98
99roprot equ true ;set to TRUE if protection to r/o files
100 ; desired.
101FCB EQU 5CH
102
103Comand_Line_Length equ 128
104quote_char equ 16h ;quote character = ^V
105
106
107PAGE
108
109 .xlist
110 INCLUDE DOSSYM.ASM
111 .list
112
113
114SUBTTL Contants and Data areas
115PAGE
116
117PROMPT EQU "*"
118STKSIZ EQU 80H
119
120CODE SEGMENT PUBLIC
121CODE ENDS
122
123CONST SEGMENT PUBLIC WORD
124CONST ENDS
125
126DATA SEGMENT PUBLIC WORD
127DATA ENDS
128
129DG GROUP CODE,CONST,DATA
130
131CONST SEGMENT PUBLIC WORD
132
133 EXTRN BADDRV:BYTE,NDNAME:BYTE,bad_vers_err:BYTE,opt_err:BYTE
134 EXTRN NOBAK:BYTE,BADCOM:BYTE,NEWFIL:BYTE,DEST:BYTE,MRGERR:BYTE
135 EXTRN NODIR:BYTE,DSKFUL:BYTE,MEMFUL:BYTE,FILENM:BYTE
136 EXTRN NOSUCH:BYTE,TOOLNG:BYTE,EOF:BYTE,ro_err:byte,bcreat:byte
137
138 PUBLIC TXT1,TXT2,FUDGE,USERDIR,HARDCH
139
140BAK DB "BAK"
141
142make db "***MAUlloa/Microsoft/V20***"
143rev db "14"
144
145 if roprot ;***** R/O *****
146roflag db 0 ; =1 if file is r/o
147 endif
148
149fourth db 0 ;fourth parameter flag
150
151loadmod db 0 ;Load mode flag, 0 = ^Z marks the
152 ; end of a file, 1 = viceversa.
153hardch dd ?
154
155the_root db 0 ;root directory flag
156
157fudge db 0 ;directory changed flag
158user_drive db 0
159
160
161optchar db "-"
162
163dirchar db "/",0
164
165userdir db "/",0
166 db (dirstrlen) dup(0)
167
168fname_buffer db Comand_Line_Length dup(0)
169;-----------------------------------------------------------------------;
170
171TXT1 DB 0,80H DUP (?)
172TXT2 DB 0,80H DUP (?)
173DELFLG DB 0
174
175CONST ENDS
176
177DATA SEGMENT PUBLIC WORD
178
179 PUBLIC QFLG,FCB2,OLDLEN,PARAM1,PARAM2,OLDDAT,SRCHFLG
180 PUBLIC COMLINE,NEWLEN,SRCHMOD,CURRENT,LSTFND,NUMPOS
181 PUBLIC LSTNUM,SRCHCNT,POINTER,START,ENDTXT,USER_DRIVE
182
183;-----------------------------------------------------------------------;
184; Be carefull when adding parameters, they have to follow the
185; order in which they apperar here. (this is a table, ergo it
186; is indexed thru a pointer, and random additions will cause the
187; wrong item to be accessed). Also param4 is known to be the
188; count parameter, and known to be the fourth entry in the table
189; so it receives special treatment. (See GETNUM)
190
191PARAM1 DW 1 DUP (?)
192PARAM2 DW 1 DUP (?)
193PARAM3 DW 1 DUP (?)
194PARAM4 DW 1 DUP (?)
195
196;-----------------------------------------------------------------------;
197
198PTR_1 DW 1 DUP (?)
199PTR_2 DW 1 DUP (?)
200PTR_3 DW 1 DUP (?)
201COPYSIZ DW 1 DUP (?)
202OLDLEN DW 1 DUP (?)
203NEWLEN DW 1 DUP (?)
204LSTFND DW 1 DUP (?)
205LSTNUM DW 1 DUP (?)
206NUMPOS DW 1 DUP (?)
207SRCHCNT DW 1 DUP (?)
208CURRENT DW 1 DUP (?)
209POINTER DW 1 DUP (?)
210ONE4TH DW 1 DUP (?)
211THREE4TH DW 1 DUP (?)
212LAST DW 1 DUP (?)
213ENDTXT DW 1 DUP (?)
214COMLINE DW 1 DUP (?)
215LASTLIN DW 1 DUP (?)
216COMBUF DB 82H DUP (?)
217EDITBUF DB 258 DUP (?)
218EOL DB 1 DUP (?)
219FCB2 DB 37 DUP (?)
220FCB3 DB 37 DUP (?)
221fake_fcb db 37 dup (?) ;fake for size figuring
222QFLG DB 1 DUP (?)
223HAVEOF DB 1 DUP (?)
224ENDING DB 1 DUP (?)
225SRCHFLG DB 1 DUP (?)
226amnt_req dw 1 dup (?) ;ammount of bytes requested to read
227olddat db 1 dup (?) ;Used in replace and search,
228 ; replace by old data flag (1=yes)
229srchmod db 1 dup (?) ;Search mode: 1=from current+1 to
230 ; end of buffer, 0=from beg. of
231 ; buffer to the end (old way).
232MOVFLG DB 1 DUP (?)
233 DB STKSIZ DUP (?)
234
235STACK LABEL BYTE
236START LABEL WORD
237
238DATA ENDS
239
240SUBTTL Main Body
241PAGE
242
243CODE SEGMENT PUBLIC
244
245ASSUME CS:DG,DS:DG,SS:DG,ES:DG
246
247 EXTRN QUIT:NEAR,QUERY:NEAR,FNDFIRST:NEAR,FNDNEXT:NEAR
248 EXTRN UNQUOTE:NEAR,LF:NEAR,CRLF:NEAR,OUT:NEAR
249 EXTRN REST_DIR:NEAR,KILL_BL:NEAR,INT_24:NEAR
250 EXTRN FINDLIN:NEAR,SHOWNUM:NEAR,SCANLN:NEAR
251
252 if Kanji
253 EXTRN TESTKANJ:NEAR
254 endif
255
256 PUBLIC CHKRANGE
257
258 ORG 100H
259
260EDLIN:
261 JMP SIMPED
262
263edl_pad db 0e00h dup (?)
264
265HEADER DB "Vers 2.14"
266
267NONAME:
268 MOV DX,OFFSET DG:NDNAME
269ERRJ: JMP xERROR
270
271SIMPED:
272 MOV BYTE PTR [ENDING],0
273 MOV SP,OFFSET DG:STACK
274
275;Code to print header
276; PUSH AX
277; MOV DX,OFFSET DG:HEADER
278; MOV AH,STD_CON_STRING_OUTPUT
279; INT 21H
280; POP AX
281
282;----- Check Version Number --------------------------------------------;
283 push ax
284 mov ah,Get_Version
285 int 21h
286 cmp al,2
287 jae vers_ok ; version >= 2, enter editor
288 mov dx,offset dg:bad_vers_err
289 jmp short errj
290;-----------------------------------------------------------------------;
291
292vers_ok:
293
294;----- Process Pathnames -----------------------------------------------;
295
296 mov ax,(char_oper shl 8) ;get switch character
297 int 21h
298 cmp dl,"/"
299 jnz slashok ;if not / , then not PC
300 mov [dirchar],"\" ;in PC, dir separator = \
301 mov [userdir],"\"
302 mov [optchar],"/" ;in PC, option char = /
303
304slashok:
305 mov si,81h ;point to cammand line
306
307 call kill_bl
308 cmp al,13 ;A carriage return?
309 je noname ;yes, file name missing
310
311 mov di,offset dg:fname_buffer
312 xor cx,cx ;zero pathname length
313
314next_char:
315 stosb ;put patname in buffer
316 inc cx
317 lodsb
318 cmp al,' '
319 je xx1
320 cmp al,13 ; a CR ?
321 je name_copied
322 cmp al,[optchar] ; an option character?
323 je an_option
324 jmp short next_char
325
326xx1:
327 dec si
328 call kill_bl
329 cmp al,[optchar]
330 jne name_copied
331
332an_option:
333 lodsb ;get the option
334 cmp al,'B'
335 je b_opt
336 cmp al,'b'
337 je b_opt
338 mov dx,offset dg:opt_err ;bad option specified
339 jmp xerror
340
341b_opt:
342 mov [loadmod],1
343
344name_copied:
345 mov byte ptr dg:[di],0 ;nul terminate the pathname
346
347 if roprot ;***** R/O *****
348;----- Check that file is not R/O --------------------------------------;
349 push cx ;save character count
350 mov dx,offset dg:fname_buffer
351 mov al,0 ;get attributes
352 mov ah,chmod
353 int 21h
354 jc attr_are_ok
355 and cl,00000001b ;mask all but: r/o
356 jz attr_are_ok ;if all = 0 then file ok to edit,
357 mov dg:[roflag],01h ;otherwise: Error (GONG!!!)
358attr_are_ok:
359 pop cx ;restore character count
360 endif
361
362;----- Scan for directory ----------------------------------------------;
363 dec di ;adjust to the end of the pathname
364
365 IF KANJI
366 mov dx,offset dg: fname_buffer
367 PUSH DX
368 PUSH DI
369 MOV BX,DI
370 MOV DI,DX
371DELLOOP:
372 CMP DI,BX
373 Jae GOTDELE
374 MOV AL,[DI]
375 INC DI
376 CALL TESTKANJ
377 JZ NOTKANJ11
378 INC DI
379 JMP DELLOOP
380
381NOTKANJ11:
382 cmp al,dg:[dirchar]
383 JNZ DELLOOP
384 MOV DX,DI ;Point to char after '/'
385 DEC DX
386 DEC DX ;Point to char before '/'
387 JMP DELLOOP
388
389GOTDELE:
390 MOV DI,DX
391 POP AX ;Initial DI
392 POP DX
393 SUB AX,DI ;Distance moved
394 SUB CX,AX ;Set correct CX
395 CMP DX,DI
396 JB sj1 ;Found a pathsep
397 JA sj2 ;Started with a pathsep, root
398 MOV AX,[DI]
399 CALL TESTKANJ
400 JNZ same_dirj
401 XCHG AH,AL
402 cmp al,dg:[dirchar]
403 jz sj1 ;One character directory
404same_dirj:
405 ELSE
406 mov al,dg:[dirchar] ;get directory separator character
407 std ;scan backwards
408 repnz scasb ;(cx has the pathname length)
409 cld ;reset direction, just in case
410 jz sj1
411 ENDIF
412
413 jmp same_dir ;no dir separator char. found, the
414 ; file is in the current directory
415 ; of the corresponding drive. Ergo,
416 ; the FCB contains the data already.
417
418sj1:
419 jcxz sj2 ;no more chars left, it refers to root
420 cmp byte ptr [di],':' ;is the prvious character a disk def?
421 jne not_root
422sj2:
423 mov dg:[the_root],01h ;file is in the root
424not_root:
425 inc di ;point to dir separator char.
426 mov al,0
427 stosb ;nul terminate directory name
428 pop ax
429 push di ;save pointer to file name
430 mov dg:[fudge],01h ;remember that the current directory
431 ; has been changed.
432
433;----- Save current directory for exit ---------------------------------;
434 mov ah,get_default_drive ;save current drive
435 int 21h
436 mov dg:[user_drive],al
437
438 mov dl,byte ptr ds:[fcb] ;get specified drive if any
439 or dl,dl ;default disk?
440 jz same_drive
441 dec dl ;adjust to real drive (a=0,b=1,...)
442 mov ah,set_default_drive ;change disks
443 int 21h
444 cmp al,-1 ;error?
445 jne same_drive
446 mov dx,offset dg:baddrv
447 jmp xerror
448
449same_drive:
450 mov ah,get_default_dpb
451 int 21h
452
453assume ds:nothing
454
455 cmp al,-1 ;bad drive? (should always be ok)
456 jne drvisok
457 mov dx,offset dg:baddrv
458 jmp xerror
459
460drvisok:
461 cmp [bx.dpb_current_dir],0
462 je curr_is_root
463 mov si,bx
464 add si,dpb_dir_text
465 mov di,offset dg:userdir + 1
466
467dir_save_loop:
468 lodsb
469 stosb
470 or al,al
471 jnz dir_save_loop
472
473curr_is_root:
474 push cs
475 pop ds
476
477assume ds:dg
478
479
480;----- Change directories ----------------------------------------------;
481 cmp [the_root],01h
482 mov dx,offset dg:[dirchar] ;assume the root
483 je sj3
484 mov dx,offset dg:[fname_buffer]
485sj3:
486 mov ah,chdir ;change directory
487 int 21h
488 mov dx,offset dg:baddrv
489 jnc no_errors
490 jmp xerror
491no_errors:
492
493;----- Set Up int 24 intercept -----------------------------------------;
494
495 mov ax,(get_interrupt_vector shl 8) or 24h
496 int 21h
497 mov word ptr [hardch],bx
498 mov word ptr [hardch+2],es
499 mov ax,(set_interrupt_vector shl 8) or 24h
500 mov dx,offset dg:int_24
501 int 21h
502 push cs
503 pop es
504
505;----- Parse filename to FCB -------------------------------------------;
506 pop si
507 mov di,fcb
508 mov ax,(parse_file_descriptor shl 8) or 1
509 int 21h
510 push ax
511
512;-----------------------------------------------------------------------;
513
514same_dir:
515 pop ax
516 OR AL,AL
517 MOV DX,OFFSET DG:BADDRV
518 jz sj4
519 jmp xerror
520sj4:
521 CMP BYTE PTR DS:[FCB+1]," "
522 jnz sj5
523 jmp noname
524sj5:
525 MOV SI,OFFSET DG:BAK
526 MOV DI,FCB+9
527 MOV CX,3
528 ;File must not have .BAK extension
529 REPE CMPSB
530 JZ NOTBAK
531 ;Open input file
532 MOV AH,FCB_OPEN
533 MOV DX,FCB
534 INT 21H
535 MOV [HAVEOF],AL
536 OR AL,AL
537 JZ HAVFIL
538
539;----- Check that file is not a directory ------------
540 mov ah,fcb_create
541 mov dx,fcb
542 int 21h
543 or al,al
544 jz sj50 ;no error found
545 mov dx,offset dg:bcreat ;creation error
546 jmp xerror
547sj50:
548 mov ah,fcb_close ;no error, close the file
549 mov dx,fcb
550 int 21h
551 mov ah,fcb_delete ;delete the file
552 mov dx,fcb
553 int 21h
554
555;-----------------------------------------------------
556
557 MOV DX,OFFSET DG:NEWFIL
558 MOV AH,STD_CON_STRING_OUTPUT
559 INT 21H
560HAVFIL:
561 MOV SI,FCB
562 MOV DI,OFFSET DG:FCB2
563 MOV CX,9
564 REP MOVSB
565 MOV AL,"$"
566 STOSB
567 STOSB
568 STOSB
569MAKFIL:
570 ;Create .$$$ file to make sure directory has room
571 MOV DX,OFFSET DG:FCB2
572 MOV AH,FCB_CREATE
573 INT 21H
574 OR AL,AL
575 JZ SETUP
576 CMP BYTE PTR [DELFLG],0
577 JNZ NOROOM
578 CALL DELBAK
579 JMP MAKFIL
580NOROOM:
581 MOV DX,OFFSET DG:NODIR
582 JMP xERROR
583NOTBAK:
584 MOV DX,OFFSET DG:NOBAK
585 JMP xERROR
586SETUP:
587 XOR AX,AX
588 MOV WORD PTR DS:[FCB+fcb_RR],AX ;Set RR field to zero
589 MOV WORD PTR DS:[FCB+fcb_RR+2],AX
590 MOV WORD PTR [FCB2+fcb_RR],AX
591 MOV WORD PTR [FCB2+fcb_RR+2],AX
592 INC AX
593 MOV WORD PTR DS:[FCB+fcb_RECSIZ],AX ;Set record length to 1
594 MOV WORD PTR [FCB2+fcb_RECSIZ],AX
595 MOV DX,OFFSET DG:START
596 MOV DI,DX
597 MOV AH,SET_DMA
598 INT 21H
599 MOV CX,DS:[6]
600 DEC CX
601 MOV [LAST],CX
602 TEST BYTE PTR [HAVEOF],-1
603 JNZ SAVEND
604 SUB CX,OFFSET DG:START ;Available memory
605 SHR CX,1 ;1/2 of available memory
606 MOV AX,CX
607 SHR CX,1 ;1/4 of available memory
608 MOV [ONE4TH],CX ;Save amount of 1/4 full
609 ADD CX,AX ;3/4 of available memory
610 MOV DX,CX
611 ADD DX,OFFSET DG:START
612 MOV [THREE4TH],DX ;Save pointer to 3/4 full
613 ;Read in input file
614 MOV DX,FCB
615 MOV AH,FCB_RANDOM_READ_BLOCK
616 mov [amnt_req],cx ;save ammount of chars requested
617 INT 21H
618 CALL SCANEOF
619 ADD DI,CX ;Point to last byte
620SAVEND:
621 CLD
622 MOV BYTE PTR [DI],1AH
623 MOV [ENDTXT],DI
624 MOV BYTE PTR [COMBUF],128
625 MOV BYTE PTR [EDITBUF],255
626 MOV BYTE PTR [EOL],10
627 MOV [POINTER],OFFSET DG:START
628 MOV [CURRENT],1
629 MOV [PARAM1],1
630 TEST BYTE PTR [HAVEOF],-1
631 JNZ COMMAND
632 CALL APPEND
633
634COMMAND:
635 MOV SP, OFFSET DG:STACK
636 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H
637 MOV DX,OFFSET DG:ABORTCOM
638 INT 21H
639 MOV AL,PROMPT
640 CALL OUT
641 MOV DX,OFFSET DG:COMBUF
642 MOV AH,STD_CON_STRING_INPUT
643 INT 21H
644 MOV [COMLINE],OFFSET DG:COMBUF + 2
645 MOV AL,10
646 CALL OUT
647PARSE:
648 MOV [PARAM2],0
649 MOV [PARAM3],0
650 MOV [PARAM4],0
651 mov [fourth],0 ;reset the fourth parameter flag
652 MOV BYTE PTR [QFLG],0
653 MOV SI,[COMLINE]
654 MOV BP,OFFSET DG:PARAM1
655 XOR DI,DI
656CHKLP:
657 CALL GETNUM
658 MOV [BP+DI],DX
659 INC DI
660 INC DI
661 CALL SKIP1
662 CMP AL,","
663 JNZ CHKNXT
664 INC SI
665CHKNXT:
666 DEC SI
667 CMP DI,8
668 JB CHKLP
669 CALL SKIP
670 CMP AL,"?"
671 JNZ DISPATCH
672 MOV [QFLG],AL
673 CALL SKIP
674DISPATCH:
675 CMP AL,5FH
676 JBE UPCASE
677 AND AL,5FH
678UPCASE:
679 MOV DI,OFFSET DG:COMTAB
680 MOV CX,NUMCOM
681 REPNE SCASB
682 JNZ COMERR
683 MOV BX,CX
684 MOV AX,[PARAM2]
685 OR AX,AX
686 JZ PARMOK
687 CMP AX,[PARAM1]
688 JB COMERR ;Param. 2 must be >= param 1
689PARMOK:
690 MOV [COMLINE],SI
691
692 if roprot ;***** R/O *****
693 cmp [roflag],01 ;file r/o?
694 jne paramok2
695 cmp byte ptr [bx+rotable],01 ;operation allowed?
696 je paramok2
697 mov dx,offset dg:ro_err ;error
698 jmp short comerr1
699paramok2:
700 endif
701
702 SHL BX,1
703 CALL [BX+TABLE]
704COMOVER:
705 MOV SI,[COMLINE]
706 CALL SKIP
707 CMP AL,0DH
708 JZ COMMANDJ
709 CMP AL,1AH
710 JZ DELIM
711 CMP AL,";"
712 JNZ NODELIM
713DELIM:
714 INC SI
715NODELIM:
716 DEC SI
717 MOV [COMLINE],SI
718 JMP PARSE
719
720COMMANDJ:
721 JMP COMMAND
722
723SKIP:
724 LODSB
725SKIP1:
726 CMP AL," "
727 JZ SKIP
728RET1: RET
729
730CHKRANGE:
731 CMP [PARAM2],0
732 JZ RET1
733 CMP BX,[PARAM2]
734 JBE RET1
735COMERR:
736 MOV DX,OFFSET DG:BADCOM
737COMERR1:
738 MOV AH,STD_CON_STRING_OUTPUT
739 INT 21H
740 JMP COMMAND
741
742
743GETNUM:
744 CALL SKIP
745 cmp di,6 ;Is this the fourth parameter?
746 jne sk1
747 mov [fourth],1 ;yes, set the flag
748sk1:
749 CMP AL,"."
750 JZ CURLIN
751 CMP AL,"#"
752 JZ MAXLIN
753 CMP AL,"+"
754 JZ FORLIN
755 CMP AL,"-"
756 JZ BACKLIN
757 MOV DX,0
758 MOV CL,0 ;Flag no parameter seen yet
759NUMLP:
760 CMP AL,"0"
761 JB NUMCHK
762 CMP AL,"9"
763 JA NUMCHK
764 CMP DX,6553 ;Max line/10
765 JAE COMERR ;Ten times this is too big
766 MOV CL,1 ;Parameter digit has been found
767 SUB AL,"0"
768 MOV BX,DX
769 SHL DX,1
770 SHL DX,1
771 ADD DX,BX
772 SHL DX,1
773 CBW
774 ADD DX,AX
775 LODSB
776 JMP SHORT NUMLP
777NUMCHK:
778 CMP CL,0
779 JZ RET1
780 OR DX,DX
781 JZ COMERR ;Don't allow zero as a parameter
782 RET
783
784CURLIN:
785 cmp [fourth],1 ;the fourth parameter?
786 je comerra ;yes, an error
787 MOV DX,[CURRENT]
788 LODSB
789 RET
790MAXLIN:
791 cmp [fourth],1 ;the fourth parameter?
792 je comerra ;yes, an error
793 MOV DX,-2
794 LODSB
795 RET
796FORLIN:
797 cmp [fourth],1 ;the fourth parameter?
798 je comerra ;yes, an error
799 CALL GETNUM
800 ADD DX,[CURRENT]
801 RET
802BACKLIN:
803 cmp [fourth],1 ;the fourth parameter?
804 je comerra ;yes, an error
805 CALL GETNUM
806 MOV BX,[CURRENT]
807 SUB BX,DX
808 jns sk2 ;if below beg of buffer then default to the
809 mov bx,1 ; beg of buffer (line1)
810sk2:
811 MOV DX,BX
812 RET
813
814comerra:
815 jmp comerr
816
817
818COMTAB DB "QTCMWASRDLPIE;",13
819
820NUMCOM EQU $-COMTAB
821
822;-----------------------------------------------------------------------;
823; Carefull changing the order of the next two tables. They are
824; linked and chnges should be be to both.
825
826TABLE DW NOCOM ;No command--edit line
827 DW NOCOM
828 DW ENDED
829 DW INSERT
830 DW PAGE
831 DW LIST
832 DW DELETE
833 dw replac_from_curr ;replace from current+1 line
834 dw search_from_curr ;search from current+1 line
835 DW APPEND
836 DW EWRITE
837 DW MOVE
838 DW COPY
839 DW MERGE
840
841 if roprot ;***** R/O *****
842 DW QUIT1
843 else
844 DW QUIT
845 endif
846
847 if roprot ;***** R/O *****
848;-----------------------------------------------------------------------;
849; If = 1 then the command can be executed with a file that
850; is r/o. If = 0 the command can not be executed, and error.
851
852ROTABLE db 0 ;NOCOM
853 db 0 ;NOCOM
854 db 0 ;ENDED
855 db 0 ;INSERT
856 db 1 ;PAGE
857 db 1 ;LIST
858 db 0 ;DELETE
859 db 0 ;replac_from_curr
860 db 1 ;search_from_curr
861 db 1 ;APPEND
862 db 1 ;EWRITE
863 db 0 ;MOVE
864 db 0 ;COPY
865 db 0 ;MERGE
866 db 1 ;QUIT
867
868;-----------------------------------------------------------------------;
869 endif
870
871 if roprot ;***** R/O *****
872quit1:
873 cmp [roflag],01 ;are we in r/o mode?
874 jne q3 ;no query....
875 MOV DX,OFFSET DG:FCB2 ;yes, quit without query.
876 MOV AH,FCB_CLOSE
877 INT 21H
878 MOV AH,FCB_DELETE
879 INT 21H
880 call rest_dir ;restore directory if needed
881 INT 20H
882q3:
883 call quit
884 endif
885
886SCANEOF:
887 cmp [loadmod],0
888 je sj52
889
890;----- Load till physical end of file
891 cmp cx,word ptr[amnt_req]
892 jb sj51
893 xor al,al
894 inc al ;reset zero flag
895 ret
896sj51:
897 jcxz sj51b
898 push di ;get rid of any ^Z at the end of the file
899 add di,cx
900 dec di ;points to last char
901 cmp byte ptr [di],1ah
902 pop di
903 jne sj51b
904 dec cx
905sj51b:
906 xor al,al ;set zero flag
907 call check_end ;check that we have a CRLF pair at the end
908 ret
909
910;----- Load till first ^Z is found
911sj52:
912 PUSH DI
913 PUSH CX
914 MOV AL,1AH
915 or cx,cx
916 jz not_found ;skip with zero flag set
917 REPNE SCASB ;Scan for end of file mark
918 jnz not_found
919 LAHF ;Save flags momentarily
920 inc cx ;include the ^Z
921 SAHF ;Restore flags
922not_found:
923 mov di,cx ;not found at the end
924 POP CX
925 LAHF ;Save flags momentarily
926 SUB CX,DI ;Reduce byte count if EOF found
927 SAHF ;Restore flags
928 POP DI
929 call check_end ;check that we have a CRLF pair at the end
930
931RET2: RET
932
933
934;-----------------------------------------------------------------------
935; If the end of file was found, then check that the last character
936; in the file is a LF. If not put a CRLF pair in.
937
938check_end:
939 jnz not_end ;end was not reached
940 pushf ;save return flag
941 push di ;save pointer to buffer
942 add di,cx ;points to one past end on text
943 dec di ;points to last character
944 cmp di,offset dg:start
945 je check_no
946 cmp byte ptr[di],0ah ;is a LF the last character?
947 je check_done ;yes, exit
948check_no:
949 mov byte ptr[di+1],0dh ;no, put a CR
950 inc cx ;one more char in text
951 mov byte ptr[di+2],0ah ;put a LF
952 inc cx ;another character at the end
953check_done:
954 pop di
955 popf
956not_end:
957 ret
958
959
960
961NOMOREJ:JMP NOMORE
962
963APPEND:
964 TEST BYTE PTR [HAVEOF],-1
965 JNZ NOMOREJ
966 MOV DX,[ENDTXT]
967 CMP [PARAM1],0 ;See if parameter is missing
968 JNZ PARMAPP
969 CMP DX,[THREE4TH] ;See if already 3/4ths full
970 JAE RET2 ;If so, then done already
971PARMAPP:
972 MOV DI,DX
973 MOV AH,SET_DMA
974 INT 21H
975 MOV CX,[LAST]
976 SUB CX,DX ;Amount of memory available
977 jnz sj53
978 jmp memerr
979sj53:
980 MOV DX,FCB
981 mov [amnt_req],cx ;save ammount of chars requested
982 MOV AH,FCB_RANDOM_READ_BLOCK
983 INT 21H ;Fill memory with file data
984 MOV [HAVEOF],AL
985 PUSH CX ;Save actual byte count
986 CALL SCANEOF
987 JNZ NOTEND
988 MOV BYTE PTR [HAVEOF],1 ;Set flag if 1AH found in file
989NOTEND:
990 XOR DX,DX
991 MOV BX,[PARAM1]
992 OR BX,BX
993 JNZ COUNTLN
994 MOV AX,DI
995 ADD AX,CX ;First byte after loaded text
996 CMP AX,[THREE4TH] ;See if we made 3/4 full
997 JBE COUNTLN
998 MOV DI,[THREE4TH]
999 MOV CX,AX
1000 SUB CX,DI ;Length remaining over 3/4
1001 MOV BX,1 ;Look for one more line
1002COUNTLN:
1003 CALL SCANLN ;Look for BX lines
1004 CMP [DI-1],AL ;Check for full line
1005 JZ FULLN
1006 STD
1007 DEC DI
1008 MOV CX,[LAST]
1009 REPNE SCASB ;Scan backwards for last line
1010 INC DI
1011 INC DI
1012 DEC DX
1013 CLD
1014FULLN:
1015 POP CX ;Actual amount read
1016 MOV WORD PTR [DI],1AH ;Place EOF after last line
1017 SUB CX,DI
1018 XCHG DI,[ENDTXT]
1019 ADD DI,CX ;Amount of file read but not used
1020 SUB WORD PTR DS:[FCB+fcb_RR],DI ;Adjust RR field in case end of file
1021 SBB WORD PTR DS:[FCB+fcb_RR+2],0 ; was not reached
1022 CMP BX,DX
1023 JNZ EOFCHK
1024 MOV BYTE PTR [HAVEOF],0
1025 RET
1026NOMORE:
1027 MOV DX,OFFSET DG:EOF
1028 MOV AH,STD_CON_STRING_OUTPUT
1029 INT 21H
1030RET3: RET
1031EOFCHK:
1032 TEST BYTE PTR [HAVEOF],-1
1033 JNZ NOMORE
1034 TEST BYTE PTR [ENDING],-1
1035 JNZ RET3 ;Suppress memory error during End
1036 JMP MEMERR
1037
1038EWRITE:
1039 MOV BX,[PARAM1]
1040 OR BX,BX
1041 JNZ WRT
1042 MOV CX,[ONE4TH]
1043 MOV DI,[ENDTXT]
1044 SUB DI,CX ;Write everything in front of here
1045 JBE RET3
1046 CMP DI,OFFSET DG:START ;See if there's anything to write
1047 JBE RET3
1048 XOR DX,DX
1049 MOV BX,1 ;Look for one more line
1050 CALL SCANLN
1051 JMP SHORT WRTADD
1052WRT:
1053 INC BX
1054 CALL FINDLIN
1055WRTADD:
1056 CMP BYTE PTR [DELFLG],0
1057 JNZ WRTADD1
1058 PUSH DI
1059 CALL DELBAK ;Want to delete the .BAK file
1060 ;as soon as the first write occurs
1061 POP DI
1062WRTADD1:
1063 MOV CX,DI
1064 MOV DX,OFFSET DG:START
1065 SUB CX,DX ;Amount to write
1066 JZ RET3
1067 MOV AH,SET_DMA
1068 INT 21H
1069 MOV DX,OFFSET DG:FCB2
1070 MOV AH,FCB_RANDOM_WRITE_BLOCK
1071 INT 21H
1072 OR AL,AL
1073 JNZ WRTERR
1074 MOV SI,DI
1075 MOV DI,OFFSET DG:START
1076 MOV [POINTER],DI
1077 MOV CX,[ENDTXT]
1078 SUB CX,SI
1079 INC CX ;Amount of text remaining
1080 REP MOVSB
1081 DEC DI ;Point to EOF
1082 MOV [ENDTXT],DI
1083 MOV [CURRENT],1
1084 RET
1085
1086WRTERR:
1087 MOV AH,FCB_CLOSE
1088 INT 21H
1089 MOV DX,OFFSET DG:DSKFUL
1090xERROR:
1091 MOV AH,STD_CON_STRING_OUTPUT
1092 INT 21H
1093;-----------------------------------------------------------------------
1094 call rest_dir ;restore to the proper directory
1095;-----------------------------------------------------------------------
1096 INT 32
1097
1098RET$5: RET
1099
1100PAGE:
1101 xor bx,bx ;get last line in the buffer
1102 call findlin
1103 mov [lastlin],dx
1104
1105 mov bx,[param1]
1106 or bx,bx ;was it specified?
1107 jnz frstok ;yes, use it
1108 mov bx,[current]
1109 cmp bx,1 ;if current line =1 start from there
1110 je frstok
1111 inc bx ;start from current+1 line
1112frstok:
1113 cmp bx,[lastlin] ;check that we are in the buffer
1114 ja ret$5 ;if not just quit
1115infile:
1116 mov dx,[param2]
1117 or dx,dx ;was param2 specified?
1118 jnz scndok ;yes,....
1119 mov dx,bx ;no, take the end line to be the
1120 add dx,22 ; start line + 23
1121scndok:
1122 inc dx
1123 cmp dx,[lastlin] ;check that we are in the buffer
1124 jbe infile2
1125 mov dx,[lastlin] ;we are not, take the last line as end
1126infile2:
1127 cmp dx,bx ;is param1 < param2 ?
1128 jbe ret$5 ;yes, no backwards listing, quit
1129 push dx ;save the end line
1130 push bx ;save start line
1131 mov bx,dx ;set the current line
1132 dec bx
1133 call findlin
1134 mov [pointer],di
1135 mov [current],dx
1136 pop bx ;restore start line
1137 call findlin ;get pointer to start line
1138 mov si,di ;save pointer
1139 pop di ;get end line
1140 sub di,bx ;number of lines
1141 jmp short display
1142
1143
1144LIST:
1145 MOV BX,[PARAM1]
1146 OR BX,BX
1147 JNZ CHKP2
1148 MOV BX,[CURRENT]
1149 SUB BX,11
1150 JA CHKP2
1151 MOV BX,1
1152CHKP2:
1153 CALL FINDLIN
1154 JNZ RET7
1155 MOV SI,DI
1156 MOV DI,[PARAM2]
1157 INC DI
1158 SUB DI,BX
1159 JA DISPLAY
1160 MOV DI,23
1161 JMP SHORT DISPLAY
1162
1163
1164DISPONE:
1165 MOV DI,1
1166
1167DISPLAY:
1168
1169; Inputs:
1170; BX = Line number
1171; SI = Pointer to text buffer
1172; DI = No. of lines
1173; Function:
1174; Ouputs specified no. of line to terminal, each
1175; with leading line number.
1176; Outputs:
1177; BX = Last line output.
1178; All registers destroyed.
1179
1180 MOV CX,[ENDTXT]
1181 SUB CX,SI
1182 JZ RET7
1183 MOV BP,[CURRENT]
1184DISPLN:
1185 PUSH CX
1186 CALL SHOWNUM
1187 POP CX
1188OUTLN:
1189 LODSB
1190 CMP AL," "
1191 JAE SEND
1192 CMP AL,10
1193 JZ SEND
1194 CMP AL,13
1195 JZ SEND
1196 CMP AL,9
1197 JZ SEND
1198 PUSH AX
1199 MOV AL,"^"
1200 CALL OUT
1201 POP AX
1202 OR AL,40H
1203SEND:
1204 CALL OUT
1205 CMP AL,10
1206 LOOPNZ OUTLN
1207 JCXZ RET7
1208 INC BX
1209 DEC DI
1210 JNZ DISPLN
1211 DEC BX
1212RET7: RET
1213
1214LOADBUF:
1215 MOV DI,2 + OFFSET DG:EDITBUF
1216 MOV CX,255
1217 MOV DX,-1
1218LOADLP:
1219 LODSB
1220 STOSB
1221 INC DX
1222 CMP AL,13
1223 LOOPNZ LOADLP
1224 MOV [EDITBUF+1],DL
1225 JZ RET7
1226TRUNCLP:
1227 LODSB
1228 INC DX
1229 CMP AL,13
1230 JNZ TRUNCLP
1231 DEC DI
1232 STOSB
1233 RET
1234
1235NOTFNDJ:JMP NOTFND
1236
1237replac_from_curr:
1238 mov byte ptr [srchmod],1 ;search from curr+1 line
1239 jmp short sj6
1240
1241REPLAC:
1242 mov byte ptr [srchmod],0 ;search from beg of buffer
1243sj6:
1244 MOV BYTE PTR [SRCHFLG],0
1245 CALL FNDFIRST
1246 JNZ NOTFNDJ
1247REPLP:
1248 MOV SI,[NUMPOS]
1249 CALL LOADBUF ;Count length of line
1250 SUB DX,[OLDLEN]
1251 MOV CX,[NEWLEN]
1252 ADD DX,CX ;Length of new line
1253 CMP DX,254
1254 JA TOOLONG
1255 MOV BX,[LSTNUM]
1256 PUSH DX
1257 CALL SHOWNUM
1258 POP DX
1259 MOV CX,[LSTFND]
1260 MOV SI,[NUMPOS]
1261 SUB CX,SI ;Get no. of char on line before change
1262 DEC CX
1263 CALL OUTCNT ;Output first part of line
1264 PUSH SI
1265 MOV SI,1+ OFFSET DG:TXT2
1266 MOV CX,[NEWLEN]
1267 CALL OUTCNT ;Output change
1268 POP SI
1269 ADD SI,[OLDLEN] ;Skip over old stuff in line
1270 MOV CX,DX ;DX=no. of char left in line
1271 ADD CX,2 ;Include CR/LF
1272 CALL OUTCNT ;Output last part of line
1273 CALL QUERY ;Check if change OK
1274 JNZ REPNXT
1275 CALL PUTCURS
1276 MOV DI,[LSTFND]
1277 DEC DI
1278 MOV SI,1+ OFFSET DG:TXT2
1279 MOV DX,[OLDLEN]
1280 MOV CX,[NEWLEN]
1281 DEC CX
1282 ADD [LSTFND],CX ;Bump pointer beyond new text
1283 INC CX
1284 DEC DX
1285 SUB [SRCHCNT],DX ;Old text will not be searched
1286 JAE SOMELEFT
1287 MOV [SRCHCNT],0
1288SOMELEFT:
1289 INC DX
1290 CALL REPLACE
1291REPNXT:
1292 CALL FNDNEXT
1293 JNZ RET8
1294 JMP REPLP
1295
1296OUTCNT:
1297 JCXZ RET8
1298OUTLP:
1299 LODSB
1300 CALL OUT
1301 DEC DX
1302 LOOP OUTLP
1303RET8: RET
1304
1305TOOLONG:
1306 MOV DX,OFFSET DG:TOOLNG
1307 JMP SHORT PERR
1308
1309search_from_curr:
1310 mov byte ptr [srchmod],1 ;search from curr+1 line
1311 jmp short sj7
1312
1313SEARCH:
1314 mov byte ptr [srchmod],0 ;search from beg of buffer
1315sj7:
1316 MOV BYTE PTR [SRCHFLG],1
1317 CALL FNDFIRST
1318 JNZ NOTFND
1319SRCH:
1320 MOV BX,[LSTNUM]
1321 MOV SI,[NUMPOS]
1322 CALL DISPONE
1323 MOV DI,[LSTFND]
1324 MOV CX,[SRCHCNT]
1325 MOV AL,10
1326 REPNE SCASB
1327 JNZ NOTFND
1328 MOV [LSTFND],DI
1329 MOV [NUMPOS],DI
1330 MOV [SRCHCNT],CX
1331 INC [LSTNUM]
1332 CALL QUERY
1333 JZ PUTCURS
1334 CALL FNDNEXT
1335 JZ SRCH
1336NOTFND:
1337 MOV DX,OFFSET DG:NOSUCH
1338PERR:
1339 MOV AH,STD_CON_STRING_OUTPUT
1340 INT 21H
1341 RET
1342
1343PUTCURS:
1344 MOV BX,[LSTNUM]
1345 DEC BX ;Current <= Last matched line
1346 CALL FINDLIN
1347 MOV [CURRENT],DX
1348 MOV [POINTER],DI
1349RET9: RET
1350
1351DELETE:
1352 MOV BX,[PARAM1]
1353 OR BX,BX
1354 JNZ DELFIN1
1355 MOV BX,[CURRENT]
1356 CALL CHKRANGE
1357DELFIN1:
1358 CALL FINDLIN
1359 JNZ RET9
1360 PUSH BX
1361 PUSH DI
1362 MOV BX,[PARAM2]
1363 OR BX,BX
1364 JNZ DELFIN2
1365 MOV BX,DX
1366DELFIN2:
1367 INC BX
1368 CALL FINDLIN
1369 MOV DX,DI
1370 POP DI
1371 SUB DX,DI
1372 JBE COMERRJ
1373 POP [CURRENT]
1374 MOV [POINTER],DI
1375 XOR CX,CX
1376 JMP SHORT REPLACE
1377
1378COMERRJ:JMP COMERR
1379
1380
1381NOCOM:
1382 DEC [COMLINE]
1383 MOV BX,[PARAM1]
1384 OR BX,BX
1385 JNZ HAVLIN
1386 MOV BX,[CURRENT]
1387 INC BX ;Default is current line plus one
1388 CALL CHKRANGE
1389HAVLIN:
1390 CALL FINDLIN
1391 MOV SI,DI
1392 MOV [CURRENT],DX
1393 MOV [POINTER],SI
1394 jz sj12
1395 ret
1396sj12:
1397 CMP SI,[ENDTXT]
1398 JZ RET12
1399 CALL LOADBUF
1400 MOV [OLDLEN],DX
1401 MOV SI,[POINTER]
1402 CALL DISPONE
1403 CALL SHOWNUM
1404 MOV AH,STD_CON_STRING_INPUT ;Get input buffer
1405 MOV DX,OFFSET DG:EDITBUF
1406 INT 21H
1407 MOV AL,10
1408 CALL OUT
1409 MOV CL,[EDITBUF+1]
1410 MOV CH,0
1411 JCXZ RET12
1412 MOV DX,[OLDLEN]
1413 MOV SI,2 + OFFSET DG:EDITBUF
1414;-----------------------------------------------------------------------
1415 call unquote ;scan for quote chars if any
1416;-----------------------------------------------------------------------
1417 MOV DI,[POINTER]
1418
1419REPLACE:
1420
1421; Inputs:
1422; CX = Length of new text
1423; DX = Length of original text
1424; SI = Pointer to new text
1425; DI = Pointer to old text in buffer
1426; Function:
1427; New text replaces old text in buffer and buffer
1428; size is adjusted. CX or DX may be zero.
1429; CX, SI, DI all destroyed. No other registers affected.
1430
1431 CMP CX,DX
1432 JZ COPYIN
1433 PUSH SI
1434 PUSH DI
1435 PUSH CX
1436 MOV SI,DI
1437 ADD SI,DX
1438 ADD DI,CX
1439 MOV AX,[ENDTXT]
1440 SUB AX,DX
1441 ADD AX,CX
1442 CMP AX,[LAST]
1443 JAE MEMERR
1444 XCHG AX,[ENDTXT]
1445 MOV CX,AX
1446 SUB CX,SI
1447 CMP SI,DI
1448 JA DOMOV
1449 ADD SI,CX
1450 ADD DI,CX
1451 STD
1452DOMOV:
1453 INC CX
1454
1455 REP MOVSB
1456 CLD
1457 POP CX
1458 POP DI
1459 POP SI
1460COPYIN:
1461 REP MOVSB
1462RET12: RET
1463
1464MEMERR:
1465 MOV DX,OFFSET DG:MEMFUL
1466 MOV AH,STD_CON_STRING_OUTPUT
1467 INT 21H
1468 JMP COMMAND
1469
1470MOVERR:
1471 MOV DX,OFFSET DG:BADCOM
1472ERRORJ:
1473 JMP COMERR
1474
1475MOVE:
1476 MOV BYTE PTR [MOVFLG],1
1477 JMP SHORT BLKMOVE
1478COPY:
1479 MOV BYTE PTR [MOVFLG],0
1480
1481BLKMOVE:
1482 MOV BX,[PARAM3] ;Third parameter must be specified
1483 OR BX,BX
1484 MOV DX,OFFSET DG:DEST
1485 JZ ERRORJ
1486 MOV BX,[PARAM1] ;Get the first parameter
1487 OR BX,BX ;Not specified?
1488 JNZ NXTARG
1489 MOV BX,[CURRENT] ;Defaults to the current line
1490 CALL CHKRANGE
1491 MOV [PARAM1],BX ;Save it since current line may change
1492 NXTARG:
1493 CALL FINDLIN ;Get a pointer to the line
1494 MOV [PTR_1],DI ;Save it
1495 MOV BX,[PARAM2] ;Get the second parameter
1496 OR BX,BX ;Not specified?
1497 JNZ HAVARGS
1498 MOV BX,[CURRENT] ;Defaults to the current line
1499 MOV [PARAM2],BX ;Save it since current line may change
1500HAVARGS:
1501 ;Parameters must not overlap
1502 MOV DX,[PARAM3]
1503 CMP DX,[PARAM1]
1504 JBE NOERROR
1505 CMP DX,[PARAM2]
1506 JBE MOVERR
1507NOERROR:
1508 INC BX ;Get pointer to line Param2+1
1509 CALL FINDLIN
1510 MOV SI,DI
1511 MOV [PTR_2],SI ;Save it
1512 MOV CX,DI
1513 MOV DI,[PTR_1] ;Restore pointer to line Param1
1514 SUB CX,DI ;Calculate number of bytes to copy
1515 MOV [COPYSIZ],CX ;Save in COPYSIZ
1516 PUSH CX ;And on the stack
1517 MOV AX,[PARAM4] ;Is count specified?
1518 OR AX,AX
1519 JZ MEM_CHECK
1520 MUL [COPYSIZ]
1521 OR DX,DX
1522 JZ COPYSIZ_OK
1523 JMP MEMERR
1524COPYSIZ_OK:
1525 MOV CX,AX
1526 MOV [COPYSIZ],CX
1527MEM_CHECK:
1528 MOV AX,[ENDTXT]
1529 MOV DI,[LAST]
1530 SUB DI,AX
1531 CMP DI,CX
1532 JAE HAV_ROOM
1533 JMP MEMERR
1534HAV_ROOM:
1535 MOV BX,[PARAM3]
1536 PUSH BX
1537 CALL FINDLIN
1538 MOV [PTR_3],DI
1539 MOV CX,[ENDTXT]
1540 SUB CX,DI
1541 INC CX
1542 MOV SI,[ENDTXT]
1543 MOV DI,SI
1544 ADD DI,[COPYSIZ]
1545 MOV [ENDTXT],DI
1546 STD
1547 REP MOVSB
1548 CLD
1549 POP BX
1550 CMP BX,[PARAM1]
1551 JB GET_PTR_2
1552 MOV SI,[PTR_1]
1553 JMP SHORT COPY_TEXT
1554GET_PTR_2:
1555 MOV SI,[PTR_2]
1556COPY_TEXT:
1557 MOV BX,[PARAM4]
1558 MOV DI,[PTR_3]
1559 POP CX
1560 MOV [COPYSIZ],CX
1561COPY_TEXT_1:
1562 REP MOVSB
1563 DEC BX
1564 CMP BX,0
1565 JLE MOV_CHK
1566 MOV [PARAM4],BX
1567 SUB SI,[COPYSIZ]
1568 MOV CX,[COPYSIZ]
1569 JMP SHORT COPY_TEXT_1
1570MOV_CHK:
1571 CMP BYTE PTR[MOVFLG],0
1572 JZ COPY_DONE
1573 MOV DI,[PTR_1]
1574 MOV SI,[PTR_2]
1575 MOV BX,[PARAM3]
1576 CMP BX,[PARAM1]
1577 JAE DEL_TEXT
1578 ADD DI,[COPYSIZ]
1579 ADD SI,[COPYSIZ]
1580DEL_TEXT:
1581 MOV CX,[ENDTXT]
1582 SUB CX,SI
1583 REP MOVSB
1584 MOV [ENDTXT],DI
1585 MOV CX,[PARAM2]
1586 SUB CX,[PARAM1]
1587 MOV BX,[PARAM3]
1588 SUB BX,CX
1589 JNC MOVE_DONE
1590COPY_DONE:
1591 MOV BX,[PARAM3]
1592MOVE_DONE:
1593 CALL FINDLIN
1594 MOV [POINTER],DI
1595 MOV [CURRENT],BX
1596 RET
1597
1598
1599MOVEFILE:
1600 MOV CX,[ENDTXT] ;Get End-of-text marker
1601 MOV SI,CX
1602 SUB CX,DI ;Calculate number of bytes to copy
1603 INC CX
1604 MOV DI,DX
1605 STD
1606 REP MOVSB ;Copy CX bytes
1607 XCHG SI,DI
1608 CLD
1609 INC DI
1610 MOV BP,SI
1611SETPTS:
1612 MOV [POINTER],DI ;Current line is first free loc
1613 MOV [CURRENT],BX ; in the file
1614 MOV [ENDTXT],BP ;End-of-text is last free loc before
1615 RET
1616
1617NAMERR:
1618 JMP COMERR1
1619
1620
1621MERGE:
1622 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 1
1623 MOV DI,OFFSET DG:FCB3
1624 INT 21H
1625 OR AL,AL
1626 MOV DX,OFFSET DG:BADDRV
1627 JNZ NAMERR
1628 MOV [COMLINE],SI
1629 MOV DX,OFFSET DG:FCB3
1630 MOV AH,FCB_OPEN
1631 INT 21H
1632 OR AL,AL
1633 MOV DX,OFFSET DG:FILENM
1634 JNZ NAMERR
1635 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H
1636 MOV DX,OFFSET DG:ABORTMERGE
1637 INT 21H
1638 MOV BX,[PARAM1]
1639 OR BX,BX
1640 JNZ MRG
1641 MOV BX,[CURRENT]
1642 CALL CHKRANGE
1643MRG:
1644 CALL FINDLIN
1645 MOV BX,DX
1646 MOV DX,[LAST]
1647 CALL MOVEFILE
1648 ;Set DMA address for reading in new file
1649 MOV DX,[POINTER]
1650 MOV AH,SET_DMA
1651 INT 21H
1652 XOR AX,AX
1653 MOV WORD PTR DS:[FCB3+fcb_RR],AX
1654 MOV WORD PTR DS:[FCB3+fcb_RR+2],AX
1655 INC AX
1656 MOV WORD PTR DS:[FCB3+fcb_RECSIZ],AX
1657 MOV DX,OFFSET DG:FCB3
1658 MOV CX,[ENDTXT]
1659 SUB CX,[POINTER]
1660 MOV AH,FCB_RANDOM_READ_BLOCK
1661 INT 21H
1662 CMP AL,1
1663 JZ FILEMRG
1664 MOV DX,OFFSET DG:MRGERR
1665 MOV AH,STD_CON_STRING_OUTPUT
1666 INT 21H
1667 MOV CX,[POINTER]
1668 JMP SHORT RESTORE
1669FILEMRG:
1670 ADD CX,[POINTER]
1671 MOV SI,CX
1672 DEC SI
1673 LODSB
1674 CMP AL,1AH
1675 JNZ RESTORE
1676 DEC CX
1677RESTORE:
1678 MOV DI,CX
1679 MOV SI,[ENDTXT]
1680 INC SI
1681 MOV CX,[LAST]
1682 SUB CX,SI
1683 REP MOVSB
1684 MOV [ENDTXT],DI
1685 MOV BYTE PTR [DI],1AH
1686 MOV DX,OFFSET DG:FCB3
1687 MOV AH,FCB_CLOSE
1688 INT 21H
1689 MOV DX,OFFSET DG:START
1690 MOV AH,SET_DMA
1691 INT 21H
1692 RET
1693
1694
1695INSERT:
1696 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H ;Set vector 23H
1697 MOV DX,OFFSET DG:ABORTINS
1698 INT 21H
1699 MOV BX,[PARAM1]
1700 OR BX,BX
1701 JNZ INS
1702 MOV BX,[CURRENT]
1703 CALL CHKRANGE
1704INS:
1705 CALL FINDLIN
1706 MOV BX,DX
1707 MOV DX,[LAST]
1708 CALL MOVEFILE
1709INLP:
1710 CALL SETPTS ;Update the pointers into file
1711 CALL SHOWNUM
1712 MOV DX,OFFSET DG:EDITBUF
1713 MOV AH,STD_CON_STRING_INPUT
1714 INT 21H
1715 CALL LF
1716 MOV SI,2 + OFFSET DG:EDITBUF
1717 CMP BYTE PTR [SI],1AH
1718 JZ ENDINS
1719;-----------------------------------------------------------------------
1720 call unquote ;scan for quote chars if any
1721;-----------------------------------------------------------------------
1722 MOV CL,[SI-1]
1723 MOV CH,0
1724 MOV DX,DI
1725 INC CX
1726 ADD DX,CX
1727 JC MEMERRJ1
1728 JZ MEMERRJ1
1729 CMP DX,BP
1730 JB MEMOK
1731MEMERRJ1:
1732 CALL END_INS
1733 JMP MEMERR
1734MEMOK:
1735 REP MOVSB
1736 MOV AL,10
1737 STOSB
1738 INC BX
1739 JMP SHORT INLP
1740
1741ABORTMERGE:
1742 MOV DX,OFFSET DG:START
1743 MOV AH,SET_DMA
1744 INT 21H
1745
1746ABORTINS:
1747 MOV AX,CS ;Restore segment registers
1748 MOV DS,AX
1749 MOV ES,AX
1750 MOV SS,AX
1751 MOV SP,OFFSET DG:STACK
1752 STI
1753 CALL CRLF
1754 CALL ENDINS
1755 JMP COMOVER
1756
1757ENDINS:
1758 CALL END_INS
1759 RET
1760
1761END_INS:
1762 MOV BP,[ENDTXT]
1763 MOV DI,[POINTER]
1764 MOV SI,BP
1765 INC SI
1766 MOV CX,[LAST]
1767 SUB CX,BP
1768 REP MOVSB
1769 DEC DI
1770 MOV [ENDTXT],DI
1771 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H
1772 MOV DX,OFFSET DG:ABORTCOM
1773 INT 21H
1774 RET
1775
1776FILLBUF:
1777 MOV [PARAM1],-1 ;Read in max. no of lines
1778 CALL APPEND
1779ENDED:
1780;Write text out to .$$$ file
1781 MOV BYTE PTR [ENDING],1 ;Suppress memory errors
1782 MOV BX,-1 ;Write max. no of lines
1783 CALL WRT
1784 TEST BYTE PTR [HAVEOF],-1
1785 JZ FILLBUF
1786 MOV DX,[ENDTXT]
1787 MOV AH,SET_DMA
1788 INT 21H
1789 MOV CX,1
1790 MOV DX,OFFSET DG:FCB2
1791 MOV AH,FCB_RANDOM_WRITE_BLOCK
1792 INT 21H ;Write end-of-file byte
1793;Close .$$$ file
1794 MOV AH,FCB_CLOSE
1795 INT 21H
1796 MOV SI,FCB
1797 LEA DI,[SI+fcb_FILSIZ]
1798 MOV DX,SI
1799 MOV CX,9
1800 REP MOVSB
1801 MOV SI,OFFSET DG:BAK
1802 MOVSW
1803 MOVSB
1804;Rename original file .BAK
1805 MOV AH,FCB_RENAME
1806 INT 21H
1807 MOV SI,FCB
1808 MOV DI,OFFSET DG:FCB2 + fcb_FILSIZ
1809 MOV CX,6
1810 REP MOVSW
1811;Rename .$$$ file to original name
1812 MOV DX,OFFSET DG:FCB2
1813 INT 21H
1814 call rest_dir ;restore directory if needed
1815 INT 20H
1816
1817ABORTCOM:
1818 MOV AX,CS
1819 MOV DS,AX
1820 MOV ES,AX
1821 MOV SS,AX
1822 MOV SP,OFFSET DG:STACK
1823 STI
1824 CALL CRLF
1825 JMP COMMAND
1826
1827DELBAK:
1828 MOV BYTE PTR [DELFLG],1
1829 MOV DI,9+OFFSET DG:FCB2
1830 MOV SI,OFFSET DG:BAK
1831 MOVSW
1832 MOVSB
1833 ;Delete old backup file (.BAK)
1834 MOV AH,FCB_DELETE
1835 MOV DX,OFFSET DG:FCB2
1836 INT 21H
1837 MOV DI,9+OFFSET DG:FCB2
1838 MOV AL,"$"
1839 STOSB
1840 STOSB
1841 STOSB
1842 RET
1843
1844CODE ENDS
1845 END EDLIN
1846 \ No newline at end of file