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

📄 ekemm.asm

📁 vhdl 8086 core
💻 ASM
字号:
	name	driver
	page	55,132
	title	'EKEMM --- EMS 3.2 Driver For Hedley's PCEMU'

;
;
;
; Based on a template (c) Ray Duncan, April 1985
; Changes Copyright 1994, Eric Korpela.; There is no warantee expressed or implied in this software.; See the file COPYRIGHT and ems.c for details.
code	segment	public	'CODE'

driver	proc	far

	assume	cs:code,ds:code,es:code

	org 	0

Max_Cmd	equ	16	; MS-DOS command code maximum

cr	equ	0dh
lf	equ	0ah
eom	equ	'$'

	page
;
; Device Driver Header
;
Header	dd	-1		; link to next device, -1=end of list

	dw	0C000h		; Device Attribute word
	dw	Strat		; Device "Strategy" entry point
	dw	Intr		; Device "Interrupt" entry point
	db	'EMMXXXX0'	; character device name

;
;  Double-word pointer to Request Header
;  Passed to Strategy routine by MS-DOS
;

RH_Ptr	dd	?
	page
;
;  MS-DOS Command Codes dispatch table.
;  The "Interrupt" Routine uses this table and the 
;  Command Code supplied in the Request Header to
;  transfer to the appropriate driver subroutine.

Dispatch:
	dw	Init		;  0=initialize driver
	dw	Media_Chk	;  1=media check on block device
	dw	Build_Bpb	;  2=build BIOS parameter block
	dw	IOCTL_Rd	;  3=I/O Control read
	dw	Read		;  4=Read from Device
	dw	ND_Read		;  5=non-destructive read
	dw	Inp_Stat	;  6=return current input status
	dw	Inp_Flush	;  7=flush device input buffers
	dw	Write		;  8=write to device
	dw	Write_Vfy	;  9=write with verify
	dw	Outp_Stat	; 10=return current output status
	dw	Outp_Flush	; 11=flush output buffers
	dw	IOCTL_Wrt	; 12=I/O control write
	dw	Dev_Open	; 13=Device Open
	dw	Dev_Close	; 14=Device Close
	dw	Rem_Media	; 15=removable media
	dw	Out_Busy	; 16=output until busy
	page
;
;  MS-DOS Request Header Structure Definition
;
;  The first 13 bytes of all Request Headers are the same
;  and are referred to as the "Static" part of the header.
;  The number and meaning of the following bytes varies.
;  In this "Struc" definition we show the Request Header
;  contents for Read and Write calls.
;
Request	struc			; Request Header template structure
				; begining of static portion
Rlength	db	?		; length of request header
Unit	db	?		; unit number for this request
Command	db	?		; request header's command code
Status	dw	?		; Driver's return status word
				; bit 15	= Error
				; bits 10-14	= Reserved
				; bit 9		= Busy
				; bit 8		= Done
				; bits 0-7	= Error code if bit 15 = 1
Reserve	db	8 dup (?)	; reserved area
				; end of Static Portion, the remainder in 
				; this example is for Read Write functions.
Media	db	?		; Media Descriptor byte
Address	dd	?		; Memory Address for Transfer
Count	dw	?		; byte/sector count value
Sector	dw	?		; Starting sector value
Request ends			; end of request header template
	page

; Device Driver Strategy Routine
;
; Each time a request is made for this device, MS-DOS
; first calls the "Strategy Routine", then immediately
; calls the "Interrupt routine".

; The Strategy routine is passed the address of the
; Request Header in ES:BX, which it saves in a local
; variable and then returns to MS-DOS.

Strat	proc	far
				; save addresss of Request Header
	mov	word ptr cs:[RH_Ptr],bx
	mov	word ptr cs:[RH_Ptr+2],es

	ret			; back to MS-DOS

Strat	endp
	page

; Device Driver Interrupt Routine

; This entry point is called by MS-DOS immediately after
; the call to the "Strategy Routine",  which saved the long
; address of the Request Header in the local variable "RH_Ptr".

; The "Interrupt Routine" uses the Command Code passed in 
; the Request Header to transfer to the appropriate device
; handling routine.  Each command code routine must place
; any necessary return information into the Request Header,
; then perform a near return with AX=Status.

Intr	proc	far

	push	ax		; save general registers
	push	bx
	push	cx
	push	dx
	push	ds
	push	es
	push	di
	push	si
	push	bp

	push	cs		; make local data addressable
	pop	ds

	les	di,[RH_Ptr]	; let ES:DI = Request header
	
				; get BX = command code
	mov	bl,es:[di.Command]
	xor	bh,bh
	cmp	bx,Max_Cmd	; make sure it's legal.
	jle	Intr1		; jump if fuction code is OK
	mov	ax,8003h	; set Error bit and "Unknown Command" code
	jmp	Intr2

Intr1:	shl	bx,1		; form index to dispatch table
				; and branch to driver routine.
	call	word ptr [bx+Dispatch]
				; should return AX = status.
	les	di,[RH_Ptr]	; restore ES:DI = addr of Request header

