⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 int2f.a86

📁 与MS-DOS兼容的DOS操作系统
💻 A86
📖 第 1 页 / 共 2 页
字号:
;    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 + -