📄 misc.a86
字号:
mov reg_BX[bp],TRUE_VERSION ; return version number
mov ax,patch_version
mov reg_DX[bp],ax ; return revision+HMA
ret
endif
;
; *****************************
; *** DOS Function 25 ***
; *** Set Interrupt Vector ***
; *****************************
;
; WARNING - use no stack as device drivers have called us re-entrantly
Public func25
func25:
mov bx,es ; is really dos_DS - save for later
xor di,di ; replace with the values in dos_DS:DX
mov es,di ; es -> zero segment
xor ah,ah ; the interrupt number
mov di,ax ; 0:di -> vector
shl di,1 ! shl di,1 ; 4 bytes per vector
cli
xchg ax,dx ; Get New Offset
stosw ; and Save
xchg ax,bx ; Get New Segment
stosw ; and Save
sti
xchg ax,dx ; recover entry AL to (preserve it)
ret
; *****************************
; *** DOS Function 35 ***
; *** Get Interrupt Vector ***
; *****************************
; WARNING - use no stack as device drivers have called us re-entrantly
Public func35
func35:
xor bx,bx
mov ds,bx ; DS:0 -> vector table
mov bl,al ; BX = the interrupt number
shl bx,1 ! shl bx,1 ; 4 bytes per vector
lds bx,ds:dword ptr [bx] ; DS:BX -> vector
les di,ss:int21regs_ptr
mov es:reg_BX[di],bx
mov es:reg_ES[di],ds
jmp get_dseg ; restore DS for return
;PC-DOS Verify and Break Flags Support
;
; *****************************
; *** DOS Function 2E ***
; *** Set/Reset Verify ***
; *****************************
Public func2E
func2E:
and al,1 ; only use bottom bit
mov verify_flag,al ; store for use later
ret
; *****************************
; *** DOS Function 54 ***
; *** Get Verify Setting ***
; *****************************
Public func54
func54:
mov al,verify_flag ; return verify flag
ret
; *****************************
; *** DOS Function 63 ***
; *** Get Lead Byte Table ***
; *****************************
;
Public func63
func63:
cmp al, 1 ; subfunction #?
jb f63_get_tbl ; subfunction 0
je f63_set_flg ; subfunction 1
cmp al, 2 ; subfunction 2?
je f63_get_flg ; yes
mov ax, ED_FUNCTION ; invalid subfunction number
jmp error_exit ; so quit
f63_get_flg:
; Get the current state of the DOS interim character console flag.
; If this flag is set int 21h functions 07h, 08h, 0Bh, 0Ch are supposed
; to return "interim character information" which I assume is incomplete
; characters. (In languages like Korean a given double byte character
; may be built by the user entering several keystrokes which form
; incomplete characters.)
mov es, current_psp
mov dl, PSP_RIC ; Return Interim Character flag
jmp return_DX ; flag returned in dl
f63_set_flg:
; Set the current state of the DOS interim character console flag.
; dos_DL = 0 - clear flag, dos_DL = 1 - set flag
mov es, current_psp
mov PSP_RIC, dl ; record flag
ret
f63_get_tbl:
; Get the current DBCS table address.
mov si,offset DBCS_tbl+2; skip the table size entry
; jmp return_DSSI
return_DSSI:
;-----------
; On Entry:
; DS:SI to be returned to caller
; On Exit:
; AX preserved
;
les di,ss:int21regs_ptr
mov es:reg_DS[di],ds
mov es:reg_SI[di],si
ret
;
; *****************************
; *** DOS Function 29 ***
; *** Parse String ***
; *****************************
Public func29
func29:
;
; Entry:
; DS:SI -> line to parse
; ES:DI -> resulting fcb
; Exit:
; DS:SI -> terminating delimeter past parsed filename
; ES:DI -> filled in fcb (Affects 16 bytes: DnnnnnnnnTTT0000)
;
push ds
push es
call reload_ES
pop ds
call parse
call return_DSSI ; return result of parse
pop ds
mov al,dh ; return result in AL
ret
;-----
parse: ; parse DOS filename delimited by TAB,SPACE,or .,+:;=|"/\[]<> or ctrl
;-----
; Entry:
; DS:SI -> line to parse
; ES:DI -> fcb to parse into
; AL == bit options:
; Bit 0 == 1: scan off leading delimiters
; Bit 1 == 1: change drive only if specified
; Bit 2 == 1: change name " " "
; Bit 3 == 1: change type " " "
; Exit:
; DS:SI -> terminating delimeter past parsed filename
; ES:DI -> filled in fcb (Affects 16 bytes: DnnnnnnnnTTT0000)
; DH == 1 if wild, 0FFh if the drive is invalid, 0 otherwise
;
push di ; (<--keep DI last on stack)
cld ; ChSh
xor dx,dx ; DH = default return value (0)
xchg al,dl ; put flags into DL, AL = 0
mov cx,1
test dl,0010b ; should we initialize drive?
call nz_store_al ; do conditional store
mov al,' ' ; use spaces for filename & typ
mov cl,8
test dl,0100b ; should we initialize the name?
call nz_store_al
mov cl,3
test dl,1000b ; should we initialize the typ?
call nz_store_al
xor ax,ax ; zero-out the 4 post-typ bytes
stos ax
stos ax
pop di ! push di ; restore DI to start of FCB
deblank_loop:
lods al ; grab char
cmp al,' ' ; is it a blank?
je deblank_loop ; Y: keep looping
cmp al,'I'-'@' ; is it a tab?
je deblank_loop ; Y: keep looping
test dl,0001b ; skip-delimiter-bit set?
jz parse_drive ; N: go start parsing
skip_delim_loop:
call check_delimiters ; check AL for delimiterness
jb parse_dec_ret ; found terminator, dec SI & leave
mov dl,dh ; flag no-more-delimiter-skip (DL = 0)
je deblank_loop ; found separator, go deblank after it
parse_drive:
dec si
cmp byte ptr 1[si],':' ; is the drive specified?
jne parse_name
lods ax ; get drive, junk colon
and al,01011111b ; upper case it
sub al,'@' ; AL = 1-relative drive #
push ax ! push ds ; Save the drive code and call
call get_dseg ; Restore our Data Segment
call valid_drive ; routine to validate drive ZR == OK
pop ds ! pop ax ; Restore drive code and User DS
jz parse_d10
dec dh ; flag drive error (0FFh)
parse_d10:
mov es:[di],al ; insert drive in fcb
parse_name:
inc di ; DI -> fname
mov cx,8
call parse_item ; parse an up-to 8 char filename
cmp dl,'.' ; was the delimeter a '.'?
jne parse_dec_ret ; N: the parse is complete
mov cl,3
call parse_item ; parse an up-to 3 char filetype
parse_dec_ret:
dec si ; bump SI back to point to delimeter
parse_ret:
pop di
ret
;-----------
nz_store_al:
;-----------
; Entry:
; DI -> destination to conditionally initialize
; CX == length of destination
; AL == byte to initialize with
; ZF set: do not initialize destination
; Exit:
; DI -> past destination (initial DI+CX)
; Changed:
; CX,DI
;
jnz skip_store ; should we initialize?
rep stosb ; Y: store them bytes
skip_store:
add di,cx ; bump DI to post-dest position
ret
;==========
parse_item: ; Parses item into fcb if item is specified
;==========
;
; Entry:
; SI -> item to parse (name or type)
; DI -> fcb area to parse it into
; CX == length of item
; DH == parse_return
; Exit:
; SI -> past ending delimeter
; DI -> past fcb area (initial DI + CX)
; CH == If zero on enter zero on exit else 0-255
; DH == updated parse_return w/possible wild bit set
; DL == character delimiter @(SI-1)
; Changed:
; AX,CX,DX,SI,DI
;
mov ah,FALSE ; specified item flag
parse_item_loop:
lods al ; get char
call check_delimiters ; is it a delimiter?
jbe pi_pad_ret ; Y: the parse is complete
jcxz parse_item_loop ; if the name is full, skip the char
mov ah,al ; flag name as present
cmp al,'?' ; is it a single wild char?
je pi_set_wild ; Y: set wild flag
cmp al,'*' ; is it a multi-char wild card?
jne pi_store ; N: store it
mov al,'?' ; Y: fill with '?' to end of name
rep stosb
pi_set_wild:
or dh,1 ; set wild flag
jcxz parse_item_loop ; skip store if name is now filled
pi_store:
dec cx ; another char done
call dbcs_lead ; is it the 1st byte of kanji ?
jne pi_store10
inc si ; skip 2nd byte
jcxz parse_item_loop ; can I copy both ?
dec cx ; yes, do so
stosb
dec si ; point at second byte
lodsb ; so we can copy it too..
pi_store10:
stos al ; put the char in the fcb
jmps parse_item_loop
pi_pad_ret:
mov dl,al ; DL = ending delimeter
or ah,ah ; the the item specified?
jz pi_ret ; N: skip padding
mov al,' ' ; Y: pad to end with spaces
rep stosb
pi_ret:
add di,cx ; bump DI out to end
ret
;----------------
check_delimiters:
;----------------
;
; Entry:
; AL == char to check in list of delimiters
; Exit:
; AL == char changed to uppercase
; CF set if it is one of the terminators: |"/\[]<> & ctrl chars != TAB
; ZF set if it is one of the separators: .,+:;= SPACE & TAB
; OR one of the non-ctrl terminators
;
cmp al,'a' ; check for lower case
jb not_lower
cmp al,'z'
ja not_lower
and al,01011111b ; uppercase it, CF clear, ZF clear
ret
not_lower:
push cx ! push di ! push es
push cs ! pop es ; ES = Code segment
mov di,offset parse_separators
mov cx,length parse_separators
repne scasb ; is AL a separator?
je cpd_pop_ret ; Y: return ZF set
mov cl,length parse_terminators
repne scasb ; is AL a terminator?
stc ; (set CF if true)
je cpd_pop_ret ; Y: return CF & ZF set
cmp al,' ' ; (AL == ' ') ZF set, (AL < ' ') CF set
cpd_pop_ret:
pop es ! pop di ! pop cx
ret
;
; *****************************
; *** DOS Function 2A ***
; *** Get Current Date ***
; *****************************
Public func2A
func2A:
;
; entry: None
;
; exit: cx = year (1980-2099)
; dh = month (1-12)
; dl = day (1-31)
; al = DOS returns day of week here
;
call ReadTimeAndDate ; Get the current Time and Date
mov cx,1980
add cx,yearsSince1980
; mov dl,dayOfMonth
; mov ah,month
mov dx,word ptr dayOfMonth
mov al,dayOfWeek
jmps f2C_10 ; exit via common routine
; *****************************
; *** DOS Function 2C ***
; *** Get Current Time ***
; *****************************
Public func2C
func2C:
;
; entry: None
;
; exit: ch = hours (0-23)
; cl = minutes (0-59)
; dh = seconds (0-59)
; dl = Hunredths seconds (0-99)
; al = 0
;
call ReadTimeAndDate ; Get the current Time and Date
mov cx,biosDate+2 ; Get the Hour and Minute
mov dx,biosDate+4 ; Get the Seconds and Hundredths
xor ax,ax ; return AL = 0
f2C_10:
call return_CX ; and return to caller
jmp return_DX
; *****************************
; *** DOS Function 2B ***
; *** Set Current Date ***
; *****************************
Public func2B
func2B:
;
; entry: cx = year (1980-2099)
; dh = month (1-12)
; dl = day (1-31)
;
; exit: al = 00H success
; = FFH failure
;
call ConvertDate ; Convert to BIOS date
jc f2B_20 ; Abort on Error
push cx ; save the converted date
call ReadTimeAndDate ; Get the current Time and Date
pop biosDate ; new date, existing time
f2B_10: ; Set the current Time and Date
call rw_clock_common ; make sure clock is there/setup regs
call device_write ; Update the Date and Time
xor ax,ax
ret
f2B_20:
mov al,0FFh ; return FAILURE
ret
; *****************************
; *** DOS Function 2D ***
; *** Set Current Time ***
; *****************************
Public func2D
func2D:
;
; entry: ch = hours (0-23)
; cl = minutes (0-59)
; dh = seconds (0-59)
; dl = hundredth seconds (0-99)
;
; exit: al = 00H success
; = FFH failure
;
cmp ch,23 ; Range check hours
ja f2B_20
cmp cl,59 ; Range check minutes
ja f2B_20
cmp dh,59 ; Range check seconds
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -