; ============================================================================
;
; MicroDOS - Parses
;
; ============================================================================
; ----------------------------------------------------------------------------
; Check reserved device name
; ----------------------------------------------------------------------------
; INPUT: DS = data segment
; ES = data segment
; OUTPUT: CY = invalid device name
; BL = device handles (0=CON, 1=AUX, 2=PRN, 3=NUL)
; BH = 0ffh (flag of device)
; ----------------------------------------------------------------------------
; ------------- Push registers
CheckDev: push ax ; push AX
push cx ; push CX
push si ; push SI
push di ; push DI
; ------------- Prepare registers
cld ; set direction up
mov si,ResDevName ; SI <- table of device names
xor bx,bx ; BX <- device index
; ------------- Find name in table
CheckDev2: mov di,CurFilename ; DI <- current filename
mov cx,4 ; CX <- length of device name
repe cmpsb ; compare name
je CheckDev6 ; name is OK
; ------------- Next name in table
add si,cx ; SI <- next name
inc bx ; device index
cmp bl,6 ; end of table?
jb CheckDev2 ; next
CheckDev4: stc ; set error flag
jmp short CheckDev8
; ------------- Check rest of filename, if there are spaces
CheckDev6: mov al,SPACE ; space
mov cl,4 ; CX <- lengt of rest of name
repe scasb ; check rest of name
jne CheckDev4 ; invalid name
; ------------- Index of device -> BL
mov bl,[bx+ResDevInx] ; BL <- device file handle
mov bh,0ffh ; BH <- flag of device
clc ; clear error flag
; ------------- Pop registers
CheckDev8: pop di ; pop DI
pop si ; pop SI
pop cx ; pop CX
pop ax ; pop AX
ret
; ----------------------------------------------------------------------------
; Test space char
; ----------------------------------------------------------------------------
; INPUT: AL = ASCII character
; OUTPUT: ZY = it is space (20h) or tabulator (09h)
; ----------------------------------------------------------------------------
TestSpace: cmp al,TAB ; is it tabulator (09h)?
je TestSpace2 ; it is tabulator
cmp al,SPACE ; is it space (20h)?
TestSpace2: ret
; ----------------------------------------------------------------------------
; Test slash
; ----------------------------------------------------------------------------
; INPUT: AL = ASCII character
; OUTPUT: ZY = it is slash (2Fh) or backslash (5Ch)
; ----------------------------------------------------------------------------
TestSlash: cmp al,'/' ; is it slash (2Fh)?
je TestSlash2 ; it is slash
cmp al,'\' ; is it backslash (5Ch)?
TestSlash2: ret
; ----------------------------------------------------------------------------
; Load character from filename
; ----------------------------------------------------------------------------
; INPUT: DS:SI = data buffer with text
; OUTPUT: SI = new pointer in data buffer
; AL = ASCII character
; ZY = invalid filename character (include dott and slash)
; ----------------------------------------------------------------------------
; ------------- Push registers
GetFileChar: push bx ; push BX
push cx ; push CX
; ------------- Load character
cld ; direction up
lodsb ; load characters from text buffer
; ------------- Convert normal character to uppercase
cmp al,'a' ; minimal lowcase character value
jb GetFileChar2 ; it is not lowcase character
cmp al,'z' ; maximal lowcase character value
ja GetFileChar2 ; it is not lowcase character
sub al,32 ; convert to uppercase
; ------------- Test character with table
GetFileChar2: mov bx,InvFileName ; table of invalid characters
mov cx,InvFileName2-InvFileName ; number of characters
GetFileChar4: cmp al,[cs:bx] ; is it invalid character?
je GetFileChar8 ; it is invalid character
inc bx ; increase table pointer (clears ZF)
loop GetFileChar4 ; next character (here is NZ)
; ------------- Pop registers
GetFileChar8: pop cx ; pop CX
pop bx ; pop BX
ret
; ----------------------------------------------------------------------------
; Check and parse FCB
; ----------------------------------------------------------------------------
; INPUT: DS:DX = FCB or XFCB
; OUTPUT: CY = invalid FCB
; SI = pointer after filename of FCB
; SS:BP = DDPB of the disk
; ----------------------------------------------------------------------------
; ------------- Push registers
LoadFCB: push ax ; push AX
push cx ; push CX
push di ; push DI
push es ; push ES
; ------------- Clear flag to open HID and SYS files
mov byte [cs:OpenHidSys],0 ; don't open HID and SYS files
; ------------- Prepare registers
push cs ; push CS
pop es ; ES <- CS
mov si,dx ; SI <- FCB
; ------------- Prepare extended FCB flag
cld ; direction up
xor ax,ax ; AX <- 0 (normal attributes)
lodsb ; AL <- disk number
mov [cs:CurExtFlag],al ; store extended FCB flag
; ------------- Load attributes
cmp al,0ffh ; use extended FCB?
jne LoadFCB2 ; use normal FCB
add si,5 ; skip reserved bytes
lodsb ; AL <- attributes
mov ah,al ; AH <- attributes
lodsb ; AL <- disk number
LoadFCB2: mov [cs:CurAttrib],ah ; store file attributes
; ------------- Get disk table (-> BP)
call GetDDPB ; get disk table
jc LoadFCB9 ; invalid disk
; ------------- Check name (first character cannot be a space)
mov di,CurFilename ; DI <- current filename
LoadFCB3: cmp byte [si],SPACE ; is it valid name?
stc ; set error flag
je LoadFCB9 ; it is not valid name
; ------------- Store filename
mov cx,FILENAMELEN ; CX <- filename length
LoadFCB4: call GetFileChar ; load character from filename
jne LoadFCB6 ; valid character
cmp al,SPACE ; SPACE is valid
stc ; set error flag
jne LoadFCB9 ; error, invalid character
LoadFCB6: cmp al,20h ; is it control character?
jb LoadFCB9 ; error, control character is ilegal
stosb ; store character
loop LoadFCB4 ; next character (here is NC)
; ------------- Pop registers
LoadFCB9: pop es ; pop ES
pop di ; pop DI
pop cx ; pop CX
pop ax ; pop AX
ret
; ----------------------------------------------------------------------------
; Check and parse second filename in FCB
; ----------------------------------------------------------------------------
; INPUT: DS:SI = second filename in FCB or XFCB
; ES:DI = buffer to store filename
; SS:BP = DDPB of the disk
; OUTPUT: CY = invalid FCB
; SI = pointer after filename of FCB
; ----------------------------------------------------------------------------
Load2FCB: push ax ; push AX
push cx ; push CX
push di ; push DI
push es ; push ES
jmp short LoadFCB3 ; parse second filename
; ----------------------------------------------------------------------------
; Data
; ----------------------------------------------------------------------------
; ------------- Table of invalid filename characters
InvFileName: db TAB ; (9) tabelator
db SPACE ; (20h) space
db '"' ; (22h) double quotes
db '+' ; (2Bh) plus
db ',' ; (2Ch) comma
db '.' ; (2Eh) dot
db '/' ; (2Fh) slash
db ':' ; (3Ah) colon
db ';' ; (3Bh) semicolon
db '<' ; (3Ch) smaller
db '=' ; (3Dh) equals
db '>' ; (3Eh) greater
db '[' ; (5Bh) left square bracket
db '\' ; (5Ch) backslash
db ']' ; (5Dh) right square bracket
db '|' ; (7Ch) vertical line
InvFileName2: ; end of table
; ------------- Table of reserved names
ResDevName: db 'CON '
db 'AUX '
db 'COM1'
db 'PRN '
db 'LPT1'
db 'NUL '
; ------------- Device file handles
ResDevInx: db DEV_CON ; CON
db DEV_AUX ; AUX
db DEV_AUX ; COM1
db DEV_PRN ; PRN
db DEV_PRN ; LPT1
db DEV_NUL ; NUL
|