Intr2:	or	ax,0100h	; merge Done bit into status, and
				; store into request header
	mov	es:[di.Status],ax

	pop	bp		; restore general registers.
	pop	si
	pop	di
	pop	es
	pop	ds
	pop	dx
	pop	cx
	pop	bx
	pop	ax
	ret			; back to MS-DOS

	page

;
; Command Code subroutines called by Interrupt Routine
;
; These routines are called with ES:DI pointing to the 
; Request Header.
;
; They should return AX = 0 if function was completed
; successfully, or AX = 8000H + Error code if function failed.
;

Write	proc	near		; Function 8 = write
	xor	ax,ax
	ret
Write	endp

Media_Chk	equ	Offset Write	; Function 1 = Media Check

Build_Bpb	equ	Offset Write	; Function 2 = Build BPB

IOCTL_Rd	proc	near	; Function 3 = I/O Control Read

	xor	ax,ax
	mov	es:[di.Count],ax
        mov	al,0FFh
	ret

IOCTL_Rd	endp

Read	equ	Offset IOCTL_Rd	; Function 4 = Read

ND_Read	equ	Offset IOCTL_Rd	; Function 5 = Non-Destructive Read

Inp_Stat	equ	Offset Write	; Function 6 = Input Status

Inp_Flush	equ	Offset Write	; Function 7 = Input Flush

Write_Vfy	equ	Offset Write 	; Function 9 = Write with Verify

Outp_Stat	equ	Offset IOCTL_Wrt	; Function 10 = Output Status

Outp_Flush	equ	Offset Write	; Function 11 = Flush Output Buffers

IOCTL_Wrt	proc 	near	; Function 12 = I/O Control Write
	mov	ax,0FFh
	ret
IOCTL_Wrt	endp

Int67		proc	far
	int 4Bh
	iret	
Int67	endp	
Dev_Open	equ	Offset Write	; Function 13 = Device Open

Dev_Close	equ	Offset Write	; Function 14 = Device Close

Rem_Media	equ	Offset Write	; Function 15 = Removable Media

Out_Busy	equ	Offset Write	; Function 16 = Output until busy

	page

; The initialization code for the driver is called only
; once, when the driver is loaded.  It is reasponsible for
; initializing the hardware, setting up any necessary
; interrupt vectors, and it must return the address 
; of the first free memory after the driver to MS-DOS.
; If it is a block device driver, Init must also return the
; address of the BIOS parameter block pointer array; if all
; units are the same, all pointers can be to the same BPB.
; Only MS-DOS services 01-0CH and 30H can be called by the
; Initialization Function.
;
; In this example, Init returns its own address to the DOS as
; the start of free memory after the driver, so that the memory
; occupied by INIT will be reclaimed after it is finished
; with its work.

Init	proc	near		; Function 0 = Initialize Driver

	push	es		; save address of Request Header.
	push	di

	mov	ax,cs		; convert load address to ASCII.
	mov	bx, offset DHaddr
	call	hexasc

	mov	ah,9		; print sign-on message and
	mov	dx,offset Ident	; the load address of the driver.
	int	21h
	push	ds
	push	dx
        mov	al,67h
	mov	dx,cs
        mov	ds,dx
	mov	dx,offset Int67
        mov	ah,25h
	int	21h

	pop	dx
	pop	ds
	pop	di		; restore Request Header addr.
	pop	es

				; set first usable memory address
	mov	word ptr es:[di.Address],offset init
	mov	word ptr es:[di.Address+2],cs

	xor	ax,ax		; Return Status
	ret

Init	endp

Ident	db	cr,lf,lf
	db	'EKEMS Device Driver 1.0'
        db	cr,lf
	db	'Device Header at '

DHaddr	db	'XXXX:0000'
	db	cr,lf,lf,eom

Intr	endp

	page

; HEXASC --- converts a binary 16 bit number into
;            a "hexidecimal" ASCII string.
;
; Call with	AX	= value to convert
;		DS:BX	= address to store 4 character string
;
; Returns	AX, BX	destroyed, other registers preserved

hexasc	proc	near

	push	cx	; save registers.
	push	dx

	mov	dx,4	; initialize character counter.

hexasc1:
	mov	cx,4	; isolate next 4 bits.
	rol	ax,cl
	mov	cx,ax
	and	cx,0fh
	add	cx,'0'	; convert to ASCII.
	cmp	cx,'9'	; is it 0-9?
	jbe	hexasc2	; yes, jump.
			; add fudge factor for A-F.
	add	cx,'A'-'9'-1

hexasc2:		; store this character.
	mov	[bx],cl
	inc	bx	; bump string pointer.

	dec	dx	; count characters converted.
	jnz	hexasc1	; loop, not four yet.

	pop	dx	; restore registers.
	pop	cx
	ret		; back to caller

hexasc	endp

Driver	endp

code	ends

	end

	

⌨️ 快捷键说明

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