	PAGE	60,132
; JELDSK - JOHN'S ELECTRONIC DISK DRIVER FOR DOS 2
; 10/30/83 BY JOHN HENDERSON FOR THE PUBLIC DOMAIN
;	FINAL DEBUGING BY HAO NGUYEN
CSEG	SEGMENT PARA PUBLIC 'CODE'
JELDSK	PROC   FAR
	ASSUME CS:CSEG, ES:CSEG,DS:CSEG

;	SPECIAL DEVICE HEADER
START   DD      -1		;POINTER TO NEXT DEVICE		
   	DW  	2000H	 	;BLOCK DEVICE (NON IBM FMAT)
    	DW 	DEV_STRATEGY 	;POINTER TO DEVICE STRAT
   	DW  	DEV_INT		;POINTER TO DEVICE INT. HNDLER		
	DB  	1		;NUMBER OF BLOCK DEVICES
	DB	'       ' 	;7 BYTES OF FILLER
;	BIOS PARAMETER BLOCK
BPB_PTR DW	BPB		;BIOS PARM BLOCK POINTER ARRAY
BPB	DW	512		;SECTOR SIZE
	DB  	1		;SECTORS/ALLOCATION UNIT
	DW	1		;NUMBER OF RESERVED SECTORS	  				 
	DB  	1		;NUMBER OF FATS
	DW	64		;NUMBER OF DIRECTORY ENTRIES
SECS	DW	132		;TOTAL NUMBER OF SECTORS
	DB	0FCH		;MEDIA DESCRIPTOR
	DW	1		;NUMBER SECTORS OF FAT

FUNTAB	DW	INIT	    	;INITIALIZATION
	DW	MEDIA_CHECK 	;MEDIA CHECK (BLOCK ONLY)
  	DW	BUILD_BPB   	;BUILD BPB   (BLOCK ONLY) 
  	DW	EXIT    	;IOCTL INPUT
  	DW	INPUT       	;INPUT (READ)
  	DW	EXIT    	;NON_DESTR. INPUT NO WAIT 		
  	DW	EXIT	    	;INPUT STATUS (CHAR. ONLY)
	DW	EXIT    	;INPUT FLUSH  (CHAR. ONLY)
  	DW	OUTPUT      	;OUTPUT (WRITE)
  	DW	OUTPUT  	;OUTPUT (WRITE) W/VERIFY
  	DW	EXIT    	;OUTPUT STATUS (CHAR ONLY)
  	DW	EXIT	  	;OUTPUT FLUSH   "       "
  	DW	EXIT	   	;IOCTL OUTPUT FLUSH

;DEVICE PSUEDO INTERRUPT HANDLER
DEV_INT: CLD	; PRESERVE MACHINE STATE ON ENTRY
	PUSH	DS
	PUSH	AX
	PUSH	CX
	PUSH	DX
	PUSH	DI
	PUSH	SI
	PUSH	ES
	MOV	AL,ES:[BX+2]	;GET FUNCTION BYTE
	SHL	AL,1		;GET OFFSET TO TABLE
	CBW
	MOV	DI,OFFSET FUNTAB ;GET ADDRESS OF FUN TAB
	ADD	DI,AX
	MOV	AX,ES:[BX+20]	;STARTING SEC NO
	MOV	CL,5
	SHL	AX,CL		;MULTIPLY GET ACT SEC
	MOV	DX,CS		;GET SEG VIRTUAL DISK
	ADD	DX,14		;ADD PROGRAM SIZE
	ADD	DX,AX		;STARTING SEG OFFSET
	XOR	SI,SI		;IT'S ON PARA BOUND.
	MOV	AX,ES:[BX+18]	;SECTOR CNT
	MOV	CL,9
	SHL	AX,CL
	JNZ	DO_IT
	DEC	AX		;MOVE IN FOR 64K
DO_IT:	XCHG	CX,AX		;MOVE LENGTH TO CX
	MOV	AX,OFFSET BPB	;FOR BUILD_BPB CALL
	JMP	WORD PTR[DI]	;GOTO FUNTAB ADR

; INITIALIZATION
INIT:	MOV	ES:BYTE PTR[BX+13],1 ;NUM DISK UNITS
	MOV	ES:[BX+14],SI	;BREAK OFFSET
	MOV	AX,SECS		;EL DSK SIZE
	MOV	CL,5
	SHL	AX,CL		;CONV TO PARAGRAPHS
	MOV	DX,CS
	ADD	DX,14		;PROGRAM SIZE
	ADD	AX,DX
	MOV	ES:[BX+16],AX	;BREAK SEG
	MOV	DI,200H		;EL DSK OFFSET
	MOV	ES,DX		;EL DSK SEGMENT
	MOV	AL,0FCH		;SET FIRST SEC FAT
	STOSB
	MOV	AX,0FFFFH
	STOSW
	MOV	CX,8190		;ZERO REST OF FAT + DIR
	INC	AX
	REP	STOSW
	MOV	AX,OFFSET BPB_PTR

;BUILD BIOS PARM BLOCK
BUILD_BPB: POP	ES
	MOV	ES:[BX+18],AX	;SAVE PNTER TO BPB
	MOV	ES:[BX+20],CS
	JMP	SHORT EXIT2

;MEDIA CHECK
MEDIA_CHECK:
	MOV	ES:BYTE PTR [BX+14],1	;NOT CHANGED	
	JMP	SHORT EXIT

; DISK READ
INPUT:	MOV	DI,ES:[BX+14]	;XFR ADR OFFSET
	MOV	ES,ES:[BX+16]	;XFR ADR SEGMENT
	JMP	SHORT COPYIT

; DISK WRITE
OUTPUT:	PUSH	DX		;EL DSK SEGMENT
	MOV	SI,ES:[BX+14]	;XFR ADR OFFSET
	MOV	DX,ES:[BX+16]	;XFR ADR SEGMENT
	XOR	DI,DI		;EL DSK OFFSET
	POP	ES		;EL DSK SEGMENT
COPYIT:	MOV	DS,DX		;XFR/EL DSK ADR SEGMENT
	REP	MOVSB		;DO THE "READ"/"WRITE"

;COMMON EXIT
EXIT:	POP	ES
EXIT2:	OR	ES:WORD PTR[BX+3],100H	;SET DONE
	POP	SI		;RESTORE REGISTERS
	POP	DI
	POP	DX	
	POP	CX
	POP	AX
	POP 	DS

;DEVICE STRATEGY		;REALLY A NOP
DEV_STRATEGY: RET

JELDSK	ENDP
CSEG	ENDS
	END
