summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/EDLIN/EDLIN.ASM
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/CMD/EDLIN/EDLIN.ASM
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0/src/CMD/EDLIN/EDLIN.ASM')
-rw-r--r--v4.0/src/CMD/EDLIN/EDLIN.ASM1843
1 files changed, 1843 insertions, 0 deletions
diff --git a/v4.0/src/CMD/EDLIN/EDLIN.ASM b/v4.0/src/CMD/EDLIN/EDLIN.ASM
new file mode 100644
index 0000000..5368db0
--- /dev/null
+++ b/v4.0/src/CMD/EDLIN/EDLIN.ASM
@@ -0,0 +1,1843 @@
1 PAGE 60,132;
2 TITLE EDLIN
3
4;======================= START OF SPECIFICATIONS =========================
5;
6; MODULE NAME: EDLIN.SAL
7;
8; DESCRIPTIVE NAME: LINE TEXT EDITOR
9;
10; FUNCTION: EDLIN IS A SIMPLE, LINE ORIENTED TEXT EDITOR. IT PROVIDES
11; USERS OF DOS THE ABILITY TO CREATE AND EDIT TEXT FILES.
12;
13; ENTRY POINT: EDLIN
14;
15; INPUT: DOS COMMAND LINE
16; EDLIN COMMANDS
17; TEXT
18;
19; EXIT NORMAL: NA
20;
21; EXIT ERROR: NA
22;
23; INTERNAL REFERENCES:
24;
25; EXTERNAL REFERENCES:
26;
27; ROUTINE: EDLCMD1 - CONTAINS ROUTINES CALLED BY EDLIN
28; EDLCMD1 - CONTAINS ROUTINES CALLED BY EDLIN
29; EDLMES - CONTAINS ROUTINES CALLED BY EDLIN
30;
31; NOTES: THIS MODULE IS TO BE PREPPED BY SALUT WITH THE "PR" OPTIONS.
32; LINK EDLIN+EDLCMD1+EDLCMD2+EDLMES+EDLPARSE
33;
34; REVISION HISTORY:
35;
36; AN000 VERSION 4.00 - REVISIONS MADE RELATE TO THE FOLLOWING:
37;
38; - IMPLEMENT SYSPARSE
39; - IMPLEMENT MESSAGE RETRIEVER
40; - IMPLEMENT DBCS ENABLING
41; - ENHANCED VIDEO SUPPORT
42; - EXTENDED OPENS
43; - SCROLLING ERROR
44;
45; COPYRIGHT: "MS DOS EDLIN UTILITY"
46; "VERSION 4.00 (C) COPYRIGHT 1988 Microsoft"
47; "LICENSED MATERIAL - PROPERTY OF Microsoft"
48;
49;
50; MICROSOFT REVISION HISTORY:
51; ;
52; V1.02 ;
53; ;
54; V2.00 9/13/82 M.A.U ;
55; ;
56; 2/23/82 Rev. 13 N. P ;
57; Changed to 2.0 system calls. ;
58; Added an error message for READ-ONLY files ;
59; ;
60; 11/7/83 Rev. 14 N. P ;
61; Changed to .EXE format and added Printf ;
62; ;
63; V2.50 11/15/83 Rev. 1 M.A. U ;
64; Official dos 2.50 version. Some random bug ;
65; fixes and message changes. ;
66; ;
67; 11/30/83 Rev. 2 MZ ;
68; Close input file before rename. ;
69; Jmp to replace after line edit ;
70; ;
71; 02/01/84 Rev. 3 M.A. U ;
72; Now it is called 3.00 dos. Repaired problem ;
73; with using printf and having %'s as data. ;
74; ;
75; 02/15/84 MZ make out of space a fatal error with output;
76; ;
77; 03/28/84 MZ fixes bogus (totally) code in MOVE/COPY ;
78; ;
79; 04/02/84 MZ fixes DELETE and changes MOVE/COPY/EDIT ;
80; ;
81; V3.20 08/29/86 Rev. 1 S.M. G ;
82; ;
83; 08/29/86 M001 MSKK TAR 593, TAB MOVEMENT ;
84; ;
85; 08/29/86 M002 MSKK TAR 157, BLKMOVE 1,1,1m, 1,3,1m ;
86; ;
87; 08/29/86 M003 MSKK TAR 476, EDLCMD2,MAKECAPS,kana char;
88; ;
89; 08/29/86 M004 MSKK TAR 191, Append load size ;
90; ;
91; 08/29/86 M005 IBMJ TAR Transfer Load command ;
92;
93;
94;======================= END OF SPECIFICATIONS =========================== ;
95
96include edlequ.asm
97
98SUBTTL Contants and Data areas
99PAGE
100 extrn parser_command:near ;an000;SYSPARSE
101
102CODE SEGMENT PUBLIC
103CODE ENDS
104
105CONST SEGMENT PUBLIC WORD
106CONST ENDS
107
108cstack segment stack
109cstack ends
110
111DATA SEGMENT PUBLIC WORD
112DATA ENDS
113
114DG GROUP CODE,CONST,cstack,DATA
115
116CONST SEGMENT PUBLIC WORD
117
118 public bak,$$$file,delflg,loadmod,txt1,txt2
119
120 EXTRN BADDRV_ptr:word,NDNAME_ptr:word,bad_vers_err:byte,opt_err_ptr:word
121 EXTRN NOBAK_ptr:word,BADCOM_ptr:word,NEWFIL_ptr:word,DEST_ptr:word,MRGERR_ptr:word
122 EXTRN NODIR_ptr:word,FILENM_ptr:word,ro_err_ptr:word,bcreat_ptr:word
123 EXTRN TOO_MANY_ptr:word,lf_ptr:word,prompt_ptr:word
124 EXTRN MemFul_Ptr:word
125
126BAK DB ".BAK",0
127
128$$$FILE DB ".$$$",0
129
130fourth db 0 ;fourth parameter flag
131
132loadmod db 0 ;Load mode flag, 0 = ^Z marks the
133 ; end of a file, 1 = viceversa.
134optchar db "-"
135
136TXT1 DB 0,80H DUP (?)
137TXT2 DB 0,80H DUP (?)
138DELFLG DB 0
139fNew DB 0 ; old file
140HAVEOF DB 0
141
142CONST ENDS
143
144cstack segment stack
145 db stksiz dup (?)
146cstack ends
147
148DATA SEGMENT PUBLIC WORD
149
150 extrn arg_buf_ptr:word ;an000;
151 extrn line_num_buf_ptr:word ;an000;
152
153 public path_name,ext_ptr,start,line_num,line_flag
154 public arg_buf,wrt_handle,temp_path
155 public current,pointer,qflg,editbuf,amnt_req,fname_len,delflg,lastlin
156 public olddat,oldlen,newlen,srchflg,srchmod
157 public comline,lstfnd,numpos,lstnum,last,srchcnt
158 public rd_handle,haveof,ending,three4th,one4th
159
160 public lc_adj ;an000;page length adj. factor
161 public lc_flag ;an000;display cont. flag
162 public pg_count ;an000;lines left on screen
163 public Disp_Len ;an000;display length
164 public Disp_Width ;an000;display width
165 public continue ;an000;boolean T/F
166 public temp_path ;an000;pointer to filespec buf
167
168Video_Buffer label word ;an000;buffer for video attr
169 db 0 ;an000;dms;
170 db 0 ;an000;dms;
171 dw 14 ;an000;dms;
172 dw 0 ;an000;dms;
173 db ? ;an000;dms;
174 db 0 ;an000;dms;
175 dw ? ;an000;dms;# of colors
176 dw ? ;an000;dms;# of pixels in width
177 dw ? ;an000;dms;# of pixels in len.
178 dw ? ;an000;dms;# of chars in width
179 dw ? ;an000;dms;# of chars in length
180
181
182video_org db ? ;an000;original video mode on
183 ; entry to EDLIN.
184lc_adj db ? ;an000;page length adj. factor
185lc_flag db ? ;an000;display cont. flag
186pg_count db ? ;an000;lines left on screen
187Disp_Len db ? ;an000;display length
188Disp_Width db ? ;an000;display width
189continue db ? ;an000;boolean T/F
190
191
192;-----------------------------------------------------------------------;
193; This is a table that is sequentially filled via GetNum. Any additions to it
194; must be placed in the correct position. Currently Param4 is known to be a
195; count and thus is treated specially.
196
197 public param1,param2,Param3,param4,ParamCt
198PARAM1 DW ?
199PARAM2 DW ?
200PARAM3 DW ?
201PARAM4 DW ?
202ParamCt DW ? ; count of passed parameters
203 if kanji ; Used in TESTKANJ:
204LBTbl dd ? ; long pointer to lead byte table
205 endif ; in the dos (from syscall 63H)
206
207;-----------------------------------------------------------------------;
208
209PUBLIC PTR_1, PTR_2, PTR_3, OLDLEN, NEWLEN, LSTFND, LSTNUM, NUMPOS, SRCHCNT
210PUBLIC CURRENT, POINTER, ONE4TH, THREE4TH, LAST, ENDTXT, COPYSIZ
211PUBLIC COMLINE, LASTLIN, COMBUF, EDITBUF, EOL, QFLG, ENDING, SRCHFLG
212PUBLIC PATH_NAME, FNAME_LEN, RD_HANDLE, TEMP_PATH, WRT_HANDLE, EXT_PTR
213PUBLIC MRG_PATH_NAME, MRG_HANDLE, amnt_req, olddat, srchmod, MOVFLG, org_ds
214if kanji
215public lbtbl
216endif
217
218;
219; These comprise the known state of the internal buffer. All editing
220; functions must preserve these values.
221;
222CURRENT DW ? ; the 1-based index of the current line
223POINTER DW ? ; pointer to the current line
224ENDTXT DW ? ; pointer to end of buffer. (at ^Z)
225LAST DW ? ; offset of last byte of memory
226;
227; The label Start is the beginning of the in-core buffer.
228;
229
230;
231; Internal temporary pointers
232;
233PTR_1 DW ?
234PTR_2 DW ?
235PTR_3 DW ?
236
237QFLG DB ? ; TRUE => query for replacement
238OLDLEN DW ?
239NEWLEN DW ?
240LSTFND DW ?
241LSTNUM DW ?
242NUMPOS DW ?
243SRCHCNT DW ?
244ONE4TH DW ?
245THREE4TH DW ?
246COPYSIZ DW ? ; total length to copy
247COPYLEN DW ? ; single copy length
248COMLINE DW ?
249LASTLIN DW ?
250COMBUF DB 82H DUP (?)
251EDITBUF DB 258 DUP (?)
252EOL DB ?
253ENDING DB ?
254SRCHFLG DB ?
255PATH_NAME DB 128 DUP(0)
256FNAME_LEN DW ?
257RD_HANDLE DW ?
258TEMP_PATH DB 128 DUP(?)
259WRT_HANDLE DW ?
260EXT_PTR DW ?
261MRG_PATH_NAME DB 128 DUP(?)
262MRG_HANDLE DW ?
263amnt_req dw ? ; amount of bytes requested to read
264olddat db ? ; Used in replace and search, replace
265 ; by old data flag (1=yes)
266srchmod db ? ; Search mode: 1=from current+1 to
267 ; end of buffer, 0=from beg. of
268 ; buffer to the end (old way).
269MOVFLG DB ?
270org_ds dw ? ;Orginal ds points to header block
271
272arg_buf db 258 dup (?)
273
274EA_Flag db False ;an000; dms;set to false
275
276EA_Buffer_Size dw ? ;an000; dms;EA buffer's size
277
278EA_Parm_List label word ;an000; dms;EA parms
279 dd dg:Start ;an000; dms;ptr to EA's
280 dw 0001h ;an000; dms;additional parms
281 db 06h ;an000; dms;
282 dw 0002h ;an000; dms;iomode
283
284
285line_num dw ?
286
287line_flag db ?,0
288 EVEN ;align on word boundaries
289;
290; Byte before start of data buffer must be < 40H !!!!!!
291;
292 dw 0 ;we scan backwards looking for
293 ;a character which can't be part
294 ;of a two-byte seqence. This
295 ;double byte sequence will cause the back
296 ;scan to stop here.
297START LABEL WORD
298
299DATA ENDS
300
301
302CODE SEGMENT PUBLIC
303
304ASSUME CS:DG,DS:NOTHING,ES:NOTHING,SS:CStack
305
306
307
308 extrn pre_load_message:near ;an000;message loader
309 extrn disp_fatal:near ;an000;fatal message
310 extrn printf:near ;an000;new PRINTF routine
311
312 extrn findlin:near,shownum:near,loadbuf:near,crlf:near,lf:near
313 extrn abortcom:near,delbak:near,unquote:near,kill_bl:near
314 extrn make_caps:near,dispone:near,display:near,query:near
315 extrn quit:near,make_cntrl:near,scanln:near,scaneof:near
316 extrn fndfirst:near,fndnext:near,replace:near,memerr:near
317 extrn xerror:near,bad_read:near,append:near
318 extrn nocom:near,pager:near,list:near,search_from_curr:near
319 extrn replac_from_curr:near,ewrite:near,wrt:near,delete:near
320
321
322 extrn filespec:byte ;an000;parser's filespec
323 extrn parse_switch_b:byte ;an000;result of switch scan
324
325 public std_printf,command,chkrange,comerr
326 ; exit from EDLIN
327
328 IF KANJI
329 extrn testkanj:near
330 ENDIF
331
332EDLIN:
333 JMP SHORT SIMPED
334
335std_printf proc near ;ac000;convert to proc
336
337 push dx
338 call printf
339 pop dx ;an000;balance the push
340 ret
341
342std_printf endp ;ac000;end proc
343
344NONAME:
345 MOV DX,OFFSET DG:NDNAME_ptr
346 JMP XERROR
347
348SIMPED:
349 mov org_ds,DS
350 push ax ;ac000;save for drive compare
351
352 push cs ;an000;exchange cs/es
353 pop es ;an000;
354
355 push cs ;an000;exchange cs/ds
356 pop ds ;an000;
357 assume ds:dg,es:dg ;an000;establish addressibility
358
359 MOV dg:ENDING,0
360 mov sp,stack
361 call EDLIN_DISP_GET ;an000;get current video
362 ; mode & set it to
363 ; text
364
365;=========================================================================
366; invoke PRE_LOAD_MESSAGE here. If the messages were not loaded we will
367; exit with an appropriate error message.
368;
369; Date : 6/14/87
370;=========================================================================
371
372 call PRE_LOAD_MESSAGE ;an000;invoke SYSLOADMSG
373; $if c ;an000;if the load was unsuccessful
374 JNC $$IF1
375 mov ah,exit ;an000;exit EDLIN. PRE_LOAD_MESSAGE
376 ; has said why we are exiting
377 mov al,00h ;an000
378 int 21h ;an000;exit
379; $endif ;an000;
380$$IF1:
381
382
383
384VERS_OK:
385;----- Check for valid drive specifier --------------------------------;
386
387 pop ax
388 OR AL,AL
389 JZ get_switch_char
390 MOV DX,OFFSET DG:BADDRV_ptr
391 JMP xerror
392get_switch_char:
393 MOV AX,(CHAR_OPER SHL 8) ;GET SWITCH CHARACTER
394 INT 21H
395 CMP DL,"/"
396 JNZ CMD_LINE ;IF NOT / , THEN NOT PC
397 MOV OPTCHAR,"/" ;IN PC, OPTION CHAR = /
398
399 IF KANJI
400 push ds ; SAVE! all regs destroyed on this
401 push es
402 push si ; call !!
403 mov ax,(ECS_call shl 8) or 00h ; get kanji lead tbl
404 int 21h
405assume ds:nothing
406assume es:nothing
407 mov word ptr [LBTbl],si
408 mov word ptr [LBTbl+2],ds
409 pop si
410 pop es
411 pop ds
412assume ds:dg
413assume es:dg
414 ENDIF
415
416
417CMD_LINE:
418 push cs
419 pop es
420 ASSUME ES:DG
421
422;----- Process any options ------------------------------------------;
423
424;=========================================================================
425; The system parser, called through PARSER_COMMAND, parses external
426; command lines. In the case of EDLIN we are looking for two parameters
427; on the command line.
428;
429; Parameter 1 - Filespec (REQUIRED)
430; Parameter 2 - \B switch (OPTIONAL)
431;
432; PARSER_COMMAND - exit_normal : ffffh
433; exit_error : not = ffffh
434;=========================================================================
435
436
437 call PARSER_COMMAND ;an000;invoke sysparse
438 ; DMS:6/11/87
439 cmp ax,nrm_parse_exit ;an000;was it a good parse
440; $if z ;an000;it was a good parse
441 JNZ $$IF3
442 call EDLIN_COMMAND ;an000;interface results
443 ; into EDLIN
444; $else ;an000;
445 JMP SHORT $$EN3
446$$IF3:
447 cmp ax,too_many ;an000;too many operands
448; $if z ;an000;we have too many
449 JNZ $$IF5
450 jmp badopt ;an000;say why and exit
451; $endif
452$$IF5:
453
454 cmp ax,op_missing ;an000;required parm missing
455; $if z ;an000;missing parm
456 JNZ $$IF7
457 jmp noname ;an000;say why and exit
458; $endif ;an000;
459$$IF7:
460
461 cmp ax,sw_missing ;an000;is it an invalid switch
462; $if z ;an000;invalid switch
463 JNZ $$IF9
464 jmp badopt ;an000;say why and exit
465; $endif ;an000;
466$$IF9:
467
468; $endif ;an000;
469$$EN3:
470
471;=========================================================================
472;======================= begin .BAK check ================================
473; Check for .BAK extension on the filename
474
475 push ds ;an000;save reg.
476 push cs ;an000;set up addressibility
477 pop ds ;an000;
478 assume ds:dg ;an000;
479
480 push ax ;an000;save reg.
481 mov ax,offset dg:path_name ;an000;point to path_name
482 add ax,[fname_len] ;an000;calculate end of path_name
483 mov si,ax ;an000;point to end of path_name
484 pop ax ;an000;restore reg.
485
486 MOV CX,4 ;compare 4 bytes
487 SUB SI,4 ;Point 4th to last char
488 MOV DI,OFFSET DG:BAK ;Point to string ".BAK"
489 REPE CMPSB ;Compare the two strings
490 pop ds
491 ASSUME DS:NOTHING
492 JNZ NOTBAK
493 JMP HAVBAK
494
495;======================= end .BAK check ==================================
496
497;======================= begin NOTBAK ====================================
498; we have a file without a .BAK extension, try to open it
499
500NOTBAK:
501 push ds
502 push cs
503 pop ds
504 ASSUME DS:DG
505
506;=========================================================================
507; implement EXTENDED OPEN
508;=========================================================================
509
510 push es ;an000;save reg.
511 mov bx,RW ;an000;open for read/write
512 mov cx,ATTR ;an000;file attributes
513 mov dx,RW_FLAG ;an000;action to take on open
514 mov di,0ffffh ;an000;nul parm list
515
516 call EXT_OPEN1 ;an000;open for R/W;DMS:6/10/87
517 pop es ;an000;restore reg.
518
519;=========================================================================
520 pop ds
521 ASSUME DS:NOTHING
522 JC CHK_OPEN_ERR ;an open error occurred
523 MOV RD_HANDLE,AX ;Save the handle
524
525 call Calc_Memory_Avail ;an000; dms;enough memory?
526
527 mov bx,RD_Handle ;an000; dms;set up for call
528 call Query_Extend_Attrib ;an000; dms;memory required?
529
530 cmp dx,cx ;an000; dms;enough memory for EA's?
531; $if b ;an000; dms;no
532 JNB $$IF12
533 call EA_Fail_Exit ;an000; dms;say why and exit
534; $endif ;an000; dms;
535$$IF12:
536
537 mov bx,RD_Handle ;an000; dms;set up for call
538 mov EA_Flag,True ;an000; dms;
539 call Get_Extended_Attrib ;an000; dms;get attribs
540
541 Jmp HavFil ;work with the opened file
542
543;======================= end NOTBAK ======================================
544
545Badopt:
546 MOV DX,OFFSET DG:OPT_ERR_ptr;Bad option specified
547 JMP XERROR
548
549;=========================================================================
550;
551; The open of the file failed. We need to figure out why and report the
552; correct message. The circumstances we can handle are:
553;
554; open returns pathnotfound => bad drive or file name
555; open returns toomanyopenfiles => too many open files
556; open returns access denied =>
557; chmod indicates read-only => cannot edit read only file
558; else => file creation error
559; open returns filenotfound =>
560; creat ok => close, delete, new file
561; creat fails => file creation error
562; else => file cre
563;
564
565CHK_OPEN_ERR:
566 cmp ax,error_path_not_found
567 jz BadDriveError
568 cmp ax,error_too_many_open_files
569 jz TooManyError
570 cmp ax,error_access_denied
571 jnz CheckFNF
572 push ds
573 push cs
574 pop ds
575 assume ds:dg
576 mov ax,(chmod shl 8)
577 MOV DX,OFFSET DG:PATH_NAME
578 int 21h
579 jc FileCreationError
580 test cx,attr_read_only
581 jz FileCreationError
582 jmp ReadOnlyError
583
584CheckFNF:
585 cmp ax,error_file_not_found
586 jnz FileCreationError
587;
588; Try to create the file to see if it is OK.
589;
590 push ds
591 push cs
592 pop ds
593 assume ds:dg
594;=========================================================================
595; implement EXTENDED OPEN
596;=========================================================================
597
598 mov bx,RW ;an000;open for read/write
599 mov cx,ATTR ;an000;file attributes
600 mov dx,CREAT_FLAG ;an000;action to take on open
601 mov di,0ffffh ;an000;null parm list
602 call EXT_OPEN1 ;an000;create file;DMS:6/10/87
603
604;=========================================================================
605
606 pop ds
607 assume ds:nothing
608 jc CreateCheck
609 mov bx,ax
610 mov ah,close
611 int 21h
612 push ds
613 push cs
614 pop ds
615 assume ds:dg
616 mov ah,unlink
617 MOV DX,OFFSET DG:PATH_NAME
618 int 21h
619 pop ds
620 assume ds:nothing
621 jc FileCreationError ; This should NEVER be taken!!!
622 MOV HAVEOF,0FFH ; Flag from a system 1.xx call
623 MOV fNew,-1
624 JMP HAVFIL
625
626CreateCheck:
627 cmp ax,error_access_denied
628 jnz BadDriveError
629DiskFull:
630 MOV DX,OFFSET DG:nodir_ptr
631 jmp xerror
632
633FileCreationError:
634 mov dx,offset dg:BCreat_PTR
635 jmp xerror
636
637ReadOnlyError:
638 MOV DX,OFFSET DG:RO_ERR_ptr
639 jmp xerror
640
641BadDriveError:
642 MOV DX,OFFSET DG:BADDRV_PTR
643 jmp xerror
644
645TooManyError:
646 MOV DX,OFFSET DG:TOO_MANY_ptr
647 jmp xerror
648
649
650CREAT_ERR:
651 CMP DELFLG,0
652 JNZ DiskFull
653 push cs
654 pop ds
655 CALL DELBAK
656 JMP MAKFIL
657
658HAVBAK:
659 MOV DX,OFFSET DG:NOBAK_ptr
660 JMP XERROR
661
662HAVFIL:
663 push cs
664 pop ds
665 ASSUME DS:DG
666 CMP fNew,0
667 JZ MakeBak
668 MOV DX,OFFSET DG:NEWFIL_ptr ; Print new file message
669 call std_printf
670MakeBak:
671 MOV SI,OFFSET DG:PATH_NAME
672 MOV CX,[FNAME_LEN]
673 PUSH CX
674 MOV DI,OFFSET DG:TEMP_PATH
675 REP MOVSB
676 DEC DI
677 MOV DX,DI
678 POP CX
679 MOV AL,"."
680 STD
681 REPNE SCASB
682 JZ FOUND_EXT
683 MOV DI,DX ;Point to last char in filename
684FOUND_EXT:
685 CLD
686 INC DI
687 MOV [EXT_PTR],DI
688 MOV SI,OFFSET DG:$$$FILE
689 MOV CX,5
690 REP MOVSB
691
692;Create .$$$ file to make sure directory has room
693MAKFIL:
694
695;=========================================================================
696; implement EXTENDED OPEN
697;=========================================================================
698
699 mov bx,RW ;an000;open for read/write
700 mov cx,ATTR ;an000;file attributes
701 mov dx,Creat_Open_Flag ;an000;action to take on open
702 cmp EA_Flag,True ;an000;EA_Buffer used?
703; $if e ;an000;yes
704 JNE $$IF14
705 mov di,offset dg:EA_Parm_List ;an000; point to buffer
706; $else ;an000;
707 JMP SHORT $$EN14
708$$IF14:
709 mov di,0ffffh ;an000;nul parm list
710; $endif ;an000;
711$$EN14:
712 call EXT_OPEN2 ;an000;create file;DMS:6/10/87
713
714;=========================================================================
715
716 JC CREAT_ERR
717 MOV [WRT_HANDLE],AX
718;
719; We determine the size of the available memory. Use the word in the PDB at
720; [2] to determine the number of paragraphs. Then truncate this to 64K at
721; most.
722;
723 push ds ;save ds for size calc
724 mov ds,[org_ds]
725 MOV CX,DS:[2]
726 MOV DI,CS
727 SUB CX,DI
728 CMP CX,1000h
729 JBE GotSize
730 MOV CX,0FFFh
731GotSize:
732 SHL CX,1
733 SHL CX,1
734 SHL CX,1
735 SHL CX,1
736 pop ds ;restore ds after size calc
737 DEC CX
738 MOV [LAST],CX
739 MOV DI,OFFSET DG:START
740 TEST fNew,-1
741 JNZ SAVEND
742 SUB CX,OFFSET DG:START ;Available memory
743 SHR CX,1 ;1/2 of available memory
744 MOV AX,CX
745 SHR CX,1 ;1/4 of available memory
746 MOV [ONE4TH],CX ;Save amount of 1/4 full
747 ADD CX,AX ;3/4 of available memory
748 MOV DX,CX
749 ADD DX,OFFSET DG:START
750 MOV [THREE4TH],DX ;Save pointer to 3/4 full
751 MOV DX,OFFSET DG:START
752SAVEND:
753 CLD
754 MOV BYTE PTR [DI],1AH
755 MOV [ENDTXT],DI
756 MOV BYTE PTR [COMBUF],128
757 MOV BYTE PTR [EDITBUF],255
758 MOV BYTE PTR [EOL],10
759 MOV [POINTER],OFFSET DG:START
760 MOV [CURRENT],1
761 MOV ParamCt,1
762 MOV [PARAM1],0 ;M004 Leave room in memory, was -1
763 TEST fNew,-1
764 JNZ COMMAND
765;
766; The above setting of PARAM1 to -1 causes this call to APPEND to try to read
767; in as many lines that will fit, BUT.... What we are doing is simulating
768; the user issuing an APPEND command, and if the user asks for more lines
769; than we get then an "Insufficient memory" error occurs. In this case we
770; DO NOT want this error, we just want as many lines as possible read in.
771; The twiddle of ENDING suppresses the memory error
772;
773 MOV BYTE PTR [ENDING],1 ;Suppress memory errors
774 CALL APPEND
775 MOV ENDING,0 ; restore correct initial value
776
777Break <Main command loop>
778
779;
780; Main read/parse/execute loop. We reset the stack all the time as there
781; are routines that JMP back here. Don't blame me; Tim Paterson write this.
782;
783COMMAND:
784 push cs ;an000;set up addressibility
785 pop ds ;an000;
786 push cs ;an000;
787 pop es ;an000;
788 assume ds:dg,es:dg ;an000;
789
790 MOV SP, STACK
791 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H
792 MOV DX,OFFSET DG:ABORTCOM
793 INT 21H
794 mov dx,offset dg:prompt_ptr
795 call std_printf
796 MOV DX,OFFSET DG:COMBUF
797 MOV AH,STD_CON_STRING_INPUT
798 INT 21H
799 MOV [COMLINE],OFFSET DG:COMBUF + 2
800 mov dx,offset dg:lf_ptr
801 call std_printf
802PARSE:
803 MOV [PARAM2],0
804 MOV [PARAM3],0
805 MOV [PARAM4],0
806 mov [fourth],0 ;reset the fourth parameter flag
807 MOV QFLG,0
808 MOV SI,[COMLINE]
809 MOV BP,OFFSET DG:PARAM1
810 XOR DI,DI
811CHKLP:
812 CALL GETNUM
813;
814; AL has first char after arg
815;
816 MOV ds:[BP+DI],DX
817 ADD DI,2
818
819 MOV ParamCt,DI ; set up count of parameters
820 SHR ParamCt,1 ; convert to index (1-based)
821
822 CALL SKIP1 ; skip to next parameter
823 CMP AL,"," ; is there a comma?
824 JZ CHKLP ; if so, then get another arg
825 DEC SI ; point at char next
826 CALL Kill_BL ; skip all blanks
827 CMP AL,"?" ; is there a ?
828 JNZ DISPATCH ; no, got command letter
829 MOV QFLG,-1 ; signal query
830 CALL Kill_BL
831DISPATCH:
832 CMP AL,5FH
833 JBE UPCASE
834 cmp al,"z"
835 ja upcase
836 AND AL,5FH
837UPCASE:
838 MOV DI,OFFSET DG:COMTAB
839 MOV CX,NUMCOM
840 REPNE SCASB
841 JNZ COMERR
842 SUB DI,1+OFFSET DG:COMTAB ; convert to index
843 MOV BX,DI
844 MOV AX,[PARAM2]
845 OR AX,AX
846 JZ PARMOK
847 CMP AX,[PARAM1]
848 JB COMERR ; Param. 2 must be >= param 1
849PARMOK:
850 MOV [COMLINE],SI
851 SHL BX,1
852 CALL [BX+TABLE]
853COMOVER:
854 MOV SI,[COMLINE]
855 CALL Kill_BL
856 CMP AL,0DH
857 JZ COMMANDJ
858 CMP AL,1AH
859 JZ DELIM
860 CMP AL,";"
861 JNZ NODELIM
862DELIM:
863 INC SI
864NODELIM:
865 DEC SI
866 MOV [COMLINE],SI
867 JMP PARSE
868
869COMMANDJ:
870 JMP COMMAND
871
872SKIP1:
873 DEC SI
874 CALL Kill_BL
875ret1: return
876
877Break <Range Checking and argument parsing>
878
879;
880; People call here. we need to reset the stack.
881; Inputs: BX has param1
882; Outputs: Returns if BX <= Param2
883;
884
885CHKRANGE:
886 CMP [PARAM2],0
887 retz
888 CMP BX,[PARAM2]
889 JBE RET1
890 POP DX ; clean up return address
891COMERR:
892 MOV DX,OFFSET DG:BADCOM_ptr
893COMERR1:
894 call std_printf
895 JMP COMMAND
896
897;
898; GetNum parses off 1 argument from the command line. Argument forms are:
899; nnn a number < 65536
900; +nnn current line + number
901; -nnn current line - number
902; . current line
903; # lastline + 1
904;
905;
906
907GETNUM:
908 CALL Kill_BL
909 cmp di,6 ;Is this the fourth parameter?
910 jne sk1
911 mov [fourth],1 ;yes, set the flag
912sk1:
913 CMP AL,"."
914 JZ CURLIN
915 CMP AL,"#"
916 JZ MAXLIN
917 CMP AL,"+"
918 JZ FORLIN
919 CMP AL,"-"
920 JZ BACKLIN
921 MOV DX,0
922 MOV CL,0 ;Flag no parameter seen yet
923NUMLP:
924 CMP AL,"0"
925 JB NUMCHK
926 CMP AL,"9"
927 JA NUMCHK
928 CMP DX,6553 ;Max line/10
929 JAE COMERR ;Ten times this is too big
930 MOV CL,1 ;Parameter digit has been found
931 SUB AL,"0"
932 MOV BX,DX
933 SHL DX,1
934 SHL DX,1
935 ADD DX,BX
936 SHL DX,1
937 CBW
938 ADD DX,AX
939 LODSB
940 JMP SHORT NUMLP
941NUMCHK:
942 CMP CL,0
943 retz
944 OR DX,DX
945 JZ COMERR ;Don't allow zero as a parameter
946 return
947
948CURLIN:
949 cmp [fourth],1 ;the fourth parameter?
950 je comerra ;yes, an error
951 MOV DX,[CURRENT]
952 LODSB
953 return
954MAXLIN:
955 cmp [fourth],1 ;the fourth parameter?
956 je comerra ;yes, an error
957 MOV DX,1
958 MOV AL,0Ah
959 PUSH DI
960 MOV DI,OFFSET DG:START
961 MOV CX,EndTxt
962 SUB CX,DI
963MLoop:
964 JCXZ MDone
965 REPNZ SCASB
966 JNZ MDone
967 INC DX
968 JMP MLoop
969MDone:
970 POP DI
971 LODSB
972 return
973FORLIN:
974 cmp [fourth],1 ;the fourth parameter?
975 je comerra ;yes, an error
976 CALL GETNUM
977 ADD DX,[CURRENT]
978 return
979BACKLIN:
980 cmp [fourth],1 ;the fourth parameter?
981 je comerra ;yes, an error
982 CALL GETNUM
983 MOV BX,[CURRENT]
984 SUB BX,DX
985 JA OkLin ; if negative or zero
986 MOV BX,1 ; use first line
987OkLin:
988 MOV DX,BX
989 return
990
991comerra:
992 jmp comerr
993
994Break <Dispatch Table>
995
996;-----------------------------------------------------------------------;
997; Careful changing the order of the next two tables. They are linked and
998; changes should be be to both.
999
1000COMTAB DB 13,";ACDEILMPQRSTW"
1001NUMCOM EQU $-COMTAB
1002
1003TABLE DW NOCOM ; Blank line
1004 DW NOCOM ; ;
1005 DW APPEND ; A(ppend)
1006 DW COPY ; C(opy)
1007 DW DELETE ; D(elete)
1008 DW ENDED ; E(xit)
1009 DW INSERT ; I(nsert)
1010 DW LIST ; L(ist)
1011 DW MOVE ; M(ove)
1012 DW PAGER ; P(age)
1013 DW QUIT ; Q(uit)
1014 dw replac_from_curr ; R(eplace)
1015 dw search_from_curr ; S(earch)
1016 DW MERGE ; T(merge)
1017 DW EWRITE ; W(rite)
1018
1019ERRORJ:
1020 JMP COMERR
1021ERROR1J:
1022 JMP COMERR1
1023
1024Break <Move and Copy commands>
1025
1026PUBLIC MOVE
1027MOVE:
1028 CMP ParamCt,3
1029 JNZ ERRORJ
1030 MOV BYTE PTR [MOVFLG],1
1031 JMP SHORT BLKMOVE
1032
1033PUBLIC COPY
1034COPY:
1035 CMP ParamCt,3
1036 JB ERRORJ
1037 MOV BYTE PTR [MOVFLG],0
1038;
1039; We are to move/copy a number of lines from one range to another.
1040;
1041; Memory looks like this:
1042;
1043; START: line 1
1044; ...
1045; pointer-> line n Current has n in it
1046; ...
1047; line m
1048; endtxt-> ^Z
1049;
1050; The algoritm is:
1051;
1052; Bounds check on args.
1053; set ptr1 and ptr2 to range before move
1054; set copysiz to number to move
1055; open up copysize * count for destination
1056; if destination is before ptr1 then
1057; add copysize * count to both ptrs
1058; while count > 0 do
1059; move from ptr1 to destination for copysize bytes
1060; count --
1061; if moving then
1062; move from ptr2 through end to ptr1
1063; set endtxt to last byte moved.
1064; set current, pointer to original destination
1065;
1066
1067BLKMOVE:
1068;
1069; Make sure that all correct arguments are specified.
1070;
1071 MOV BX,[PARAM3] ; get destination of move/copy
1072 OR BX,BX ; must be specified (non-0)
1073 MOV DX,OFFSET DG:DEST_ptr
1074 JZ ERROR1J ; is 0 => error
1075;
1076; get arg 1 (defaulting if necessary) and range check it.
1077;
1078 MOV BX,[PARAM1] ; get first argument
1079 OR BX,BX ; do we default it?
1080 JNZ NXTARG ; no, assume it is OK.
1081 MOV BX,[CURRENT] ; Defaults to the current line
1082 CALL CHKRANGE ; Make sure it is good.
1083 MOV [PARAM1],BX ; set it
1084NXTARG:
1085 CALL FINDLIN ; find first argument line
1086 JNZ ErrorJ ; line not found
1087 MOV [PTR_1],DI
1088;
1089; get arg 2 (defaulting if necessary) and range check it.
1090;
1091 MOV BX,[PARAM2] ; Get the second parameter
1092 OR BX,BX ; do we default it too?
1093 JNZ HAVARGS ; Nope.
1094 MOV BX,[CURRENT] ; Defaults to the current line
1095 MOV [PARAM2],BX ; Stash it away
1096HAVARGS:
1097 CALL FindLin
1098 JNZ ErrorJ ; line not found
1099 MOV BX,Param2
1100 INC BX ;Get pointer to line Param2+1
1101 CALL FINDLIN
1102 MOV [PTR_2],DI ;Save it
1103;
1104; We now have true line number arguments and pointers to the relevant places.
1105; ptr_1 points to beginning of region and ptr_2 points to first byte beyond
1106; that region.
1107;
1108; Check args for correct ordering of first two arguments
1109;
1110 mov dx,[param1]
1111 cmp dx,[param2]
1112 jbe havargs1 ; first must be <= second
1113 jmp comerr
1114havargs1:
1115;
1116; make sure that the third argument is not contained in the first range
1117;
1118 MOV DX,[PARAM3]
1119 CMP DX,[PARAM1] ; third must be <= first or
1120 JBE NOERROR
1121 CMP DX,[PARAM2]
1122 JA NoError ; third must be > last
1123 JMP ComErr
1124NOERROR:
1125;
1126; Determine number to move
1127;
1128 MOV CX,Ptr_2
1129 SUB CX,Ptr_1 ; Calculate number of bytes to copy
1130 MOV CopySiz,CX
1131 MOV CopyLen,CX ; Save for individual move.
1132 MOV AX,[PARAM4] ; Was count defaulted?
1133 OR AX,AX
1134 JZ SizeOk ; yes, CX has correct value
1135 MUL [COPYSIZ] ; convert to true size
1136 MOV CX,AX ; move to count register
1137 OR DX,DX ; overflow?
1138 JZ SizeOK ; no
1139 JMP MEMERR ; yes, bomb.
1140SizeOK:
1141 MOV [COPYSIZ],CX
1142;
1143; Check to see that we have room to grow by copysiz
1144;
1145 MOV AX,[ENDTXT] ; get pointer to last byte
1146 MOV DI,[LAST] ; get offset of last location in memory
1147 SUB DI,AX ; remainder of space
1148 CMP DI,CX ; is there at least copysiz room?
1149 JAE HAV_ROOM ; yes
1150 JMP MEMERR
1151HAV_ROOM:
1152;
1153; Find destination of move/copy
1154;
1155 MOV BX,[PARAM3]
1156 CALL FINDLIN
1157 MOV [PTR_3],DI
1158;
1159; open up copysiz bytes of space at destination
1160;
1161; move (p3, p3+copysiz, endtxt-p3);
1162;
1163 MOV SI,EndTxt ; get source pointer to end
1164 MOV CX,SI
1165 SUB CX,DI ; number of bytes from here to end
1166 INC CX ; remember ^Z at end
1167 MOV DI,SI ; destination starts at end
1168 ADD DI,[COPYSIZ] ; plus size we are opening
1169 MOV [ENDTXT],DI ; new end point
1170 STD ; go backwards
1171 REP MOVSB ; and store everything
1172 CLD ; go forward
1173;
1174; relocate ptr_1 and ptr_2 if we moved them
1175;
1176 MOV BX,Ptr_3
1177 CMP BX,Ptr_1 ; was dest before source?
1178 JA NoReloc ; no, above. no relocation
1179 MOV BX,CopySiz
1180 ADD Ptr_1,BX
1181 ADD Ptr_2,BX ; relocate pointers
1182NoReloc:
1183;
1184; Now we copy for count times copylen bytes from ptr_1 to ptr_3
1185;
1186; move (ptr_1, ptr_3, copylen);
1187;
1188 MOV BX,Param4 ; count (0 and 1 are both 1)
1189 MOV DI,Ptr_3 ; destination
1190CopyText:
1191 MOV CX,CopyLen ; number to move
1192 MOV SI,Ptr_1 ; start point
1193 REP MOVSB ; move the bytes
1194 SUB BX,1 ; exhaust count?
1195 JG CopyText ; no, go for more
1196;
1197; If we are moving
1198;
1199 CMP BYTE PTR MovFlg,0
1200 JZ CopyDone
1201;
1202; Delete the source text between ptr_1 and ptr_2
1203;
1204; move (ptr_2, ptr_1, endtxt-ptr_2);
1205;
1206 MOV DI,Ptr_1 ; destination
1207 MOV SI,Ptr_2 ; source
1208 MOV CX,EndTxt ; pointer to end
1209 SUB CX,SI ; number of bytes to move
1210 CLD ; forwards
1211 REP MOVSB
1212 MOV BYTE PTR ES:[DI],1Ah ; remember ^Z terminate
1213 MOV EndTxt,DI ; new end of file
1214;
1215; May need to relocate current line (parameter 3).
1216;
1217 MOV BX,Param3 ; get new current line
1218 CMP BX,Param1 ; do we need to relocate
1219 JBE CopyDone ; no, current line is before removed M002
1220 ADD BX,Param1 ; add in first
1221 SUB BX,Param2 ; current += first-last - 1;
1222 DEC BX
1223 MOV Param3,BX
1224CopyDone:
1225;
1226; we are done. Make current line the destination
1227;
1228 MOV BX,Param3 ; set parameter 3 to be current
1229 CALL FINDLIN
1230 MOV [POINTER],DI
1231 MOV [CURRENT],BX
1232 return
1233
1234Break <MoveFile - open up a hole in the internal file>
1235
1236;
1237; MoveFile moves the text in the buffer to create a hole
1238;
1239; Inputs: DX is spot in buffer for destination
1240; DI is spot in buffer for source
1241MOVEFILE:
1242 MOV CX,[ENDTXT] ;Get End-of-text marker
1243 MOV SI,CX
1244 SUB CX,DI ;Calculate number of bytes to copy
1245 INC CX ; remember ^Z
1246 MOV DI,DX
1247 STD
1248 REP MOVSB ;Copy CX bytes
1249 XCHG SI,DI
1250 CLD
1251 INC DI
1252 MOV BP,SI
1253SETPTS:
1254 MOV [POINTER],DI ;Current line is first free loc
1255 MOV [CURRENT],BX ; in the file
1256 MOV [ENDTXT],BP ;End-of-text is last free loc before
1257 return
1258
1259NAMERR:
1260 cmp ax,error_file_not_found
1261 jne otherMergeErr
1262 MOV DX,OFFSET DG:FILENM_ptr
1263 JMP COMERR1
1264
1265otherMergeErr:
1266 MOV DX,OFFSET DG:BADDRV_ptr
1267 JMP COMERR1
1268
1269PUBLIC MERGE
1270MERGE:
1271 CMP ParamCt,1
1272 JZ MergeOK
1273 JMP Comerr
1274MergeOK:
1275 CALL KILL_BL
1276 DEC SI
1277 MOV DI,OFFSET DG:MRG_PATH_NAME
1278 XOR CX,CX
1279 CLD
1280MRG1:
1281 LODSB
1282 CMP AL," "
1283 JE MRG2
1284 CMP AL,9
1285 JE MRG2
1286 CMP AL,CR
1287 JE MRG2
1288 CMP AL,";"
1289 JE MRG2
1290 STOSB
1291 JMP SHORT MRG1
1292MRG2:
1293 MOV BYTE PTR[DI],0
1294 DEC SI
1295 MOV [COMLINE],SI
1296
1297;=========================================================================
1298; implement EXTENDED OPEN
1299;=========================================================================
1300
1301 push es ;an000;save reg.
1302 mov bx,ext_read ;an000;open for read
1303 mov cx,ATTR ;an000;file attributes
1304 mov dx,OPEN_FLAG ;an000;action to take on open
1305 mov di,0ffffh ;an000;null parm list
1306 call EXT_OPEN3 ;an000;create file;DMS:6/10/87
1307 pop es ;an000;restore reg.
1308
1309;=========================================================================
1310
1311 JC NAMERR
1312
1313 MOV [MRG_HANDLE],AX
1314 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H
1315 MOV DX,OFFSET DG:ABORTMERGE
1316 INT 21H
1317 MOV BX,[PARAM1]
1318 OR BX,BX
1319 JNZ MRG
1320 MOV BX,[CURRENT]
1321 CALL CHKRANGE
1322MRG:
1323 CALL FINDLIN
1324 MOV BX,DX
1325 MOV DX,[LAST]
1326 CALL MOVEFILE
1327 MOV DX,[POINTER]
1328 MOV CX,[ENDTXT]
1329 SUB CX,[POINTER]
1330 PUSH CX
1331 MOV BX,[MRG_HANDLE]
1332 MOV AH,READ
1333 INT 21H
1334 POP DX
1335 MOV CX,AX
1336 CMP DX,CX
1337 JA FILEMRG ; M005
1338 MOV DX,OFFSET DG:MRGERR_ptr
1339 call std_printf
1340 MOV CX,[POINTER]
1341 JMP SHORT RESTORE
1342FILEMRG:
1343 ADD CX,[POINTER]
1344 MOV SI,CX
1345 dec si
1346 LODSB
1347 CMP AL,1AH
1348 JNZ RESTORE
1349 dec cx
1350RESTORE:
1351 MOV DI,CX
1352 MOV SI,[ENDTXT]
1353 INC SI
1354 MOV CX,[LAST]
1355 SUB CX,SI
1356 inc cx ; remember ^Z
1357 REP MOVSB
1358 dec di ; unremember ^Z
1359 MOV [ENDTXT],DI
1360 MOV BX,[MRG_HANDLE]
1361 MOV AH,CLOSE
1362 INT 21H
1363 return
1364
1365PUBLIC INSERT
1366INSERT:
1367 CMP ParamCt,1
1368 JBE OKIns
1369 JMP ComErr
1370OKIns:
1371 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H ;Set vector 23H
1372 MOV DX,OFFSET DG:ABORTINS
1373 INT 21H
1374 MOV BX,[PARAM1]
1375 OR BX,BX
1376 JNZ INS
1377 MOV BX,[CURRENT]
1378 CALL CHKRANGE
1379INS:
1380 CALL FINDLIN
1381 MOV BX,DX
1382 MOV DX,[LAST]
1383 CALL MOVEFILE
1384INLP:
1385 CALL SETPTS ;Update the pointers into file
1386 CALL SHOWNUM
1387 MOV DX,OFFSET DG:EDITBUF
1388 MOV AH,STD_CON_STRING_INPUT
1389 INT 21H
1390 CALL LF
1391 MOV SI,2 + OFFSET DG:EDITBUF
1392 CMP BYTE PTR [SI],1AH
1393 JZ ENDINS
1394;-----------------------------------------------------------------------
1395 call unquote ;scan for quote chars if any
1396;-----------------------------------------------------------------------
1397 MOV CL,[SI-1]
1398 MOV CH,0
1399 MOV DX,DI
1400 INC CX
1401 ADD DX,CX
1402 JC MEMERRJ1
1403 JZ MEMERRJ1
1404 CMP DX,BP
1405 JB MEMOK
1406MEMERRJ1:
1407 CALL END_INS
1408 JMP MEMERR
1409MEMOK:
1410 REP MOVSB
1411 MOV AL,10
1412 STOSB
1413 INC BX
1414 JMP SHORT INLP
1415
1416ABORTMERGE:
1417 MOV DX,OFFSET DG:START
1418 MOV AH,SET_DMA
1419 INT 21H
1420
1421ABORTINS:
1422 MOV AX,CS ;Restore segment registers
1423 MOV DS,AX
1424 MOV ES,AX
1425 MOV AX,CSTACK
1426 MOV SS,AX
1427 MOV SP,STACK
1428 STI
1429 CALL CRLF
1430 CALL ENDINS
1431 JMP COMOVER
1432
1433ENDINS:
1434 CALL END_INS
1435 return
1436
1437END_INS:
1438 MOV BP,[ENDTXT]
1439 MOV DI,[POINTER]
1440 MOV SI,BP
1441 INC SI
1442 MOV CX,[LAST]
1443 SUB CX,BP
1444 REP MOVSB
1445 DEC DI
1446 MOV [ENDTXT],DI
1447 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H
1448 MOV DX,OFFSET DG:ABORTCOM
1449 INT 21H
1450 return
1451
1452
1453FILLBUF:
1454 MOV [PARAM1],-1 ;Read in max. no of lines
1455 MOV ParamCt,1
1456 CALL APPEND
1457 MOV Param1,0
1458PUBLIC ENDED
1459ENDED:
1460
1461;Write text out to .$$$ file
1462
1463 CMP ParamCt,1
1464 JZ ENDED1
1465CERR: JMP ComErr
1466Ended1:
1467 CMP Param1,0
1468 JNZ Cerr
1469 MOV BYTE PTR [ENDING],1 ;Suppress memory errors
1470 MOV BX,-1 ;Write max. no of lines
1471 CALL WRT
1472 TEST BYTE PTR [HAVEOF],-1
1473 JZ FILLBUF
1474 MOV DX,[ENDTXT]
1475 MOV CX,1
1476 MOV BX,[WRT_HANDLE]
1477 MOV AH,WRITE
1478 INT 21H ;Write end-of-file byte
1479
1480;Close input file ; MZ 11/30
1481 ; MZ 11/30
1482 MOV BX,[RD_HANDLE] ; MZ 11/30
1483 MOV AH,CLOSE ; MZ 11/30
1484 INT 21H ; MZ 11/30
1485
1486;Close .$$$ file
1487
1488 MOV BX,[WRT_HANDLE]
1489 MOV AH,CLOSE
1490 INT 21H
1491
1492;Rename original file .BAK
1493
1494 MOV DI,[EXT_PTR]
1495 MOV SI,OFFSET DG:BAK
1496 MOVSW
1497 MOVSW
1498 MOVSB
1499 MOV DX,OFFSET DG:PATH_NAME
1500 MOV DI,OFFSET DG:TEMP_PATH
1501 MOV AH,RENAME
1502 INT 21H
1503 MOV DI,[EXT_PTR]
1504 MOV SI,OFFSET DG:$$$FILE
1505 MOVSW
1506 MOVSW
1507 MOVSB
1508
1509;Rename .$$$ file to original name
1510
1511 MOV DX,OFFSET DG:TEMP_PATH
1512 MOV DI,OFFSET DG:PATH_NAME
1513 MOV AH,RENAME
1514 INT 21H
1515 ; mode
1516 mov ah,exit
1517 xor al,al
1518 int 21h
1519
1520;=========================================================================
1521; EDLIN_DISP_GET: This routine will give us the attributes of the
1522; current display, which are to be used to restore the screen
1523; back to its original state on exit from EDLIN. We also
1524; set the screen to a text mode here with an 80 X 25 color
1525; format.
1526;
1527; Inputs : VIDEO_GET - 0fH (get current video mode)
1528; VIDEO_SET - 00h (set video mode)
1529; VIDEO_TEXT- 03h (80 X 25 color mode)
1530;
1531; Outputs : VIDEO_ORG - Original video attributes on entry to EDLIN
1532;
1533;=========================================================================
1534
1535EDLIN_DISP_GET proc near ;an000;video attributes
1536
1537 push ax ;an000;save affected regs.
1538 push bx ;an000;
1539 push cx ;an000;
1540 push dx ;an000;
1541 push si ;an000;
1542 push ds ;an000;
1543
1544 push cs ;an000;exchange cs/ds
1545 pop ds ;an000;
1546
1547 mov ax,440Ch ;an000;generic ioctl
1548 mov bx,Std_Out ;an000;Console
1549 mov cx,(Display_Attr shl 8) or Get_Display ;an000;get display
1550 mov dx,offset dg:Video_Buffer ;an000;buffer for video attr.
1551 int 21h ;an000;
1552; $if nc ;an000;function returned a
1553 JC $$IF17
1554 ; buffer
1555 mov si,dx ;an000;get pointer
1556 mov ax,word ptr dg:[si].Display_Length_Char ;an000;get video len.
1557 dec ax ;an000;allow room for message
1558 mov dg:Disp_Len,al ;an000;put it into var.
1559 mov ax,word ptr dg:[si].Display_Width_Char ;an000;get video width
1560 mov dg:Disp_Width,al ;an000;put it into var.
1561; $else ;an000;function failed use
1562 JMP SHORT $$EN17
1563$$IF17:
1564 ; default values
1565 mov al,Def_Disp_Len ;an000;get default length
1566 dec al ;an000;leave room for messages
1567 mov dg:Disp_Len,al ;an000;use default length
1568 mov dg:Disp_Width,Def_Disp_Width;an000;use default width
1569; $endif ;an000;
1570$$EN17:
1571
1572 pop ds ;an000;restore affected regs.
1573 pop si ;an000;
1574 pop dx ;an000;
1575 pop cx ;an000;
1576 pop bx ;an000;
1577 pop ax ;an000;
1578
1579 ret ;an000;return to caller
1580
1581EDLIN_DISP_GET endp ;an000;end proc.
1582
1583
1584;=========================================================================
1585; EXT_OPEN1 : This routine opens a file for read/write access. If the file
1586; if not present for opening the open will fail and return with a
1587; carry set.
1588;
1589; Inputs : BX - Open mode
1590; CX - File attributes
1591; DX - Open action
1592;
1593; Outputs: CY - If error
1594;
1595; Date : 6/10/87
1596;=========================================================================
1597
1598EXT_OPEN1 proc near ;an000;open for R/W
1599
1600 assume ds:dg
1601 push ds ;an000;save regs
1602 push si ;an000;
1603
1604 mov ah,ExtOpen ;an000;extended open
1605 mov al,0 ;an000;reserved by system
1606 mov si,offset dg:path_name ;an000;point to PATH_NAME
1607
1608 int 21h ;an000;invoke function
1609 pop si ;an000;restore regs
1610 pop ds ;an000;
1611
1612 ret ;an000;return to caller
1613
1614EXT_OPEN1 endp ;an000;end proc.
1615
1616;=========================================================================
1617; EXT_OPEN2 : This routine will attempt to create a file for read/write
1618; access. If the files exists the create will fail and return
1619; with the carry set.
1620;
1621; Inputs : BX - Open mode
1622; CX - File attributes
1623; DX - Open action
1624;
1625; Outputs: CY - If error
1626;
1627; Date : 6/10/87
1628;=========================================================================
1629
1630EXT_OPEN2 proc near ;an000;create a file
1631
1632 assume ds:dg
1633 push ds ;an000;save regs
1634 push si ;an000;
1635
1636 mov ah,ExtOpen ;an000;extended open
1637 mov al,0 ;an000;reserved by system
1638 mov si,offset dg:temp_path ;an000;point to TEMP_PATH
1639
1640 int 21h ;an000;invoke function
1641
1642 pop si ;an000;restore regs
1643 pop ds ;an000;
1644
1645 ret ;an000;return to caller
1646
1647EXT_OPEN2 endp ;an000;end proc.
1648
1649;=========================================================================
1650; EXT_OPEN3 : This routine will attempt to create a file for read
1651; access. If the files exists the create will fail and return
1652; with the carry set.
1653;
1654; Inputs : BX - Open mode
1655; CX - File attributes
1656; DX - Open action
1657;
1658; Outputs: CY - If error
1659;
1660; Date : 6/10/87
1661;=========================================================================
1662
1663EXT_OPEN3 proc near ;an000;create a file
1664
1665 assume ds:dg
1666 push ds ;an000;save regs
1667 push si ;an000;
1668
1669 mov ah,ExtOpen ;an000;extended open
1670 mov al,0 ;an000;reserved by system
1671 mov si,offset dg:mrg_path_name ;an000;point to mrg_path_name
1672
1673 int 21h ;an000;invoke function
1674
1675 pop si ;an000;restore regs
1676 pop ds ;an000;
1677
1678 ret ;an000;return to caller
1679
1680EXT_OPEN3 endp ;an000;end proc.
1681
1682
1683;=========================================================================
1684; EDLIN_COMMAND : This routine provides an interface between the new
1685; parser and the existing logic of EDLIN. We will be
1686; interfacing the parser with three existing variables.
1687;
1688; Inputs : FILESPEC - Filespec entered by the user and passed by
1689; the parser.
1690;
1691; PARSE_SWITCH_B - Contains the result of the parse for the
1692; /B switch. This is passed by the parser.
1693;
1694; Outputs: PATH_NAME - Filespec
1695; LOADMOD - Flag for /B switch
1696; FNAME_LEN - Length of filespec
1697;
1698; Date : 6/11/87
1699;=========================================================================
1700
1701EDLIN_COMMAND proc near ;an000;interface parser
1702
1703 push ax ;an000;save regs.
1704 push cx ;an000;
1705 push di ;an000
1706 push si ;an000;
1707
1708 mov si,offset dg:filespec ;an000;get its offset
1709 mov di,offset dg:path_name ;an000;get its offset
1710
1711 mov cx,00h ;an000;cx will count filespec
1712 ; length
1713 cmp parse_switch_b,true ;an000;do we have /B switch
1714; $if z ;an000;we have the switch
1715 JNZ $$IF20
1716 mov [LOADMOD],01h ;an000;signal switch found
1717; $endif ;an000
1718$$IF20:
1719
1720; $do ;an000;while we have filespec
1721$$DO22:
1722 lodsb ;an000;move byte to al
1723 cmp al,nul ;an000;see if we are at
1724 ; the end of the
1725 ; filespec
1726; $leave e ;an000;exit while loop
1727 JE $$EN22
1728 stosb ;an000;move byte to path_name
1729 inc cx ;an000;increment the length
1730 ; of the filespec
1731; $enddo ;an000;end do while
1732 JMP SHORT $$DO22
1733$$EN22:
1734
1735 mov [FNAME_LEN],cx ;an000;save filespec's length
1736
1737 pop si ;an000; restore regs
1738 pop di ;an000;
1739 pop cx ;an000;
1740 pop ax ;an000;
1741
1742 ret ;an000;return to caller
1743
1744EDLIN_COMMAND endp ;an000;end proc
1745
1746;=========================================================================
1747; Get_Extended_Attrib : This routine gets the extended attributes of
1748; the file that was opened.
1749;
1750;=========================================================================
1751
1752Get_Extended_Attrib proc near ;an000; dms;
1753
1754 mov ax,5702h ;an000; dms;get extended attrib
1755 mov si,0ffffh ;an000; dms;all attribs
1756 mov cx,dg:EA_Buffer_Size ;an000; dms;buffer size
1757 mov di,offset dg:Start ;an000; dms;point to buffer
1758 int 21h ;an000; dms;
1759 ret ;an000; dms;
1760
1761Get_Extended_Attrib endp ;an000; dms;
1762
1763
1764;=========================================================================
1765; Query_Extend_Attrib : This routine gets the extended attributes of
1766; the file that was opened.
1767;
1768; Inputs : Start - Buffer for extended attributes
1769;
1770; Outputs : CX - size in paras
1771;
1772;=========================================================================
1773
1774Query_Extend_Attrib proc near ;an000; dms;
1775
1776 mov ax,5702h ;an000; dms;get extended attrib
1777 mov si,0ffffh ;an000; dms;all attribs
1778 mov cx,0000h ;an000; dms;get buffer size
1779 mov di,offset dg:Start ;an000; dms;point to buffer
1780 int 21h ;an000; dms;
1781 mov dg:EA_Buffer_Size,cx ;an000; dms;save buffer size
1782 ret ;an000; dms;
1783
1784Query_Extend_Attrib endp ;an000; dms;
1785
1786
1787;=========================================================================
1788; Calc_Memory_Avail : This routine will calculate the memory
1789; available for use by EDLIN.
1790;
1791; Inputs : ORG_DS - DS of PSP
1792;
1793; Outputs : DX - paras available
1794;=========================================================================
1795
1796Calc_Memory_Avail proc near ;an000; dms;
1797
1798 push ds ;save ds for size calc
1799 push cx ;an000; dms;
1800 push di ;an000; dms;
1801
1802 mov ds,cs:[org_ds]
1803 MOV CX,DS:[2]
1804 MOV DI,CS
1805 SUB CX,DI
1806 mov dx,cx ;an000; dms;put paras in DX
1807
1808 pop di ;an000; dms;
1809 pop cx ;an000; dms;
1810 pop ds ;an000; dms;
1811
1812 ret ;an000; dms;
1813
1814Calc_Memory_Avail endp ;an000; dms;
1815
1816;=========================================================================
1817; EA_Fail_Exit : This routine tells the user that there was
1818; Insufficient memory and exits EDLIN.
1819;
1820; Inputs : MemFul_Ptr - "Insufficient memory"
1821;
1822; Outputs : message
1823;=========================================================================
1824
1825EA_Fail_Exit proc near ;an000; dms;
1826
1827 mov dx,offset dg:MemFul_Ptr ;an000; dms;"Insufficient
1828
1829 push cs ;an000; dms;xchange ds/cs
1830 pop ds ;an000; dms;
1831 ; memory"
1832 call Std_Printf ;an000; dms;print message
1833 mov ah,exit ;an000; dms;exit
1834 xor al,al ;an000; dms;clear al
1835 int 21h ;an000; dms;
1836 ret ;an000; dms;
1837
1838EA_Fail_Exit endp ;an000; dms;
1839
1840CODE ENDS
1841 END EDLIN
1842
1843 \ No newline at end of file