From 80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6 Mon Sep 17 00:00:00 2001 From: Rich Turner Date: Fri, 12 Aug 1983 17:53:34 -0700 Subject: MS-DOS v2.0 Release --- v2.0/source/EDLIN.ASM | 1846 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1846 insertions(+) create mode 100644 v2.0/source/EDLIN.ASM (limited to 'v2.0/source/EDLIN.ASM') 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 @@ + title EDLIN for MSDOS 2.0 + +;-----------------------------------------------------------------------; +; REVISION HISTORY: ; +; ; +; V1.02 ; +; ; +; V2.00 9/13/82 M.A. Ulloa ; +; Modified to use Pathnames in command line file ; +; specification, modified REPLACE to use an empty ; +; string intead of the old replace string when this ; +; is missing, and search and replace now start from ; +; first line of buffer (like old version of EDLIN) ; +; instead than current+1 line. Also added the U and ; +; V commands that search (replace) starting from the ; +; current+1 line. ; +; ; +; 9/15/82 M.A. Ulloa ; +; Added the quote character (^V). ; +; ; +; 9/16/82 M.A. Ulloa ; +; Corrected bug about use of quote char when going ; +; into default insert mode. Also corrected the problem ; +; with ^Z being the end of file marker. End of file is ; +; reached when an attempt to read returns less chars ; +; than requested. ; +; ; +; 9/17/82 M.A. Ulloa ; +; Corrected bug about boundaries for Copy ; +; ; +; 10/4/82 Rev. 1 M.A. Ulloa ; +; The IBM version now does NOT have the U and V ; +; commands. The MSDOS version HAS the U and V commands. ; +; Added the B switch, and modified the effect of ; +; the quote char. ; +; ; +; 10/7/82 Rev. 2 M.A. Ulloa ; +; Changed the S and R commands to start from the ; +; current line+1 (as U and V did). Took away U and V in ; +; all versions. ; +; ; +; 10/13/82 Rev. 3 M.A. Ulloa ; +; Now if parameter1 < 1 then parameter1 = 1 ; +; ; +; 10/15/82 Rev. 4 M.A. Ulloa ; +; Param4 if specified must be an absolute number that ; +; reprecents the count. ; +; ; +; 10/18/82 Rev. 5 M.A. Ulloa ; +; Fixed problem with trying to edit files with the ; +; same name as directories. Also, if the end of file is ; +; reached it checks that a LF is the last character, ; +; otherwise it inserts a CRLF pair at the end. ; +; ; +; 10/20/82 Rev. 6 M.A.Ulloa ; +; Changed the text of some error messages for IBM and ; +; rewrite PAGE. ; +; ; +; 10/25/82 Rev. 7 M.A.Ulloa ; +; Made all messages as in the IBM vers. ; +; ; +; 10/28/82 Rev. 8 M.A.Ulloa ; +; Corrected problem with parsing for options. ; +; ; +; Rev. 9 Aaron Reynolds ; +; Made error messages external. ; +; ; +; 12/08/82 Rev. 10 M.A. Ulloa ; +; Corrected problem arising with having to restore ; +; the old directory in case of a file name error. ; +; ; +; 12/17/82 Rev. 11 M.A. Ulloa ; +; Added the ROPROT equate for R/O file protection. ; +; It causes only certain operations (L,P,S,W,A, and Q) ; +; to be allowed on read only files. ; +; ; +; 12/29/82 Rev. 12 M.A. Ulloa : +; Added the creation error message. ; +; ; +; 4/14/83 Rev. 13 N.Panners ; +; Fixed bug in Merge which lost char if not ^Z. ; +; Fixed bug in Copy to correctly check ; +; for full buffers. ; +; ; +; ; +; 7/23/83 Rev. 14 N.Panners ; +; Split EDLIN into two seperate modules to ; +; allow assembly of sources on an IBM PC ; +; EDLIN and EDLPROC ; +; ; +;-----------------------------------------------------------------------; + + +FALSE EQU 0 +TRUE EQU NOT FALSE + +KANJI EQU FALSE + +roprot equ true ;set to TRUE if protection to r/o files + ; desired. +FCB EQU 5CH + +Comand_Line_Length equ 128 +quote_char equ 16h ;quote character = ^V + + +PAGE + + .xlist + INCLUDE DOSSYM.ASM + .list + + +SUBTTL Contants and Data areas +PAGE + +PROMPT EQU "*" +STKSIZ EQU 80H + +CODE SEGMENT PUBLIC +CODE ENDS + +CONST SEGMENT PUBLIC WORD +CONST ENDS + +DATA SEGMENT PUBLIC WORD +DATA ENDS + +DG GROUP CODE,CONST,DATA + +CONST SEGMENT PUBLIC WORD + + EXTRN BADDRV:BYTE,NDNAME:BYTE,bad_vers_err:BYTE,opt_err:BYTE + EXTRN NOBAK:BYTE,BADCOM:BYTE,NEWFIL:BYTE,DEST:BYTE,MRGERR:BYTE + EXTRN NODIR:BYTE,DSKFUL:BYTE,MEMFUL:BYTE,FILENM:BYTE + EXTRN NOSUCH:BYTE,TOOLNG:BYTE,EOF:BYTE,ro_err:byte,bcreat:byte + + PUBLIC TXT1,TXT2,FUDGE,USERDIR,HARDCH + +BAK DB "BAK" + +make db "***MAUlloa/Microsoft/V20***" +rev db "14" + + if roprot ;***** R/O ***** +roflag db 0 ; =1 if file is r/o + endif + +fourth db 0 ;fourth parameter flag + +loadmod db 0 ;Load mode flag, 0 = ^Z marks the + ; end of a file, 1 = viceversa. +hardch dd ? + +the_root db 0 ;root directory flag + +fudge db 0 ;directory changed flag +user_drive db 0 + + +optchar db "-" + +dirchar db "/",0 + +userdir db "/",0 + db (dirstrlen) dup(0) + +fname_buffer db Comand_Line_Length dup(0) +;-----------------------------------------------------------------------; + +TXT1 DB 0,80H DUP (?) +TXT2 DB 0,80H DUP (?) +DELFLG DB 0 + +CONST ENDS + +DATA SEGMENT PUBLIC WORD + + PUBLIC QFLG,FCB2,OLDLEN,PARAM1,PARAM2,OLDDAT,SRCHFLG + PUBLIC COMLINE,NEWLEN,SRCHMOD,CURRENT,LSTFND,NUMPOS + PUBLIC LSTNUM,SRCHCNT,POINTER,START,ENDTXT,USER_DRIVE + +;-----------------------------------------------------------------------; +; Be carefull when adding parameters, they have to follow the +; order in which they apperar here. (this is a table, ergo it +; is indexed thru a pointer, and random additions will cause the +; wrong item to be accessed). Also param4 is known to be the +; count parameter, and known to be the fourth entry in the table +; so it receives special treatment. (See GETNUM) + +PARAM1 DW 1 DUP (?) +PARAM2 DW 1 DUP (?) +PARAM3 DW 1 DUP (?) +PARAM4 DW 1 DUP (?) + +;-----------------------------------------------------------------------; + +PTR_1 DW 1 DUP (?) +PTR_2 DW 1 DUP (?) +PTR_3 DW 1 DUP (?) +COPYSIZ DW 1 DUP (?) +OLDLEN DW 1 DUP (?) +NEWLEN DW 1 DUP (?) +LSTFND DW 1 DUP (?) +LSTNUM DW 1 DUP (?) +NUMPOS DW 1 DUP (?) +SRCHCNT DW 1 DUP (?) +CURRENT DW 1 DUP (?) +POINTER DW 1 DUP (?) +ONE4TH DW 1 DUP (?) +THREE4TH DW 1 DUP (?) +LAST DW 1 DUP (?) +ENDTXT DW 1 DUP (?) +COMLINE DW 1 DUP (?) +LASTLIN DW 1 DUP (?) +COMBUF DB 82H DUP (?) +EDITBUF DB 258 DUP (?) +EOL DB 1 DUP (?) +FCB2 DB 37 DUP (?) +FCB3 DB 37 DUP (?) +fake_fcb db 37 dup (?) ;fake for size figuring +QFLG DB 1 DUP (?) +HAVEOF DB 1 DUP (?) +ENDING DB 1 DUP (?) +SRCHFLG DB 1 DUP (?) +amnt_req dw 1 dup (?) ;ammount of bytes requested to read +olddat db 1 dup (?) ;Used in replace and search, + ; replace by old data flag (1=yes) +srchmod db 1 dup (?) ;Search mode: 1=from current+1 to + ; end of buffer, 0=from beg. of + ; buffer to the end (old way). +MOVFLG DB 1 DUP (?) + DB STKSIZ DUP (?) + +STACK LABEL BYTE +START LABEL WORD + +DATA ENDS + +SUBTTL Main Body +PAGE + +CODE SEGMENT PUBLIC + +ASSUME CS:DG,DS:DG,SS:DG,ES:DG + + EXTRN QUIT:NEAR,QUERY:NEAR,FNDFIRST:NEAR,FNDNEXT:NEAR + EXTRN UNQUOTE:NEAR,LF:NEAR,CRLF:NEAR,OUT:NEAR + EXTRN REST_DIR:NEAR,KILL_BL:NEAR,INT_24:NEAR + EXTRN FINDLIN:NEAR,SHOWNUM:NEAR,SCANLN:NEAR + + if Kanji + EXTRN TESTKANJ:NEAR + endif + + PUBLIC CHKRANGE + + ORG 100H + +EDLIN: + JMP SIMPED + +edl_pad db 0e00h dup (?) + +HEADER DB "Vers 2.14" + +NONAME: + MOV DX,OFFSET DG:NDNAME +ERRJ: JMP xERROR + +SIMPED: + MOV BYTE PTR [ENDING],0 + MOV SP,OFFSET DG:STACK + +;Code to print header +; PUSH AX +; MOV DX,OFFSET DG:HEADER +; MOV AH,STD_CON_STRING_OUTPUT +; INT 21H +; POP AX + +;----- Check Version Number --------------------------------------------; + push ax + mov ah,Get_Version + int 21h + cmp al,2 + jae vers_ok ; version >= 2, enter editor + mov dx,offset dg:bad_vers_err + jmp short errj +;-----------------------------------------------------------------------; + +vers_ok: + +;----- Process Pathnames -----------------------------------------------; + + mov ax,(char_oper shl 8) ;get switch character + int 21h + cmp dl,"/" + jnz slashok ;if not / , then not PC + mov [dirchar],"\" ;in PC, dir separator = \ + mov [userdir],"\" + mov [optchar],"/" ;in PC, option char = / + +slashok: + mov si,81h ;point to cammand line + + call kill_bl + cmp al,13 ;A carriage return? + je noname ;yes, file name missing + + mov di,offset dg:fname_buffer + xor cx,cx ;zero pathname length + +next_char: + stosb ;put patname in buffer + inc cx + lodsb + cmp al,' ' + je xx1 + cmp al,13 ; a CR ? + je name_copied + cmp al,[optchar] ; an option character? + je an_option + jmp short next_char + +xx1: + dec si + call kill_bl + cmp al,[optchar] + jne name_copied + +an_option: + lodsb ;get the option + cmp al,'B' + je b_opt + cmp al,'b' + je b_opt + mov dx,offset dg:opt_err ;bad option specified + jmp xerror + +b_opt: + mov [loadmod],1 + +name_copied: + mov byte ptr dg:[di],0 ;nul terminate the pathname + + if roprot ;***** R/O ***** +;----- Check that file is not R/O --------------------------------------; + push cx ;save character count + mov dx,offset dg:fname_buffer + mov al,0 ;get attributes + mov ah,chmod + int 21h + jc attr_are_ok + and cl,00000001b ;mask all but: r/o + jz attr_are_ok ;if all = 0 then file ok to edit, + mov dg:[roflag],01h ;otherwise: Error (GONG!!!) +attr_are_ok: + pop cx ;restore character count + endif + +;----- Scan for directory ----------------------------------------------; + dec di ;adjust to the end of the pathname + + IF KANJI + mov dx,offset dg: fname_buffer + PUSH DX + PUSH DI + MOV BX,DI + MOV DI,DX +DELLOOP: + CMP DI,BX + Jae GOTDELE + MOV AL,[DI] + INC DI + CALL TESTKANJ + JZ NOTKANJ11 + INC DI + JMP DELLOOP + +NOTKANJ11: + cmp al,dg:[dirchar] + JNZ DELLOOP + MOV DX,DI ;Point to char after '/' + DEC DX + DEC DX ;Point to char before '/' + JMP DELLOOP + +GOTDELE: + MOV DI,DX + POP AX ;Initial DI + POP DX + SUB AX,DI ;Distance moved + SUB CX,AX ;Set correct CX + CMP DX,DI + JB sj1 ;Found a pathsep + JA sj2 ;Started with a pathsep, root + MOV AX,[DI] + CALL TESTKANJ + JNZ same_dirj + XCHG AH,AL + cmp al,dg:[dirchar] + jz sj1 ;One character directory +same_dirj: + ELSE + mov al,dg:[dirchar] ;get directory separator character + std ;scan backwards + repnz scasb ;(cx has the pathname length) + cld ;reset direction, just in case + jz sj1 + ENDIF + + jmp same_dir ;no dir separator char. found, the + ; file is in the current directory + ; of the corresponding drive. Ergo, + ; the FCB contains the data already. + +sj1: + jcxz sj2 ;no more chars left, it refers to root + cmp byte ptr [di],':' ;is the prvious character a disk def? + jne not_root +sj2: + mov dg:[the_root],01h ;file is in the root +not_root: + inc di ;point to dir separator char. + mov al,0 + stosb ;nul terminate directory name + pop ax + push di ;save pointer to file name + mov dg:[fudge],01h ;remember that the current directory + ; has been changed. + +;----- Save current directory for exit ---------------------------------; + mov ah,get_default_drive ;save current drive + int 21h + mov dg:[user_drive],al + + mov dl,byte ptr ds:[fcb] ;get specified drive if any + or dl,dl ;default disk? + jz same_drive + dec dl ;adjust to real drive (a=0,b=1,...) + mov ah,set_default_drive ;change disks + int 21h + cmp al,-1 ;error? + jne same_drive + mov dx,offset dg:baddrv + jmp xerror + +same_drive: + mov ah,get_default_dpb + int 21h + +assume ds:nothing + + cmp al,-1 ;bad drive? (should always be ok) + jne drvisok + mov dx,offset dg:baddrv + jmp xerror + +drvisok: + cmp [bx.dpb_current_dir],0 + je curr_is_root + mov si,bx + add si,dpb_dir_text + mov di,offset dg:userdir + 1 + +dir_save_loop: + lodsb + stosb + or al,al + jnz dir_save_loop + +curr_is_root: + push cs + pop ds + +assume ds:dg + + +;----- Change directories ----------------------------------------------; + cmp [the_root],01h + mov dx,offset dg:[dirchar] ;assume the root + je sj3 + mov dx,offset dg:[fname_buffer] +sj3: + mov ah,chdir ;change directory + int 21h + mov dx,offset dg:baddrv + jnc no_errors + jmp xerror +no_errors: + +;----- Set Up int 24 intercept -----------------------------------------; + + mov ax,(get_interrupt_vector shl 8) or 24h + int 21h + mov word ptr [hardch],bx + mov word ptr [hardch+2],es + mov ax,(set_interrupt_vector shl 8) or 24h + mov dx,offset dg:int_24 + int 21h + push cs + pop es + +;----- Parse filename to FCB -------------------------------------------; + pop si + mov di,fcb + mov ax,(parse_file_descriptor shl 8) or 1 + int 21h + push ax + +;-----------------------------------------------------------------------; + +same_dir: + pop ax + OR AL,AL + MOV DX,OFFSET DG:BADDRV + jz sj4 + jmp xerror +sj4: + CMP BYTE PTR DS:[FCB+1]," " + jnz sj5 + jmp noname +sj5: + MOV SI,OFFSET DG:BAK + MOV DI,FCB+9 + MOV CX,3 + ;File must not have .BAK extension + REPE CMPSB + JZ NOTBAK + ;Open input file + MOV AH,FCB_OPEN + MOV DX,FCB + INT 21H + MOV [HAVEOF],AL + OR AL,AL + JZ HAVFIL + +;----- Check that file is not a directory ------------ + mov ah,fcb_create + mov dx,fcb + int 21h + or al,al + jz sj50 ;no error found + mov dx,offset dg:bcreat ;creation error + jmp xerror +sj50: + mov ah,fcb_close ;no error, close the file + mov dx,fcb + int 21h + mov ah,fcb_delete ;delete the file + mov dx,fcb + int 21h + +;----------------------------------------------------- + + MOV DX,OFFSET DG:NEWFIL + MOV AH,STD_CON_STRING_OUTPUT + INT 21H +HAVFIL: + MOV SI,FCB + MOV DI,OFFSET DG:FCB2 + MOV CX,9 + REP MOVSB + MOV AL,"$" + STOSB + STOSB + STOSB +MAKFIL: + ;Create .$$$ file to make sure directory has room + MOV DX,OFFSET DG:FCB2 + MOV AH,FCB_CREATE + INT 21H + OR AL,AL + JZ SETUP + CMP BYTE PTR [DELFLG],0 + JNZ NOROOM + CALL DELBAK + JMP MAKFIL +NOROOM: + MOV DX,OFFSET DG:NODIR + JMP xERROR +NOTBAK: + MOV DX,OFFSET DG:NOBAK + JMP xERROR +SETUP: + XOR AX,AX + MOV WORD PTR DS:[FCB+fcb_RR],AX ;Set RR field to zero + MOV WORD PTR DS:[FCB+fcb_RR+2],AX + MOV WORD PTR [FCB2+fcb_RR],AX + MOV WORD PTR [FCB2+fcb_RR+2],AX + INC AX + MOV WORD PTR DS:[FCB+fcb_RECSIZ],AX ;Set record length to 1 + MOV WORD PTR [FCB2+fcb_RECSIZ],AX + MOV DX,OFFSET DG:START + MOV DI,DX + MOV AH,SET_DMA + INT 21H + MOV CX,DS:[6] + DEC CX + MOV [LAST],CX + TEST BYTE PTR [HAVEOF],-1 + JNZ SAVEND + SUB CX,OFFSET DG:START ;Available memory + SHR CX,1 ;1/2 of available memory + MOV AX,CX + SHR CX,1 ;1/4 of available memory + MOV [ONE4TH],CX ;Save amount of 1/4 full + ADD CX,AX ;3/4 of available memory + MOV DX,CX + ADD DX,OFFSET DG:START + MOV [THREE4TH],DX ;Save pointer to 3/4 full + ;Read in input file + MOV DX,FCB + MOV AH,FCB_RANDOM_READ_BLOCK + mov [amnt_req],cx ;save ammount of chars requested + INT 21H + CALL SCANEOF + ADD DI,CX ;Point to last byte +SAVEND: + CLD + MOV BYTE PTR [DI],1AH + MOV [ENDTXT],DI + MOV BYTE PTR [COMBUF],128 + MOV BYTE PTR [EDITBUF],255 + MOV BYTE PTR [EOL],10 + MOV [POINTER],OFFSET DG:START + MOV [CURRENT],1 + MOV [PARAM1],1 + TEST BYTE PTR [HAVEOF],-1 + JNZ COMMAND + CALL APPEND + +COMMAND: + MOV SP, OFFSET DG:STACK + MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H + MOV DX,OFFSET DG:ABORTCOM + INT 21H + MOV AL,PROMPT + CALL OUT + MOV DX,OFFSET DG:COMBUF + MOV AH,STD_CON_STRING_INPUT + INT 21H + MOV [COMLINE],OFFSET DG:COMBUF + 2 + MOV AL,10 + CALL OUT +PARSE: + MOV [PARAM2],0 + MOV [PARAM3],0 + MOV [PARAM4],0 + mov [fourth],0 ;reset the fourth parameter flag + MOV BYTE PTR [QFLG],0 + MOV SI,[COMLINE] + MOV BP,OFFSET DG:PARAM1 + XOR DI,DI +CHKLP: + CALL GETNUM + MOV [BP+DI],DX + INC DI + INC DI + CALL SKIP1 + CMP AL,"," + JNZ CHKNXT + INC SI +CHKNXT: + DEC SI + CMP DI,8 + JB CHKLP + CALL SKIP + CMP AL,"?" + JNZ DISPATCH + MOV [QFLG],AL + CALL SKIP +DISPATCH: + CMP AL,5FH + JBE UPCASE + AND AL,5FH +UPCASE: + MOV DI,OFFSET DG:COMTAB + MOV CX,NUMCOM + REPNE SCASB + JNZ COMERR + MOV BX,CX + MOV AX,[PARAM2] + OR AX,AX + JZ PARMOK + CMP AX,[PARAM1] + JB COMERR ;Param. 2 must be >= param 1 +PARMOK: + MOV [COMLINE],SI + + if roprot ;***** R/O ***** + cmp [roflag],01 ;file r/o? + jne paramok2 + cmp byte ptr [bx+rotable],01 ;operation allowed? + je paramok2 + mov dx,offset dg:ro_err ;error + jmp short comerr1 +paramok2: + endif + + SHL BX,1 + CALL [BX+TABLE] +COMOVER: + MOV SI,[COMLINE] + CALL SKIP + CMP AL,0DH + JZ COMMANDJ + CMP AL,1AH + JZ DELIM + CMP AL,";" + JNZ NODELIM +DELIM: + INC SI +NODELIM: + DEC SI + MOV [COMLINE],SI + JMP PARSE + +COMMANDJ: + JMP COMMAND + +SKIP: + LODSB +SKIP1: + CMP AL," " + JZ SKIP +RET1: RET + +CHKRANGE: + CMP [PARAM2],0 + JZ RET1 + CMP BX,[PARAM2] + JBE RET1 +COMERR: + MOV DX,OFFSET DG:BADCOM +COMERR1: + MOV AH,STD_CON_STRING_OUTPUT + INT 21H + JMP COMMAND + + +GETNUM: + CALL SKIP + cmp di,6 ;Is this the fourth parameter? + jne sk1 + mov [fourth],1 ;yes, set the flag +sk1: + CMP AL,"." + JZ CURLIN + CMP AL,"#" + JZ MAXLIN + CMP AL,"+" + JZ FORLIN + CMP AL,"-" + JZ BACKLIN + MOV DX,0 + MOV CL,0 ;Flag no parameter seen yet +NUMLP: + CMP AL,"0" + JB NUMCHK + CMP AL,"9" + JA NUMCHK + CMP DX,6553 ;Max line/10 + JAE COMERR ;Ten times this is too big + MOV CL,1 ;Parameter digit has been found + SUB AL,"0" + MOV BX,DX + SHL DX,1 + SHL DX,1 + ADD DX,BX + SHL DX,1 + CBW + ADD DX,AX + LODSB + JMP SHORT NUMLP +NUMCHK: + CMP CL,0 + JZ RET1 + OR DX,DX + JZ COMERR ;Don't allow zero as a parameter + RET + +CURLIN: + cmp [fourth],1 ;the fourth parameter? + je comerra ;yes, an error + MOV DX,[CURRENT] + LODSB + RET +MAXLIN: + cmp [fourth],1 ;the fourth parameter? + je comerra ;yes, an error + MOV DX,-2 + LODSB + RET +FORLIN: + cmp [fourth],1 ;the fourth parameter? + je comerra ;yes, an error + CALL GETNUM + ADD DX,[CURRENT] + RET +BACKLIN: + cmp [fourth],1 ;the fourth parameter? + je comerra ;yes, an error + CALL GETNUM + MOV BX,[CURRENT] + SUB BX,DX + jns sk2 ;if below beg of buffer then default to the + mov bx,1 ; beg of buffer (line1) +sk2: + MOV DX,BX + RET + +comerra: + jmp comerr + + +COMTAB DB "QTCMWASRDLPIE;",13 + +NUMCOM EQU $-COMTAB + +;-----------------------------------------------------------------------; +; Carefull changing the order of the next two tables. They are +; linked and chnges should be be to both. + +TABLE DW NOCOM ;No command--edit line + DW NOCOM + DW ENDED + DW INSERT + DW PAGE + DW LIST + DW DELETE + dw replac_from_curr ;replace from current+1 line + dw search_from_curr ;search from current+1 line + DW APPEND + DW EWRITE + DW MOVE + DW COPY + DW MERGE + + if roprot ;***** R/O ***** + DW QUIT1 + else + DW QUIT + endif + + if roprot ;***** R/O ***** +;-----------------------------------------------------------------------; +; If = 1 then the command can be executed with a file that +; is r/o. If = 0 the command can not be executed, and error. + +ROTABLE db 0 ;NOCOM + db 0 ;NOCOM + db 0 ;ENDED + db 0 ;INSERT + db 1 ;PAGE + db 1 ;LIST + db 0 ;DELETE + db 0 ;replac_from_curr + db 1 ;search_from_curr + db 1 ;APPEND + db 1 ;EWRITE + db 0 ;MOVE + db 0 ;COPY + db 0 ;MERGE + db 1 ;QUIT + +;-----------------------------------------------------------------------; + endif + + if roprot ;***** R/O ***** +quit1: + cmp [roflag],01 ;are we in r/o mode? + jne q3 ;no query.... + MOV DX,OFFSET DG:FCB2 ;yes, quit without query. + MOV AH,FCB_CLOSE + INT 21H + MOV AH,FCB_DELETE + INT 21H + call rest_dir ;restore directory if needed + INT 20H +q3: + call quit + endif + +SCANEOF: + cmp [loadmod],0 + je sj52 + +;----- Load till physical end of file + cmp cx,word ptr[amnt_req] + jb sj51 + xor al,al + inc al ;reset zero flag + ret +sj51: + jcxz sj51b + push di ;get rid of any ^Z at the end of the file + add di,cx + dec di ;points to last char + cmp byte ptr [di],1ah + pop di + jne sj51b + dec cx +sj51b: + xor al,al ;set zero flag + call check_end ;check that we have a CRLF pair at the end + ret + +;----- Load till first ^Z is found +sj52: + PUSH DI + PUSH CX + MOV AL,1AH + or cx,cx + jz not_found ;skip with zero flag set + REPNE SCASB ;Scan for end of file mark + jnz not_found + LAHF ;Save flags momentarily + inc cx ;include the ^Z + SAHF ;Restore flags +not_found: + mov di,cx ;not found at the end + POP CX + LAHF ;Save flags momentarily + SUB CX,DI ;Reduce byte count if EOF found + SAHF ;Restore flags + POP DI + call check_end ;check that we have a CRLF pair at the end + +RET2: RET + + +;----------------------------------------------------------------------- +; If the end of file was found, then check that the last character +; in the file is a LF. If not put a CRLF pair in. + +check_end: + jnz not_end ;end was not reached + pushf ;save return flag + push di ;save pointer to buffer + add di,cx ;points to one past end on text + dec di ;points to last character + cmp di,offset dg:start + je check_no + cmp byte ptr[di],0ah ;is a LF the last character? + je check_done ;yes, exit +check_no: + mov byte ptr[di+1],0dh ;no, put a CR + inc cx ;one more char in text + mov byte ptr[di+2],0ah ;put a LF + inc cx ;another character at the end +check_done: + pop di + popf +not_end: + ret + + + +NOMOREJ:JMP NOMORE + +APPEND: + TEST BYTE PTR [HAVEOF],-1 + JNZ NOMOREJ + MOV DX,[ENDTXT] + CMP [PARAM1],0 ;See if parameter is missing + JNZ PARMAPP + CMP DX,[THREE4TH] ;See if already 3/4ths full + JAE RET2 ;If so, then done already +PARMAPP: + MOV DI,DX + MOV AH,SET_DMA + INT 21H + MOV CX,[LAST] + SUB CX,DX ;Amount of memory available + jnz sj53 + jmp memerr +sj53: + MOV DX,FCB + mov [amnt_req],cx ;save ammount of chars requested + MOV AH,FCB_RANDOM_READ_BLOCK + INT 21H ;Fill memory with file data + MOV [HAVEOF],AL + PUSH CX ;Save actual byte count + CALL SCANEOF + JNZ NOTEND + MOV BYTE PTR [HAVEOF],1 ;Set flag if 1AH found in file +NOTEND: + XOR DX,DX + MOV BX,[PARAM1] + OR BX,BX + JNZ COUNTLN + MOV AX,DI + ADD AX,CX ;First byte after loaded text + CMP AX,[THREE4TH] ;See if we made 3/4 full + JBE COUNTLN + MOV DI,[THREE4TH] + MOV CX,AX + SUB CX,DI ;Length remaining over 3/4 + MOV BX,1 ;Look for one more line +COUNTLN: + CALL SCANLN ;Look for BX lines + CMP [DI-1],AL ;Check for full line + JZ FULLN + STD + DEC DI + MOV CX,[LAST] + REPNE SCASB ;Scan backwards for last line + INC DI + INC DI + DEC DX + CLD +FULLN: + POP CX ;Actual amount read + MOV WORD PTR [DI],1AH ;Place EOF after last line + SUB CX,DI + XCHG DI,[ENDTXT] + ADD DI,CX ;Amount of file read but not used + SUB WORD PTR DS:[FCB+fcb_RR],DI ;Adjust RR field in case end of file + SBB WORD PTR DS:[FCB+fcb_RR+2],0 ; was not reached + CMP BX,DX + JNZ EOFCHK + MOV BYTE PTR [HAVEOF],0 + RET +NOMORE: + MOV DX,OFFSET DG:EOF + MOV AH,STD_CON_STRING_OUTPUT + INT 21H +RET3: RET +EOFCHK: + TEST BYTE PTR [HAVEOF],-1 + JNZ NOMORE + TEST BYTE PTR [ENDING],-1 + JNZ RET3 ;Suppress memory error during End + JMP MEMERR + +EWRITE: + MOV BX,[PARAM1] + OR BX,BX + JNZ WRT + MOV CX,[ONE4TH] + MOV DI,[ENDTXT] + SUB DI,CX ;Write everything in front of here + JBE RET3 + CMP DI,OFFSET DG:START ;See if there's anything to write + JBE RET3 + XOR DX,DX + MOV BX,1 ;Look for one more line + CALL SCANLN + JMP SHORT WRTADD +WRT: + INC BX + CALL FINDLIN +WRTADD: + CMP BYTE PTR [DELFLG],0 + JNZ WRTADD1 + PUSH DI + CALL DELBAK ;Want to delete the .BAK file + ;as soon as the first write occurs + POP DI +WRTADD1: + MOV CX,DI + MOV DX,OFFSET DG:START + SUB CX,DX ;Amount to write + JZ RET3 + MOV AH,SET_DMA + INT 21H + MOV DX,OFFSET DG:FCB2 + MOV AH,FCB_RANDOM_WRITE_BLOCK + INT 21H + OR AL,AL + JNZ WRTERR + MOV SI,DI + MOV DI,OFFSET DG:START + MOV [POINTER],DI + MOV CX,[ENDTXT] + SUB CX,SI + INC CX ;Amount of text remaining + REP MOVSB + DEC DI ;Point to EOF + MOV [ENDTXT],DI + MOV [CURRENT],1 + RET + +WRTERR: + MOV AH,FCB_CLOSE + INT 21H + MOV DX,OFFSET DG:DSKFUL +xERROR: + MOV AH,STD_CON_STRING_OUTPUT + INT 21H +;----------------------------------------------------------------------- + call rest_dir ;restore to the proper directory +;----------------------------------------------------------------------- + INT 32 + +RET$5: RET + +PAGE: + xor bx,bx ;get last line in the buffer + call findlin + mov [lastlin],dx + + mov bx,[param1] + or bx,bx ;was it specified? + jnz frstok ;yes, use it + mov bx,[current] + cmp bx,1 ;if current line =1 start from there + je frstok + inc bx ;start from current+1 line +frstok: + cmp bx,[lastlin] ;check that we are in the buffer + ja ret$5 ;if not just quit +infile: + mov dx,[param2] + or dx,dx ;was param2 specified? + jnz scndok ;yes,.... + mov dx,bx ;no, take the end line to be the + add dx,22 ; start line + 23 +scndok: + inc dx + cmp dx,[lastlin] ;check that we are in the buffer + jbe infile2 + mov dx,[lastlin] ;we are not, take the last line as end +infile2: + cmp dx,bx ;is param1 < param2 ? + jbe ret$5 ;yes, no backwards listing, quit + push dx ;save the end line + push bx ;save start line + mov bx,dx ;set the current line + dec bx + call findlin + mov [pointer],di + mov [current],dx + pop bx ;restore start line + call findlin ;get pointer to start line + mov si,di ;save pointer + pop di ;get end line + sub di,bx ;number of lines + jmp short display + + +LIST: + MOV BX,[PARAM1] + OR BX,BX + JNZ CHKP2 + MOV BX,[CURRENT] + SUB BX,11 + JA CHKP2 + MOV BX,1 +CHKP2: + CALL FINDLIN + JNZ RET7 + MOV SI,DI + MOV DI,[PARAM2] + INC DI + SUB DI,BX + JA DISPLAY + MOV DI,23 + JMP SHORT DISPLAY + + +DISPONE: + MOV DI,1 + +DISPLAY: + +; Inputs: +; BX = Line number +; SI = Pointer to text buffer +; DI = No. of lines +; Function: +; Ouputs specified no. of line to terminal, each +; with leading line number. +; Outputs: +; BX = Last line output. +; All registers destroyed. + + MOV CX,[ENDTXT] + SUB CX,SI + JZ RET7 + MOV BP,[CURRENT] +DISPLN: + PUSH CX + CALL SHOWNUM + POP CX +OUTLN: + LODSB + CMP AL," " + JAE SEND + CMP AL,10 + JZ SEND + CMP AL,13 + JZ SEND + CMP AL,9 + JZ SEND + PUSH AX + MOV AL,"^" + CALL OUT + POP AX + OR AL,40H +SEND: + CALL OUT + CMP AL,10 + LOOPNZ OUTLN + JCXZ RET7 + INC BX + DEC DI + JNZ DISPLN + DEC BX +RET7: RET + +LOADBUF: + MOV DI,2 + OFFSET DG:EDITBUF + MOV CX,255 + MOV DX,-1 +LOADLP: + LODSB + STOSB + INC DX + CMP AL,13 + LOOPNZ LOADLP + MOV [EDITBUF+1],DL + JZ RET7 +TRUNCLP: + LODSB + INC DX + CMP AL,13 + JNZ TRUNCLP + DEC DI + STOSB + RET + +NOTFNDJ:JMP NOTFND + +replac_from_curr: + mov byte ptr [srchmod],1 ;search from curr+1 line + jmp short sj6 + +REPLAC: + mov byte ptr [srchmod],0 ;search from beg of buffer +sj6: + MOV BYTE PTR [SRCHFLG],0 + CALL FNDFIRST + JNZ NOTFNDJ +REPLP: + MOV SI,[NUMPOS] + CALL LOADBUF ;Count length of line + SUB DX,[OLDLEN] + MOV CX,[NEWLEN] + ADD DX,CX ;Length of new line + CMP DX,254 + JA TOOLONG + MOV BX,[LSTNUM] + PUSH DX + CALL SHOWNUM + POP DX + MOV CX,[LSTFND] + MOV SI,[NUMPOS] + SUB CX,SI ;Get no. of char on line before change + DEC CX + CALL OUTCNT ;Output first part of line + PUSH SI + MOV SI,1+ OFFSET DG:TXT2 + MOV CX,[NEWLEN] + CALL OUTCNT ;Output change + POP SI + ADD SI,[OLDLEN] ;Skip over old stuff in line + MOV CX,DX ;DX=no. of char left in line + ADD CX,2 ;Include CR/LF + CALL OUTCNT ;Output last part of line + CALL QUERY ;Check if change OK + JNZ REPNXT + CALL PUTCURS + MOV DI,[LSTFND] + DEC DI + MOV SI,1+ OFFSET DG:TXT2 + MOV DX,[OLDLEN] + MOV CX,[NEWLEN] + DEC CX + ADD [LSTFND],CX ;Bump pointer beyond new text + INC CX + DEC DX + SUB [SRCHCNT],DX ;Old text will not be searched + JAE SOMELEFT + MOV [SRCHCNT],0 +SOMELEFT: + INC DX + CALL REPLACE +REPNXT: + CALL FNDNEXT + JNZ RET8 + JMP REPLP + +OUTCNT: + JCXZ RET8 +OUTLP: + LODSB + CALL OUT + DEC DX + LOOP OUTLP +RET8: RET + +TOOLONG: + MOV DX,OFFSET DG:TOOLNG + JMP SHORT PERR + +search_from_curr: + mov byte ptr [srchmod],1 ;search from curr+1 line + jmp short sj7 + +SEARCH: + mov byte ptr [srchmod],0 ;search from beg of buffer +sj7: + MOV BYTE PTR [SRCHFLG],1 + CALL FNDFIRST + JNZ NOTFND +SRCH: + MOV BX,[LSTNUM] + MOV SI,[NUMPOS] + CALL DISPONE + MOV DI,[LSTFND] + MOV CX,[SRCHCNT] + MOV AL,10 + REPNE SCASB + JNZ NOTFND + MOV [LSTFND],DI + MOV [NUMPOS],DI + MOV [SRCHCNT],CX + INC [LSTNUM] + CALL QUERY + JZ PUTCURS + CALL FNDNEXT + JZ SRCH +NOTFND: + MOV DX,OFFSET DG:NOSUCH +PERR: + MOV AH,STD_CON_STRING_OUTPUT + INT 21H + RET + +PUTCURS: + MOV BX,[LSTNUM] + DEC BX ;Current <= Last matched line + CALL FINDLIN + MOV [CURRENT],DX + MOV [POINTER],DI +RET9: RET + +DELETE: + MOV BX,[PARAM1] + OR BX,BX + JNZ DELFIN1 + MOV BX,[CURRENT] + CALL CHKRANGE +DELFIN1: + CALL FINDLIN + JNZ RET9 + PUSH BX + PUSH DI + MOV BX,[PARAM2] + OR BX,BX + JNZ DELFIN2 + MOV BX,DX +DELFIN2: + INC BX + CALL FINDLIN + MOV DX,DI + POP DI + SUB DX,DI + JBE COMERRJ + POP [CURRENT] + MOV [POINTER],DI + XOR CX,CX + JMP SHORT REPLACE + +COMERRJ:JMP COMERR + + +NOCOM: + DEC [COMLINE] + MOV BX,[PARAM1] + OR BX,BX + JNZ HAVLIN + MOV BX,[CURRENT] + INC BX ;Default is current line plus one + CALL CHKRANGE +HAVLIN: + CALL FINDLIN + MOV SI,DI + MOV [CURRENT],DX + MOV [POINTER],SI + jz sj12 + ret +sj12: + CMP SI,[ENDTXT] + JZ RET12 + CALL LOADBUF + MOV [OLDLEN],DX + MOV SI,[POINTER] + CALL DISPONE + CALL SHOWNUM + MOV AH,STD_CON_STRING_INPUT ;Get input buffer + MOV DX,OFFSET DG:EDITBUF + INT 21H + MOV AL,10 + CALL OUT + MOV CL,[EDITBUF+1] + MOV CH,0 + JCXZ RET12 + MOV DX,[OLDLEN] + MOV SI,2 + OFFSET DG:EDITBUF +;----------------------------------------------------------------------- + call unquote ;scan for quote chars if any +;----------------------------------------------------------------------- + MOV DI,[POINTER] + +REPLACE: + +; Inputs: +; CX = Length of new text +; DX = Length of original text +; SI = Pointer to new text +; DI = Pointer to old text in buffer +; Function: +; New text replaces old text in buffer and buffer +; size is adjusted. CX or DX may be zero. +; CX, SI, DI all destroyed. No other registers affected. + + CMP CX,DX + JZ COPYIN + PUSH SI + PUSH DI + PUSH CX + MOV SI,DI + ADD SI,DX + ADD DI,CX + MOV AX,[ENDTXT] + SUB AX,DX + ADD AX,CX + CMP AX,[LAST] + JAE MEMERR + XCHG AX,[ENDTXT] + MOV CX,AX + SUB CX,SI + CMP SI,DI + JA DOMOV + ADD SI,CX + ADD DI,CX + STD +DOMOV: + INC CX + + REP MOVSB + CLD + POP CX + POP DI + POP SI +COPYIN: + REP MOVSB +RET12: RET + +MEMERR: + MOV DX,OFFSET DG:MEMFUL + MOV AH,STD_CON_STRING_OUTPUT + INT 21H + JMP COMMAND + +MOVERR: + MOV DX,OFFSET DG:BADCOM +ERRORJ: + JMP COMERR + +MOVE: + MOV BYTE PTR [MOVFLG],1 + JMP SHORT BLKMOVE +COPY: + MOV BYTE PTR [MOVFLG],0 + +BLKMOVE: + MOV BX,[PARAM3] ;Third parameter must be specified + OR BX,BX + MOV DX,OFFSET DG:DEST + JZ ERRORJ + MOV BX,[PARAM1] ;Get the first parameter + OR BX,BX ;Not specified? + JNZ NXTARG + MOV BX,[CURRENT] ;Defaults to the current line + CALL CHKRANGE + MOV [PARAM1],BX ;Save it since current line may change + NXTARG: + CALL FINDLIN ;Get a pointer to the line + MOV [PTR_1],DI ;Save it + MOV BX,[PARAM2] ;Get the second parameter + OR BX,BX ;Not specified? + JNZ HAVARGS + MOV BX,[CURRENT] ;Defaults to the current line + MOV [PARAM2],BX ;Save it since current line may change +HAVARGS: + ;Parameters must not overlap + MOV DX,[PARAM3] + CMP DX,[PARAM1] + JBE NOERROR + CMP DX,[PARAM2] + JBE MOVERR +NOERROR: + INC BX ;Get pointer to line Param2+1 + CALL FINDLIN + MOV SI,DI + MOV [PTR_2],SI ;Save it + MOV CX,DI + MOV DI,[PTR_1] ;Restore pointer to line Param1 + SUB CX,DI ;Calculate number of bytes to copy + MOV [COPYSIZ],CX ;Save in COPYSIZ + PUSH CX ;And on the stack + MOV AX,[PARAM4] ;Is count specified? + OR AX,AX + JZ MEM_CHECK + MUL [COPYSIZ] + OR DX,DX + JZ COPYSIZ_OK + JMP MEMERR +COPYSIZ_OK: + MOV CX,AX + MOV [COPYSIZ],CX +MEM_CHECK: + MOV AX,[ENDTXT] + MOV DI,[LAST] + SUB DI,AX + CMP DI,CX + JAE HAV_ROOM + JMP MEMERR +HAV_ROOM: + MOV BX,[PARAM3] + PUSH BX + CALL FINDLIN + MOV [PTR_3],DI + MOV CX,[ENDTXT] + SUB CX,DI + INC CX + MOV SI,[ENDTXT] + MOV DI,SI + ADD DI,[COPYSIZ] + MOV [ENDTXT],DI + STD + REP MOVSB + CLD + POP BX + CMP BX,[PARAM1] + JB GET_PTR_2 + MOV SI,[PTR_1] + JMP SHORT COPY_TEXT +GET_PTR_2: + MOV SI,[PTR_2] +COPY_TEXT: + MOV BX,[PARAM4] + MOV DI,[PTR_3] + POP CX + MOV [COPYSIZ],CX +COPY_TEXT_1: + REP MOVSB + DEC BX + CMP BX,0 + JLE MOV_CHK + MOV [PARAM4],BX + SUB SI,[COPYSIZ] + MOV CX,[COPYSIZ] + JMP SHORT COPY_TEXT_1 +MOV_CHK: + CMP BYTE PTR[MOVFLG],0 + JZ COPY_DONE + MOV DI,[PTR_1] + MOV SI,[PTR_2] + MOV BX,[PARAM3] + CMP BX,[PARAM1] + JAE DEL_TEXT + ADD DI,[COPYSIZ] + ADD SI,[COPYSIZ] +DEL_TEXT: + MOV CX,[ENDTXT] + SUB CX,SI + REP MOVSB + MOV [ENDTXT],DI + MOV CX,[PARAM2] + SUB CX,[PARAM1] + MOV BX,[PARAM3] + SUB BX,CX + JNC MOVE_DONE +COPY_DONE: + MOV BX,[PARAM3] +MOVE_DONE: + CALL FINDLIN + MOV [POINTER],DI + MOV [CURRENT],BX + RET + + +MOVEFILE: + MOV CX,[ENDTXT] ;Get End-of-text marker + MOV SI,CX + SUB CX,DI ;Calculate number of bytes to copy + INC CX + MOV DI,DX + STD + REP MOVSB ;Copy CX bytes + XCHG SI,DI + CLD + INC DI + MOV BP,SI +SETPTS: + MOV [POINTER],DI ;Current line is first free loc + MOV [CURRENT],BX ; in the file + MOV [ENDTXT],BP ;End-of-text is last free loc before + RET + +NAMERR: + JMP COMERR1 + + +MERGE: + MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 1 + MOV DI,OFFSET DG:FCB3 + INT 21H + OR AL,AL + MOV DX,OFFSET DG:BADDRV + JNZ NAMERR + MOV [COMLINE],SI + MOV DX,OFFSET DG:FCB3 + MOV AH,FCB_OPEN + INT 21H + OR AL,AL + MOV DX,OFFSET DG:FILENM + JNZ NAMERR + MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H + MOV DX,OFFSET DG:ABORTMERGE + INT 21H + MOV BX,[PARAM1] + OR BX,BX + JNZ MRG + MOV BX,[CURRENT] + CALL CHKRANGE +MRG: + CALL FINDLIN + MOV BX,DX + MOV DX,[LAST] + CALL MOVEFILE + ;Set DMA address for reading in new file + MOV DX,[POINTER] + MOV AH,SET_DMA + INT 21H + XOR AX,AX + MOV WORD PTR DS:[FCB3+fcb_RR],AX + MOV WORD PTR DS:[FCB3+fcb_RR+2],AX + INC AX + MOV WORD PTR DS:[FCB3+fcb_RECSIZ],AX + MOV DX,OFFSET DG:FCB3 + MOV CX,[ENDTXT] + SUB CX,[POINTER] + MOV AH,FCB_RANDOM_READ_BLOCK + INT 21H + CMP AL,1 + JZ FILEMRG + MOV DX,OFFSET DG:MRGERR + MOV AH,STD_CON_STRING_OUTPUT + INT 21H + MOV CX,[POINTER] + JMP SHORT RESTORE +FILEMRG: + ADD CX,[POINTER] + MOV SI,CX + DEC SI + LODSB + CMP AL,1AH + JNZ RESTORE + DEC CX +RESTORE: + MOV DI,CX + MOV SI,[ENDTXT] + INC SI + MOV CX,[LAST] + SUB CX,SI + REP MOVSB + MOV [ENDTXT],DI + MOV BYTE PTR [DI],1AH + MOV DX,OFFSET DG:FCB3 + MOV AH,FCB_CLOSE + INT 21H + MOV DX,OFFSET DG:START + MOV AH,SET_DMA + INT 21H + RET + + +INSERT: + MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H ;Set vector 23H + MOV DX,OFFSET DG:ABORTINS + INT 21H + MOV BX,[PARAM1] + OR BX,BX + JNZ INS + MOV BX,[CURRENT] + CALL CHKRANGE +INS: + CALL FINDLIN + MOV BX,DX + MOV DX,[LAST] + CALL MOVEFILE +INLP: + CALL SETPTS ;Update the pointers into file + CALL SHOWNUM + MOV DX,OFFSET DG:EDITBUF + MOV AH,STD_CON_STRING_INPUT + INT 21H + CALL LF + MOV SI,2 + OFFSET DG:EDITBUF + CMP BYTE PTR [SI],1AH + JZ ENDINS +;----------------------------------------------------------------------- + call unquote ;scan for quote chars if any +;----------------------------------------------------------------------- + MOV CL,[SI-1] + MOV CH,0 + MOV DX,DI + INC CX + ADD DX,CX + JC MEMERRJ1 + JZ MEMERRJ1 + CMP DX,BP + JB MEMOK +MEMERRJ1: + CALL END_INS + JMP MEMERR +MEMOK: + REP MOVSB + MOV AL,10 + STOSB + INC BX + JMP SHORT INLP + +ABORTMERGE: + MOV DX,OFFSET DG:START + MOV AH,SET_DMA + INT 21H + +ABORTINS: + MOV AX,CS ;Restore segment registers + MOV DS,AX + MOV ES,AX + MOV SS,AX + MOV SP,OFFSET DG:STACK + STI + CALL CRLF + CALL ENDINS + JMP COMOVER + +ENDINS: + CALL END_INS + RET + +END_INS: + MOV BP,[ENDTXT] + MOV DI,[POINTER] + MOV SI,BP + INC SI + MOV CX,[LAST] + SUB CX,BP + REP MOVSB + DEC DI + MOV [ENDTXT],DI + MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H + MOV DX,OFFSET DG:ABORTCOM + INT 21H + RET + +FILLBUF: + MOV [PARAM1],-1 ;Read in max. no of lines + CALL APPEND +ENDED: +;Write text out to .$$$ file + MOV BYTE PTR [ENDING],1 ;Suppress memory errors + MOV BX,-1 ;Write max. no of lines + CALL WRT + TEST BYTE PTR [HAVEOF],-1 + JZ FILLBUF + MOV DX,[ENDTXT] + MOV AH,SET_DMA + INT 21H + MOV CX,1 + MOV DX,OFFSET DG:FCB2 + MOV AH,FCB_RANDOM_WRITE_BLOCK + INT 21H ;Write end-of-file byte +;Close .$$$ file + MOV AH,FCB_CLOSE + INT 21H + MOV SI,FCB + LEA DI,[SI+fcb_FILSIZ] + MOV DX,SI + MOV CX,9 + REP MOVSB + MOV SI,OFFSET DG:BAK + MOVSW + MOVSB +;Rename original file .BAK + MOV AH,FCB_RENAME + INT 21H + MOV SI,FCB + MOV DI,OFFSET DG:FCB2 + fcb_FILSIZ + MOV CX,6 + REP MOVSW +;Rename .$$$ file to original name + MOV DX,OFFSET DG:FCB2 + INT 21H + call rest_dir ;restore directory if needed + INT 20H + +ABORTCOM: + MOV AX,CS + MOV DS,AX + MOV ES,AX + MOV SS,AX + MOV SP,OFFSET DG:STACK + STI + CALL CRLF + JMP COMMAND + +DELBAK: + MOV BYTE PTR [DELFLG],1 + MOV DI,9+OFFSET DG:FCB2 + MOV SI,OFFSET DG:BAK + MOVSW + MOVSB + ;Delete old backup file (.BAK) + MOV AH,FCB_DELETE + MOV DX,OFFSET DG:FCB2 + INT 21H + MOV DI,9+OFFSET DG:FCB2 + MOV AL,"$" + STOSB + STOSB + STOSB + RET + +CODE ENDS + END EDLIN + \ No newline at end of file -- cgit v1.2.3