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

📄 int2f.a86

📁 一个dos操作系统DRDOS的源码
💻 A86
📖 第 1 页 / 共 2 页
字号:
; 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 + -