mirror of
https://github.com/microsoft/MS-DOS.git
synced 2024-11-29 17:15:47 +00:00
1846 lines
54 KiB
NASM
1846 lines
54 KiB
NASM
|
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
|
|||
|
|