INT2F.A86
资源名称:drdossrc.zip [点击查看]
上传用户:xiaogehua
上传日期:2007-01-08
资源大小:1183k
文件大小:29k
源码类别:
操作系统开发
开发平台:
Asm
- ; 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
- ; 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