📄 dosif.asm
字号:
; BYTE Month
; BYTE Day
; BYTE Day of the Week (Ignored on SET DATE)
Public _ms_getdate
;-----------
_ms_getdate:
;-----------
push bp
mov bp,sp
mov dx,04[bp] ; Get the structure address
mov cl,T_GETDATE ; and call the BDOS
call bdos_entry
pop bp
CRET 2
Public _ms_setdate
;----------
_ms_setdate:
;----------
push bp
mov bp,sp
mov dx,4[bp] ; and get the structure address
mov cl,T_SETDATE ; and call the BDOS to do the work
call bdos_entry ; Return 0 Good and FFFF Bad
pop bp
CRET 2
; Time information is passed and return in a structure which
; has the following format.
;
; BYTE Hours (0 - 23)
; BYTE Minutes (0 - 59)
; BYTE Seconds (0 - 59)
; BYTE Hundredths of a second (0 - 99)
Public _ms_gettime
;----------
_ms_gettime:
;----------
push bp
mov bp,sp
mov dx,04[bp] ; Get the Time Structure address
mov cl,T_GETTIME ; and call the OS
call bdos_entry
pop bp
CRET 2
Public _ms_settime
;----------
_ms_settime:
;----------
push bp
mov bp,sp
mov dx,4[bp] ; and get the structure address
mov cl,T_SETTIME ; and call the BDOS SET Time Function
call bdos_entry ; Return 0 Good and FFFF Bad
pop bp
CRET 2
Public _ms_f_verify
;-----------
_ms_f_verify:
;-----------
push bp
mov bp,sp
push es
mov ax,04[bp] ; Get the required state
les bx,_pd ; Update the Verify flag in
and es:P_SFLAG[bx],not PSF_VERIFY ; current PD
or ax,ax ; Set the Flag
jz ms_fv10 ; No
or es:P_SFLAG[bx],PSF_VERIFY ; Flag set in PD
ms_fv10:
pop es
pop bp
ret
Public _ms_f_getverify
;--------------
_ms_f_getverify:
;--------------
push es
xor ax,ax ; Assume the flag is RESET
les bx,_pd ; now test the state of the
test es:P_SFLAG[bx],PSF_VERIFY ; flag in the current PD
jz ms_fgv10 ; Verify = OFF
inc ax ; Verify = ON
ms_fgv10:
pop es
ret
;
; mem_alloc(BYTE FAR * NEAR * bufaddr, UWORD * bufsize, UWORD min, UWORD max);
;
; max 10[bp]
; min 08[bp]
; bufsize 06[bp]
; buffadr 04[bp]
;
Public _mem_alloc
;---------
_mem_alloc:
;---------
push bp
mov bp,sp
mov mpb_start,0
mov ax,08[bp] ; Get the Minimum and Maximum values
mov mpb_min,ax ; and fill in the parameter block
mov ax,10[bp]
mov mpb_max,ax
mov mpb_pdadr,0
mov mpb_flags,0
mov cx,M_ALLOC ; Call the Concurrent Allocate function
mov dx,dataOFFSET mpb_start ;
call bdos_entry
xor cx,cx ; Assume that the function fails
mov dx,cx ; and zero the start and size fields
cmp ax,0
jnz mem_all10
mov cx,mpb_min ; Get the Allocation Size
mov dx,mpb_start ; and the starting segment
mem_all10:
mov bx,04[bp] ; Update the Buffer Address
mov word ptr 00[bx],0 ; Offset 0
mov word ptr 02[bx],dx ; Segment DX
mov bx,06[bp] ; Now Update the Buffer Size
mov word ptr 00[bx],cx ; and return to the caller
pop bp
ret
;
; mem_free(BYTE FAR * NEAR * bufaddr);
;
; buffadr 04[bp]
;
Public _mem_free
;---------
_mem_free:
;---------
push bp
mov bp,sp
xor ax,ax
mov bx,04[bp] ; Get the Buffer Pointer address
xchg ax,word ptr 02[bx] ; and from this the segment of the
cmp ax,0 ; allocated memory. If the memory
jz mem_free10 ; has already been freed the quit
mov mfpb_start,ax ; Otherwise Free the Memory
mov mfpb_res,0
mov cx,M_FREE
mov dx,dataOFFSET mfpb_start
call bdos_entry
mem_free10:
pop bp
ret
;
; findfile(BYTE *loadpath, UWORD *loadtype)
;
Public _findfile
_findfile:
push bp
mov bp,sp
mov al,OK_RF ; Retry, Ignore or Fail
call fdos_retry
mov ax,word ptr 04[bp]
mov exec_pathoff,ax
mov exec_pathseg,ds
mov cx,P_PATH
mov dx,dataOFFSET exec_block
call ppath_entry
or ax,ax
jnz ff_error
mov al,exec_filetype
cbw
mov bx,word ptr 06[bp]
mov word ptr [bx],ax
xor ax,ax
ff_error:
pop bp
ret
;
fdos_retry:
xor ah,ah
mov valid,ax ; Save the Valid Error responses
pop retry_ip ; Get the return Address
mov retry_sp,sp ; and Stack Pointer
jmp retry_ip
;
; FDOS_ENTRY is an internal function entry point which makes the
; F_DOS function call. As the F_DOS data area used by COMMAND.COM
; is always FDOS_DATA.
;
; WORD PASCAL critical_error(error, valid, drive, mode, server);
;
; critical_error will return an WORD response which (R,I,A,F)
; after displaying the appropriate error message and get the
; correct response from the user.
;
fdos_entry:
mov cl,F_DOS
mov dx,dataOFFSET fdos_data
ppath_entry:
call bdos_entry
cmp ax,ED_LASTERROR ; Did an Error Occur
jb fdos_exit ; No So Exit OK
cmp crit_flg,TRUE ; Already in handler
jz fdos_exit ; Yes Skip Critical Error
cmp ax,ED_PROTECT ; Is this a Physical Error
jg fdos_exit ; if so then simulate a
cmp ax,ED_GENFAIL ; Critical Error by calling
jge fdos_e05 ; the COMMAND routine Critical
; error
cmp ax,ED_NETPWD ; Now check for DR-NET errors
jg fdos_exit ; if so then simulate a
cmp ax,ED_NETLOG ; Critical Error by calling
jge fdos_e05 ; the COMMAND routine Critical
; error
fdos_exit:
ret
fdos_e05:
push retry_ip ; Save Retry IP and SP and valid
push retry_sp ; responses
push valid
mov crit_flg,TRUE ; Start Critical Section
mov cx,es ; Save the Segment Regsiter
push ax ; Save the Error Code
push valid ; Save the Valid Responses (R,I,F)
les bx,_pd ; Get the PD address
mov es,es:P_UDA[bx] ; and then the UDA address
xor ah,ah ; Zero the top byte of AX and
mov al,es:byte ptr 15h ;;U_ERR_DRV ; Get the Failing Drive
push ax ; Save on the Stack
mov al,es:byte ptr 14h ;;U_ERR_RW ; Get the Error Mode
push ax ; and Save
mov ax,00FFH ; Default Server NO is (INVALID)
les bx,_pd ; Get the PD address Again
mov bx,es:P_NDA[bx] ; and then the NDA address
cmp bx,0 ; Are we attached to DR-NET
jz fdos_e08 ; NO
mov es,bx ; ES -> DR-Net NDA
mov al,es:byte ptr 0Ch ;; NDA_CXRTN
fdos_e08:
push ax ; Pass the DR-NET Server No.
mov es,cx ; Restore ES
call CRITICAL_ERR ; Handle the Critical Error. Parameters
; are removed by the CALLEE
mov crit_flg,FALSE ; Critical Section complete
pop valid ; Restore our original RETRY IP
pop retry_sp ; and SP values which have been
pop retry_ip ; corrupted by the "CRITICAL_ERROR"
; routine during message printing
cmp ax,0 ; Ignore the Error
jz fdos_exit ; Then Exit with no Error
cmp ax,1 ; Retry the Operation
jnz fdos_e10 ; using information saved by FDOS_RETRY
mov sp,retry_sp ; Reset the Stack Pointer
jmp retry_ip ; and retry the Operation
fdos_e10:
cmp ax,3 ; FAIL this function
mov ax,ED_FAIL ; Fail the function
jz fdos_exit ; Yes otherwise ABORT
call _int_break ; Simulate a Control C to terminate
; We are never coming back
;
; BDOS_ENTRY is the usual method of calling the Operating System.
; In order to provide a DOS compatible environment this function.
; does Control-C checking on function exit.
;
bdos_entry:
int BDOS_INT
push es
les bx,_pd ; Get our process descriptor address
test es:P_SFLAG[bx],PSF_CTLC ; Check if a Control-C has been typed
jnz bdos_e10 ; Jump to Abort Handler
mov bx,ax ; Restore BX and Return.
pop es
ret
bdos_e10:
and es:P_SFLAG[bx],not PSF_CTLC
pop es
bdos_e20:
mov cl,C_RAWIO ; Flush the Character buffer until
mov dl,0FFh ; Return the character or 00 if queue
int BDOS_INT ; is empty. Repeat till the Keyboard
or al,al ; Buffer has been flushed
jnz bdos_e20
push ds
push cs
pop ds
mov cl,C_WRITESTR
mov dx,offset break_str ; echo ^C to screen
int BDOS_INT
pop ds
call _int_break ; Place the Control Break Code on the
; Stack and the call the error handler
; ** We will never return **
break_str db '^C$'
endif
ifndef DOSPLUS
Public __BDOS
;-------
__BDOS:
;-------
push bp
mov bp,sp
push si
push di
mov cl,4[bp]
mov dx,6[bp]
int BDOS_INT
pop di
pop si
pop bp
ret
;
endif
ifdef DOSPLUS
ifndef EXT_SUBST
Public _physical_drvs ; Physical Drives returns a LONG
_physical_drvs: ; Vector with bits set for every drive
mov ax,0 ; start with drive A:
mov cx,16 ; check the first 16 drives
mov bx,0
p_d10:
push ax ; pass drive no. to _physical_drive
call _physical_drive ; call it
cmp ax,0 ; check return value
pop ax ; restore ax
jz p_d20 ; if zero skip setting the bit in
or bx,1 ; the bitmap
p_d20:
ror bx,1 ; shift bitmap right
inc ax ; next drive
loop p_d10 ; Loop 16 Times
mov cx,10 ; Finally check the last 10 drives
mov dx,0
p_d30:
push ax ; pass drive no. to _physical_drive
call _physical_drive ; call it
cmp ax,0 ; check return val
pop ax ; restore ax
jz p_d40 ; id zero skip setting the bit in
or dx,1 ; the bitmap
p_d40:
ror dx,1 ; shift bitmap right
inc ax ; next drive
loop p_d30 ; Loop 10 Times
mov cl,6 ; Now rotate the contents of
ror dx,cl ; DX 6 more times for correct
; alignment of the Physical Drive Vector
mov ax,bx
mov bx,dx ; Return the long value in both
; AX:BX and AX:DX
ret
Public _logical_drvs ; Logical Drives returns a LONG
_logical_drvs: ; vector with bits set for every
mov cx,16 ; check the first 16 drives
mov ax,0 ; start with drive A:
mov bx,ax
l_d10:
push ax ; pass the drive to _logical_drive
call _logical_drive ; call it
cmp ax,0 ; check return value
pop ax ; restore ax
jz l_d20 ; skip if zero return
or bx,1 ; set bit in bitmap
l_d20:
ror bx,1 ; shift bitmap right
inc ax ; next drive
loop l_d10 ; Loop 16 Times
mov cx,10 ; Finally check the last 10 drives
mov dx,0
l_d30:
push ax ; pass the drive to _logical_drive
call _logical_drive ; call it
cmp ax,0 ; check return value
pop ax ; restore ax
jz l_d40 ; skip if zero return
or dx,1 ; set bit in bitmap
l_d40:
ror dx,1 ; shift bitmap right
inc ax ; next drive
loop l_d30 ; Loop 10 Times
mov cl,6 ; Now rotate the contents of
ror dx,cl ; DX 6 more times for correct
; alignment of bits
mov ax,bx
mov bx,dx ; Return the long value in both
ret ; AX:BX and AX:DX
Public _network_drvs ; Network Drives returns a LONG
_network_drvs: ; vector with bits set for every drive
xor ax,ax ; Start with BX:AX as
mov bx,ax ; zeros.
mov cx,'Z'-'A' ; We look at drives A-Z
n_d10:
add ax,ax ; we move the dword vector
adc bx,bx ; one place left
push ax
push bx ; save the vector
mov ah,MS_X_IOCTL
mov al,9 ; is device local ?
mov bl,cl ; drive number in BL
int DOS_INT
pop bx
pop ax ; recover the vector
jc n_d20 ; if an error skip network bit
test dx,1000h ; is device local ?
jz n_d20 ; if not then
or ax,1 ; set bit for this drive
n_d20:
loop n_d10
mov dx,bx ; long value in both AX:BX and AX:DX
ret
public _physical_drive
_physical_drive PROC NEAR
; BOOLEAN physical_drive(WORD);
; returns true if given drive (0-25) is physical.
;
push bp
mov bp,sp
push ds
push es
push si
push di
push dx
push cx
push bx
mov bx,4[bp] ; get the drive number
inc bx ; A=1, B=2, etc
mov ax,4409h ; IOCTL Network/Local
int 21h ; do it
jc not_phys ; carry means invalid drive
and dx,1000h ;
cmp dx,0
jne not_phys ; its a network drive
mov ax,cs
mov ds,ax
mov es,ax
mov si,offset func60_in
mov di,offset func60_out
mov ax,4[bp] ; insert drive letter in input string
add al,'A'
mov [si],al ;
mov ah,60h ; Expand Path string
int 21h ; do it
jc not_phys ; carry set means invalid drive
mov ax,4[bp] ; if drive letter changes then drive is
add al,'A' ; substed
cmp al,cs:[func60_out]
jne not_phys
mov ax,-1
jmp phys_exit
not_phys:
mov ax,0
phys_exit:
pop bx
pop cx
pop dx
pop di
pop si
pop es
pop ds
pop bp
ret
func60_in db "d:con",0
func60_out db 0,0,0,0,0,0,0,0,0,0
_physical_drive ENDP
;
; This function translates a logical to physical drive.
;
Public _pdrive
;------
_pdrive:
;------
push bp
mov bp,sp
push ds
push es
push si
push di
mov ax,cs
mov ds,ax
mov es,ax
mov si,offset func60_in
mov di,offset func60_out
mov ax,4[bp] ; insert drive letter in input string
add al,'A'
mov [si],al
mov ah,60h ; Expand Path string
int 21h ; do it
mov ax,4[bp] ; assume invalid, hence no change
jc pdrive_exit ; carry set means invalid drive
mov al,cs:[func60_out]
sub al,'A'
pdrive_exit:
pop di
pop si
pop es
pop ds
pop bp
CRET 2
public _logical_drive
_logical_drive PROC NEAR
; BOOLEAN logical_drive(WORD);
; returns TRUE if given drive (0-25) is logical
;
push bp
mov bp,sp
push ds
push es
push si
push di
push dx
push cx
push bx
mov bx,4[bp] ; get the drive number
inc bx ; A=1, B=2, etc
mov ax,4409h ; IOCTL Network/Local
int 21h ; do it
jc not_logical ; carry means invalid drive
and dx,1000h ;
cmp dx,0
jne not_logical ; its a network drive
mov ax,cs
mov ds,ax
mov es,ax
mov si,offset func60_in
mov di,offset func60_out
mov ax,4[bp] ; insert drive letter in input string
add al,'A'
mov [si],al ;
mov ah,60h ; Expand Path string
int 21h ; do it
jc not_logical ; carry set means invalid drive
mov ax,4[bp] ; if drive letter changes then drive is
add al,'A' ; substed
cmp al,cs:[func60_out]
je not_logical
mov ax,-1
jmp logical_exit
not_logical:
mov ax,0
logical_exit:
pop bx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -