1203 lines
28 KiB
NASM
1203 lines
28 KiB
NASM
PAGE 60,132
|
||
TITLE Edlcmd2 - PART2 procedures called from EDLIN
|
||
;/*
|
||
; * Microsoft Confidential
|
||
; * Copyright (C) Microsoft Corporation 1991
|
||
; * All Rights Reserved.
|
||
; */
|
||
|
||
|
||
;======================= START OF SPECIFICATIONS =========================
|
||
;
|
||
; MODULE NAME: EDLCMD2.SAL
|
||
;
|
||
; DESCRIPTIVE NAME: EDLIN ROUTINES
|
||
;
|
||
; FUNCTION: THIS MODULE PROVIDES ROUTINES NEEDED FOR EDLIN'S EXECUTION.
|
||
;
|
||
; ENTRY POINT: ANY CALLED ROUTINE
|
||
;
|
||
; EXIT NORMAL: NA
|
||
;
|
||
; EXIT ERROR : NA
|
||
;
|
||
; INTERNAL REFERENCES:
|
||
;
|
||
; EXTERNAL REFERENCES:
|
||
;
|
||
; ROUTINE: EDLCMD1 - ROUTINES MAY BE CALLED FROM EDLCMD1
|
||
; EDLMES - ROUTINES MAY BE CALLED FROM EDLMES
|
||
;
|
||
; NOTES: THIS MODULE IS TO BE PREPPED BY SALUT WITH THE "PR" OPTIONS.
|
||
; LINK EDLIN+EDLCMD1+EDLCMD2+EDLMES+EDLPARSE
|
||
;
|
||
;
|
||
; REVISION HISTORY:
|
||
;
|
||
; AN000 VERSION DOS 4.00 - REVISIONS MADE RELATE TO THE FOLLOWING:
|
||
;
|
||
; - IMPLEMENT SYSPARSE
|
||
; - IMPLEMENT MESSAGE RETRIEVER
|
||
; - IMPLEMENT DBCS ENABLING
|
||
; - ENHANCED VIDEO SUPPORT
|
||
; - EXTENDED OPENS
|
||
; - SCROLLING ERROR
|
||
;
|
||
; COPYRIGHT: "MS DOS EDLIN UTILITY"
|
||
; "VERSION 4.00 (C) COPYRIGHT 1988 Microsoft"
|
||
;
|
||
;======================= END OF SPECIFICATIONS ===========================
|
||
|
||
include edlequ.asm
|
||
include syscall.inc
|
||
|
||
CODE SEGMENT PUBLIC
|
||
CODE ENDS
|
||
|
||
CONST SEGMENT PUBLIC WORD
|
||
CONST ENDS
|
||
|
||
cstack segment stack
|
||
cstack ends
|
||
|
||
DATA SEGMENT PUBLIC WORD
|
||
DATA ENDS
|
||
|
||
|
||
DG GROUP CODE,CONST,cstack,DATA
|
||
|
||
CONST SEGMENT PUBLIC WORD
|
||
extrn msg_crlf:abs,msg_lf:abs,qmes_ptr:byte,ask_ptr:byte
|
||
extrn bak:byte,$$$file:byte,delflg:byte,loadmod:byte,txt1:byte
|
||
extrn txt2:byte,memful_ptr:word
|
||
|
||
extrn Del_Bak_Ptr:byte ;an000;dms;
|
||
extrn cont_ptr:byte ;an000;dms:6/10/87
|
||
|
||
CONST ENDS
|
||
|
||
DATA SEGMENT PUBLIC WORD
|
||
extrn ParamCt:WORD
|
||
extrn current:word,pointer:word,start:word,endtxt:word
|
||
extrn wrt_handle:word,editbuf:byte,ext_ptr:word,qflg:byte
|
||
extrn temp_path:byte,line_num:word,line_flag:byte
|
||
extrn line_num_buf_ptr:byte,arg_buf:byte,arg_buf_ptr:word
|
||
extrn olddat:byte,oldlen:word,newlen:word,param1:word,param2:word
|
||
extrn srchflg:byte,srchmod:byte,comline:word,lstfnd:word,numpos:word
|
||
extrn lstnum:word,last_mem:word,srchcnt:word,amnt_req:word
|
||
|
||
extrn lc_adj:byte ;an000;dms:6/10/87
|
||
extrn continue:byte ;an000;dms:6/10/87
|
||
extrn pg_count:byte ;an000;dms:6/10/87
|
||
extrn Disp_Len:byte ;an000;dms;
|
||
extrn Disp_Width:byte ;an000;dms;
|
||
extrn lc_flag:byte ;an000;dms:6/10/87
|
||
|
||
ifdef DBCS
|
||
extrn lbtbl:dword
|
||
endif
|
||
|
||
DATA ENDS
|
||
|
||
CODE SEGMENT PUBLIC
|
||
|
||
ASSUME CS:DG,DS:DG,SS:CStack,ES:DG
|
||
|
||
public findlin,shownum,loadbuf,crlf,lf,abortcom,unquote
|
||
public kill_bl,make_caps,display,dispone,make_cntrl
|
||
public query,quit,scanln,delbak,scaneof,memerr
|
||
public fndfirst,fndnext,replace
|
||
ifdef DBCS
|
||
public testkanj
|
||
endif
|
||
extrn std_printf:near,command:near,chkrange:near,ComErr:NEAR
|
||
extrn Xerror:near
|
||
extrn display_message:near
|
||
|
||
|
||
FINDLIN:
|
||
|
||
; Inputs
|
||
; BX = Line number to be located in buffer (0 means last line+1)
|
||
; Outputs:
|
||
; DX = Actual line found
|
||
; DI = Pointer to start of line DX
|
||
; Zero set if BX = DX (if specified line found)
|
||
; AL,CX destroyed. No other registers affected.
|
||
|
||
MOV DX,[CURRENT]
|
||
MOV DI,[POINTER]
|
||
CMP BX,DX ; fast find. Current = requested
|
||
retz
|
||
JA FINDIT ; start scanning at current?
|
||
OR BX,BX ; special case of EOF?
|
||
JZ FINDIT ; yes
|
||
MOV DX,1 ; set up for scan at beginning
|
||
MOV DI,OFFSET DG:START
|
||
CMP BX,DX ; at beginning?
|
||
retz
|
||
FINDIT:
|
||
MOV CX,[ENDTXT] ; count of bytes in buffer
|
||
SUB CX,DI ; for scan
|
||
SCANLN:
|
||
MOV AL,10 ; LF is what we look for.
|
||
OR AL,AL ; Clear zero flag for JCXZ
|
||
FINLIN:
|
||
JCXZ RET4 ; at end? Yes, no skip.
|
||
REPNE SCASB ; find EOL
|
||
INC DX ; increment count
|
||
CMP BX,DX ; find correct line?
|
||
JNZ FINLIN ; no, try again.
|
||
RET4: return
|
||
|
||
; Inputs:
|
||
; BX = Line number to be displayed
|
||
; Function:
|
||
; Displays line number on terminal in 8-character
|
||
; format, suppressing leading zeros.
|
||
; AX, CX, DX destroyed. No other registers affected.
|
||
|
||
SHOWNUM:
|
||
mov dx,offset dg:line_num_buf_ptr
|
||
mov line_num,bx
|
||
MOV line_flag,"*"
|
||
CMP BX,[CURRENT]
|
||
JZ STARLIN
|
||
MOV line_flag," "
|
||
STARLIN:
|
||
call std_printf
|
||
ret5: return
|
||
|
||
|
||
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
|
||
retz ; no lines to display
|
||
;=========================================================================
|
||
; Initialize screen size and line counts for use by display.
|
||
;
|
||
; Date : 6/10/87
|
||
;=========================================================================
|
||
|
||
push ax ;an000;save affected regs
|
||
|
||
mov al,dg:disp_len ;an000;length of video display
|
||
mov pg_count,al ;an000;init. screen size ctr.
|
||
|
||
pop ax ;an000;restore affected regs
|
||
|
||
;=========================================================================
|
||
|
||
mov dx,di ;number of lines to print
|
||
;
|
||
; CX is the number of bytes in the buffer
|
||
; dx is the number of lines to be output
|
||
;
|
||
DISPLN:
|
||
SaveReg <CX,DX>
|
||
CALL SHOWNUM
|
||
RestoreReg <DX,CX>
|
||
mov di,offset dg:arg_buf
|
||
;
|
||
; Copy chars until CR/LF or end of line hit
|
||
;
|
||
OUTLN:
|
||
LODSB
|
||
CMP DI,254+offset dg:arg_buf ; are we at end of buffer?
|
||
JAE StoreDone ; Yes, do NOT store
|
||
CMP AL," "
|
||
JAE SEND
|
||
CMP AL,10
|
||
JZ SEND
|
||
CMP AL,13
|
||
JZ SEND
|
||
CMP AL,9
|
||
JZ SEND
|
||
MOV AH,"^"
|
||
OR AL,40h
|
||
XCHG AL,AH
|
||
STOSW
|
||
JMP short StoreDone
|
||
SEND:
|
||
stosb
|
||
StoreDone:
|
||
CMP AL,10 ; perform copy until LF is seen
|
||
LOOPNZ OUTLN
|
||
;
|
||
; Make sure buffer ends with CRLF
|
||
;
|
||
cmp byte ptr [di-1],10
|
||
jz Terminate
|
||
;
|
||
; No LF seen. See if CR
|
||
;
|
||
cmp byte ptr [di-1],CR
|
||
jz StoreLF
|
||
mov al,CR
|
||
stosb
|
||
StoreLF:
|
||
mov al,10
|
||
stosb
|
||
Terminate:
|
||
mov byte ptr [di],0
|
||
|
||
call EDLIN_DISP_COUNT ;an000;determine lines printed
|
||
; DMS:6/10/87
|
||
push dx
|
||
mov dx,offset dg:arg_buf_ptr
|
||
call std_printf
|
||
pop dx
|
||
JCXZ ret7
|
||
INC BX
|
||
|
||
call EDLIN_PG_COUNT ;an000;adjust screen line count
|
||
; DMS:6/10/87
|
||
cmp lc_flag,false ;an000;continue DISPLAY?
|
||
; DMS:6/10/87
|
||
JNZ DISPLN
|
||
DEC BX
|
||
ret7: return
|
||
|
||
FNDFIRST:
|
||
MOV DI,1+OFFSET DG:TXT1
|
||
mov byte ptr[olddat],1 ;replace with old value if none new
|
||
CALL GETTEXT
|
||
OR AL,AL ;Reset zero flag in case CX is zero
|
||
JCXZ RET7
|
||
cmp al,1ah ;terminated with a ^Z ?
|
||
jne sj8
|
||
mov byte ptr[olddat],0 ;do not replace with old value
|
||
sj8:
|
||
MOV [OLDLEN],CX
|
||
XOR CX,CX
|
||
CMP AL,0DH
|
||
JZ SETBUF
|
||
CMP BYTE PTR [SRCHFLG],0
|
||
JZ NXTBUF
|
||
SETBUF:
|
||
DEC SI
|
||
NXTBUF:
|
||
MOV [COMLINE],SI
|
||
MOV DI,1+OFFSET DG:TXT2
|
||
CALL GETTEXT
|
||
CMP BYTE PTR [SRCHFLG],0
|
||
JNZ NOTREPL
|
||
CMP AL,0DH
|
||
JNZ HAVCHR
|
||
DEC SI
|
||
HAVCHR:
|
||
MOV [COMLINE],SI
|
||
NOTREPL:
|
||
MOV [NEWLEN],CX
|
||
MOV BX,[PARAM1]
|
||
OR BX,BX
|
||
JNZ CALLER
|
||
cmp byte ptr[srchmod],0
|
||
jne sj9
|
||
mov bx,1 ;start from line number 1
|
||
jmp short sj9a
|
||
sj9:
|
||
MOV BX,[CURRENT]
|
||
INC BX ;Default search and replace to current+1
|
||
sj9a:
|
||
CALL CHKRANGE
|
||
CALLER:
|
||
CALL FINDLIN
|
||
MOV [LSTFND],DI
|
||
MOV [NUMPOS],DI
|
||
MOV [LSTNUM],DX
|
||
MOV BX,[PARAM2]
|
||
CMP BX,1
|
||
SBB BX,-1 ;Decrement everything except zero
|
||
CALL FINDLIN
|
||
MOV CX,DI
|
||
SUB CX,[LSTFND]
|
||
OR AL,-1
|
||
JCXZ aret
|
||
CMP CX,[OLDLEN]
|
||
jae sj10
|
||
aret: return
|
||
sj10:
|
||
MOV [SRCHCNT],CX
|
||
|
||
FNDNEXT:
|
||
|
||
; Inputs:
|
||
; [TXT1+1] has string to search for
|
||
; [OLDLEN] has length of the string
|
||
; [LSTFND] has starting position of search in text buffer
|
||
; [LSTNUM] has line number which has [LSTFND]
|
||
; [SRCHCNT] has length to be searched
|
||
; [NUMPOS] has beginning of line which has [LSTFND]
|
||
; Outputs:
|
||
; Zero flag set if match found
|
||
; [LSTFND],[LSTNUM],[SRCHCNT] updated for continuing the search
|
||
; [NUMPOS] has beginning of line in which match was made
|
||
|
||
MOV AL,[TXT1+1]
|
||
MOV CX,[SRCHCNT]
|
||
MOV DI,[LSTFND]
|
||
SCAN:
|
||
OR DI,DI ;Clear zero flag in case CX=0
|
||
REPNE SCASB ;look for first byte of string
|
||
|
||
retnz ;return if you don't find
|
||
ifdef DBCS
|
||
call kanji_check ;see if the found byte is on a character boundary
|
||
jnz scan
|
||
endif
|
||
MOV DX,CX
|
||
MOV BX,DI ;Save search position
|
||
MOV CX,[OLDLEN]
|
||
DEC CX
|
||
MOV SI,2 + OFFSET DG:TXT1
|
||
CMP AL,AL ;Set zero flag in case CX=0
|
||
REPE CMPSB
|
||
MOV CX,DX
|
||
MOV DI,BX
|
||
JNZ SCAN
|
||
MOV [SRCHCNT],CX
|
||
MOV CX,DI
|
||
MOV [LSTFND],DI
|
||
MOV DI,[NUMPOS]
|
||
SUB CX,DI
|
||
MOV AL,10
|
||
MOV DX,[LSTNUM]
|
||
;Determine line number of match
|
||
GETLIN:
|
||
INC DX
|
||
MOV BX,DI
|
||
REPNE SCASB
|
||
JZ GETLIN
|
||
DEC DX
|
||
MOV [LSTNUM],DX
|
||
MOV [NUMPOS],BX
|
||
XOR AL,AL
|
||
return
|
||
|
||
ifdef DBCS
|
||
|
||
;Kanji_check idea is to scan backwards to the first
|
||
; character which can't be a kanji or part of one
|
||
; (.lt. DB_SP_LO) then scan forward to see if the
|
||
; current byte is on character boundary
|
||
;
|
||
;Output ZR <==> we're on a character boundary
|
||
; NZ <==> we're not on character boundary i.e. No Match
|
||
kanji_check:
|
||
push ax ;save search character
|
||
push di
|
||
dec di ;point to the character we found
|
||
mov si,di ;start searching bakwards from there
|
||
std
|
||
srch_loop:
|
||
lodsb
|
||
cmp al,DB_SP_LO
|
||
jae srch_loop
|
||
inc si ;point to first non-kanji
|
||
cld ;forward search
|
||
kan_loop:
|
||
cmp si,di ;are we at current byte?
|
||
jae passed_char ;if we are, or are passed it, exit
|
||
call next_char ;otherwise advance si to next char
|
||
jmp short kan_loop ;and loop
|
||
passed_char:
|
||
pop di
|
||
pop ax
|
||
ret
|
||
|
||
;Next_char si points to a character boundary
|
||
; advance si to point to the beginning of the next char
|
||
;
|
||
;
|
||
next_char:
|
||
push ax
|
||
lodsb
|
||
call testkanj
|
||
jz not_kanj
|
||
inc si
|
||
not_kanj:
|
||
pop ax
|
||
ret
|
||
|
||
;--------------------------------------------------------------------;
|
||
; TESTKANJ ~ FIND OUT IS THE BYTE IS A KANJI PREFIX ;
|
||
; ;
|
||
; entry: AL byte to test ;
|
||
; ;
|
||
; exit: NZ if lead byte ortherwise ZR ;
|
||
; ;
|
||
; modifies: AX ;
|
||
; ;
|
||
;--------------------------------------------------------------------;
|
||
|
||
testkanj:
|
||
push ax
|
||
xchg ah,al ;put byte in ah
|
||
push ds
|
||
push si
|
||
lds si,cs:[lbtbl] ;get pointer to lead byte table
|
||
ktlop:
|
||
lodsb ;direction flag should be OK
|
||
or al,al ;are we at the end of table?
|
||
jz notlead ;brif so
|
||
cmp al,ah ;is START RANGE > CHARACTER?
|
||
ja notlead ;brif so, not a lead character (carry clear)
|
||
lodsb ;get second range byte
|
||
cmp ah,al ;is CHARACTER > END RANGE
|
||
ja ktlop ;brif so, not a lead character (check next range)
|
||
or al,al ;make NZ
|
||
notl_exit:
|
||
pop si
|
||
pop ds
|
||
pop ax
|
||
ret
|
||
notlead:
|
||
cmp al,al
|
||
jmp notl_exit
|
||
|
||
endif
|
||
|
||
GETTEXT:
|
||
|
||
; Inputs:
|
||
; SI points into command line buffer
|
||
; DI points to result buffer
|
||
; Function:
|
||
; Moves [SI] to [DI] until ctrl-Z (1AH) or
|
||
; RETURN (0DH) is found. Termination char not moved.
|
||
; Outputs:
|
||
; AL = Termination character
|
||
; CX = No of characters moved.
|
||
; SI points one past termination character
|
||
; DI points to next free location
|
||
|
||
XOR CX,CX
|
||
|
||
GETIT:
|
||
LODSB
|
||
;-----------------------------------------------------------------------
|
||
cmp al,quote_char ;a quote character?
|
||
jne sj101 ;no, skip....
|
||
lodsb ;yes, get quoted character
|
||
call make_cntrl
|
||
jmp short sj102
|
||
;-----------------------------------------------------------------------
|
||
sj101:
|
||
CMP AL,1AH
|
||
JZ DEFCHK
|
||
sj102:
|
||
CMP AL,0DH
|
||
JZ DEFCHK
|
||
STOSB
|
||
INC CX
|
||
JMP SHORT GETIT
|
||
|
||
DEFCHK:
|
||
OR CX,CX
|
||
JZ OLDTXT
|
||
PUSH DI
|
||
SUB DI,CX
|
||
MOV BYTE PTR [DI-1],cl
|
||
POP DI
|
||
return
|
||
|
||
OLDTXT:
|
||
cmp byte ptr[olddat],1 ;replace with old text?
|
||
je sj11 ;yes...
|
||
mov byte ptr[di-1],cl ;zero text buffer char count
|
||
return
|
||
|
||
sj11:
|
||
MOV CL,BYTE PTR [DI-1]
|
||
ADD DI,CX
|
||
return
|
||
|
||
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_MEM]
|
||
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
|
||
return
|
||
|
||
MEMERR:
|
||
MOV DX,OFFSET DG:MEMFUL_ptr
|
||
call std_printf
|
||
JMP COMMAND
|
||
|
||
|
||
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
|
||
retz
|
||
TRUNCLP:
|
||
LODSB
|
||
INC DX
|
||
CMP AL,13
|
||
JNZ TRUNCLP
|
||
DEC DI
|
||
STOSB
|
||
return
|
||
|
||
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
|
||
return
|
||
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
|
||
return
|
||
|
||
;----- 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
|
||
|
||
return
|
||
|
||
|
||
;-----------------------------------------------------------------------
|
||
; 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:
|
||
return
|
||
|
||
CRLF:
|
||
push dx
|
||
mov ax,msg_crlf
|
||
call display_message
|
||
pop dx
|
||
return
|
||
LF:
|
||
mov ax,msg_lf
|
||
jmp display_message
|
||
|
||
ABORTCOM:
|
||
MOV AX,CS
|
||
MOV DS,AX
|
||
MOV ES,AX
|
||
MOV AX,cstack
|
||
MOV SS,AX
|
||
MOV SP,STACK
|
||
STI
|
||
CALL CRLF
|
||
JMP COMMAND
|
||
|
||
DELBAK:
|
||
;Delete old backup file (.BAK)
|
||
|
||
MOV BYTE PTR [DELFLG],1
|
||
MOV DI,[EXT_PTR]
|
||
MOV SI,OFFSET DG:BAK
|
||
MOVSW
|
||
MOVSW
|
||
MOVSB
|
||
MOV AH,UNLINK
|
||
MOV DX,OFFSET DG:TEMP_PATH
|
||
INT 21H
|
||
; $if c ;error ? ;an000; dms;
|
||
JNC $$IF1
|
||
cmp ax,Access_Denied ;file read only? ;an000; dms;
|
||
; $if e ;yes ;an000; dms;
|
||
JNE $$IF2
|
||
mov bx,[Wrt_Handle] ;close .$$$ file ;an000; dms;
|
||
mov ah,Close ;close function ;an000; dms;
|
||
int 21h ;close it ;an000; dms;
|
||
|
||
mov di,[Ext_Ptr] ;point to extension ;an000; dms;
|
||
mov si,offset dg:$$$File ;point to .$$$ extension;an000; dms;
|
||
movsw ;get .$$$ extension ;an000; dms;
|
||
movsw ; ;an000; dms;
|
||
movsb ; ;an000; dms;
|
||
mov dx,offset dg:Temp_Path ;point to .$$$ file ;an000; dms;
|
||
mov ah,Unlink ;delete it ;an000; dms;
|
||
int 21h ; ;an000; dms;
|
||
|
||
mov di,[Ext_Ptr] ;point to extension ;an000; dms;
|
||
mov si,offset dg:BAK ;point to .BAK extension;an000; dms;
|
||
movsw ;get .BAK extension ;an000; dms;
|
||
movsw ; ;an000; dms;
|
||
movsb ; ;an000; dms;
|
||
mov dx,offset dg:Del_Bak_Ptr;point to error message ;an000; dms;
|
||
jmp Xerror ;display message & exit ;an000; dms;
|
||
; $endif
|
||
$$IF2:
|
||
; $endif
|
||
$$IF1:
|
||
|
||
MOV DI,[EXT_PTR]
|
||
MOV SI,OFFSET DG:$$$FILE
|
||
MOVSW
|
||
MOVSW
|
||
MOVSB
|
||
return
|
||
|
||
|
||
;-----------------------------------------------------------------------;
|
||
; Will scan buffer given pointed to by SI and get rid of quote
|
||
;characters, compressing the line and adjusting the length at the
|
||
;begining of the line.
|
||
; Preserves al registers except flags and AX .
|
||
|
||
unquote:
|
||
push cx
|
||
push di
|
||
push si
|
||
mov di,si
|
||
mov cl,[si-1] ;length of buffer
|
||
xor ch,ch
|
||
mov al,quote_char
|
||
cld
|
||
unq_loop:
|
||
jcxz unq_done ;no more chars in the buffer, exit
|
||
repnz scasb ;search for quote character
|
||
jnz unq_done ;none found, exit
|
||
push cx ;save chars left in buffer
|
||
push di ;save pointer to quoted character
|
||
push ax ;save quote character
|
||
mov al,byte ptr[di] ;get quoted character
|
||
call make_cntrl
|
||
mov byte ptr[di],al
|
||
pop ax ;restore quote character
|
||
mov si,di
|
||
dec di ;points to the quote character
|
||
inc cx ;include the carriage return also
|
||
rep movsb ;compact line
|
||
pop di ;now points to after quoted character
|
||
pop cx
|
||
jcxz sj13 ;if quote char was last of line do not adjust
|
||
dec cx ;one less char left in the buffer
|
||
sj13: pop si
|
||
dec byte ptr[si-1] ;one less character in total buffer count also
|
||
push si
|
||
jmp short unq_loop
|
||
|
||
unq_done:
|
||
pop si
|
||
pop di
|
||
pop cx
|
||
return
|
||
|
||
|
||
;-----------------------------------------------------------------------;
|
||
; Convert the character in AL to the corresponding control
|
||
; character. AL has to be between @ and _ to be converted. That is,
|
||
; it has to be a capital letter. All other letters are left unchanged.
|
||
|
||
make_cntrl:
|
||
push ax
|
||
and ax,11100000b
|
||
cmp ax,01000000b
|
||
pop ax
|
||
jne sj14
|
||
and ax,00011111b
|
||
sj14:
|
||
return
|
||
|
||
|
||
;---- Kill spaces in buffer --------------------------------------------;
|
||
;=========================================================================
|
||
; kill_bl : Parses over spaces in a buffer.
|
||
;
|
||
; Date : 6/10/86
|
||
;=========================================================================
|
||
kill_bl:
|
||
|
||
push bx ;an000;save affected reg.
|
||
kill_bl_cont:
|
||
|
||
lodsb ;get rid of blanks
|
||
cmp al,9
|
||
je kill_bl_cont ;an000;it is a tab
|
||
|
||
cmp al,10
|
||
je kill_bl_cont ;an000;if LF
|
||
|
||
cmp al,' '
|
||
je kill_bl_cont ;an000;we have a space
|
||
|
||
ifdef DBCS ;an000;is this a kanji assembly
|
||
call testkanj ;an000;do we have a dbcs lead byte
|
||
; $if nz ;an000;yes, we have a lead byte
|
||
JZ $$IF5
|
||
cmp al,DB_SP_HI ;an000;is it DB_SP_HI
|
||
; $if z ;an000;it is DB_SP_HI
|
||
JNZ $$IF6
|
||
mov bl,ds:[si] ;an000;set up for compare
|
||
cmp bl,DB_SP_LO ;an000;is it DB_SP_LO
|
||
; $if z ;an000;we have an asian blank
|
||
JNZ $$IF7
|
||
lodsb ;an000;skip byte containing 81h
|
||
jmp kill_bl_cont
|
||
; $endif ;an000;
|
||
$$IF7:
|
||
; $endif ;an000;fall through no delim
|
||
$$IF6:
|
||
; found
|
||
; $endif ;an000;end test for dbcs lead byte
|
||
$$IF5:
|
||
endif ;an000;end conditional assembly
|
||
|
||
pop bx ;an000;restore affected reg.
|
||
return
|
||
|
||
;----- Capitalize the character in AL ----------------------------------;
|
||
; ;
|
||
; Input: ;
|
||
; ;
|
||
; AL contains a character to capitalize ;
|
||
; ;
|
||
; Output: ;
|
||
; ;
|
||
; AL contains a capitalized character ;
|
||
; ;
|
||
;-----------------------------------------------------------------------;
|
||
|
||
MAKE_CAPS:
|
||
CMP AL,"a"
|
||
JB CAPS1
|
||
CMP AL,"z"
|
||
ifdef DBCS
|
||
JA CAPS1 ; M003 MSKK TAR 476, kana chars
|
||
else
|
||
JG CAPS1
|
||
endif
|
||
AND AL,0DFH
|
||
CAPS1:
|
||
return
|
||
|
||
QUIT:
|
||
CMP ParamCt,1
|
||
JZ Quit1
|
||
CERR: JMP ComErr
|
||
Quit1: CMP Param1,0
|
||
JNZ CERR
|
||
MOV DX,OFFSET DG:QMES_ptr
|
||
call std_printf
|
||
|
||
IFDEF DBCS
|
||
CALL TESTKANJ
|
||
JZ ASCII
|
||
MOV AX, (STD_CON_INPUT_FLUSH SHL 8) + 0
|
||
INT 21H ; Eat the trailing byte.
|
||
JMP CRLF
|
||
ASCII:
|
||
ENDIF
|
||
;=========================================================================
|
||
; We are invoking the VAL_YN proc here. This will replace the
|
||
; method of Y/N validation used prior to DOS 4.00.
|
||
;
|
||
; Date : 6/10/87
|
||
;=========================================================================
|
||
|
||
call val_yn ;an000;pass Y/N byte in AL to macro
|
||
cmp ax,yes ;an000;did we return a Y
|
||
jz NoCRLF ;an000; dms; close the file
|
||
cmp ax,no ;an000; dms; return N?
|
||
; $if ne ;an000; dms; neither N or Y - reprompt
|
||
JE $$IF11
|
||
call crlf ; spit out crlf
|
||
jmp Quit1 ;an000; dms; reprompt
|
||
; $endif ;an000; dms;
|
||
$$IF11:
|
||
call crlf ; spit out CRLF
|
||
return ;an000; dms;
|
||
|
||
;=========================================================================
|
||
; End of Y/N validation check for qmes_ptr
|
||
;=========================================================================
|
||
|
||
NOCRLF:
|
||
MOV BX,[WRT_HANDLE]
|
||
MOV AH,CLOSE
|
||
INT 21H
|
||
MOV DX,OFFSET DG:TEMP_PATH
|
||
MOV AH,UNLINK
|
||
INT 21H
|
||
mov ah,exit
|
||
xor al,al
|
||
INT 21H
|
||
|
||
QUERY:
|
||
TEST BYTE PTR [QFLG],-1
|
||
retz
|
||
MOV DX,OFFSET DG:ASK_ptr
|
||
call std_printf
|
||
PUSH AX
|
||
CALL CRLF
|
||
POP AX
|
||
IFDEF DBCS
|
||
CALL TESTKANJ
|
||
JZ ASCII1
|
||
PUSH AX
|
||
MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0
|
||
INT 21H ;Eat the trailing byte
|
||
XOR AX,AX
|
||
INC AX ; non zero flag
|
||
POP AX
|
||
return
|
||
ASCII1:
|
||
ENDIF
|
||
CMP AL,13 ;Carriage return means yes
|
||
retz
|
||
;=========================================================================
|
||
; We are invoking the VAL_YN proc here. This will replace the
|
||
; method of Y/N validation used prior to DOS 4.00.
|
||
; This invocation of val_yn will return ZR if Y is found, otherwise
|
||
; it will return NZ.
|
||
;
|
||
; Date : 6/10/87
|
||
;=========================================================================
|
||
|
||
call val_yn ;an000;pass Y/N byte in AL to macro
|
||
cmp ax,yes ;an000;did we return a Y
|
||
je Query_Exit ;an000; dms; exit Y/N validation
|
||
cmp ax,no ;an000; dms; N response?
|
||
jne Query ;an000; dms; no - reprompt user
|
||
cmp ax,yes ;an000; dms; must have N response - force
|
||
; NZ flag
|
||
Query_Exit:
|
||
|
||
|
||
;=========================================================================
|
||
; End of Y/N validation check for ask_ptr
|
||
;=========================================================================
|
||
|
||
return
|
||
|
||
;=========================================================================
|
||
; EDLIN_DISP_COUNT: This routine will determine the number of lines
|
||
; actually displayed to the screen. Lines displayed to
|
||
; the screen for one EDLIN line printed will be calculated
|
||
; by the following formula:
|
||
;
|
||
; LINES_PRINTED = (LINE_LEN + 10) / SCREEN_WIDTH
|
||
;
|
||
; LINES_PRINTED - Actual number of lines printed on screen
|
||
; for one EDLIN line. If LINES_PRINTED has
|
||
; a remainder, it will be rounded up.
|
||
;
|
||
; LINE_LEN - The length, in bytes, of the EDLIN line
|
||
; printed.
|
||
;
|
||
; SCREEN_WIDTH - The width in bytes of the current display.
|
||
;
|
||
; Inputs : DI - offset into buffer containing line printed
|
||
; DISP_WIDTH - width of current video output
|
||
;
|
||
; Outputs: LC_ADJ - factor to adjust line counter by
|
||
;
|
||
; Date : 6/10/87
|
||
;=========================================================================
|
||
|
||
EDLIN_DISP_COUNT proc near ;an000;lines printed
|
||
|
||
push dx ;an000;save affected regs
|
||
push di ;an000;
|
||
push ax ;an000;
|
||
push bx ;an000;
|
||
push cx ;an000;
|
||
|
||
mov bx,offset dg:arg_buf ;an000;arg_buf holds line
|
||
; printed
|
||
mov ax,di ;an000;where print line ends
|
||
sub ax,bx ;an000;diff = line's length
|
||
add ax,10 ;an000;adjust for leading blks
|
||
mov cl,dg:disp_width ;an000;set up for division
|
||
div cl ;an000;divide AX by the
|
||
; width of the console
|
||
cmp ah,0 ;an000;see if a remainder
|
||
; $if nz ;an000;if a remainder
|
||
JZ $$IF13
|
||
add al,1 ;an000;increment AL 1
|
||
; to round upward
|
||
; $endif ;an000;
|
||
$$IF13:
|
||
|
||
mov lc_adj,al ;an000;number of lines printed
|
||
; on console
|
||
pop cx ;an000;restore affected regs
|
||
pop bx ;an000;
|
||
pop ax ;an000;
|
||
pop di ;an000;
|
||
pop dx ;an000;
|
||
|
||
ret ;an000;return to caller
|
||
|
||
EDLIN_DISP_COUNT endp ;an000;end proc
|
||
|
||
;=========================================================================
|
||
; EDLIN_PG_COUNT : This routine determines whether or not we will continue
|
||
; displaying text lines based on the count of lines that
|
||
; can be output to the current video screen.
|
||
;
|
||
; Inputs : LC_ADJ - adjustment factor for number of lines printed
|
||
; PG_COUNT - number of lines remaining on current video
|
||
; display
|
||
; DX - holds the total number of lines to print
|
||
; CONTINUE - signals if the user wants to continue
|
||
; printing lines.
|
||
;
|
||
; Outputs: LC_FLAG - used to signal completion of print
|
||
;
|
||
; Date : 6/10/87
|
||
;=========================================================================
|
||
|
||
EDLIN_PG_COUNT proc near ;an000;track remaining lines
|
||
|
||
push ax ;an000;save affected regs
|
||
|
||
mov lc_flag,true ;an000;init. flag to signal
|
||
; continue printing
|
||
|
||
mov al,pg_count ;an000;set up for page adj.
|
||
cmp al,lc_adj ;an000;see if we are at end
|
||
; $if be ;an000
|
||
JNBE $$IF15
|
||
mov pg_count,0 ;an000;set pg_count to 0
|
||
; $else
|
||
JMP SHORT $$EN15
|
||
$$IF15:
|
||
sub al,lc_adj ;an000;adjust number of lines
|
||
mov pg_count,al ;an000;save remaining line ct.
|
||
; $endif ;an000;
|
||
$$EN15:
|
||
|
||
dec dx ;an000;decrease total number
|
||
; of lines to print by 1
|
||
; $if nz ;an000;more lines to print
|
||
JZ $$IF18
|
||
cmp pg_count,0 ;an000;have we printed screen
|
||
; $if be ;an000;we have printed screen
|
||
JNBE $$IF19
|
||
call EDLIN_PG_PROMPT ;an000;prompt the user to
|
||
; "Continue(Y/N)?"
|
||
cmp continue,true ;an000;did user say continue
|
||
; $if z ;an000;continue
|
||
JNZ $$IF20
|
||
mov al,dg:disp_len ;an000;begin init of screen
|
||
; dec al ;an000; length
|
||
mov pg_count,al ;an000;
|
||
; $else ;an000;do not continue
|
||
JMP SHORT $$EN20
|
||
$$IF20:
|
||
mov lc_flag,false ;an000;signal no more to print
|
||
; $endif ;an000;
|
||
$$EN20:
|
||
; $endif ;an000;
|
||
$$IF19:
|
||
; $else ;an000;total lines printed
|
||
JMP SHORT $$EN18
|
||
$$IF18:
|
||
mov lc_flag,false ;an000;signal no more to print
|
||
; $endif ;an000;
|
||
$$EN18:
|
||
|
||
pop ax ;an000;restore affected regs
|
||
|
||
ret ;an000;return to caller
|
||
|
||
EDLIN_PG_COUNT endp ;an000;end procedure
|
||
|
||
;=========================================================================
|
||
; EDLIN_PG_PROMPT : This routine prompts the user as to whether or not to
|
||
; continue printing lines to the video display, if lines
|
||
; are still present for printing.
|
||
;
|
||
; Inputs : none
|
||
;
|
||
; Outputs: CONTINUE - flag that signals other routines whether or
|
||
; not to continue printing.
|
||
;
|
||
; Date : 6/10/87
|
||
;=========================================================================
|
||
|
||
EDLIN_PG_PROMPT proc near ;an000;ask user to continue?
|
||
|
||
push dx ;an000;save affected regs.
|
||
push ax ;an000;
|
||
|
||
EPP_Reprompt:
|
||
|
||
mov dx,offset dg:cont_ptr ;an000;point to Continue msg.
|
||
call std_printf ;an000;invoke message ret.
|
||
|
||
push ax ;an000;save affected regs.
|
||
call crlf ;an000;send crlf
|
||
pop ax ;an000;restore affected regs.
|
||
|
||
call val_yn ;an000;Y/N validation
|
||
|
||
cmp ax,yes ;an000;did we have a Y
|
||
jz EPP_True_Exit ;an000;we had a Y
|
||
cmp ax,no ;an000;did we have a N
|
||
jz EPP_False_Exit ;an000;yes
|
||
jmp EPP_Reprompt ;an000;neither Y or N - reprompt
|
||
|
||
EPP_True_Exit:
|
||
|
||
mov Continue,True ;an000;flag Y found
|
||
jmp short EPP_Exit ;an000;exit routine
|
||
|
||
EPP_False_Exit:
|
||
|
||
mov Continue,False ;an000;flag N found
|
||
|
||
EPP_Exit:
|
||
|
||
pop ax ;an000;restore affected regs.
|
||
pop dx ;an000;
|
||
|
||
ret ;an000;return to caller
|
||
|
||
EDLIN_PG_PROMPT endp ;an000;end procedure
|
||
|
||
;=========================================================================
|
||
; val_yn: This proc validates a Y/N response entered by the user. The
|
||
; routine uses the new functionality of "GET EXTENDED COUNTRY
|
||
; INFORMATION" being implemented in DOS 4.00.
|
||
;
|
||
; Inputs : AL - character to be validated for Y/N response
|
||
;
|
||
; Outputs: AX - 00h = "N"o
|
||
; - 01h = "Y"es
|
||
;=========================================================================
|
||
|
||
val_yn proc near ;an000;validate Y/N response
|
||
|
||
push dx ;an000;save affected registers
|
||
push cx ;an000;
|
||
push bx ;an000;
|
||
|
||
mov dl,al ;an000;character to be checked for Y/N
|
||
mov ah,GetExtCntry ;an000;get extended country information
|
||
mov al,yn_chk ;an000;perform Y/N checking
|
||
mov cx,max_len ;an000;max. len. of Y/N char.
|
||
int 21h ;an000;invoke function
|
||
|
||
pop bx ;an000;restore affected registers
|
||
pop cx ;an000;
|
||
pop dx ;an000;
|
||
|
||
ret ;an000;return to caller
|
||
|
||
val_yn endp ;an000;end proc
|
||
|
||
|
||
|
||
code ends
|
||
end
|
||
|