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

📄 0cd.asm

📁 硬盘模拟光驱,可以模拟多达八个光驱
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	mov	bx,[@@Handle]	; Filehandle in bx
	int	21h	; Call DOS interrupt
	mov	[cs:Quiet],00h	; Turn of quiet mode
	call	LStrWrite, offset DataTooBig	; Write error msg
	call	CleanUp	; Clean up
	ExitCode	0001h	; Exit to DOS
@@OkSize:
	mov	[@@Size],ax	; Save size	of file
	shr	ax,4	; Divide by	16
	inc	ax	; And add 1
	mov	bx,ax	; Number of	segments in	bx
	mov	ah,48h	; Dos Fn 48h = AllocMem
	int	21h	; Call DOS interrupt
	jc	@@NoMem	; Error -->	@@NoMem
	mov	es,ax	; Segment in es
	mov	[@@NewSeg],ax	; Store new	segment

	mov	ax,4200h	; Dos Fn 42	= LSeek
	mov	bx,[@@Handle]	; Filehandle in bx
	xor	cx,cx	; High 16 bits of position
	xor	dx,dx	; Low 16 bits of position
	int	21h	; Call DOS interrupt

	mov	ah,3fh	; Dos Fn 3fh = Read file
	mov	bx,[@@Handle]	; Filehandle in bx
	push	ds	; Save ds
	push	es	; Put ds ...
	pop	ds	; ... in es
	xor	dx,dx	; High 16 bits of size in dx
	mov	cx,[@@Size]	; Low 16 bits of size in cx
	int	21h	; Call DOS interrupt
	pop	ds	; Restore ds

	mov	al,[byte ptr @@DriveID]	; Get driveletter
	mov	[ReadData2],al	; Update message text
	call	LStrWrite, offset ReadData1	; Write text
	call	LStrWrite, offset DataName	; Write filename
	call	LStrWrite, offset CRLF		; Newline
	mov	bx,[@@Handle]	; Filehandle in bx
	mov	ah,3eh	; Dos Fn 3eh = Close file
	int	21h	; Call DOS interrupt
	jmp	@@Exit	; Exit
@@NoMem:
	mov	bx,[@@Handle]	; Filehandle in bx
	mov	ah,3eh	; Dos Fn 3eh = Close file
	int	21h	; Call DOS interrupt
	mov	[cs:Quiet],00h	; Turn off quiet mode
	call	LStrWrite, offset DataNoMem	; Write error msg
	call	CleanUp	; Clean up
	ExitCode	0001h	; Exit to dos
@@Exit:
	lea	si,[Datas]	; ds:si point to Datas
	mov	cx,[@@DriveID]	; Get drive	letter
	sub	cl,[cs:FirstID]	; Make 0-based
	cmp	cl,0	; First drive ?
	je	@@DoExit	; Yes --> @@DoExit
@@Loop:
	add	si,2	; Next data	index
	dec	cl	; One less to skip
	jnz	@@Loop	; More --> @@Loop
@@DoExit:
	mov	es,[@@NewSeg]	; Return segment in es
	mov	[ds:si],es	; Save segment in Datas
	ret		; Return to	caller
endp

; Report procedure
proc	Report
	cmp	[cs:CoMSCDEX],01h	;	MSCDEX co-existance	?
	jne	@@NoCoEXIST
	call	LStrWrite, offset CoMsg	;	Write	message
@@NoCoExist:
	cmp	[cs:AudioTru],00h	;	Audio	throughput ?
	je	@@NoTru	;	No --> @@NoTru
	call	LStrWrite, offset TruMsg	;	Write	message
@@NoTru:
	cmp	[cs:AltSimul],00h	;	Alternate	simulation ?
	je	@@NoAlt	;	No --> @@NoAlt
	call	LStrWrite, offset AltMsg	;	Write	message
@@NoAlt:
	cmp	[cs:DoFailure],00h	;	Failure	or success ?
	je	@@Success
	call	LStrWrite, offset FailMsg	;	Write	message
	jmp	@@OkFail
@@Success:
	call	LStrWrite, offset SuccessMsg	;	Write	message
@@OkFail:
	cmp	[cs:WriteProt],00h	; Write-protected ?
	je	@@NotProt	; No --> @@NotProt
	call	LStrWrite, offset IsProt	; Write message
	jmp	@@Size	; --> @@Size
@@NotProt:
	call	LStrWrite, offset NotProt	; Write message
@@Size:
	cmp	[cs:RetZero],00h	;	Zero disk	free ?
	je	@@NotZero	;	No --> @@NotZero
	call	LStrWrite, offset CD0	;	Write	message
	jmp	@@Exit	;	Exit
@@NotZero:
	call	LStrWrite, offset CDSize	;	Write	message
@@Exit:
	call	LStrWrite, offset CRLF	;	Write	an empty line
	ret		;	Return to	caller
endp

; SaveDir procedure
proc	SaveDir
uses	ax, si, dx
	mov	ah,47h	;	Dos	Fn 47h = GetCurDir
	lea	si,[OldDir+1]	;	Destination in ds:si
	push	ds
	push	cs
	pop	ds
	mov	[byte ptr ds:si-1],'\'	;	Make \ relative
	mov	dl,00h	;	Set	to current drive
	int	21h	;	Call DOS interrupt
	pop	ds

	mov	ah,19h	;	Dos	Fn 19h = GetCurDrive
	int	21h	;	Call DOS interrupt
	mov	[cs:OldDrive],al	;	Save drive
	ret		;	Return to	caller
endp

; ReturnDir	procedure
proc	ReturnDir
uses	ax, dx
	mov	ah,0eh	;	Dos	Fn 0eh = SetCurDrive
	mov	dl,[cs:OldDrive]	;	Drive	no in dl
	int	21h	;	Call DOS interrupt

	mov	ah,3bh	;	Dos	Fn 3bh = SetCurDir
	lea	dx,[OldDir]	;	Directory	in ds:dx
	push	ds
	push	cs
	pop	ds
	int	21h	;	Call DOS interrupt
	pop	ds
	ret		;	Return to	caller
endp

; LStrWrite procedure
proc	LStrWrite
arg	@@Str:word
	cmp	[cs:Quiet],1	;	Quiet	mode ?
	je	@@Exit	;	Yes	-->	@@Exit
	cmp	[cs:Inited],0	;	Already	shown version	?
	jne	@@Ok	;	Yes	-->	@@Ok
	mov	[cs:Inited],1	;	Set	version shown flag
	call	StrWrite, cs offset InitMsg	;	Show version message
@@Ok:
	call	StrWrite, [@@Str]	;	Write	text
@@Exit:
	ret		;	Return to	caller
endp

; Init procedure
proc	Init
	call	GetFirstDrive
	call	ReadDescription
	call	Needed
	call	CheckMSCDEX
	ret
endp

; GetCOMSPEC procedure
proc	GetCOMSPEC
uses	ax, si, di, es, ds
	mov	ah,62h	;	Dos	Fn 62h = Get PSP
	int	21h	;	Call DOS interrupt
	mov	es,bx	;	Segment	of PSP in es
	mov	es,[es:002ch]	;	Get	environment segment
	xor	si,si	;	Start	of environment
@@Loop:
	call	StrLIComp, es si, ds offset CSEnv, 8	;	COMSPEC=xxx ?
	jc	@@Next	;	No --> @@Next
	add	si,8	;	Skip to	xxx
	call	StrCopy, cs offset ProgName, es si	;	Save program name
	jmp	@@Exit	;	Exit
@@Next:
	inc	si	;	Next character
	cmp	[byte ptr es:si],0	;	At end of	string ?
	jne	@@Next	;	No --> @@Next
	inc	si	;	Skip end-of-string char
	cmp	[byte ptr es:si],0	;	End	of environment ?
	jne	@@Loop	;	No --> @@Loop
@@Exit:
	ret		;	Return to	caller
endp

; Needed procedure
proc	Needed
	cmp	[AnyRedir],1	;	Any	redirections at all ?
	je	@@Exit	;	Yes	-->	@@Exit
	call	LStrWrite, offset NoRedirs	;	Write	error message
	call	CleanUp	;	Clean	up
	ExitCode	0001h	;	Exit to	dos
@@Exit:
	call	CheckFile	;	Check	for	program to run
	ret		;	Return to	caller
endp

; CheckFile	procedure
proc	CheckFile
	mov	ax,3d00h	;	Dos	Fn 3d	= Open file
	push	ds
	push	cs
	pop	ds
	lea	dx,[RunName]	;	Filename in ds:dx
	int	21h	;	Call DOS interrupt
	pop	ds
	jc	@@NoFile	;	Error	-->	@@NoFile
	mov	bx,ax	;	Filehandle in bx
	mov	ah,3eh	;	Dos	Fn 3eh = Close file
	int	21h	;	Call DOS interrupt
	call	LStrWrite, offset RunProg	;	Show run message
	push	ds cs	;	Save ds	and	put	cs ...
	pop	ds	;	...	into ds
	call	LStrWrite, offset RunName	;	Show name of program
	pop	ds	;	Restore	ds
	call	LStrWrite, offset CRLF	;	Newline
	jmp	@@Exit	;	Exit
@@NoFile:
	mov	[byte ptr cs:Params],0	;	No parameters to COMSPEC
@@Exit:
	ret		;	Return to	caller
endp

; GetCDS procedure
; Returns pointer in	es:bx, and carry set if success, or	0:0	in es:bx and
; carry clear if failure
proc	GetCDS
arg	@@DriveID:word
uses	ax
	call	UpCase, [@@DriveID]	;	Make letter uppercase
	mov	[@@DriveID],ax	;	Store	in @@DriveID

	mov	ah,52h	;	Dos	Fn 52h = Get DosSysVars
	int	21h	;	Call DOS interrupt
	add	bx,16h	;	Skip to	CDS entry
	les	bx,[dword ptr es:bx]	;	Get	pointer to CDS in	es:bx
	mov	al,'A'	;	First	drive letter in	CDS
@@Loop:
	cmp	al,[byte ptr @@DriveID]	;	Correct	CDS record ?
	je	@@Found	;	Yes	-->	@@Found
	add	bx,88	;	Skip record
	inc	al	;	Next drive letter
	cmp	al,'['	;	Beyond end of CDS ?
	jb	@@Loop	;	No --> @@Loop
	xor	bx,bx	;	Zero offset
	mov	es,bx	;	Zero segment
	clc		;	Signal failure via carry
	jmp	@@Exit	;	Exit
@@Found:
	stc		;	Signal success via carry
@@Exit:
	ret		;	Return
endp

; GetFirstDrive procedure
proc	GetFirstDrive
local	@@DriveID:word
uses	ax
	mov	[@@DriveID],'D'	;	First	available drive	letter
@@Loop:
	call	GetCDS, [@@DriveID]	;	Get	CDS	entry for drive
	jnc	@@Exit	;	Failure	--> @@Exit
	cmp	[word ptr es:bx+67],0000h	;	Drive	available ?
	jne	@@Next	;	No --> @@Next
	cmp	[word ptr es:bx+69],0000h	;	Drive	available ?
	jne	@@Next	;	No --> @@Next
	cmp	[word ptr es:bx+71],0000h	;	Drive	available ?
	jne	@@Next	;	No --> @@Next
	mov	al,[byte ptr @@DriveID]	;	Get	drive	ID
	mov	[DriveID],al	;	Store	ID
	jmp	@@Exit	;	Exit
@@Next:
	inc	[@@DriveID]	;	Next ID
	cmp	[@@DriveID],'['	;	Beyond available IDs?
	je	@@Err	;	Yes	-->	@@Err
	jmp	@@Loop	;	Loop
@@Exit:
	mov	al,[DriveID]	;	Get	drive	ID
	mov	[cs:FirstID],al	;	Save as	first ID
	ret		;	Return to	caller
@@Err:
	mov	[cs:Quiet],0	;	Turn off quiet mode
	call	LStrWrite, offset NoDrives	;	Write	error message
	call	CleanUp	;	Clean	up
	ExitCode	0001h	;	Exit to	dos
endp

; CheckMSCDEX procedure
proc	CheckMSCDEX
	push	0dadah	;	Put	0dadah on stack
	mov	ax,1100h	;	Multiplex	Fn 1100h = MSCDEX
	mov	si,'0C'	;	si:ds	=	'0CD6' ...
	mov	di,'D7'	;	...
	int	2fh	;	Call multiplex interrupt
	pop	bx	;	Get	stack	entry
	cmp	al,0ffh	;	MSCDEX installed ?
	jne	@@NoMSCDEX	;	No --> @@NoMSCDEX
	cmp	bx,0adadh	;	Correct	entry on stack ?
	jne	@@NoMSCDEX	;	No --> @@NoMSCDEX
@@Installed:
	cmp	[cs:AudioTru],01h	;	Audio	throughput ?
	je	@@ExitInstalled	;	Yes	-->	@@ExitInstalled
	cmp	si,'7D'	;	0cd signature ?
	jne	@@MSC	;	No --> @@MSC
	cmp	di,'C0'	;	...
	jne	@@MSC	;	...
	call	LStrWrite, offset Installed	;	Show installed message
	jmp	@@Quit	;	Exit to	dos
@@NoMSCDEX:
	cmp	[cs:AudioTru],01h	;	Audio	through-put	enabled	?
	jne	@@Exit	;	No --> @@Exit
	call	LStrWrite, offset NoMSCDEX	;	Write	warning	message
	mov	[cs:AudioTru],00h	;	Disable	audio	throughput
	jmp	@@Exit	;	Exit
@@MSC:
	mov	[cs:AltSimul],00h	;	Disable	alternate	simulation
	cmp	[cs:CoMSCDEX],01h	;	MSCDEX co-existance	?
	je	@@Exit	;	Yes	-->	@@Exit
	call	LStrWrite, offset MSCDEX	;	Show MSCDEX message
@@Quit:
	call	CleanUp	;	Clean	up
	ExitCode	0001h	;	Exit to	dos
@@ExitInstalled:
	mov	[cs:AltSimul],00h	;	Disable	alternate	simulation
	mov	ax,1500h	;	Get	number of	drives
	int	2fh	;	Call old driver
	mov	[cs:FirstRealCD],cl	;	Store	first	unit
@@Exit:
	ret		;	Return to	caller
endp

; ReadDescription procedure
proc	ReadDescription
local	@@File:word
	mov	ah,62h	;	Dos	Fn 62h = Get PSP
	int	21h	;	Call DOS interrupt
	mov	es,bx	;	Segment	of PSP in es
	mov	si,81h	;	Offset 81h = Parameters
	lea	di,[Line]	;	Point	ds:di to Line
	mov	[byte ptr ds:di],0	;	Terminate	Line variable
	mov	cl,[es:si-1]	;	Get	number of characters
	cmp	cl,0	;	Any	at all ?
	je	@@Exit	;	No --> @@Exit
@@Loop:
	mov	al,[es:si]	;	Get	character
	inc	si	;	Skip character
	cmp	al,09h	; Tab character ?
	je	@@Space	;	Yes	-->	@@Space
	cmp	al,20h	;	Space	character
	je	@@Space	;	Yes	-->	@@Space
	cmp	al,0dh	;	End	of parameters ?
	je	@@Space	;	Yes	-->	@@Space
	mov	[ds:di],al	;	Store	character in Line
	inc	di	;	Skip character in Line
	mov	[byte ptr ds:di],0	;	Terminate	Line variable
@@Next:
	dec	cl	;	One	less character to	process
	jnz	@@Loop	;	More --> @@Loop
	call	Parse	;	Parse	current parameter
	jmp	@@Exit	;	Exit
@@Space:
	cmp	[byte ptr Line],0	;	Parameter	?
	je	@@NoLine	;	No --> @@NoLine
	call	Parse	;	Parse	current parameter
@@NoLine:
	mov	[byte ptr Line],0	;	Empty	Line variable
	lea	di,[Line]	;	Rewind pointer to Line
	jmp	@@Next	;	Next character
@@Exit:
	ret		;	Return to	caller
endp

; Parse procedure
proc	Parse
uses	si, ax, cx, bx, ds, es
	cmp	[byte ptr ds:Line],'/'	;	Option character ?
	je	@@Option	;	Yes	-->	@@Option
	cmp	[byte ptr ds:Line],'-'	;	Option character ?
	je	@@Option	;	Yes	-->	@@Option
	call	Redirect	;	Redirect new drive
	jmp	@@Exit	;	Exit
@@Option:
	mov	al,[byte ptr ds:Line+1]	;	Get	option character
	call	UpCase, ax	;	Convert	to uppercase
	cmp	al,'V'	;	Revision option	?
	je	@@ShowRev
	cmp	al,'M'	;	MSCDEX option	?
	je	@@MSCDEX	;	Yes	-->	@@MSCDEX
	cmp	al,'A'	;	Alternate	option ?
	je	@@Alt	;	Yes	-->	@@Alt
	cmp	al,'F'	;	Failure	option ?
	je	@@Failure	;	Yes	-->	@@Failure
	cmp	al,'I'	;	Simulation option	?
	je	@@Simulate	;	Yes	-->	@@Simulate
	cmp	al,'R'	;	Run	option ?
	je	@@SetRun	;	Yes	-->	@@SetRun
	cmp	al,'D'	;	DataFile option ?
	je	@@Data	;	Yes	-->	@@Data
	cmp	al,'0'	;	0-free option ?
	je	@@ZeroRet	;	Yes	-->	@@ZeroRet
	cmp	al,'L'	;	Letter option ?
	je	@@NewLetter	;	Yes	-->	@@NewLetter

⌨️ 快捷键说明

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