📄 genercfg.a86
字号:
jae func_return20 ; no, cannot RETURN
pop cfg_seekhi
pop cfg_seeklo ; restore position in file
mov cfg_tail,0 ; force a read
push bx
call atoi ; returning a value ?
pop bx
jnc func_return10 ; default to 0
xor ax,ax
func_return10:
mov error_level,ax ; return result in error level
func_return20:
push bx ; save return address
ret ; and return to it
func_goto: ; GOTO="label"
;---------
mov di,offset dev_name ; Copy the label into a
mov byte ptr [di],0 ; local buffer and zero terminate
call copy_file
jc func_goto10 ; ignore if any problems
mov cfg_seeklo,0 ; Seek to start of file
mov cfg_seekhi,0
mov cfg_tail,0 ; force a re-read
func_goto5:
call readline ; read in a line
jc func_goto10 ; stop if end of file
call strupr ; upper case possible label
mov bx,offset cfg_buffer
cmp ds:byte ptr [bx],':' ; is it a label ?
jne func_goto5 ; no, try next line
mov si,offset dev_name
func_goto6:
inc bx ; next char in possible label
lodsb ; get a character
test al,al ; end of label ?
je func_goto10 ; we have a match !
cmp al,ds:byte ptr [bx] ; does it match
jne func_goto5 ; no, try next line
jmps func_goto6 ; yes, look at next character
func_goto10:
ret
func_exit:
; Stop processing CONFIG.SYS
call readline ; read in a line
jnc func_exit ; until we can read no more..
ret
func_cls:
; CLEAR SCREEN
; This is PC specific - sorry
mov ah,15 ; get current
int 10h ; screen mode
mov ah,0
int 10h ; reset it to clear screen
ret
func_cpos:
; Set cursor position
call atoi ; AX = row
jnc func_cpos10 ; check for error
xor ax,ax ; default to top left
jmps func_cpos40
func_cpos10:
push ax ; save row
call separator ; look for ','
jc func_cpos20 ; no col specified
call atoi ; get col
jnc func_cpos30
func_cpos20:
mov ax,1 ; default to left
func_cpos30:
pop dx
mov ah,dl ; AH = row, AL = col
sub ax,0101h ; compensate for being one based
func_cpos40:
xchg ax,dx ; DH = row, DL = col
xor bx,bx ; page zero
mov ah,2 ; set cursor position
int 10h ; Eeeek!! call the ROS
ret
func_timeout:
; set TIMEOUT for keyboard input
call atoi ; AX = # timeout count
jnc func_timeout10 ; check for error
xor ax,ax ; bad values mean no timeout
func_timeout10:
mov keyb_timeout,ax ; save timeout count
call separator ; look for ','
jc func_timeout20
lodsb ; get default query char
cmp al,LF ! je func_timeout20
cmp al,CR ! je func_timeout20
mov default_query_char,al
call separator ; look for ','
jc func_timeout20
lodsb ; get default switch char
cmp al,CR ! je func_timeout20
cmp al,LF ! je func_timeout20
mov default_switch_char,al
func_timeout20:
ret
func_error:
; ERROR='n'
call atoi ; AX = error count to match
jc func_error10
mov error_level,ax ; set error level
func_error10:
ret
func_onerror:
; ONERROR='n' optional command
;
call whitespace ; Scan off all white space
xor bx,bx ; index relationship = 1st item
xor dx,dx ; DX is bit to set
func_onerror10:
or bx,dx ; set reationship bit
lodsb ; now process a character
mov dx,2
cmp al,'=' ; if '=' set bit 1
je func_onerror10
mov dx,4
cmp al,'<' ; if '<' set bit 2
je func_onerror10
mov dx,8
cmp al,'>' ; if '>' set bit 3
je func_onerror10
dec si ; point at char
push bx ; save relationship
call atoi ; AX = error count to match
pop bx ; recover relationship
jc func_onerror20
cmp error_level,ax ; is it the error level we want ?
jmp func_onerror_tbl[bx] ; jump to handler
func_onerror20:
ret
func_onerror_tbl:
dw func_onerror_eq ; . . .
dw func_onerror_eq ; . . =
dw func_onerror_lt ; . < .
dw func_onerror_le ; . < =
dw func_onerror_gt ; > . .
dw func_onerror_ge ; > . =
dw func_onerror_ne ; > < .
dw func_onerror_take ; > < =
func_onerror_eq:
je func_onerror_take
ret
func_onerror_ne:
jne func_onerror_take
ret
func_onerror_lt:
jb func_onerror_take
ret
func_onerror_le:
jbe func_onerror_take
ret
func_onerror_gt:
ja func_onerror_take
ret
func_onerror_ge:
jae func_onerror_take
ret
func_onerror_take:
pop ax ; discard return address
xor ax,ax ; boot key options = none
jmp cfg_continue ; and execute this command
func_query:
; ?optional command
cmp boot_options,F5KEY ; if F5 has been pressed then
je func_query50 ; do nothing
call whitespace ; discard any following whitespace
lodsb ; get a character
cmp al,'?' ; is it another '?', is so swallow it
je func_query ; and go round again
dec si ; it wasn't a '?', forget we looked
push si ; save current position
lodsb ; get next real char
xor cx,cx ; assume no prompt string
cmp al,'"' ; '?"user prompt"' - keep silent as
jne func_query10 ; user has supplied prompt
xchg ax,cx ; CL = " if user prompt
lodsb
func_query10:
cmp al,cl ; is this the user prompt char ?
je func_query20 ; then stop now
xchg ax,dx ; DL= character
mov ah,MS_C_WRITE
int DOS_INT ; output the character
lodsb
cmp al,CR ; is it the end of the line ?
jne func_query10 ; no, do another character
mov ah,MS_C_WRITESTR ; Output msg of form " (Y/N) ? "
mov dx,offset confirm_msg1
int DOS_INT ; do " ("
mov ah,MS_C_WRITE
mov dl,yes_char
int DOS_INT ; do "Y"
mov dl,'/'
int DOS_INT ; do "/"
mov dl,no_char
int DOS_INT ; do "N"
mov ah,MS_C_WRITESTR
mov dx,offset confirm_msg2
int DOS_INT ; do ") ? "
func_query20:
jcxz func_query30 ; if no user supplied prompt
pop ax ; don't discard original starting
push si ; position
func_query30:
call wait_for_key ; wait until a key is pressed
mov al,default_query_char ; if we timeout default
jc func_query40
mov ah,MS_C_RAWIN
int DOS_INT ; read a char
test al,al ; is it a function key ?
jnz func_query40
mov ah,MS_C_RAWIN
int DOS_INT ; throw away function keys
jmps func_query30
func_query40:
push ax ; save response
mov ah,MS_C_WRITE
mov dl,al
int DOS_INT ; echo the char
mov ah,MS_C_WRITESTR
mov dx,offset confirm_msg3
int DOS_INT ; now do CR/LF to tidy up
pop ax
call toupper ; make response upper case
pop si ; recover starting position
cmp al,yes_char
jne func_query50
pop ax ; Discard Return Address
xor ax,ax ; boot key options = none
jmp cfg_continue ; Execute the command
func_query50:
ret ; Return without Executing Command
func_getkey: ; GETKEY
call wait_for_key ; wait until a key is pressed
mov ax,CONFIG_ERRLVL ; assume we have timed out
jc func_getkey10 ; ignore if timeout
mov ah,MS_C_RAWIN
int DOS_INT ; read a char
xor ah,ah ; convert to word
func_getkey10:
mov error_level,ax
ret
; CONFIG_ERROR is the global error handler for the CONFIG.SYS
; commands. It is called with SI pointing to the CR/LF terminated string
; that caused the error and with DX pointing to an "informative" error
; message.
;
; On Entry:- AL Terminating Character
; DX Offset of Error Message
; SI 0000 No Message to display
; Offset of AL terminated string
;
config_error:
if ADDDRV
mov error_flag,1
endif
push ax
mov ah,MS_C_WRITESTR ; Print the Error Message
int DOS_INT ; passed in DX
pop ax
mov ah,al ; AH = terminating character
test si,si ; display the failing string ?
jz cfg_e20 ; YES then scan for terminator
cfg_e10:
lodsb ; get char to display
cmp al,ah ; have we reached the terminator ?
je cfg_e20
xchg ax,dx ; DL = character to display
mov ah,MS_C_WRITE ; print a character at a time
int DOS_INT
xchg ax,dx ; terminator back in AH
jmps cfg_e10
cfg_e20:
;; jmp crlf ; Terminate with a CRLF
Public crlf
crlf:
push dx
mov dx,offset msg_crlf ; Print a CR LF
mov ah,MS_C_WRITESTR
int DOS_INT
pop dx
ret
;
; Scan the command table for a match with the first entry in the
; CR/LF terminated string passed in SI
scan:
call whitespace ; scan off all white space
push bx ; save the CONFIG Handle
mov bx,offset cfg_table - CFG_SIZE
scan_10:
add bx,CFG_SIZE ; bx -> next entry in table
mov di,CFG_NAME[bx] ; es:di -> next entry name
test di,di ; end of table ?
stc ; assume so
jz scan_exit ; Yes Exit with the Carry Flag Set
push si ; Save the String Offset
call compare
pop ax ; Remove String Address
jnc scan_20 ; String Matched
xchg ax,si ; Restore the original String Address
jmps scan_10 ; and test the next entry
scan_20:
and CFG_FLAGS[bx],not CF_QUERY
test CFG_FLAGS[bx],CF_LC ; should we upper case line ?
jnz scan_50 ; skip if not
xchg ax,si
call strupr ; upper case the command line
xchg ax,si
scan_30:
call whitespace ; Scan off all white space before and
lodsb ; after the option '=' character
cmp al,'?' ; are we querying things ?
jne scan_40
or CFG_FLAGS[bx],CF_QUERY ; remember the query, now go and
jmps scan_30 ; remove any other whitespace
scan_40:
cmp al,'=' ; '=' character.
je scan_30
dec si
scan_50:
mov di,bx ; Save the Table Entry
xor ax,ax ; and exit with the Carry Flag Reset
scan_exit:
pop bx
ret
; Compare two strings in case insensitive manner
; On Entry:
; ds:si -> String 1 (upper/lower case, length determined by string 2)
; es:di -> String 2 (uppercase, null terminated)
; On Exit:
; Carry clear: strings are the same
; ds:si -> character immediately following end of string 1
; es:di -> character immediately following end on string 2
;
; Carry set: strings different
; ds:si -> As on entry
; es:di -> undefined
;
compare:
;-------
push bx
push si ; save starting position
compare10:
mov al,es:[di] ; al = next character
inc di
test al,al ; end of string 2 yet ?
jz compare40 ; yes, strings must be equal
call dbcs_lead ; DBCS lead byte?
jnz compare20 ; no
mov ah,al
lodsb ; is 1st byte of pair the same ?
cmp al,ah
jne compare30
cmpsb ; is 2nd byte of pair equal ?
jne compare30
jmps compare10
compare20:
call toupper ; just uppercase this byte
xchg ax,bx ; BL = string2 character
lodsb ; al = next char in string 1
call toupper ; (can't be KANJI if it matches)
cmp al,bl ; check the characters are
je compare10 ; identical stop the compare
compare30:
stc ; on a mismatch and set CY
compare40:
pop bx ; recover starting position
jnc compare50
mov si,bx ; SI = original start
compare50:
pop bx
ret
separator:
;---------
; On Entry:
; DS:SI -> string
; On Exit:
; DS:SI -> next option
; CY set if end of line
;
; Strips off all whitespace, and the optional ','
; CY set at end of line
call whitespace ; deblank string and
lodsb ; check for ',' separator
cmp al,',' ; discarding if found
je separator10
cmp al,CR ; end of the line ?
stc ; assume so
je separator10
dec si ; something else, leave alone
clc ; not end of line
separator10:
ret
separator20:
call whitespace ; strip of following spaces
clc ; not end of line
ret
strupr:
;------
; Uppercase a null terminated string.
; Entry
; ds:si -> null terminated string
; Exit
; none (string is uppercased)
; Lost
; no registers changed
push si
push ax
spr_loop:
mov al, [si] ; al = next byte from string
test al, al ; end of string?
jz spr_done ; yes - exit
; cmp al,' ' ; BAP. End at first space
; je spr_done ; or comma or slash
; cmp al,',' ; so that parameters
; je spr_done ; are not uppercased
; cmp al,'/' ; Took out again cos it caused
; je spr_done ; problems with labels (I think).
call dbcs_lead ; DBCS lead byte?
jnz spr_not_dbcs ; no
inc si ; yes - skip first and second bytes of
inc si ; pair as they cannot be uppercased
jmp spr_loop ; loop round
spr_not_dbcs:
call toupper ; just uppercase this byte
mov [si], al ; return the result to the string
inc si
jmp spr_loop ; continue
spr_done:
pop ax
pop si
ret
dbcs_lead:
;---------
; Return true if given byte is the first of a double byte character.
; Entry
; al = byte to be tested
; Exit
; Z Flag = 1 - byte is a DBCS lead
; 0 - byte is not a DBCS lead
; Lost
; no registers changed
push ds
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -