📄 int2f.a86
字号:
; File : $Workfile$
;
; Description :
;
; Original Author :
;
; Last Edited By : $Author$
;
;-----------------------------------------------------------------------;
; Copyright Work of Caldera, Inc. All Rights Reserved.
;
; THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
; PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
; ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
; WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
; THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
; HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
; AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
; AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
; COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
; CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
; TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
; CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
; AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
; CIVIL LIABILITY.
;-----------------------------------------------------------------------;
;
; *** Current Edit History ***
; *** End of Current Edit History ***
;
; $Log$
; INT2F.A86 1.23 94/11/14 10:34:17
; Fixed the NWDOS.386 stuff. Still point at startupinfo, but take out the
; vxdname and the vxdnameseg entries.
; INT2F.A86 1.22 94/10/07 09:05:11
; Added patch 005 as source fix. Removed the stuff to load NWDOS.386 as
; the vxd is no longer needed.
; INT2F.A86 1.21 94/03/24 18:40:10
; Support para-aligned HMA allocations (Stacker 4 bug)
; INT2F.A86 1.20 93/09/28 19:43:12
; Extra field to export upper memory root on windows startup
; INT2F.A86 1.19 93/09/06 15:37:35
; Startup Broadcast fills entry ES:BX into SwStartupInfo "next" link field
; INT2F.A86 1.16 93/08/06 16:35:58
; Change DELWATCH int 2F hook for getnblk to getblk
; INT2F.A86 1.15 93/07/20 22:47:21
; Pass on Int 2F/12FF to BIOS - (really to CONFIG)
; INT2F.A86 1.11 93/06/11 02:10:01
; GateA20 disabled on EXEC for EXEPACKED apps
; ENDLOG
;
; DOS INT 2F Support
;
include pcmode.equ
include i:msdos.equ
include i:mserror.equ
include i:driver.equ
include i:psp.def
include i:doshndl.def
include i:redir.equ
PCM_CODE CSEG BYTE
extrn get_dseg:near ; in PCMIF.PCM
extrn do_int24:near ; in PCMIF.PCM
extrn dos_entry:near
extrn strlen:near ; in SUPPORT.PCM
extrn toupper:near ; in UTILS.FDO (in BDOS_CODE)
extrn ReadTOD:near ; in UTILS.FDO (in BDOS_CODE)
extrn share_delay:near ; in UTILS.FDO (in BDOS_CODE)
eject
PointHMA:
;--------
; On Entry:
; None
; On Exit:
; DS = DOS data seg
; BX = bytes available (0 if none)
; ES:DI -> start of available area (FFFF:FFFF if none)
; All other regs preserved
;
call get_dseg ; DS = DOS data
mov di,0FFFFh
mov es,di ; ES:DI = FFFF:FFFF
mov bx,hmaRoot
test bx,bx ; have we an HMA ?
jz PointHMA10
mov di,bx ; ES:DI = start of HMA free area
mov bx,es:2[bx] ; BX = length
sub bx,4 ; forget the header
and bl,not 15 ; make it complete para's
PointHMA10:
ret
QueryHMA:
;--------
; On Entry:
; None
; On Exit:
; BX = bytes available (0 if none)
; ES:DI -> start of available area (FFFF:FFFF if none)
; All other regs preserved
;
push ds
call PointHMA ; registers ready for return
jmps int2F_BIOS ; give CONFIG processing a chance
AllocHMA:
;--------
; On Entry:
; BX = bytes required
; On Exit:
; ES:DI -> start of available area (FFFF:FFFF if none)
;
push ds
xchg ax,bx ; AX = bytes required
add ax,15
and al,not 15 ; round up to para's
call PointHMA
xchg ax,bx
cmp ax,bx ; enough room up there ?
jae AllocHMA10
mov di,es ; ES:DI = FFFF:FFFF
jmps AllocHMA20
AllocHMA10:
add hmaRoot,bx ; set new start
mov ax,es:2[di] ; get length
sub ax,bx ; subtract what we just allocated
mov es:2[di+bx],ax ; set new length
cmp ax,4 ; have we shrunk to zero spare ?
mov ax,es:[di] ; move link field to
mov es:[di+bx],ax ; new head
ja AllocHMA20
mov hmaRoot,ax ; set new hmaRoot
AllocHMA20:
mov ax,4A02h ; "restore" AX
pop ds
iret
eject
; ++++++++++++++++++++++++++++
; Int 2F - Multiplex Interrupt
; ++++++++++++++++++++++++++++
;
; This interrupt is used by DBASE III Plus
;
; On Entry:- AH - Multi-Plex Number
; 01 - Print Spooler
; 02 - Assign Command (Documented)
; 05 - Critical Error Msg
; 06 - Assign Command (By Inspection)
; 08 - DRIVER.SYS Interface for MS-DOS 3.xx
; 10 - Share Command
; 11 - Internal DOS - Network Hooks
; 12 - Internal DOS - Support Services
; 13 - Original INT 13 ROS ISR Address (BIOS)
; 14 - NLSFUNC utility
; AD - IBM CodePage Screen Driver
; B7 - Append Command
; B8 - Network Command
;
; AL - Function Code
; 00 - Get Installed State (All)
; 01 - Submit File (PRINT)
; 02 - Cancel File (PRINT)
; 03 - Cancel All Files (PRINT)
; 04 - Spooler Status (PRINT)
; 05 - End of Status (PRINT)
;
; The Network Test returns the current Network configuration in
; BX when the Get Installed State is requested.
;
; BX = 0008h Redirector | Increasing
; BX = 0080h Receiver | Network
; BX = 0004h Messenger | Functionality
; BX = 0040h Server V
;
Public int2F_entry
int2F_entry:
sti
cld
cmp ah,012h ! je i2f_12 ; intercept the AH=12 subfunctions
cmp ah,011h ! je i2f_11 ; intercept the AH=11 subfunctions
cmp ah,010h ! je i2f_10 ; intercept the AH=10 subfunctions
cmp ah,005h ! je i2f_05 ; intercept the AH=05 subfunctions
cmp ax,4A01h! je QueryHMA ; intercept Query Free HMA Space
cmp ax,4A02h! je AllocHMA ; intercept Allocate HMA space
cmp ah,016h ! jne int2F_exit ; intercept the AH=16 subfucntions
jmp WindowsHooks ; go do windows things...
int2F_exit:
push ds ; pass onto BIOS now
call get_dseg ; trying to remain ROMMABLE
int2F_BIOS:
jmpf ds:int2FNext ; hence this complication
eject
i2f_05:
;------
; CRITICAL ERROR MSG
; This is the critical error message interceptor.
; On Entry: AL = extended error code.
; On Exit: if CY clear then ES:DI -> ASCIIZ string to be used in place
; of the default error message
stc ; please use the default message
retf 2 ; IRET, but keep flags
eject
i2f_10:
;------
; SHARE
cmp al,i2f_10size ; do we do this one ?
jae int2F_exit ; no, skip it
shl al,1 ; we need a word offset
jz int2F_exit ; exit if share installation check
cbw ; zero AH
xchg ax,bx ; we will index with it
push ds
call get_dseg ; get PCMode data seg
push ds ! pop es
call i2f_10tbl[bx] ; execute the function
pop ds
retf 2 ; and return
eject
i2f_11:
;------
; MSNET redirector
test al,al ; is it installation check ?
jz i2f_11_10
mov ax,1 ; no, return ED_FUNCTION error
stc ; indicate an error
i2f_11_10:
retf 2 ; return
eject
i2f_12:
;------
; DOS Internal
; Support DOS internal functions here
cmp al,0FFh ; should we pass it on to the BIOS ?
je int2F_exit ; yes, do so
cmp al,i2f_12size ; do we do this one ?
jae i2f_12_bad ; no, skip it
push bp
xor ah,ah
add ax,ax ; make sub-func a word
mov bp,ax ; we need offset in pointer register
mov ax,i2f_12tbl[bp] ; get address of service routine
mov bp,sp ; BP points to stack frame
call ax ; call the service routine
pop bp
i2f_12_exit:
retf 2 ; IRET, but returning flags
i2f_12_bad:
mov ax,-ED_FUNCTION
stc
retf 2
i2f_12tbl dw i2f_1200
dw i2f_1201
dw i2f_1202
dw i2f_1203
dw i2f_1204
dw i2f_1205
dw i2f_1206
dw i2f_12nyi ; Move disk buffer
dw i2f_1208
dw i2f_12nyi ; DS:DI -> Disk Buffer ??
dw i2f_120A
dw i2f_120B
dw i2f_120C
dw i2f_120D
if DOS5
dw share_delay ; delay
else
dw i2f_120E ; get buffers
endif
dw i2f_12nyi ; relink buffer ES:DI ([DI+5].20 <- 0) - Trout
dw i2f_1210
dw i2f_1211
dw i2f_1212
dw i2f_1213
dw i2f_1214
dw i2f_12nyi ; Disk buffer DS:SI ??? (Write - Trout)
dw i2f_1216
dw i2f_1217
dw i2f_1218
dw i2f_1219
dw i2f_121A
dw i2f_121B
dw i2f_121C
dw i2f_121D
dw i2f_121E
dw i2f_121F
dw i2f_1220
dw i2f_1221
dw i2f_1222
dw i2f_1223
dw share_delay
dw i2f_1225
dw i2f_1226
dw i2f_1227
dw i2f_1228
dw i2f_1229
dw i2f_122A
dw i2f_122B
dw i2f_122C
dw i2f_122D
i2f_12size equ ((offset $) - (offset i2f_12tbl))/2
i2f_12nyi:
; Sets CY the falls through to installation check - so returns ax = 00FF
; Who knows what to do ?
stc ; indicate problem ?
i2f_1200:
mov ax,00FFh
ret
i2f_1201:
; Close file ??? (at current_dhndl)
les di,current_dhndl
mov bx,es:DHNDL_WATTR[di]
test bh,DHAT_REMOTE/100h
jz i2f_1201_10 ; is it networked ?
mov ax,I2F_CLOSE
int 2fh ; then close using int 2f call
i2f_1201_10: ; else do nothing for now
ret
i2f_1202:
; Get Interrupt Vector pointer
xor bx,bx
mov es,bx ; point at the vectors
mov bl,8[bp] ; pick up which vector
add bx,bx
add bx,bx ; make it a DWORD offset
ret
i2f_1203:
; Get DOS Data segment
jmp get_dseg ; return DS = DOS data seg
i2f_1204:
; Normalise path character
mov ax,8[bp] ; the char is on the stack
tobslash:
cmp al,'/' ; if it's a fslash
jne i2f_1204_10
mov al,'\' ; make it a bslash
i2f_1204_10:
cmp al,'\' ; set ZF if bslash
ret
i2f_1205:
; Output Character on the stack
push dx
mov ah,MS_C_WRITE
mov dx,8[bp] ; get char from the stack
call dos_entry ; and output it
pop dx
ret
i2f_1206:
; Invoke critical error INT 24
push ds
mov ax,8[bp] ; action/drive on stack
mov es,0[bp] ; seg was in BP
call get_dseg ; get the segment right
call do_int24 ; invoke the critical error handler
push ax
les ax,int24_esbp
mov [bp],ax ; really return new BP
pop ax
pop ds
ret
i2f_1208:
; Decrement word at ES:DI, skipping zero
mov ax,es:word ptr [di] ; return the word in AX
i2f_1208_10:
dec es:word ptr [di] ; dec it
jz i2f_1208_10 ; dec again if it's zero
ret
i2f_120A:
push ds
lds si,current_ddsc ; point at current driver
lodsb ; get the drive
cbw ; pretend dos area read
pop ds
mov err_drv,al
mov rwmode,ah ; set error drive for Int 24h
mov ax,3 ; return a Fail ?
stc ; return as error
ret
i2f_120B:
; ES:DI -> system file table entry
mov ax,20h ; sharing violation
stc ; return as error
ret
i2f_120C:
; Open file ??? (at current_dhndl)
les di,current_dhndl
; would need to call the device driver, but as we don't support this for
; block devices and as it is generally not supported for remote files (but
; only known to be called from redirectors) we leave this out for later
test es:byte ptr DHNDL_MODE+1[di],DHM_FCB/100h
jz i2f_120C_10 ; is it an FCB open ?
mov ax,current_psp
mov es:DHNDL_PSP[di],ax ; update owning PSP field
i2f_120C_10: ; else do nothing for now
ret
i2f_120D:
; Get Date/Time
push ds
push es
push cx
push bx
push si
push di
push ss
pop ds
call ReadTOD
pop di
pop si
pop bx
pop cx
pop es
pop ds
ret
if DOS5 eq 0
i2f_120E:
; Disk Buffers
; On Return ES:DI -> first disk buffer
;
les di,ss:bcb_root ; get head of buffer chain
ret
endif
i2f_1210:
; Find Dirty Buffer Entry DS:SI -> 1st buffer, On exit DS:SI-> 1st dirty buffer
; ZF set if none found
xor ax,ax ; never find dirty buffers
ret
i2f_1211:
; Normalise ASCIIZ filename DS:SI -> source buffer, ES:DI -> dest buffer
; make uppercase, fslash becomes bslash
; (Stops at slash - Trout)
lodsb ; get a character
call toupper ; upper case it
call tobslash ; convert '/' to '\'
stosb ; plant it
test al,al ; terminating zero ?
jnz i2f_1211
mov ax,8[bp] ; AX from stack
ret
i2f_1212:
; Get length of ASCIIZ string ES:DI
push ds ! push si
push es ! pop ds
mov si,di ; make DS:SI -> ASCIIZ
call i2f_1225 ; then use our other primitive
pop si ! pop ds
ret
i2f_1213:
; Upperase character on stack
mov ax,8[bp] ; get the character
jmp toupper ; use BDOS Intl routine
i2f_1214:
; Compare far pointers DS:SI with ES:DI
cmp di,si
jne i2f_1214_10
push ax ! push bx
mov ax,ds
mov bx,es
cmp ax,bx
pop bx ! pop ax
i2f_1214_10:
ret
i2f_1216:
; Get address in ES:DI of DOSHNDL for file BX
push ds
call get_dseg ; we work with the PCMODE data
les di,file_ptr ; get the address of the first entry
pop ds
push bx ; handle # in BX
i2f_1216_10:
cmp bx,es:DCNTRL_COUNT[di] ; handle in this block?
jb i2f_1216_20 ; skip if yes
sub bx,es:DCNTRL_COUNT[di] ; update the internal file number
les di,es:DCNTRL_DSADD[di] ; get the next entry and check
cmp di,0FFFFh ; for the end of the list
jnz i2f_1216_10
pop ax ; handle # back in AX
stc ; invalid file handle number
ret
i2f_1216_20:
push dx ; save DX and calculate the offset
mov ax,DHNDL_LEN ; of the DOS Handle
mul bx
add di,ax ; add structure offset (should be 0)
add di,DCNTRL_LEN ; and then skip the header
pop dx
pop ax ; handle # back in AX
; clc
ret ; valid file handle number
i2f_1217:
; Default Drive ???
; On Exit:
; AL = drive we have set to, DS:SI -> LDT structure
call get_dseg ; DS -> PCMODE data
mov ax,8[bp] ; get the drive
cmp al,last_drv ; do we have an LDT for it ?
jae i2f_1217_10 ; if not do no more
cmp word ptr ldt_ptr+2,0 ; valid LDT ?
je i2f_1217_10
push ax
mov ah,LDT_LEN
mul ah
lds si,ldt_ptr
add si,ax ; DS:SI -> requested LDT, current_LDT
mov ss:word ptr current_ldt,si
mov ss:word ptr current_ldt+2,ds
pop ax
stc ; indicate NO error (CY inverted)
i2f_1217_10:
cmc
ret ; CY set if invalid
i2f_1218:
; DS:SI -> User register on DOS Call
call get_dseg ; we save SS:SP after PUSH$DOS
lds si,int21regs_ptr ; in this location
ret
i2f_1219:
; Stack = drive (0=default, 1 = A: etc)
push ds ! push si ! push word ptr 8[bp]
dec byte ptr 8[bp] ; make drive zero based
cmp byte ptr 8[bp],0ffh ; do we want the default ?
jne i2f_1219_10
call get_dseg
mov al,current_dsk
mov byte ptr 8[bp],al ; use the default drive
i2f_1219_10:
call i2f_1217 ; set's up current_ldt
jc i2f_1219_20
test ds:byte ptr 44h[si],40h ; is it valid LDT ?
jnz i2f_1219_20
stc ; indicate an error
i2f_1219_20:
pop word ptr 8[bp] ! pop si ! pop ds
ret
i2f_121A:
; Get files drive DS:SI -> drives, AL = drive
xor ax,ax ; assume default drive
cmp ds:byte ptr 1[si],':'
jne i2f_121A_10 ; if no drive letter, then default
mov al,ds:byte ptr [si]
test al,al ; null string ?
jz i2f_121A_10 ; then it's the default drive
call toupper
sub al,'A'-1 ; make one based
jbe i2f_121A_20 ; it's invalid..
push ds
call get_dseg
cmp al,last_drv ; is it a valid drive ?
pop ds
ja i2f_121A_20 ; yes, return it
i2f_121A_10:
clc
ret
i2f_121A_20:
mov al,0FFh ; invalid drive
stc
ret
i2f_121B:
; On Entry CX = year-1980
; On Exit AL = days in February
push bx
mov bx,offset days_in_month+1
mov ds:byte ptr [bx],28 ; assume 28 days in Feb
test cl,3 ; is it a leap year ?
jnz i2f_121B_10
inc ds:byte ptr [bx] ; yes, we have 29
i2f_121B_10:
mov yearsSince1980,cl ; save the year
mov al,ds:byte ptr [bx] ; return the days in Feb
pop bx
ret
i2f_121C:
; Checksum Memory CX bytes at DS:SI, DX = initial checksum
; DX = final checksum
; I've seen this used to total days in N months.
; On Entry:
; CX = current month
; DX = total days in prior years
; DS:SI -> days-per-month table
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -