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

📄 0cd.asm

📁 硬盘模拟光驱,可以模拟多达八个光驱
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	cmp	al,[cs:FirstID]	;	< First ID ?
	jb	@@Nope	;	Yes	-->	@@Nope
	cmp	al,[cs:LastID]	;	>	Last ID	?
	ja	@@Nope	;	Yes	-->	@@Nope
	jmp	@@GotIt	;	Got	it
@@CheckIt:
	mov	al,[cs:FirstID]	;	Get	first	emulated id
@@GetLoop:
	call	GetCDS,ax	;	Get	CDS	entry
	mov	bl,[es:bx]	;	Get	host drive letter
	cmp	bl,[byte ptr @@DriveID]	;	Id to	check	?
	je	@@GotIt	;	Yes	-->	@@GotIt
	inc	al	;	Next drive
	cmp	al,[cs:LastID]	;	Our drive ?
	jbe	@@GetLoop	;	Yes	-->	@@GetLoop
@@Nope:
	clc		;	Signal external	drive
	jmp	@@Exit	;	Exit
@@GotIt:
	stc		;	Signal own drive
@@Exit:
	ret		;	Return to	caller
endp

; NewInt21
OldInt21	dw	0,0

proc	NewInt21	far
	cmp	ah,4eh	;	FindFirst	function ?
	je	@@FindFirst	;	Yes	-->	@@FindFirst
	cmp	ah,36h	;	DiskFree function	?
	je	@@DiskFree	;	Yes	-->	@@DiskFree

	cmp	[cs:WriteProt],00h	;	Writeprotect flag	?
	je	@@NotWriteProtected	;	No --> @@NotWriteProtected
	cmp	ah,3ch	;	CreateFile function	?
	je	@@DoKillSomething	;	Yes	-->	@@DoKillSomething
	cmp	ah,0fh	;	Open FCB function	?
	je	@@DoFCB	;	Yes	-->	@@DoFCB
	cmp	ah,16h	;	Create FCB function	?
	je	@@DoFCB	;	Yes	-->	@@DoFCB
	cmp	ah,17h	;	Rename FCB function	?
	je	@@DoFCB	;	Yes	-->	@@DoFCB
	cmp	ah,39h	;	MkDir	function ?
	je	@@DoKillSomething	;	Yes	-->	@@DoKillSomething
	cmp	ah,3ah	;	RmDir	function ?
	je	@@DoKillSomething	;	Yes	-->	@@DoKillSomething
	cmp	ah,41h	;	Delete file	function ?
	je	@@DoKillSomething	;	Yes	-->	@@DoKillSomething
@@NotWriteProtected:
	jmp	@@CallOld	;	Call old interrupt handler
@@DoKillSomething:
	push	si	;	Save si
	mov	si,dx	;	ds:dx	=	Filename
	cmp	[byte ptr ds:si+1],':'	;	Contains drive letter	?
	je	@@HasDriveToKill	;	Yes	-->	@@HasDriveToKill
	push	ax	;	Save ax
	mov	ah,19h	;	Dos	Fn 19h = GetCurDrive
	int	21h	;	Call DOS interrupt
	mov	[@@TempB],al	;	Save drive letter
	pop	ax	;	Restore	ax
	mov	al,[@@TempB]	;	Drive	letter in	al
	pop	si	;	Restore	si
	add	al,'A'	;	Convert	to A-Z
	jmp	@@KillIt	;	-->	@@KillIt
@@HasDriveToKill:
	mov	al,[ds:si]	;	Get	drive	letter
	pop	si	;	Restore	si
@@KillIt:
	call	IsOwn, ax, 0000h	;	Our	drive	?
	jnc	@@CallOld	;	No --> @@CallOld
	iSTC		;	Signal error
	mov	ax,0013h	;	Write	protected	error
	iret		;	Return to	interrupt	caller
@@DoFCB:
	push	si	;	Save si
	mov	si,dx	;	Filename in	ds:si
	mov	al,[ds:si]	;	Get	drive	no
	pop	si	;	Restore	si
	call	ZeroDefault, ax	;	Calculate	drive	letter
	call	IsOwn, ax, 0001h	;	Our	drive	?
	jnc	@@CallOld	;	No --> @@CallOld
	mov	al,0ffh	;	Signal error
	iret		;	Return to	interrupt	caller
@@DiskFree:
	cmp	[cs:RetZero],1	;	Return zero	free ?
	jne	@@CallOld	;	No --> @@CallOld

	push	ax bx cx dx	;	Save registers

	call	ZeroDefault, dx	;	Calculate	drive	letter
	call	IsOwn, ax, 0000h	;	Our	drive	?
	jc	@@FakeIt	;	Yes	-->	@@FakeIt
	call	IsOwn, ax, 0001h	;	Our	drive	?
	jnc	@@NotFree	;	No --> @@NotFree
@@GotIt:
	pop	dx cx bx ax	;	Restore	registers
	int	66h	;	Call old interrupt handler
	cmp	ax,0ffffh	;	Error	?
	je	@@DiskFreeError	;	No --> @@NoDiskFreeError
	xor	bx,bx	;	0	clusters	free
@@DiskFreeError:
	iret		;	Return to	interrupt	caller
@@FakeIt:
	pop	dx cx bx ax	;	Restore	registers
	push	ax dx ds si	;	Save registers
	call	ZeroDefault, dx	;	Calculate	drive	id
	call	GetData, ax	;	Get	cd data structure
	jc	@@NoFreeData	;	Error	-->	@@NoFreeData
	mov	ax,[ds:si+153]	;	Get	sectors	per	cluster
	mov	bx,[ds:si+155]	;	Get	available	clusters
	mov	cx,[ds:si+157]	;	Get	bytes	per	sector
	mov	dx,[ds:si+159]	;	Get	total	clusters
	pop	si ds	;	Restore	registers
	add	sp,4	;	Remove two words from	stack
	iCLC		;	Signal ok
	iret		;	Return to	interrupt	caller
@@NoFreeData:
	pop	si ds dx ax	;	Restore	registers
	mov	ax,0001h	;	1	sector per cluster
	mov	bx,0000h	;	0	sectors	free
	mov	cx,0800h	;	2048 bytes per sector
	mov	dx,0ffffh	;	65535	total	clusters
	iCLC		;	Signal ok
	iret		;	Return to	interrupt	caller
@@NotFree:
	pop	dx cx bx ax	;	Restore	registers
	jmp	@@CallOld	;	Call old interrutp handler
@@FindFirst:
	test	cx,0008h	;	Volume label search	?
	jz	@@CallOld	;	No --> @@CallOld
@@CheckLabel:
	push	es bx ds si ax dx	;	Save registers

	mov	si,dx	;	Filename in	ds:si

	cmp	[byte ptr ds:si+1],':'	;	Contains drive letter	?
	je	@@OkDrive	;	Yes	-->	@@OkDrive
	push	ax	;	Save ax
	mov	ah,19h	;	Dos	Fn 19h = GetCurDrive
	int	21h	;	Call DOS interrupt
	mov	[@@TempB],al	;	Save drive letter
	pop	ax	;	Restore	ax
	mov	al,[@@TempB]	;	Get	drive	letter
	mov	bl,al	;	Put	drive	letter in	bl
	jmp	@@CheckDrive	;	-->	@@CheckDrive
@@OkDrive:
	mov	bl,[ds:si]	;	Get	drive	letter
	push	ax	;	Save ax
	call	UpCase, bx	;	Convert	to uppercase
	mov	bx,ax	;	Put	new	letter in	bx
	pop	ax	;	Restore	ax
@@CheckDrive:
	cmp	bl,[cs:FirstID]	;	Our	drive	?
	jb	@@DoCallOld	;	No --> @@DoCallOld
	cmp	bl,[cs:LastID]	;	Our	drive	?
	ja	@@DoCallOld	;	No --> @@DoCallOld
	jmp	@@CheckOk	;	-->	@@CheckOk
@@DoCallOld:
	pop	dx ax si ds bx es	;	Restore	registers
	jmp	@@CallOld	;	Call old interrupt handler
@@CheckOk:
	call	GetData, bx	;	Get	cd data
	jc	@@NoLabel	;	No data	-->	@@NoLabel
	add	si,141	;	Adjust offset
	cmp	[byte ptr ds:si],0	;	Label	?
	je	@@NoLabel	;	No --> @@NoLabel
	mov	ah,2fh	;	Get	DTA	pointer
	int	21h	;	Call DOS interrupt
	mov	[byte ptr es:bx+15h],08h	;	Set	attribute
	mov	[word ptr es:bx+16h],0000h	;	Zero time
	mov	[word ptr es:bx+18h],0000h	;	Zero date
	mov	[word ptr es:bx+1ah],0000h	;	Zero size	low
	mov	[word ptr es:bx+1ch],0000h	;	Zero size	high
	add	bx,001eh	;	Adjust offset
@@Loop:
	mov	al,[ds:si]	;	Get	character
	inc	si	;	Skip character read
	mov	[es:bx],al	;	Store	character
	inc	bx	;	Skip character stored
	test	al,al	;	End	of label ?
	jnz	@@Loop	;	No --> @@Loop
	pop	dx ax si ds bx es	;	Restore	registers
	iCLC		;	Signal success
	jmp	@@Exit	;	Exit
@@NoLabel:
	pop	dx ax si ds bx es	;	Restore	registers
	iSTC		;	Signal failure
	mov	ax,0002h	;	File not found error
	iret		;	Return to	interrupt	caller
@@CallOld:
	jmp	[dword ptr cs:OldInt21]	;	Call old interrupt handler
@@Exit:
	iret		;	Return to	interrupt	caller
@@TempB	db	1
@@TempW	dw	0
endp

; GetData procedure
proc	GetData
uses	cx
arg	@@DriveID:word
	mov	cx,[@@DriveID]	;	Get	drive	ID
	cmp	cl,[cs:FirstID]	;	Our	drive	?
	jb	@@NoData	;	No --> @@NoData
	cmp	cl,[cs:LastID]	;	Our	drive	?
	ja	@@NoData	;	No --> @@NoData
	lea	si,[Datas]	;	ds:si	-->	Datas
	sub	cl,[cs:FirstID]	;	Make drive id	0-based
	cmp	cl,0	;	First	id ?
	je	@@OkData	;	Yes	-->	@@OkData
@@NextData:
	add	si,2	;	Next index in	Datas
	dec	cl	;	Next drive
	jnz	@@NextData	;	More --> @@NextData
@@OkData:
	mov	si,[cs:si]	;	Get	segment	of data
	test	si,si	;	Data there ?
	jz	@@NoData	;	No --> @@NoData
	mov	ds,si	;	Put	segment	in ds
	xor	si,si	;	Zero offset
	clc		;	Signal success
	jmp	@@Exit	;	Exit
@@NoData:
	stc		;	Signal failure
@@Exit:
	ret		;	Return to	caller
endp

; NewInt2F
OldInt2F	dw	0,0
proc	NewInt2f	far
	mov	[cs:@@OldAX],ax
	cmp	ax,1100h	;	MSCDEX check ?
	je	@@CheckMSCDEX	;	Yes	-->	@@CheckMSCDEX
	cmp	ax,1500h	;	Installation check ?
	je	@@CheckInstall	;	Yes	-->	@@CheckInstall
	cmp	ax,1501h	;	DeviceList function	?
	je	@@DeviceList	;	Yes	-->	@@DeviceList
	cmp	ax,1502h	;	GetCopyright function	?
	je	@@GetFileName	;	Yes	-->	@@GetFileName
	cmp	ax,1503h	;	GetAbstract	function ?
	je	@@GetFilename	;	Yes	-->	@@GetFileName
	cmp	ax,1504h	;	GetBibliographical function ?
	je	@@GetFilename	;	Yes	-->	@@GetFileName

	cmp	[cs:AltSimul],01h	;	Alternate	simulation ?
	je	@@AltSimul

	cmp	ax,1505h	;	VTOC read	function ?
	je	@@ReadVTOC	;	Yes	-->	@@ReadVTOC
	cmp	ax,1508h	;	Absolute read	function ?
	je	@@AbsRead	;	Yes	-->	@@AbsRead
	cmp	ax,1509h	;	Absolute write function	?
	je	@@Dummy	;	Yes	-->	@@Dummy
	cmp	ax,150bh	;	DriveCheck function	?
	je	@@DriveCheck	;	Yes	-->	@@DriveCheck
	cmp	ax,150ch	;	Version	check	function ?
	je	@@GetVersion	;	Yes	-->	@@CheckVersion
	cmp	ax,150eh	;	Descriptor function	?
	je	@@GetDescriptorPreference	;	Yes	-->	@@GetDescriptorPreference
	cmp	ax,150fh	;	Get	directory	entry	?
	je	@@GetDirEntry	;	Yes	-->	@@GetDirEntry
	cmp	ax,1510h	;	Device request ?
	je	@@DeviceRqz	;	Yes	-->	@@DeviceRqz
	cmp	ax,150dh	;	DriveList function ?
	je	@@DriveList	;	Yes	-->	@@DriveList
@@CallOld:
	mov	ax,[cs:@@OldAX]
	jmp	[dword ptr cs:OldInt2F]	;	Call old interrupt handler
@@AltSimul:
	cmp	ax,150bh	;	DriveCheck function	?
	je	@@DriveCheck	;	Yes	-->	@@DriveCheck
	cmp	ax,150ch	;	Version	check	function ?
	je	@@GetVersion	;	Yes	-->	@@CheckVersion
	cmp	ax,150dh	;	DriveList function ?
	je	@@DriveList	;	Yes	-->	@@DriveList
	cmp	ax,1510h	;	Device request ?
	je	@@SuccessDev	;	Yes	-->	@@SuccessDev
	jmp	@@CallOld	;	Call old
@@AbsRead:
	test	dx,dx	;	Sector count > 0	?
	jz	@@ReadFinished	;	Yes	-->	@@ReadFinished
	push	cx ds si	;	Save registers
	add	cl,'A'	;	Convert	drive letter to A-Z
	push	ax	;	Save ax
	call	GetSpeed, cx	;	Get	drive	speed
	mov	[@@DelaySize],ax	;	Save speed of	delay
	pop	ax	;	Restore	ax
	call	GetData, cx	;	Get	cd data
	jc	@@NoAbsRead	;	Error	-->	@@NoAbsRead
	mov	si,[ds:si+2]	;	Adjust offset
	cmp	si,0ffffh	;	Sector data ?
	je	@@NoAbsRead	;	No --> @@NoAbsRead
	push	bx dx	;	Save registers
@@ReadDataLoop:
	push	ds si es bx	;	Save registers
	call	DeCrunch, ds si, es bx	;	Decrunch sector	data
	pop	bx es si ds	;	Restore	registers
	add	bx,2048	;	Next sector	offset
	dec	dx	;	One	less sector	to read
	jnz	@@ReadDataLoop	;	More --> @@ReadDataLoop
	pop	dx bx si ds cx	;	Restore	registers
@@ReadFinished:
	push	ax cx dx	;	Save registers
	cmp	[@@DelaySize],0	;	Any	delay	?
	je	@@NoDelay	;	No --> @@NoDelay
@@DelayLoop:
	test	dx,dx	;	Sectors	=	0	?
	jz	@@NoDelay	;	Yes	-->	@@NoDelay
	push	dx	;	Save dx
	mov	ah,86h	;	AT Fn	86h	=	Wait
	mov	cx,0	;	High 16	bit	of delay
	mov	dx,[@@DelaySize]	;	Low	16 bit of	delay
	int	15h	;	Call AT	interrupt
	pop	dx	;	Restore	dx
	dec	dx	;	One	less delay to	perform
	jmp	@@DelayLoop	;	Loop
@@NoDelay:
	pop	dx cx ax	;	Restore	registers
	iCLC		;	Signal success
	iret		;	Return to	interrupt caller
@@NoAbsRead:
	pop	si ds cx	;	Restore	registers
	cmp	[cs:DoFailure],01h	;	Failure	on exit	?
	jne	@@Dummy	;	No --> @@Dummy
	iSTC		;	Signal failure
	mov	ax,0015h	;	Drive	not	ready	error
	iret		;	Return to	interrupt	caller
@@GetDescriptorPreference:
	cmp	bx,0	;	Get	function ?
	je	@@GetPreference	;	Yes	-->	@@GetPreference
	iCLC		;	Signal success
	iret		;	Return to	interrupt	caller
@@GetPreference:
	mov	dx,0100h	;	Set	return bits
	iCLC		;	Signal success
	iret		;	Return to	interrupt	caller
@@Dummy:
	iCLC		;	Signal success
	iret		;	Return to	interrupt	caller
@@ReadVTOC:
	push	ds si	;	Save registers
	add	cl,'A'	;	Convert	id to	A-Z
	call	GetData, cx	;	Get	cd data
	jc	@@HasNoVTOC	;	Error	-->	@@HasNoVTOC
	mov	si,[ds:si]	; Adjust offset
@@GetVTOC:
	cmp	[word ptr ds:si],0ffffh	;	Last sector	?
	je	@@ReadFlags	;	Yes	-->	@@ReadFlags
	cmp	[ds:si],dx	;	Sector wanted	?
	je	@@ReadTheVTOC	;	Yes	-->	@@ReadFlags
	add	si,2	; Skip index word
	add	si,[word ptr ds:si]	; Skip _ax+_flags+data
	jmp	@@GetVTOC	;	Loop
@@ReadTheVTOC:
	push	ax cx si	;	Save registers
	add	si,8	;	Adjust offset
	call	DeCrunch, ds si, es bx	;	Decrunch sector
	pop	si cx ax	;	Restore	registers
@@ReadFlags:
	mov	ax,[word ptr ds:si+6]	;	Get	flags	to return

	push	bp	;	Save bp
	mov	bp,sp	;	Point	bp to	sp in	stack
	mov	[word ptr bp+10],ax	;	Adjust flags on	stack
	pop	bp	;	Restore	bp

	mov	ax,[word ptr ds:si+4]	;	Get	ax to	return
	pop	si ds	;	Restore	registers
	cmp	[cs:DoFailure],01h	;	Failure	on exit	?
	jne	@@Dummy	;	No --> @@Dummy
	mov	al,17h
	iSTC		;	Signal failure
	iret		;	Return to	interrupt	caller
@@HasNoVTOC:
	pop	si ds	;	Restore	registers
@@NoVTOC:
	cmp	[cs:DoFailure],01h	;	Failure	on exit	?
	jne	@@Dummy	;	No --> @@Dummy
	iSTC		;	Signal failure
	mov	al,17h	;	Error	code
	iret		;	Return to	interrupt	caller
@@DeviceRqz:
	mov	cl,[cs:FirstRealCD]	;	Get	the	real cd-drive
	mov	al,[byte ptr es:bx+2]	;	Get	device command code
	cmp	al,1	;	Media	check	function ?
	je	@@ErrRqz	;	Yes	-->	@@ErrRqz
	cmp	al,2	;	Build	BPB	?
	je	@@ErrRqz	;	Yes	-->	@@ErrRqz
	cmp	al,3	;	IOCTL	input	?
	je	@@IOCTLI	;	Yes	-->	@@IOCTLI
	cmp	al,4	;	Input	?
	je	@@ErrRqz	;	Yes	-->	@@ErrRqz
	cmp	al,5	;	Nondestructive read	?
	je	@@ErrRqz	;	Yes	-->	@@ErrRqz
	cmp	al,6	;	Input	status ?
	je	@@ErrRqz	;	Yes	-->	@@ErrRqz
	cmp	al,8	;	Output ?
	je	@@ErrRqz	;	Yes	-->	@@ErrRqz
	cmp	al,9	;	Output with	verify ?
	je	@@ErrRqz	;	Yes	-->	@@ErrRqz
	cmp	al,10	;	Output status	?
	je	@@ErrRqz	;	Yes	-->	@@ErrRqz
	cmp	al,11	;	Output flush ?
	je	@@ErrRqz	;	Yes	-->	@@ErrRqz
	cmp	al,12	;	IOCTL	output ?

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -