mirror of
https://github.com/microsoft/MS-DOS.git
synced 2024-12-01 18:15:47 +00:00
531 lines
13 KiB
NASM
531 lines
13 KiB
NASM
|
||
|
||
FALSE EQU 0
|
||
TRUE EQU NOT FALSE
|
||
|
||
KANJI EQU FALSE
|
||
|
||
roprot equ FALSE ;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
|
||
|
||
EXTRN TXT1:BYTE,TXT2:BYTE,FUDGE:BYTE,HARDCH:DWORD,USERDIR:BYTE
|
||
|
||
CONST ENDS
|
||
|
||
DATA SEGMENT PUBLIC WORD
|
||
|
||
EXTRN OLDLEN:WORD,OLDDAT:BYTE,SRCHFLG:BYTE,COMLINE:WORD
|
||
EXTRN PARAM1:WORD,PARAM2:WORD,NEWLEN:WORD,SRCHMOD:BYTE
|
||
EXTRN CURRENT:WORD,POINTER:WORD,START:BYTE,ENDTXT:WORD
|
||
EXTRN USER_DRIVE:BYTE,LSTNUM:WORD,NUMPOS:WORD,LSTFND:WORD
|
||
EXTRN SRCHCNT:WORD
|
||
|
||
DATA ENDS
|
||
|
||
DG GROUP CODE,CONST,DATA
|
||
|
||
CODE SEGMENT PUBLIC
|
||
|
||
ASSUME CS:DG,DS:DG,SS:DG,ES:DG
|
||
|
||
PUBLIC REST_DIR,KILL_BL,INT_24,SCANLN,FINDLIN,SHOWNUM
|
||
PUBLIC FNDFIRST,FNDNEXT,CRLF,LF,OUT,UNQUOTE
|
||
|
||
if kanji
|
||
PUBLIC TESTKANJ
|
||
endif
|
||
|
||
EXTRN CHKRANGE:NEAR
|
||
|
||
EDLPROC:
|
||
|
||
RET1: RET
|
||
|
||
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 RET1
|
||
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: ret
|
||
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
|
||
JNZ RET11
|
||
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
|
||
if kanji
|
||
dec si ;Want to look at the first character again
|
||
dec di
|
||
kanjchar:
|
||
lodsb
|
||
call testkanj
|
||
jz nxt_kj_char
|
||
xchg ah,al
|
||
lodsb
|
||
mov bx,[di]
|
||
add di,2
|
||
cmp ax,bx
|
||
jnz not_kj_match
|
||
dec cx
|
||
loop kanjchar
|
||
nxt_kj_char:
|
||
cmp al,byte ptr[di]
|
||
jnz not_kj_match
|
||
inc di
|
||
loop kanjchar
|
||
|
||
not_kj_match:
|
||
else
|
||
REPE CMPSB
|
||
endif
|
||
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
|
||
RET11: RET
|
||
|
||
|
||
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
|
||
RET
|
||
|
||
OLDTXT:
|
||
cmp byte ptr[olddat],1 ;replace with old text?
|
||
je sj11 ;yes...
|
||
mov byte ptr[di-1],cl ;zero text buffer char count
|
||
ret
|
||
|
||
sj11:
|
||
MOV CL,BYTE PTR [DI-1]
|
||
ADD DI,CX
|
||
RET
|
||
|
||
|
||
FINDLIN:
|
||
|
||
; Inputs
|
||
; BX = Line number to be located in buffer (0 means last line)
|
||
; Outputs:
|
||
; DX = Actual line found
|
||
; DI = Pointer to start of line DX
|
||
; Zero set if BX = DX
|
||
; AL,CX destroyed. No other registers affected.
|
||
|
||
MOV DX,[CURRENT]
|
||
MOV DI,[POINTER]
|
||
CMP BX,DX
|
||
JZ RET4
|
||
JA FINDIT
|
||
OR BX,BX
|
||
JZ FINDIT
|
||
MOV DX,1
|
||
MOV DI,OFFSET DG:START
|
||
CMP BX,DX
|
||
JZ RET4
|
||
FINDIT:
|
||
MOV CX,[ENDTXT]
|
||
SUB CX,DI
|
||
SCANLN:
|
||
MOV AL,10
|
||
OR AL,AL ;Clear zero flag
|
||
FINLIN:
|
||
JCXZ RET4
|
||
REPNE SCASB
|
||
INC DX
|
||
CMP BX,DX
|
||
JNZ FINLIN
|
||
RET4: RET
|
||
|
||
|
||
SHOWNUM:
|
||
|
||
; 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.
|
||
|
||
PUSH BX
|
||
MOV AL," "
|
||
CALL OUT
|
||
CALL CONV10
|
||
MOV AL,":"
|
||
CALL OUT
|
||
MOV AL,"*"
|
||
POP BX
|
||
CMP BX,[CURRENT]
|
||
JZ STARLIN
|
||
MOV AL," "
|
||
STARLIN:
|
||
JMP OUT
|
||
|
||
|
||
CONV10:
|
||
|
||
;Inputs:
|
||
; BX = Binary number to be displayed
|
||
; Function:
|
||
; Ouputs binary number. Five digits with leading
|
||
; zero suppression. Zero prints 5 blanks.
|
||
|
||
XOR AX,AX
|
||
MOV DL,AL
|
||
MOV CX,16
|
||
CONV:
|
||
SHL BX,1
|
||
ADC AL,AL
|
||
DAA
|
||
XCHG AL,AH
|
||
ADC AL,AL
|
||
DAA
|
||
XCHG AL,AH
|
||
ADC DL,DL
|
||
LOOP CONV
|
||
MOV BL,"0"-" "
|
||
XCHG AX,DX
|
||
CALL LDIG
|
||
MOV AL,DH
|
||
CALL DIGITS
|
||
MOV AL,DL
|
||
DIGITS:
|
||
MOV DH,AL
|
||
SHR AL,1
|
||
SHR AL,1
|
||
SHR AL,1
|
||
SHR AL,1
|
||
CALL LDIG
|
||
MOV AL,DH
|
||
LDIG:
|
||
AND AL,0FH
|
||
JZ ZERDIG
|
||
MOV BL,0
|
||
ZERDIG:
|
||
ADD AL,"0"
|
||
SUB AL,BL
|
||
JMP OUT
|
||
|
||
RET5: RET
|
||
|
||
|
||
CRLF:
|
||
MOV AL,13
|
||
CALL OUT
|
||
LF:
|
||
MOV AL,10
|
||
OUT:
|
||
PUSH DX
|
||
XCHG AX,DX
|
||
MOV AH,STD_CON_OUTPUT
|
||
INT 21H
|
||
XCHG AX,DX
|
||
POP DX
|
||
RET
|
||
|
||
|
||
;-----------------------------------------------------------------------;
|
||
; 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
|
||
ret
|
||
|
||
|
||
;-----------------------------------------------------------------------;
|
||
; 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:
|
||
ret
|
||
|
||
|
||
;---- Kill spaces in buffer --------------------------------------------;
|
||
kill_bl:
|
||
lodsb ;get rid of blanks
|
||
cmp al,' '
|
||
je kill_bl
|
||
ret
|
||
|
||
|
||
;----- Restore INT 24 vector and old current directory -----------------;
|
||
rest_dir:
|
||
cmp [fudge],0
|
||
je no_fudge
|
||
|
||
mov ax,(set_interrupt_vector shl 8) or 24h
|
||
lds dx,[hardch]
|
||
int 21h
|
||
push cs
|
||
pop ds
|
||
|
||
mov dx,offset dg:userdir ;restore directory
|
||
mov ah,chdir
|
||
int 21h
|
||
mov dl,[user_drive] ;restore old current drive
|
||
mov ah,set_default_drive
|
||
int 21h
|
||
|
||
no_fudge:
|
||
ret
|
||
|
||
;----- INT 24 Processing -----------------------------------------------;
|
||
|
||
int_24_retaddr dw offset dg:int_24_back
|
||
|
||
int_24 proc far
|
||
assume ds:nothing,es:nothing,ss:nothing
|
||
|
||
pushf
|
||
push cs
|
||
push [int_24_retaddr]
|
||
push word ptr [hardch+2]
|
||
push word ptr [hardch]
|
||
ret
|
||
int_24 endp
|
||
|
||
int_24_back:
|
||
cmp al,2 ;abort?
|
||
jnz ireti
|
||
push cs
|
||
pop ds
|
||
|
||
assume ds:dg
|
||
|
||
call rest_dir
|
||
int 20h
|
||
ireti:
|
||
iret
|
||
|
||
IF KANJI
|
||
TESTKANJ:
|
||
CMP AL,81H
|
||
JB NOTLEAD
|
||
CMP AL,9FH
|
||
JBE ISLEAD
|
||
CMP AL,0E0H
|
||
JB NOTLEAD
|
||
CMP AL,0FCH
|
||
JBE ISLEAD
|
||
NOTLEAD:
|
||
PUSH AX
|
||
XOR AX,AX ;Set zero
|
||
POP AX
|
||
RET
|
||
|
||
ISLEAD:
|
||
PUSH AX
|
||
XOR AX,AX ;Set zero
|
||
INC AX ;Reset zero
|
||
POP AX
|
||
RET
|
||
ENDIF
|
||
|
||
;-----------------------------------------------------------------------;
|
||
|
||
CODE ENDS
|
||
END EDLPROC
|
||
|