;********************************************************************
;
;	IC Memory Card Device Driver
;
;	1991.03.08	make By Ken
;
;********************************************************************
		.386p

rmcode		segment dword public use16 'CODE'
rmcode		ends
pmcode		segment dword public use32 'CODE'
pmcode		ends
incode		segment dword public use16 'CODE'
incode		ends
DGROUP		group	rmcode,pmcode,incode

CARD_IO		equ	048Ah
CARD_TOP	equ	0C0000000h

extrn		end_of_adr:byte
extrn		hmemcpy:near
extrn		gdt_init:near
extrn		open_msg:near

rmcode		segment

device_head	label	word
		dd	-1
		dw	2000h
		dw	strategy
		dw	cmdentry
		db	1
 
command		dw	init
		dw	md_chk
		dw	build_bpb
		dw	exit
		dw	read
		dw	exit
		dw	exit
		dw	exit
		dw	write
		dw	write
		dw	exit
		dw	exit
		dw	exit

cmd_pkt		dd	?

BPB_tbl		label	word
BPB_sect	dw	512		; Sector Size
		db	2		; Alloc sect
		dw	1		; Sect offset
		db	2		; FAT Count
		dw	64		; Dir Entry
		dw	256		; Total Sector
BPB_id		db	0		; ID dummy
		dw	1		; FAT sect Count

BPB_ptr		dw	BPB_tbl

IPL_head	db	0,0,0,0,0,0
CARD_offset	dd	0

		assume	cs:rmcode,ds:nothing

strategy	proc	far
		mov	word ptr cs:[cmd_pkt],bx
		mov	word ptr cs:[cmd_pkt+2],es
		ret
strategy	endp

req_head	struc
req_len		db	?
req_unit	db	?
req_cmd		db	?
req_stat	dw	?
req_res		db	?,?,?,?,?,?,?,?
req_head	ends

cmdentry	proc	far
		pushfd
		pushad
		push	ds
		push	es
		push	gs
		push	fs
 
		les	bx,cs:[cmd_pkt]
		mov	al,es:[bx].req_cmd
		cmp	al,12
		ja	error
		xor	ah,ah
		shl	ax,1
		mov	si,offset command
		add	si,ax
 
		push	cs
		pop	ds

		assume	ds:DGROUP

		call	word ptr ds:[si]
		jmp	ret_ent

error:		mov	ax,8100h+3
ret_ent:	lds	bx,cs:[cmd_pkt]
		mov	ds:[bx].req_stat, ax

		pop	fs
		pop	gs
		pop	es
		pop	ds
		popad
		popfd
		ret

cmdentry	endp

exit		proc	near
		mov	ax,0100h	; Nothing Return
		ret
exit		endp

init_head	struc
init_len	db	?
init_unit	db	?
init_cmd	db	?
init_stat	dw	?
init_res	db	?,?,?,?,?,?,?,?
init_unit_max	db	?
init_break_ofs	dw	?
init_break_seg	dw	?
init_bpb_ofs	dw	?
init_bpb_seg	dw	?
init_head	ends

init		proc	near

		mov	es:[bx].init_unit_max,1
		mov	es:[bx].init_break_ofs,offset DGROUP:end_of_adr
		mov	es:[bx].init_break_seg,cs
		mov	es:[bx].init_bpb_ofs,offset BPB_ptr
		mov	es:[bx].init_bpb_seg,cs

		call	gdt_init
		call	open_msg

		mov	ax,0100h			; No Error
		ret

init		endp

chk_head	struc
chk_len		db	?
chk_unit	db	?
chk_cmd		db	?
chk_stat	dw	?
chk_res		db	?,?,?,?,?,?,?,?
chk_id		db	?
chk_now		dw	?
chk_head	ends

md_chk		proc	near
		mov	dx,CARD_IO
		in	al,dx
		test	al,6
		jnz	dev_not_rdy

		test	al,80h
		jnz	md_chk_chg

		mov	es:[bx].chk_now,1
		jmp	md_chk_ret
md_chk_chg:
		mov	es:[bx].chk_now,0FFFFh
md_chk_ret:
		mov	ax,0100h			; No Error
		ret

dev_not_rdy:	mov	ax,8100h+2
		ret

md_chk		endp

build_head	struc
build_len	db	?
build_unit	db	?
build_cmd	db	?
build_stat	dw	?
build_res	db	?,?,?,?,?,?,?,?
build_id	db	?
build_work	dd	?
build_bpb_ofs	dw	?
build_bpb_seg	dw	?
build_head	ends

boot_sec_chk	proc	near

		xor	eax,eax
		mov	ax,cs
		shl	eax,4
		add	eax,offset IPL_head
		mov	edi,eax

		xor	esi,esi
boot_sec_lop:
		push	esi
		push	edi
		add	esi,CARD_TOP
		mov	ecx,6
		call	hmemcpy
		pop	edi
		pop	esi

		cmp	word ptr [IPL_head],5049h
		jne	boot_chk_2
		cmp	byte ptr [IPL_head+2],4Ch
		je	boot_chk_ok

boot_chk_2:	cmp	word ptr [IPL_head+3],5049h
		jne	boot_chk_3
		cmp	byte ptr [IPL_head+5],4Ch
		je	boot_chk_ok

boot_chk_3:	add	esi,0100h
		cmp	esi,0500h
		jne	boot_sec_lop
		stc
		ret

boot_chk_ok:	mov	[CARD_offset],esi
		clc
		ret

boot_sec_chk	endp

build_bpb	proc
		mov	dx,CARD_IO
		in	al,dx
		test	al,6
		jnz	dev_not_rdy

		call	boot_sec_chk
		jnc	build_bpb_get
		mov	ax,8100h+8
		ret

build_bpb_get:	xor	eax,eax
		mov	ax,cs
		shl	eax,4
		add	eax,offset BPB_tbl
		mov	edi,eax
		mov	esi,CARD_TOP+11
		add	esi,[CARD_offset]
		mov	ecx,13
		call	hmemcpy

		mov	es:[bx].build_bpb_ofs,offset BPB_tbl
		mov	es:[bx].build_bpb_seg,cs

;		mov	al,[BPB_id]
;		mov	es:[bx].build_id,al

		mov	al,es:[bx].build_id
		xor	al,0FFh
		mov	[BPB_id],al
		mov	es:[bx].build_id,al

		mov	ax,0100h			; No Error
		ret
build_bpb	endp

rdwt_head	struc
rdwt_len	db	?
rdwt_unit	db	?
rdwt_cmd	db	?
rdwt_stat	dw	?
rdwt_res	db	?,?,?,?,?,?,?,?
rdwt_id		db	?
rdwt_buff_ofs	dw	?
rdwt_buff_seg	dw	?
rdwt_count	dw	?
rdwt_sect	dw	?
rdwt_head	ends

read		proc	near
		mov	dx,CARD_IO
		in	al,dx
		test	al,6
		jnz	rd_wt_err

		movzx	eax,es:[bx].rdwt_buff_seg
		shl	eax,4
		movzx	edx,es:[bx].rdwt_buff_ofs
		add	eax,edx
		mov	edi,eax

		movzx	eax,es:[bx].rdwt_sect
		movzx	edx,[BPB_sect]
		imul	eax,edx
		add	eax,CARD_TOP
		add	eax,[CARD_offset]
		mov	esi,eax

		movzx	eax,es:[bx].rdwt_count
		imul	eax,edx
		mov	ecx,eax

		call	hmemcpy

		mov	ax,0100h			; No Error
		ret

rd_wt_err:	mov	es:[bx].rdwt_count,0
		mov	ax,8100h+2
		ret

read		endp

write		proc	near
		mov	dx,CARD_IO
		in	al,dx
		test	al,6
		jnz	rd_wt_err
		test	al,1
		jnz	write_prot

		movzx	eax,es:[bx].rdwt_buff_seg
		shl	eax,4
		movzx	edx,es:[bx].rdwt_buff_ofs
		add	eax,edx
		mov	esi,eax

		movzx	eax,es:[bx].rdwt_sect
		movzx	edx,[BPB_sect]
		imul	eax,edx
		add	eax,CARD_TOP
		add	eax,[CARD_offset]
		mov	edi,eax

		movzx	eax,es:[bx].rdwt_count
		imul	eax,edx
		mov	ecx,eax

		call	hmemcpy

		mov	ax,0100h			; No Error
		ret

write_prot:	mov	es:[bx].rdwt_count,0
		mov	ax,8100h+0
		ret

write		endp

rmcode		ends
		end
