📄 int2f.a86
字号:
; On Exit:
; DX = Total days to start of current month
;
xor ax,ax ; clear AX
jcxz i2f_121C_20 ; check for zero bytes
i2f_121C_10:
lodsb ; get a byte
add dx,ax ; add to the checksum
loop i2f_121C_10 ; until we run out
i2f_121C_20:
ret
i2f_121D:
; Calculate Date
; On Entry:
; CX = 0
; DX = total day count this year
; DS:SI -> days-per-month table
; On Exit:
; CX = Month
; DX = Day
;
xor ax,ax
i2f_121D_10:
lodsb
inc cx
sub dx,ax
jnb i2f_121D_10
dec cx ; undo the last count
add dx,ax ; undo the sub
cmp dx,ax ; get the flags right
ret
i2f_121E:
; Compare Filenames at DS:SI and ES:DI
push si ! push di ! push cx
call i2f_1225 ; find length of DS:SI filename
push cx
call i2f_1212 ; find length of ES:DI filename
pop ax
cmp ax,cx ; if lengths not the same
jne i2f_121E_20 ; don't even bother
i2f_121E_10:
push cx
lodsb
call toupper
call tobslash ; normalise slash characters
push ax ; save it
mov al,es:byte ptr [di]
inc di
call toupper
call tobslash ; normalise slash again
pop cx ; recover the character
cmp al,cl ; are they the same?
pop cx
loope i2f_121E_10 ; yes, try again if we have any left
i2f_121E_20:
pop cx ! pop di ! pop si
mov ax,8[bp] ; return stack value in AX
ret
i2f_121F:
; Build drive info into block
; Stack = Drive (1=A: etc)
push ds ! push si ! push dx
call get_dseg
les di,current_ldt
push di
mov ax,8[bp] ; get the drive we want to do
stosb ; plant the ASCII
xchg ax,dx ; save drive in DX
mov ax,'\:'
stosw ; we have d:\
xor ax,ax
mov cx,LDT_FLAGS-3
rep stosb ; zero rest of name and flags
; lea di,LDT_FLAGS
and dl,1fh ; convert from ASCII
dec dx ; into zero based drive number
cmp dl,phys_drv ; valid physical drive ?
jae i2f_121F_10 ; mark it as such
mov ax,LFLG_PHYSICAL
i2f_121F_10:
stosw ; set flags
; lea di,LDT_PDT
lea si,ddsc_ptr-18h
i2f_121F_20:
lds si,18h[si]
cmp si,-1
je i2f_121F_30
cmp dl,[si] ; is this the DDSC for the drive
jne i2f_121F_20 ; if so save it away
i2f_121F_30:
xchg ax,si ; AX = DDSC offset
stosw
mov ax,ds ; AX = DDSC seg
stosw
; lea di,LDT_BLK
mov ax,0FFFFh ; AX = FFFF
stosw ! stosw ! stosw ; fill in block info
; lea di,LDT_ROOTLEN
mov ax,2
stosw ; set root length
pop di
pop dx ! pop si ! pop ds
ret
i2f_1220:
; Get pointer to system file table number for handle BX into ES:DI
push ds
call get_dseg
mov es,current_psp
mov ax,6 ; assume illegal
cmp bx,PSP_XFNMAX ; is it a legal handle
cmc ; invert CY for error return
jc i2f_1220_10 ; no, forget it
les di,PSP_XFTPTR ; get XFT from PSP
add di,bx ; add in the offset
; clc
i2f_1220_10:
pop ds
ret
i2f_1221:
mov ah,MS_X_EXPAND ; let the FDOS do the walking...
call DOS ; and call our internal entry point
jnc i2f_1221_10
neg ax ; get error code correct
stc ; before returning error
i2f_1221_10:
ret
i2f_1222:
; Store error class, locus, action from DS:SI
i2f_1222_10:
lodsw
cmp al,byte ptr error_code ; have we found the error ?
je i2f_1222_20
inc al ; or hit the end of the list ?
jz i2f_1222_20
lodsw ; skip this one
jmp i2f_1222_10 ; and try the next
i2f_1222_20:
cmp ah,0ffh ; valid error class ?
je i2f_1222_30
mov error_class,ah
i2f_1222_30:
lodsw
cmp al,0ffh
je i2f_1222_40
mov error_action,al
i2f_1222_40:
cmp ah,0ffh
je i2f_1222_50
mov error_locus,ah
i2f_1222_50:
ret
i2f_1223:
; On Entry buffer at 4E6 filled with Device name - eg. "NAME1 "
; Preserve word ptr [4E6]
; if byte ptr [4E6] = 5 then byte ptr [4E6] = E5
; if byte ptr [506] & 8 then exit now with STC
; otherwise work down device chain
; Find device driver for device NAME1
; Check if character device
push ds
call get_dseg
if FALSE
push word ptr name_buf ; save 1st char of name
test magic_byte,8 ; magic location and number ??
jnz i2f_1223_40 ; can we do the check ?
cmp name_buf,5
jne i2f_1223_10 ; if 1st char is 5, make it
mov name_buf,0e5h ; an E5
i2f_1223_10:
endif
mov si,offset nul_device ; start from NUL
i2f_1223_20:
test ds:DH_ATTRIB[si],DA_CHARDEV
jz i2f_1223_30 ; skip unless character device
mov cx,8
lea di,name_buf ; point at name we are looking for
push si
lea si,ds:DH_NAME[si] ; point a device name
repe cmpsb ; compare the names
pop si
jne i2f_1223_30 ; if we found it, save info
mov es:word ptr current_device,si
mov es:word ptr current_device+2,ds
mov bh,ds:byte ptr DH_ATTRIB[si]
or bh,0e0h
xor bh,20h ; clear this bit
clc ; we found it
jmps i2f_1223_50
i2f_1223_30:
lds si,ds:DH_NEXT[si]
cmp si,0ffffh ; any more entries ?
jne i2f_1223_20 ; yes, do them
i2f_1223_40:
stc
i2f_1223_50:
if FALSE
pushf
call get_dseg ; we may have scambled DS
popf
pop word ptr name_buf ; restore 1st character
endif
pop ds
ret
i2f_1225:
; Get length of ASCIIZ string DS:SI
call strlen
inc cx ; include the terminating zero
mov ax,8[bp] ; restore AX from stack
ret
; The following are NOT required for MSNET - they are used by NLSFUNC
i2f_1226:
; Open the file at DS:DX
mov al,cl ; open mode in CL on entry
mov ah,MS_X_OPEN ; open the file
DOS:
push ds ! push es ! pop ds ! pop es
call dos_entry ; reverse DS/ES before for dos_entry
push ds ! push es ! pop ds ! pop es
ret
i2f_1227:
; Close file BX
mov ah,MS_X_CLOSE ; close the file
jmps DOS
i2f_1228:
; LSEEK on file BX
mov ax,[bp] ; seek mode in BP on entry
mov ah,MS_X_LSEEK ; do the seek
jmps DOS
i2f_1229:
; Read from file BX
mov ah,MS_X_READ
jmps DOS
i2f_122A:
; Set fastopen entry point to DS:SI
; SI = FFFF, sdont't set - just check if installed
mov ax,si ; AX = offset
inc ax ; AX = 0 if it's an installation check
stc ; assume it is, and say not installed
jne i2f_122A_10
clc ; fail new installation
i2f_122A_10:
ret
i2f_122B:
; IOCTL
mov al,[bp] ; get IOCTL minor
mov ah,MS_X_IOCTL
jmps DOS
i2f_122C:
; Get 2nd device driver header address
push ds
call get_dseg
lds ax,ds:dword ptr nul_device
mov bx,ds ; BX:AX -> 2nd device header
pop ds
ret
i2f_122D:
; Get extended error code
mov ax,error_code
ret
;
; Our FDOS extentions live here
;
if DELWATCH
extrn locate_buffer:near
extrn flush_drive:near
extrn delfat:near
extrn allocate_cluster:near
extrn getblk:near
extrn change_fat_entry:near
extrn fixup_hashing:near
; for speed/code size we just call directly in BLACK.A86
endif
i2f_10tbl dw i2f_10nyi ; never gets here...
dw i2f_1001 ; install fdos hook
if DELWATCH
if FALSE
dw i2f_1002 ; read buffer
dw i2f_1003 ; flush buffers
dw i2f_1004 ; free fat chain
dw i2f_1005 ; allocate cluster
dw i2f_1006 ; next cluster
dw i2f_1007 ; update fat entry
dw i2f_1008 ; fixup checksums
else
dw locate_buffer ; ask BLACK to find that buffer
dw flush_drive ; ask BLACK to flush buffers
dw delfat ; ask BLACK to release FAT chain
dw allocate_cluster; ask DEBLOCK to allocate space
dw getblk ; ask DEBLOCK to return next block
dw change_fat_entry; ask DEBLOCK to update fat entry
dw fixup_hashing ; ask BLACK to fixup hashing/checksums
endif
dw i2f_1009 ; directory buffer info
endif
i2f_10size equ (offset $ - offset i2f_10tbl)/2
i2f_1001:
;--------
; install fdos stub
;
; On Entry:
; DX:AX -> new fdos_stub entry address
; On Exit:
; None
;
call get_dseg ; get PCMode data seg
mov word ptr fdos_stub,ax ; fixup our share stubs
mov word ptr fdos_stub+WORD,dx
i2f_10nyi:
ret
if DELWATCH
if FALSE
i2f_1002:
;--------
; read buffer
; On Entry:
; CH = 0FFh (pre-read required)
; CL = BF_ISFAT/BF_ISDIR/BF_ISDATA
; AH:DX = 24 bit sector number
; On Exit:
; ES:SI -> Buffer control block
;
jmp locate_buffer
i2f_1003:
;--------
; flush buffers
; On Entry:
; AL = drive
; AH = buffer type to flush (BF_ISFAT+BF_ISDIR+BF_ISDATA)
; On Exit:
; None
;
jmp flush_drive
i2f_1004:
;--------
; free fat chain
; On Entry:
; AX = 1st block to release on current drive
; On Exit:
; None
jmp delfat
i2f_1005:
;--------
; allocate cluster
; On Entry:
; AX = block to start search from (eg. current end of file)
; 0000 = start of disk
; On Exit:
; AX = 0000 if none available
; else allocated block (marked as End Of Chain)
;
jmp allocate_cluster ; ask DEBLOCK.A86 to allocate some space
i2f_1006:
;--------
; get next cluster
; On Entry:
; AX = current block
; On Exit:
; AX = next block in chain
;
jmp getblk ; ask DEBLOCK.A86 to return next block
i2f_1007:
;--------
; change fat entry
; On Entry:
; AX = fat entry to change
; DX = new value
; On Exit:
; None
;
jmp change_fat_entry ; ask DEBLOCK.A86 to modify FAT entry
i2f_1008:
;--------
; update hash code for directory entry on current drive
; On Entry:
; AX = segment of dir buffer
; CX = cluster to fixup (0 = root)
; DI = directory entry index(clipped to cluster if subdir)
; AX:SI-> dir entry (single entry for hashing)
; On Exit:
; None
;
jmp fixup_hashing
endif
i2f_1009:
;--------
; return dirbuf info
; On Entry:
; None
; On Exit:
; ES:DI -> 128 byte directory record buffer
; ES:SI -> dir bcb structure
; 0[si] = drive (FF = invalid)
; 1[si] = low byte of record number
; 2[si] = mid byte of record number
; 3[si] = hi byte of record number
;
push cs ! pop es
mov si,offset invalid_dir_bcb
ret
invalid_dir_bcb db 0ffh ; drive is invalid
; db ?,?,? ; don't bother about record number
endif ;DELWATCH
WindowsHooks:
;------------
; On Entry:
; AH = 16h, it's a windows broadcast
; AL = subfunction, other regs as appropriate
; On Exit:
; Various
;
if DOS5
cmp al,07h ; 1607: Virtual device init
je WindowsDOSMGR
endif
test dx,1 ; is it a DOSX broadcast ?
jnz WindowsExit
cmp al,05h ; 1605: Windows enhanced mode init
je WindowsStartup
if DOS5
cmp al,06h ; 1606: Windows enhanced mode exit
je WindowsShutdown
endif
WindowsExit:
iret
WindowsStartup:
;--------------
push ds
call get_dseg ; DS -> our data
if DOS5
inc criticalSectionEnable ; enable Int 2Ah for Windows
inc WindowsHandleCheck
endif
;;if 0 Put this back in, as instance data still required
;; Removed pointer to vxd in HEADER.A86 BAP
mov SwStartupInfo+2,bx ; Commented out, as NWDOS.386
mov SwStartupInfo+4,es ; no longer needed.
push ds
pop es ; ES -> pcmode data
mov bx,offset SwStartupInfo
;;endif
jmp int2F_BIOS ; pass on to the BIOS
if DOS5
WindowsShutdown:
;---------------
push ds
call get_dseg ; DS -> our data
dec criticalSectionEnable ; enable Int 2Ah for Windows
dec WindowsHandleCheck
pop ds
sub dx,dx ; return success
iret
WindowsDOSMGR:
;-------------
cmp bx,15h ; is it DOS manager?
jne WindowsExit ; forget the others
; cmp cx,0
jcxz WindowsCX0
dec cx
jcxz WindowsCX1
dec cx ! dec cx ! dec cx
jcxz WindowsCX4
dec cx
jcxz WindowsCX5
iret
WindowsCX0:
;----------
push ds
call get_dseg
push ds
pop es ; ES = DOS data segment
pop ds
lea bx,windowsData ; ES:BX -> secret variables
inc cx ; tell them we've responded
iret
WindowsCX1:
;----------
mov bx,dx ; entry DX=1Fh, exit BX=1Fh
mov ax,0B97Ch ; AX, DX are magic values
mov dx,0A2ABh
; xor cx,cx ; CX = 0
iret
WindowsCX4:
;----------
xor dx,dx
; xor cx,cx ; CX = 0
iret
WindowsCX5:
;----------
; entry: ES:DI -> device driver
; determine device driver size in bytes
push ds
test di,di ; not primary DEVICE= driver?
jnz WindowsCX5NoDev ; can't have DMD preceeding it
mov ax,es ; get device segment
dec ax ; DMD is one paragraph lower down
mov ds,ax ; DS:DI -> device DMD
inc ax ; AX = device driver segment
cmp ds:byte ptr 0[di],'D' ; see if 'D'device=
jne WindowsCX5NoDev ; skip if not
cmp ax,ds:word ptr 1[di] ; owned by the driver ?
jne WindowsCX5NoDev ; skip if not
mov ax,10h ; bytes per paragraph
mul ds:word ptr 3[di] ; bytes in device driver
pop ds
mov bx,dx ; BX = high word
xchg ax,cx ; CX = low word
mov ax,0B97Ch ; AX, DX are magic values
mov dx,0A2ABh
iret
WindowsCX5NoDev:
; ES:DI -> not an external device
pop ds
xor ax,ax
xor dx,dx
; xor cx,cx ; CX = 0
iret
endif
eject
PCMODE_DATA DSEG WORD
extrn hmaRoot:word
extrn last_drv:byte
extrn phys_drv:byte
extrn ddsc_ptr:dword
extrn current_psp:word
extrn current_dsk:byte
extrn net_delay:word
extrn nul_device:byte
extrn error_code:word
extrn error_class:byte
extrn error_action:byte
extrn error_locus:byte
extrn file_ptr:dword
extrn ldt_ptr:dword
extrn current_device:dword
extrn current_ldt:dword
extrn current_dhndl:dword
extrn current_ddsc:dword
extrn yearsSince1980:byte
extrn days_in_month:byte
extrn name_buf:byte
extrn int21regs_ptr:dword
extrn int24_esbp:dword
extrn int2FNext:dword
extrn fdos_stub:dword
extrn SwStartupInfo:word
extrn err_drv:byte
extrn rwmode:byte
if DOS5
extrn indos_flag:byte, machine_id:byte, internal_data:byte, dmd_upper_root:word
extrn criticalSectionEnable:byte
extrn WindowsHandleCheck:byte
GLOBAL_DATA dseg
windowsData dw 5 ; version number ?
dw $ ; dummy
dw $ ; dummy
dw offset indos_flag
dw offset machine_id
dw offset internal_data-10
dw offset dmd_upper_root
else
extrn bcb_root:dword
endif
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -