;	[]===========================================================[]
;
;	NOTICE: THIS PROGRAM BELONGS TO AWARD SOFTWARE INTERNATIONAL(R)
;	        INC. IT IS CONSIDERED A TRADE SECRET AND IS NOT TO BE 	
;	        DIVULGED OR USED BY PARTIES WHO HAVE NOT RECEIVED	
;	        WRITTEN AUTHORIZATION FROM THE OWNER.
;
; 	[]===========================================================[]
;

 PAGE   60,132
 TITLE  INT13X - EXTENDED FIXED DISK INTERRUPT SERVICE CODE

;=============================================================================
;FILE:  INT13X.ASM
;
;DESC:  Extended functions for Interrupt service handler 13h
;       And ATAPI interface (optional--CD_ROM flag)
;BY:    HauWei Yu and JohnH
;DATE:  17-November-1994
;=============================================================================
;Rev  Date       Author  Description
;     19 Jan 95  JohnH   Adapted for Elite Bios
;                        Does not save parameters for CD mapped as HDD,
;                        so cannot work with HDD image.
;                        MASM 5.10 insists on unique identifiers for 
;                        structure fields, and doesn't accept the 
;                        (StructName ptr [di]).Field syntax.
;     07 Feb 95  JohnH & HauWei
;                        Works with HDD image; also re-wrote parts of low-
;                        level atapi code.
;     08 Feb 95  JohnH & HauWei
;                        Make Wait_Busy independent of system speed; don't
;                        fail if TestUnitRdy returns carry.
;-----------------------------------------------------------------------------
;R40A	04/29/99 KVN	Fixed ZIP R/W fail on old ZIP media (cyls=512/heads=12)
;			by R40
;R42	04/28/99 KVN	Fixed access HDD of SCSI fail after terminate emulate of
;			CDROM.This case occur on boot from win98 CD and emulate
;			as drive A then choice boot from HDD.This time SCSI device
;			disappear.
;R41	04/20/99 KVN	Support ATAPI device (LS120/ZIP) bootable in Boot Block.
;			This function available only boot block size over 16k
;			and BIOS.CFG should define "Support_ATAPI_In_BOOTROM"
;R39A	04/15/99 KVN	Fixed LITE-ON CDROM(LTN-301) boot fail by R39
;R40	04/14/99 KVN	Fixed ZIP drive access failure in PTS-DOS system
;R39	04/14/99 KVN	Modify some code to solve LS120 drive test failure.
;			The test method is boot from LS120 and execute some
;			test program then reboot again over 1000 times.
;R38	04/13/99 KVN	Don't wait interrupt if IRQ vector be replaced by driver.
;			Mitsumi provide a CD-ROM device driver v1.44(10/14/1995)
;			it will replace IRQ vector of CDROM channel and can't
;			set INT flag for 40:8eh when IRQ occrued.
;R37	03/09/99 KVN	Fixed extension function 4Bh of int 13h return wrong
;			data that will cause some test program (e.g. DISKTEST.EXE)
;			hang
;R33B	12/23/98 KVN	Fixed Creative DVD ROM (Model is : DVD2240E) boot fail.
;			That reason is some register to be destroyed by R33A
;R36	12/16/98 KVN	Wait a short time for busy bit of Status byte after
;			send packet command bytes.This request is for TEAC
;			CDROM which takes 1200ns to change the status from 58h
;			to 0D8h.
;R35	12/02/98 KVN	Fixed Pioneer DVD boot fail.The DVD model is
;			[Pioneer DVD-ROM ATAPIMOdel DVD-A02X 0105]
;R34	11/27/98 KVN	Fixed no error to be reported when LS120 of media with
;			some bad track.
;R33A	11/26/98 KVN	Fixed HDD boot fail when HDD connected to primary and
;			LS120/ZIP connected to secondary by R33 coding
;R33	11/16/98 KVN	Fixed system hang within NT5.0 CDROM boot process.The
;			CDROM model is Acer 632A [firmware=322P]
;R29B	10/30/98 KVN	Set byte count to correct for request sense command.
;			Otherwise ZIP or some CDROM will work abnormally.
;			(e.g. CDROM model is Acer 632A [firmware=322P])
;R29A	10/28/98 KVN	Don't send "request sense command" to ZIP.That will
;			cause system waste long time to wait ZIP drive respond.
;R32A	09/28/98 KVN	Fixed CDROM boot failure waste much time when not media
;			present in drive
;R32	09/18/98 KVN	Increase ATAPI device access performance
;R31	09/04/98 KVN	Fixed CDROM read fail during boot process.The CDROM
;			model is [TOSHIBA CD-ROM XM-5302TA]
;R04B	08/13/98 KVN	Fixed LS120 boot or R/W fail when connect to same channel
;			with HDD
;R30	08/12/98 KVN	Fixed coding mistake that will cause function 8 return
;			bad parameter to caller
;R29	08/11/98 KVN	Added "request sense command" to exactly report ATAPI
;			access status.That will dont delay or loop for some
;			boot fail CDROM
;R04A	07/31/98 KVN	Fixed LS120 R/W fail while copy or delete file itself
;			and elapsed a long time (maybe ten hours).This drive
;			model is [LDM-F734-1] and F/W=0420M414.The manufactured
;			on April 1998
;R23A	07/30/98 KVN	Added a switch to set IOMEGA ZIP to floppy or removable
;			mode by jumper of ZIP drive.If you want control floppy
;			mode by jumper then define "ZIP_Floppy_Depand_on_Jumper"
;			in BIOS.CFG
;R28	07/06/98 KVN    Added Extend_4B_func to correctly.This returns all
;			floppy or hard disks to their normal device numbers
;R27A	06/18/98 BAR    Added a Define to support Update EDDS to Ver 3.0 
;			 "Support_EDDS30".
;R27	06/15/98 BAR    Update EDDS to Ver 3.0 
;R26	06/02/98 BAR    Fixed  Media type formed DD(720K) code 25h to  11h .
;R25	05/19/98 KVN	Report exactly number of cylinders for function 08h
;R24	05/05/98 KVN	Fixed format 120MB diskette error if drive parameter
;			is wrong.That means get parameter by identify command
;			but retrun value is not correctly of 120MB parameter.
;R23	04/16/98 KVN	IOMEGA release new ZIP drive support both original
;			ZIP mode and floppy emluation mode. BIOS need to 
;			program the new drive to Floppy mode, otherwise
;			it can be booted as drive A when new firmware is
;			used.
;R22	04/08/98 MAX	Remove INT13_Extensions code to 0F8000-0FFFFF from
;			0F0000-0F7FFF to fix WIN95 hang problem if config.sys
;			add 'device=EMM386.exe highscan noems'
;R21	03/31/98 KVN	Fixed Wearnes CDROM (Model = "WPI CDS-32X") boot failure
;R20A	11/19/97 KVN	Fix R20 coding not complete
;R20	11/13/97 KVN	Fix LS120 can't format 1.44MB in DOS even add /f:1.44
;			parameter if use HD-COPY.EXE formated it in Win95 to
;			1.68MB or 1.6MB media first.(p.s. HD-COPY.EXE is a tool
;			for access diskette to special media.this tool is issue
;			by Oliver Fromme)
;R15A	11/11/97 KVN	Fix LS120 can't format 1.44MB in DOS
;R18B	11/11/97 KVN	Fix no 120MB item in WIN95-OSR2 drive A/B of format
;			funtion if support FDPTE in function 48h
;R19	10/24/97 BAR	Fixed boot sequence CD_ROM frist very slow
;			if media is audio CD or can't bootable.
;			This CDROM model list follow:
;			   Panasonic "MATSHITA CR_585"
;R01C	10/22/97 KVN	Force set LBA access method in int13 extention
;			(to fixed GHOST tool problem)
;R01B	10/22/97 KVN	Support LBA access method in int13 extention if define
;			"ExtInt13_LBA"
;R18A	10/14/97 KVN	Exactly report parameter of EDD table in Int13
;			extension function 48h.otherwise will cause system
;			error while execute FDISK.EXE in Windows 95
;R18	10/07/97 BAR	Added Fixed Disk Parameter Table Extension(FDPTE)
;R14A	08/14/97 KVN	Fix can't format 1.44MB diskette in LS120 drive when
;			dirve A is 1.44MB standard Floppy and drive B is LS120
;R17B	07/24/97 KVN	Fix some CDROM read error (e.g. mitsuimi 4x) when data
;			transfer count is 64K bytes
;R17A	07/08/97 KVN	Fix ZIP100 boot fail by R17
;R17	07/03/97 KVN	Fix TEAC CDROM (model is CD-524E) boot fail
;R16	06/19/97 KVN	Fix can't format ZIP 100MB diskette
;R15	06/13/97 KVN	Fix can't format 120MB diskette in WIN95-OSR2 when insert
;			720KB or 1.44MB diskette in drive before WIN95 boot
;R14	06/13/97 KVN	Fix can't format 120MB diskette in WIN95-OSR2 when dirve
;			A is 1.44MB standard Floppy and drive B is LS120 drive
;R13	06/10/97 KVN	Fix CDROM can't boot if connected it behind LS120 or Zip
;R12	05/09/97 KVN	Fix SCO OS bootable CDROM for install error
;R11	05/07/97 KVN	Add ZIP100 bootable same as LS120
;R07B	05/01/97 KVN	Fixed LS120 device change line error if it's emulate
;			to floppy B
;R10	04/09/97 KVN	Fixed some CDROM read error during boot routine.These
;			CDROM model list follow:
;			1. Pioneer CD-ROM ATAPI Model DR-A12X 0100
;			2. CREATIVE CD1220E
;			3. WEARNES CDD-820
;R01A	02/25/97 KVN	Fixed system hang at EMM386.exe add HIGHSCAN parameter
;			if BIOS include "Int13_Extensions" function
;R09	02/19/97 KVN	Fixed LS120 drive format 120MB media disc error
;R08	02/01/97 KVN	Support IOMEGA ZIP-100 drive active
;R07A	01/27/97 KVN	Fixed R07 coding mistake that will cause CDROM could't
;			bootable
;R07	01/22/97 KVN	Support dual LS120 drive active
;R06	01/16/97 KVN	Fixed identify LS-120 to drive letter became C or later
;			in WIN95 while there has no diskette is existed in LS-120
;R05	12/30/96 KVN	Support LS-120 1.2MB Toshiba(capacity is 1.21MB) read,
;			write and bootability
;R04	12/17/96 KVN	Fixed some LS-120 drive (Model = LKM-F333-102) access
;			error
;R03	11/28/96 KVN	Fixed LS-120 can't access when connect on same channel
;			with HDD (e.g. HDD is master and LS-120 is slave)
;R02	11/26/96 KVN	Fixed 1.44MB floppy with WINDOS v4.1 system can't boot
;			in LS-120 drive
;R01	11/15/96 KVN	Added IDE HDD Int13 Extensions function
;R00	11/01/96 KVN	Added LS-120 support and recode for increase CDROM
;			performance

.386

; MINIMIZE SEGMENT 0 ACCESS IN PROTECTED MODE (EXCEPTION 5)

SEG_0		SEGMENT	USE16 AT 1
		INCLUDE	SEG_0.INC
SEG_0		ENDS

G_RAM		SEGMENT	USE16 AT 40H
		INCLUDE	G_RAM.INC
G_RAM		ENDS


DGROUP		GROUP	FCODE

		include	PORT61.EQU
		include	8259.equ		;R33
		include	ahdsk.equ
ExtInt13_LBA		equ	1				;R01C
ifndef COMPILE_FOR_BTINT13X			;R41
		extrn	WAIT_INT:near		;R33
		extrn gethparm:near
;R22;R18 - start
;R22		Public	FDPTE_Drive0
;R22		Public	FDPTE_Drive1
;R22		Public	FDPTE_Drive2
;R22		Public	FDPTE_Drive3
;R22		extrn	AHDSK_ERROR_RET:near	;R18A
;R22;R18 - end

		extrn	WAIT_FOR_PORT:near
		extrn	HD5_PARMS:byte
		extrn	HD_PARMS:byte
		extrn	ED_PARMS:byte
;R01 start
;R22ifdef	Int13_Extensions
;R22		extrn	FUN10_2:near
;R22		extrn	GOOD_RET:near
;R22		extrn	CONT_CMD:near
;R22		extrn	Detect_LBA_Mode:near
;R22endif	;Int13_Extensions
;R22 start
		extrn	FDPTE_Drive0:near
		extrn	FDPTE_Drive1:near
		extrn	FDPTE_Drive2:near
		extrn	FDPTE_Drive3:near
;R22 end
;R01 end
		extrn	IoMegaZip_Flag:near	;R23
endif ;COMPILE_FOR_BTINT13X			;R41

;R34WAIT_UHD_BUSY_HI	EQU	5
;R34WAIT_UHD_BUSY_LO	EQU	1615h
;R34WAIT_UHD_DRQ_HI		EQU	0
;R34WAIT_UHD_DRQ_LO		EQU	8000h

;R34 start
;R39 WAIT_UHD_BUSY_HI	EQU	0ch		;for 25 seconds time out
;R39 WAIT_UHD_BUSY_LO	EQU	0b737h
;R39 WAIT_UHD_DRQ_HI		EQU	0ch		;for 25 seconds time out
;R39 WAIT_UHD_DRQ_LO		EQU	0b737h
;R39 start
WAIT_UHD_BUSY_HI	EQU	5
WAIT_UHD_BUSY_LO	EQU	1615h
WAIT_UHD_DRQ_HI		EQU	0
WAIT_UHD_DRQ_LO		EQU	8000h
;R39 end

Get_SenseKey_Code	equ	7fh
;R34 end
FDPARMS		STRUC
		FD_SPECIFY_1	DB	0DFH	;00: 1st Specify byte
		FD_SPECIFY_2	DB	002H	;01: 2nd Specify byte
		FD_MOTOR_OFF	DB	025H	;02: motor wait before turn off.
		FD_SEC_SIZE	DB	002H	;03: 128 * 2^N bytes per sector
		FD_EOT		DB	009H	;04: End of track
		FD_NORMAL_GAP	DB	02AH	;05: GAP length
		FD_DTL		DB	0FFH	;06: data length, if 03: = 0
		FD_FORMAT_GAP	DB	050H	;07: gap length for format
		FD_FILL		DB	0F6H	;08: fill byte for format
		FD_HEAD_WAIT	DB	00FH	;09: milliseconds for head settle time
		FD_MOTOR_ON	DB	008H	;10: 1/8 of seconds for motor spin up.
		FD_LAST_CYL	DB	027H	;11: # of last cylinder
		FD_XFER_RATE	DB	080H	;12: Xfer rate, as sent to port.
FDPARMS		ENDS

FCODE		SEGMENT	USE16 PARA PUBLIC 'CODE'	  
		ASSUME	CS:DGROUP

.xlist
  include	bios.cfg
  include	cd_rom.equ
  include	int13x.equ    ; structure defs
  include	btromseg.equ	;R41
  include	common.mac
  include	common.equ
.list

  PAGE

;R41ifdef ATAPI_COMMAND_SUPPORT
;R41 start
if ATAPI_COMMAND_SUPPORT	eq	1

ifdef COMPILE_FOR_BTINT13X
HD5_PARMS LABEL	BYTE
FDPARMS	<0DFH,002H,025H,002H,00FH,01BH,0FFH,054H,0F6H,00FH,008H,04FH,000H>
HD_PARMS LABEL	BYTE
FDPARMS	<0AFH,002H,025H,002H,012H,01BH,0FFH,06CH,0F6H,00FH,008H,04FH,000H>
ED_PARMS LABEL	BYTE
FDPARMS	<0AFH,002H,025H,002H,024H,01BH,0FFH,054H,0F6H,00FH,008H,04FH,0C0H>	;R02  (was 6CH)

WAIT_INT	PROC	NEAR
		sti
		MOV	AX,9000H
		INT	15H
		MOV	AX,8000H		; n = ST_TIMEOUT
		JC	SHORT .D887

		sti
		MOV	CX,G_RAM		; es:di points to
		MOV	ES,CX			; flag variable.
		ASSUME	ES:G_RAM
		MOV	DI,OFFSET HDC_INT
		mov	ah,0c0h
		MOV	BH,WAIT_UHD_BUSY_HI
		MOV	CX,WAIT_UHD_BUSY_LO
		extrn	WAIT_FOR_MEM:near
		extrn	WAIT_FOR_PORT:near
		CALL	WAIT_FOR_MEM		; returns ah=80h if timeout.
		XOR	AL,AL			; al=0
		OR	AH,AH			; if timeout, don't clear
		JNE	SHORT .D887		; flag: recalibrate case.

.D875:		MOV	BYTE PTR ES:[DI],0	; interrupt occurred

.D887:
		CLI
		RET
WAIT_INT	ENDP

IoMegaZip_Flag		DB	0	;bit0 = 1 indicate primary master ZIP is floppy mode
					;bit1 = 1 indicate primary slave ZIP is floppy mode
					;bit2 = 1 indicate secondary master ZIP is floppy mode
					;bit3 = 1 indicate secondary slave ZIP is floppy mode
endif ;COMPILE_FOR_BTINT13X
;R41 end

UHD_PARMS LABEL	BYTE
FDPARMS	<0DFH,002H,025H,002H,020H,01BH,0FFH,065H,0F6H,00FH,008H,04FH,000H>
;****************************************************************************
;       (standard) Int 13 function translation to ATAPI 
;       This is provided for booting from CD (floppy or hard disk image)
;Entry: AH = subfunction
;       DL = drive (40 if FDD, Cx if HDD image
;       BX-DX = as specified in INT 13 function 
;Exit:  AH = error code
;       CC = no error; CS = error
;****************************************************************************
public std_atapi
std_atapi proc
	push	eax					;R02
	push	bp
	sub	sp,CDROM_RSV_byte
	mov	bp,sp
	push	ax
	push	bx
	push	cx
	push	dx
	push	si
	push	di
	push	es
	push	ds

	mov	ax,G_RAM
	mov	ds,ax
	assume	ds:G_RAM

	mov	CDROM_port,1f0h
	mov	al,G_RAM:[CDROM_ALLOCATE]
	and	al,3
	mov	INT13X_FLAG,0		;clear flag
ifdef LS120_SUPPORT
	mov	ah,G_RAM:[ATAPI_Byte]
;R07A	mov	al,ah			;R07
	mov	dh,ah			;R07A
	mov	cl,ah
	and	cl,3
	test	ah,4			;have any ATAPI drive exist?
	jz	short @F		;No,skip
	test	ah,40h			;R08 drive 0 is LS-120?
;R11	jnz	short @F		;R08 No,skip
	jnz	short Not_LS120		;R11
	shr	ah,3
	and	ah,1
	cmp	dl,ah
;R07	jne	short @F
;R07 start
;R07B	lea	bx,G_RAM:[Floptical0_EMUL_CYL_SEC]
	je	short Set_LS120_emul
Not_LS120:				;R11
;R08 start
	cmp	dl,1
	jne	short @F
	test	dh,80h
	jnz	short @F
;R08 end
;R07A	mov	cl,al
	mov	cl,dh					;R07A
	shr	cl,4
	and	cl,3
	jz	short @F		;R11
;R07A	shr	al,6
;R07A	and	al,1
;R08	shr	dh,6					;R07A
;R08	and	dh,1					;R07A
;R07B	lea	bx,G_RAM:[Floptical1_EMUL_CYL_SEC]
;R07A	cmp	dl,al
;R08	cmp	dl,dh					;R07A
;R08	jne	short @F
Set_LS120_emul:
;R20A;R07B start
;R20A	lea	bx,G_RAM:[Floptical0_EMUL_CYL_SEC]
;R20A	test	G_RAM:[ATAPI_Byte],30h			;R14
;R20A	jz	short Is_dirveA				;R14
;R20A	or	dl,dl
;R20A	jz	short Is_dirveA
;R20A	lea	bx,G_RAM:[Floptical1_EMUL_CYL_SEC]
;R20AIs_dirveA:
;R20A;R07B end
;R20A;R07A	mov	ax,G_RAM:[bx]
;R20A;R07A	mov	LS120_EMUL_CYL_SEC,ax
;R20A;R07A	mov	ax,G_RAM:[bx+2]
;R20A;R07A	mov	LS120_EMUL_HEAD,al
;R20A;R07A	mov	LS120_Medium_Type,ah
;R20A	mov	dx,G_RAM:[bx]				;R07A
;R20A	mov	LS120_EMUL_CYL_SEC,dx			;R07A
;R20A	mov	dx,G_RAM:[bx+2]				;R07A
;R20A	mov	LS120_EMUL_HEAD,dl			;R07A
;R20A	mov	LS120_Medium_Type,dh			;R07A
;R07 end
	mov	al,cl
	or	INT13X_FLAG,Sector_200b+Floptical_Exist+Write_Assert
	jmp	short Found_ATAPI_drive	;R08
@@:
;R07	mov	ah,10h
;R07	shl	ah,cl
;R07	test	G_RAM:[ATAPI_Byte],ah
;R07	jz	short No_INTRQ
;R07	or	INT13X_FLAG,INTRQ_Assert
;R07No_INTRQ:
endif ;LS120_SUPPORT
;R08 start
ifdef IOMEGA_ZIP_Support
	mov	ah,G_RAM:[ATAPI_Byte]
	test	ah,4
	jz	short None_IOMEGA_ZIP



;R11 start
	mov	dh,ah
	mov	cl,ah
	and	cl,3
	test	ah,40h			;drive 0 is ZIP100?
	jz	short Not_Zip
	shr	ah,3
	and	ah,1
	cmp	dl,ah
	je	short Found_IOMEGA_ZIP
Not_Zip:
	cmp	dl,1
;R13	jne	short @F
	jne	short Found_ATAPI_drive		;R13
	test	dh,80h
;R13	jz	short @F
	jz	short Found_ATAPI_drive		;R13
	mov	cl,dh
	shr	cl,4
	and	cl,3
;R13	jz	short @F
	jz	short Found_ATAPI_drive		;R13
Found_IOMEGA_ZIP:
;R16 start
;R40A	mov	LS120_EMUL_CYL_SEC,0a0h
	mov	LS120_EMUL_CYL_SEC,6020h	;R40A
	mov	LS120_EMUL_HEAD,IOMEGA_ZIP_Heads
	mov	LS120_Medium_Type,31h
;R16 end
	mov	al,cl
;R11 end


;R11	cmp	dl,1				;Is Drive B?
;R11	jne	short Check_ZIP_A		;No,go ahead to check
;R11	test	ah,80h				;check ATAPI drive 1 is ZIP?
;R11	jz	short None_IOMEGA_ZIP		;if not then skip
;R11	shr	ah,4				;get second ZIP scheme
;R11	and	ah,3				;have any ATAPI drive 1?
;R11	jnz	short Found_IOMEGA_ZIP		;Yes,set INT13X_FLAG
;R11Check_ZIP_A:
;R11	test	ah,40h				;check ATAPI drive 0 is ZIP?
;R11	jz	short None_IOMEGA_ZIP		;if not then skip
;R11	mov	dh,ah
;R11	shr	dh,3
;R11	and	dh,1
;R11	cmp	dh,dl
;R11	jne	short None_IOMEGA_ZIP
;R11Found_IOMEGA_ZIP:
;R11	mov	al,ah
;R11	and	al,3
	or	INT13X_FLAG,Sector_200b+IOMEGA_ZIP_Exist+Write_Assert
None_IOMEGA_ZIP:
endif	;IOMEGA_ZIP_Support
Found_ATAPI_drive:
;R08 end
	mov	ah,not 40h			;R33 assume IRQ 14
	cmp	al,2
	jb	short @F
	sub	CDROM_port,80h
	mov	ah,not 80h			;R33 IRQ 15
@@:
	mov	CDROM_drive,0a0h
	test	al,1
	jz	short @F
	mov	CDROM_drive,0b0h
@@:
;R33 start
	pushf					;R39
	cli
	in	al,A8259+1
	newiodelay
	and	al,not 4			;enable IRQ 2
	out	A8259+1,al
	newiodelay
	in	al,B8259+1
	newiodelay
	and	al,ah				;enable IRQ for IDE channel
	out	B8259+1,al
	newiodelay
;R39	sti
	popf					;R39
;R33 end
		mov	dx,CDROM_port
		add	dl,6			;dx = 1X6h
		mov	al,CDROM_drive
		out	dx,al
		newiodelay
;R32	mov	CMD_Pkt_buffer.CD_Reserved0,0
;R32	mov	CMD_Pkt_buffer.CD_Reserved1,0
;R32	mov	CMD_Pkt_buffer.CD_Reserved2,0
;R32	mov	CMD_Pkt_buffer.CD_Reserved3,0
;R32	mov	CMD_Pkt_buffer.CD_Reserved4,0
		call	Clear_CMD_Pkt_buffer	;R32

; handle the requests we expect
	cmp	BP_AH,02				; read?
	jnz	@f
	mov	bl,ATAPI_Read
;R08	or	INT13X_FLAG,RW_Flag
	or	INT13X_FLAG,RW_Flag+IOMEGA_ZIP_RW	;R08
	call	std_atapi_access
	jmp	std_atapi_ret
@@:
;R08ifdef LS120_SUPPORT
	cmp	BP_AH,03				; write?
	jne	short @F
	test	INT13X_FLAG,Write_Assert
	jz	short @F
	mov	bl,ATAPI_Write
	and	INT13X_FLAG,not RW_Flag
	or	INT13X_FLAG,IOMEGA_ZIP_RW	;R08
	call	std_atapi_access
	jmp	std_atapi_ret
@@:
;R08endif ;LS120_SUPPORT
	cmp	BP_AH,04				; verify?
	jne	short @f
	mov	bl,ATAPI_Verify
	or	INT13X_FLAG,RW_Flag
	call	std_atapi_access
	jmp	std_atapi_ret
@@:
;R16 ifdef LS120_SUPPORT
	cmp	BP_AH,05				; format?
;R24	jne	short @f
	jne	@f					;R24
	test	INT13X_FLAG,Write_Assert
;R24	jz	short @F
	jz	@F					;R24
	call	Send_Test_Unit_Ready
;R16 start
ifdef IOMEGA_ZIP_Support
;R40A	cmp	LS120_EMUL_CYL_SEC,0a0h
	cmp	LS120_EMUL_CYL_SEC,6020h		;R40A
	je	short False_Format
endif ;IOMEGA_ZIP_Support
ifdef LS120_SUPPORT
;R16 end
	mov	CMD_Pkt_buffer.S_LBA,11h
;R07	cmp	G_RAM:[Floptical_EMUL_CYL_SEC],5009h	;720kb disk
	cmp	LS120_EMUL_CYL_SEC,5009h		;R07
	je	short Go_Format
	mov	CMD_Pkt_buffer.S_LBA,24h
;R07	cmp	G_RAM:[Floptical_EMUL_CYL_SEC],5012h	;1.44Mb disk
	cmp	LS120_EMUL_CYL_SEC,5012h		;R07
	je	short Go_Format

	mov	CMD_Pkt_buffer.S_LBA,23h
;R07	cmp	G_RAM:[Floptical_EMUL_CYL_SEC],500fh	;1.2Mb disk
	cmp	LS120_EMUL_CYL_SEC,500fh		;R07
	je	short Go_Format
;R09	mov	CMD_Pkt_buffer.S_LBA,31h
;R07	cmp	G_RAM:[Floptical_EMUL_CYL_SEC],0c3e0h	;120Mb disk
	cmp	LS120_EMUL_CYL_SEC,0c3e0h		;R07
;R09	je	short Go_Format
	je	short False_Format			;R09
endif ;LS120_SUPPORT					;R16
;R24 start
	cmp	LS120_Medium_Type,30h
	je	short False_Format
	cmp	LS120_Medium_Type,31h
	je	short False_Format
;R24 end

	jmp	short Format_error
False_Format:						;R09
	xor	ah,ah					;R09
	jmp	std_atapi_ret				;R09
Go_Format:
	mov	CMD_Pkt_buffer.OpCode,ATAPI_Format
	mov	al,bp_dh
	and	al,1
	shl	al,2
	or	al,22h
	mov	CMD_Pkt_buffer.CD_Reserved1,al
	mov	al,bp_ch
	mov	byte ptr CMD_Pkt_buffer.S_Length,al
	and	INT13X_FLAG,not RW_Flag
	call	Ctlr_Drive_Ready
	dec	dl
	mov	al,CDROM_drive
	out	dx,al
	newiodelay
	call	Send_Pkt_Cmd
	jnc	std_atapi_ret
Format_error:
	mov	ah,80h
	jmp	std_atapi_ret
@@:
;R16 endif ;LS120_SUPPORT
	cmp	BP_AH,0				; reset?
	jnz	@f
	call	atapi_reset
	jmp	std_atapi_ret
@@:
ifndef COMPILE_FOR_BTINT13X			;R41
	cmp	BP_AH,41h			;check for extension support
	jne	@f
;R27	mov	BP_AH,0			;major version
ifdef Support_EDDS30						;R27A
	mov	BP_AH,30h 			;major version 	;R27
else; Support_EDDS30						;R27A
	mov	BP_AH,21H			;major version	;R27A
endif; Support_EDDS30						;R27A
	mov	BP_AL,0				;minor version
	mov	BP_BX,0aa55h			;must return to confirm
						;extensions are supported
	mov	BP_CX,04h			;EED support ;R18  
	mov	cx,3
	xor	ah,ah				;successfully status return
	jmp	std_atapi_ret1
@@:
	cmp	BP_AH,42h			;extend read?
	jne	@f
	call	Extend_atapi_rd
	jmp	std_atapi_ret
@@:
	cmp	BP_AH,4bh			;extend 4bh func?
	jne	@f
	call	Extend_4B_func
	jmp	std_atapi_ret
@@:
;R08ifdef LS120_SUPPORT
;R18;R08 start
;R18	test	INT13X_FLAG,IOMEGA_ZIP_Exist+Floptical_Exist	;check is floptical drive?
;R18	jz	Not_is_Floptical
;R18;R08 end
	cmp	BP_AH,48h
;R08	jne	short @F
	jne	Not_Func48		;R08
	mov	es,bp_ds
	mov	di,bp_si
;R18	mov	word ptr es:[di],26		;buffer size
;R18	mov	word ptr es:[di+2],11010110b	;information flags
;R18 start


;R18B start
	mov	ax,es:[di]			;get buffer size
	cmp	ax,26				;check buffer size
	jae	short @F			;>= 26 then set parameter to buffer
	mov	ah,1				;set status = bad command
	jmp	std_atapi_ret
@@:
;R27	mov	word ptr es:[di],26		;set buffer size = 26
;R27	cmp	ax,30				;check buffer size
;R27	jb	short @F			;< 26 then set parameter to buffer
;R27	mov	word ptr es:[di],30		;set buffer size = 30
;R27@@:
;R18B end
ifdef Support_EDDS30				;R27A
;R27 - start
	mov	word ptr es:[di],65		;set buffer size = 65
	cmp	ax,65				;check buffer size
	jae	short Set_Buffer_size_end	;>= 65 then set parameter to buffer
endif; Support_EDDS30				;R27A
	mov	word ptr es:[di],30		;set buffer size = 30
	cmp	ax,30				;check buffer size
	jae	short Set_Buffer_size_end	;>= 30 then set parameter to buffer
	mov	word ptr es:[di],26		;set buffer size = 26
Set_Buffer_size_end:
;R27 - end

	mov	word ptr es:[di+2],01011110b	;information flags(assume write and verify assert)
;R18B	mov	word ptr es:[di],30		;buffer size 
	test	INT13X_FLAG,Write_Assert	;Write enable ?
	jnz	short @F			;Yes,skip
	mov	word ptr es:[di+2],01010110b	;information flags(deassert write and verify)
@@:
	mov	cx,ds:CDROM_EMUL_CYL_SEC	;get CDROM emulate Cyl. and sectors
	mov	al,cl				;associate cylinder bits
	xchg	ch,cl				;
	shr	ch,6				;clear ch bit 0-5
;R18 - end
	xor	bx,bx				;BX = 0 for clear high word
;R07	mov	cx,ds:Floptical_EMUL_CYL_SEC
	test	INT13X_FLAG,Floptical_Exist	;R08
	jz	short @F			;R08
;R15	mov	cx,LS120_EMUL_CYL_SEC		;R07
;R15	mov	al,cl
;R15	xchg	ch,cl
;R15	shr	ch,6
	mov	cx,3c3h				;R15
;R08 start
@@:
	test	INT13X_FLAG,IOMEGA_ZIP_Exist
	jz	short @F
	mov	cx,IOMEGA_ZIP_Cylinders
@@:
;R08 end
	mov	word ptr es:[di+4],cx		;physical cylinders
	mov	word ptr es:[di+6],bx		;set high word = 0
;R07	mov	ah,ds:Floptical_EMUL_HEAD
	mov	ah,ds:CDROM_EMUL_HEAD		;R18
	test	INT13X_FLAG,Floptical_Exist	;R08
	jz	short @F			;R08
;R15	mov	ah,LS120_EMUL_HEAD		;R07
	mov	ah,8				;R15
;R08 start
@@:
	test	INT13X_FLAG,IOMEGA_ZIP_Exist
	jz	short @F
	mov	ah,IOMEGA_ZIP_Heads
@@:
;R08 end
	mov	byte ptr es:[di+8],ah		;physical heads
	mov	byte ptr es:[di+9],bl		;set high byte = 0
	mov	word ptr es:[di+10],bx		;set high word = 0
	test	INT13X_FLAG,Floptical_Exist	;R08
	jz	short @F			;R08
;R15	and	al,3fh
	mov	al,20h				;R15
;R08 start
@@:
ifdef IOMEGA_ZIP_Support
	test	INT13X_FLAG,IOMEGA_ZIP_Exist
	jz	short @F
	mov	al,IOMEGA_ZIP_Sectors
@@:
endif ;IOMEGA_ZIP_Support
;R08 end
	mov	byte ptr es:[di+12],al		;physical sectors per track
	mov	byte ptr es:[di+13],bl		;set high byte = 0
	mov	word ptr es:[di+14],bx		;set high word = 0
	mul	ah
	mul	cx
	mov	word ptr es:[di+16],ax
	mov	word ptr es:[di+18],dx
;R27 - start
;?	cmp	dx,00ech		  	;if Number of Physical sector
;?	ja	short Above_EC4000		; is greater than 15,482,880
;?	jb	short Below_EC4000		; is smaller than 15,482,880
;?	cmp	ax,4000				; (EC4000h) offset 2, bit 1 cleared
;?	jb	short Below_EC4000		; to 0
;?Above_EC4000:
;?	and	word ptr es:[di+2],not 01 
;?Below_EC4000:
;R27 - end

	mov	word ptr es:[di+20],bx		;set high dword = 0
	mov	word ptr es:[di+22],bx
	mov	word ptr es:[di+24],800h	;R27  bytes in a sectors
	test	INT13X_FLAG,Sector_200b		;R27
	jz	short Sector_800B		;R27
	mov	word ptr es:[di+24],200h	;bytes in a sectors
Sector_800B:					;R27

;R18 start
;------ Get_ATAPI_Allocate ------
	cmp	word ptr es:[di],30		;R18B
;R27	jb	short Dont_set_FDPTE		;R18B
	jb	Dont_set_FDPTE			;R27
	xor	dx,dx
 	cmp	CDROM_port,1F0h			;Test channel0/channel1
	je	short @F
	or	dl,020h
@@:
   	test	CDROM_drive,10h			;Test master/slave
	jz	short @F
	or	dl,010h
@@:
	mov	ax,offset cs:FDPTE_Drive0
	add	ax,dx				;get FDPTE address	
	mov	word ptr es:[si+26],ax		
	mov	word ptr es:[si+28],0f000h	;save segment
ifdef Support_EDDS30						;R27A
;R27 - start
	cmp	word ptr es:[di],65
	jb	Dont_set_FDPTE
	mov	word ptr es:[si+30],0BEDDh	;indicates presence of device Path information
	mov	byte ptr es:[si+32],36		;length
	mov	byte ptr es:[si+33],0		;Reserved
	mov	word ptr es:[si+34],0		;Reserved

	mov	dword ptr es:[si+36],'ISA '	;Legacy 16 bit fixed bus
	mov	dx,CDROM_port			;16 bit address 1f0/170h
	mov	word ptr es:[si+48],dx		;16 bit address 1f0/170h
	mov	word ptr es:[si+50],0		;Reserved
	mov	dword ptr es:[si+52],0		;Reserved
	
	call	Host_Bus_type
	jc	short IDE_Use_ISA
	mov	dword ptr es:[si+36],'PCI '
	mov	byte ptr es:[si+48],0		;bus number
	mov	byte ptr es:[si+49],ah		;slot = device number
	mov	byte ptr es:[si+50],al		;Function number
IDE_Use_ISA:
	mov	dword ptr es:[si+40],'I   '	;8 bytes for ASCII
	mov	dword ptr es:[si+44],'ATAP'
	xor	al,al		
	cmp	CDROM_drive,0a0h		;test master/slave
	je	short	@F
	inc	al				;slave
@@:
	mov	byte ptr es:[si+56],al		;master/slave
	mov	al,BP_DL			;logical unit number
	mov	byte ptr es:[si+57],al		;logical unit number
	mov	word ptr es:[si+58],0		;Reserved
	mov	dword ptr es:[si+60],0		;Reserved

	mov	byte ptr es:[si+64],0		;Reserved
	pusha
	movzx	cx,byte ptr es:[si+32]		;length
	dec	cx
	xor	ax,ax		
@@:
	add	al,byte ptr es:[si+30]
	inc	si
	loop	short @B
	neg	al
	mov	byte ptr es:[si+30],al		;Checksum 2's
	popa
;R27 - end
endif; Support_EDDS30				;R27A
Dont_set_FDPTE:					;R18B
;--------------------------------
;R18 end

	xor	ah,ah
	jmp	std_atapi_ret
;R08@@:
Not_Func48:					;R08
endif ;COMPILE_FOR_BTINT13X			;R41
	cmp   BP_AH,15h
	jnz   short @F
	mov	bp_ah,2
	xor	ah,ah
	jmp	std_atapi_ret1
@@:
	cmp   BP_AH,16h
	jnz   short @F
	call	Send_Test_Unit_Ready
;R05	cmp	ah,6
;R05	je	short Media_Change
;R05	xor	ah,ah
;R05Media_Change:
	jmp	std_atapi_ret
@@:
	cmp   BP_AH,17h
	jnz   short @F
	xor	ah,ah
	jmp	std_atapi_ret
@@:
	test	INT13X_FLAG,Floptical_Exist	;R08;check is floptical drive?
	jz	Not_is_Floptical		;R08
	cmp	BP_AH,18h
	jne	short @F
	call	Send_Test_Unit_Ready
	jnc	short Do_Func18
	cmp	ah,6
	mov	ah,80h			;no media present
	jne	short Type_Not_Support
Do_Func18:
	lea	si,UHD_PARMS
	cmp	bp_cx,0c2e0h
	je	short Found_Parms
	lea	si,HD_PARMS
	mov	ah,4
Scan_Parm_Loop:
	mov	cl,cs:[si].FD_EOT		; get last track
	mov	ch,cs:[si].FD_LAST_CYL	; get last cylinder
	cmp	cx,bp_cx
	je	short Found_Parms
	sub	si,SIZE FDPARMS		; else get to next table
	dec	ah
	jnz	short Scan_Parm_Loop
Type_Not_Support:
	mov	ah,0ch			;not support or drive type unknown
	jmp	std_atapi_ret
Found_Parms:
;R20 start
	inc	ch
	lea	bx,G_RAM:[Floptical0_EMUL_CYL_SEC]
	test	G_RAM:[ATAPI_Byte],30h
	jz	short Fun18_Is_dirveA
	lea	bx,G_RAM:[Floptical1_EMUL_CYL_SEC]
Fun18_Is_dirveA:
	mov	G_RAM:[bx],cx
;R20 end
	mov	bp_di,si
	mov	bp_es,cs
	xor	ah,ah
	jmp	std_atapi_ret
@@:
	cmp	BP_AH,20h
	jnz	short @F
	call	Send_Test_Unit_Ready
	jnc	short Media_Present
	cmp	ah,6
	jne	short Media_Not_Present
Media_Present:
;R07	mov	bl,ds:Floptical_Medium_Type
	mov	bl,LS120_Medium_Type		;R07
	xor	ah,ah				;media present
	mov	bp_al,0fh			;assume NEC 3 mode
	cmp	bl,22h				;NEC 3 mode?
	je	std_atapi_ret
	mov	bp_al,0eh			;assume Toshiba 3 mode
	cmp	bl,23h				;Toshiba 3 mode?
	je	std_atapi_ret
	mov	bp_al,4				;assume 1.44M
	cmp	bl,20h				;1.44M unformated?
	je	std_atapi_ret
	cmp	bl,24h				;1.44M ?
	je	std_atapi_ret
	cmp	bl,26h				;R20A 1.68M ?
	je	std_atapi_ret			;R20A
	mov	bp_al,3				;assume 720K
	cmp	bl,10h				;720K unformatted?
	je	std_atapi_ret
;R26 	cmp	bl,25h				;720K ?
 	cmp	bl,11h				;720K ?  ;R26
	je	std_atapi_ret
	mov	ah,32h				;Non-default media
	mov	bp_al,10h			;assume 120M
	cmp	bl,30h				;120M unformatted?
	je	std_atapi_ret
	cmp	bl,31h				;120M ?
	je	std_atapi_ret
Media_Not_Present:
	mov	ah,31h
	jmp	std_atapi_ret
@@:
Not_is_Floptical:
;R08endif ;LS120_SUPPORT
;R23 start
ifdef IOMEGA_ZIP_Support
ifndef ZIP_Floppy_Depand_on_Jumper		;R23A
		cmp	BP_CX,'PO'		;signature
		jne	short Next_func
		cmp	BP_BX,'ST'		;signature
		jne	short Next_func
		mov	eax,0eah		;enable floppy mode feature
		cmp	BP_AH,0feh
		je	short Set_ZIP_Feature
		mov	al,0dah			;disable floppy mode feature
		cmp	BP_AH,0fdh
		jne	short Next_func
Set_ZIP_Feature:
		call	Clear_CMD_Pkt_buffer		;R32
		mov	CMD_Pkt_buffer.OpCode,0dh	;misc command code
;R32		mov	CMD_Pkt_buffer.CD_Reserved0,0	;reserved
		mov	CMD_Pkt_buffer.S_LBA,eax	;subfunction code
;R32		mov	CMD_Pkt_buffer.CD_Reserved1,0	;reserved
;R32		mov	CMD_Pkt_buffer.S_Length,0	;reserved
;R32		mov	CMD_Pkt_buffer.CD_Reserved2,0	;reserved
;R32		mov	CMD_Pkt_buffer.CD_Reserved3,0	;reserved
;R32		mov	CMD_Pkt_buffer.CD_Reserved4,0	;reserved
		mov	cx,10				;send counter
Resend_MISC_Loop:
		push	cx
		call	Send_Pkt_Cmd			;send it to drive
		pop	cx
		jnc	std_atapi_ret			;Not error then jump
		cmp	ah,6				;media change?
		jne	short Send_MISC_Err		;No,skip
		loop	Resend_MISC_Loop		;error but is media change then continue
Send_MISC_Err:
		mov	ah,80h				;indicate error
		jmp	std_atapi_ret
Next_func:
endif ;ZIP_Floppy_Depand_on_Jumper		;R23A
endif ;IOMEGA_ZIP_Support
;R23 end
	mov	ah,1
  cmp   BP_AH,8						; get parameters?
  jnz   std_atapi_ret
ifdef LS120_SUPPORT
	test	INT13X_FLAG,Floptical_Exist
	jz	short @F
;R15	or	INT13X_FLAG,RW_Flag		;R04
;R15	call	Send_Test_Unit_Ready
;R05 start
;R15	jnc	short Media_In_Diskette
;R15	cmp	ah,6
;R15	je	short Media_In_Diskette
;R15	mov	bp_dh,1
;R15	mov	ax,5012h
;R15	jmp	short Check_Media
;R15Media_In_Diskette:
;R05 end
;R07	mov	al,ds:Floptical_EMUL_HEAD
;R15	mov	al,LS120_EMUL_HEAD		;R07
;R15	dec	al
;R15	mov	bp_dh,al
;R07	mov	ax,ds:Floptical_EMUL_CYL_SEC
;R15	mov	ax,LS120_EMUL_CYL_SEC		;R07
;R15Check_Media:					;R05
;R05	mov	bl,2
;R06	mov	bl,4				;R05
;R15	mov	di,offset HD5_PARMS
;R15	mov	bp_cx,500fh
;R05	cmp	ax,500fh			;1.2MB floppy?
;R15	mov	bp_cx,4f0fh			;R05
;R15	je	short Set_parm
;R05	mov	bl,4
;R15	mov	di,offset HD_PARMS
;R05	mov	bp_cx,5012h
;R15	mov	bp_cx,4f12h			;R05
;R15	cmp	ah,50h				;1.44MB/720KB floppy?
;R15	je	short Set_parm
;R06	mov	bl,10h
;R15	mov	bp_cx,ax
;R15Set_parm:
;R06	mov	bp_bl,bl
;R15A	mov	bp_cx,0c3e0h			;R15
;R15A	mov	bp_dh,7				;R15
;R15A start
	or	INT13X_FLAG,RW_Flag
	call	Send_Test_Unit_Ready
	jnc	short Media_In_Diskette
	cmp	ah,6
	je	short Media_In_Diskette
	mov	bp_dh,1
	mov	ax,5012h
	jmp	short Check_Media
Media_In_Diskette:
	mov	al,LS120_EMUL_HEAD
	dec	al
	mov	bp_dh,al
	mov	ax,LS120_EMUL_CYL_SEC
	dec	ah				;R25
Check_Media:
	mov	di,offset HD5_PARMS
	mov	bp_cx,500fh
	mov	bp_cx,4f0fh
	je	short Set_parm
	mov	di,offset HD_PARMS
	mov	bp_cx,4f12h
	cmp	ah,50h				;1.44MB/720KB floppy?
	je	short Set_parm
	mov	bp_cx,ax
Set_parm:
;R15A end
	mov	bp_bl,10h			;R06
	mov	BP_ES,cs
	mov	BP_DI,di

	mov	ah,byte ptr HARDWARE
	shr	ah,6
	inc	ah
	mov	bp_dl,ah
	xor	ah,ah
	jmp	short std_atapi_ret
@@:
endif ;LS120_SUPPORT
;R08 start
ifdef IOMEGA_ZIP_Support
	test	INT13X_FLAG,IOMEGA_ZIP_Exist
	jz	short @F
	mov	bp_dh,1
	mov	bp_cx,4f12h
	mov	bp_bl,10h
	mov	BP_ES,cs
	mov	BP_DI,offset HD_PARMS

	mov	ah,byte ptr HARDWARE
	shr	ah,6
	inc	ah
	mov	bp_dl,ah
	xor	ah,ah
	jmp	short std_atapi_ret
@@:
endif ;IOMEGA_ZIP_Support
;R08 end
  call  get_atapi_parm
  mov   ah,0
  cmp	bp_dl,80h
  jae	short Not_Floppy
  mov	bl,2
  cmp	cl,0fh
  je	short @F
  add	bl,2
  cmp	cl,12h
  je	short @F
  inc	bl
@@:
	mov	BP_ES,cs
	mov	di,offset HD5_PARMS
	cmp	bl,2
	je	short @F
	mov	di,offset HD_PARMS
	cmp	bl,4
	je	short @F
	mov	di,offset ED_PARMS
@@:
	mov	bp_di,di
  mov	bp_bl,bl
Not_Floppy:
  mov   bp_cx,cx
  mov   bp_dx,dx
std_atapi_ret:
	mov	bp_ah,ah
std_atapi_ret1:
	pop	ds
	pop	es
	pop	di
	pop	si
	pop	dx
	pop	cx
	pop	bx
	mov	bp,ax
	pop	ax
	add	sp,CDROM_RSV_byte
	xchg	ax,bp
	or	ah,ah
	xchg	ax,bp
	pop	bp
	xchg	sp,bp			;R04
	mov	[bp],ax			;R04
	xchg	sp,bp			;R04
	pop	eax					;R02
	clc
	jz	short @F
	stc
@@:
	ret
std_atapi endp

;=============================================================================
;Func:  ATAPI_RESET
;Desc:  Do soft reset, diagnostic mode, and test unit ready to init CD
;Entry: none (use controller address in BDA)
;Exit:  CC/CS
;=============================================================================
atapi_reset proc near
		call	CTLR_BUSY
		jnc	short @F
		dec	dl
		mov	al,CDROM_drive
		out	dx,al
		newiodelay
		call	CTLR_BUSY
		mov	al,ATAPI_Soft_Reset
		out	dx,al
@@:
		ret
atapi_reset endp

;=============================================================================
;Func:  Extend_ATAPI_RD
;Desc:  Translate standard int 13 call parameters and read atapi
;Entry: AH = 42h (extend read function)
;       DL = drive number
;       DS:SI = Disk-address packet
;=============================================================================
Extend_ATAPI_RD proc near
		mov	ax,BP_DS
		mov	es,ax
		mov	bx,BP_SI
		mov	al,es:[bx].DAP_Packet_Size
		cmp	al,10h
		jae	short @F
		mov	ah,1
		ret
@@:
		mov	ax,BP_ES
		push	ax
		mov	ax,BP_BX
		push	ax
		mov	al,BP_AL
		push	ax

		mov	eax,es:[bx].DAP_Buffer_Address
		mov	BP_BX,ax
		shr	eax,16
		mov	BP_ES,ax

		mov	ax,es:[bx].DAP_Block_Count
		shl	ax,2
		mov	BP_AL,al
		mov	DAP_Block_Count_hi,ah

		mov	eax,es:[bx].DAP_Lo_Block_Number
		rol	ax,8
		rol	eax,16
		rol	ax,8
		xor	cl,cl
		mov	Start_Capt_Sec,0

		mov	CMD_Pkt_buffer.OpCode,ATAPI_Read
		or	INT13X_FLAG,RW_Flag
		call	Set_ATAPI_Parm

		pop	bx
		mov	BP_AL,bl
		pop	bx
		mov	BP_BX,bx
		pop	bx
		mov	BP_ES,bx
		ret

Extend_ATAPI_RD endp

;=============================================================================
;Func:  Extend_4B_func
;Desc:  This function returns the system to a configuration that matches a
;	normal floppy or hard disk boot
;Entry: AH = 4Bh (extend read function)
;	AL = 00,return status and terminate emulation
;	AL = 01,return status only,do not terminate emulation
;       DL = drive number to terminate, 7F = terminate all
;       DS:SI = Empty specification packet for return
;
;	else detial see (EI Torito bootable CD-ROM SPEC)
;
;=============================================================================
Extend_4B_func	proc near
;R12		cmp	bp_al,1
;R12		jne	short Ext4B_exit
;R12		mov	byte ptr ds:[si].F4B_Packet_Size,size Func4B_Specify_Pkt
;R12		mov	byte ptr ds:[si].F4B_media_type,40h
;R12		mov	byte ptr ds:[si].F4B_drive_num,CDROM_EMUL_NUM
;R12		mov	byte ptr ds:[si].F4B_controller_index,0	;?????
;R12		mov	eax,ds:CDROM_EMUL_START_SECTOR
;R12		mov	ds:[si].F4B_LBA,eax
;R12		mov	al,ds:[CDROM_ALLOCATE]
;R12		mov	ah,al
;R12		and	al,1
;R12		shr	ah,1
;R12		mov	ds:[si].F4B_drive_specify,ax
;R12		mov	ds:[si].F4B_buffer_seg,2000h	;user buffer segment
;R12		mov	ds:[si].F4B_load_seg,7c0h
;R12		mov	ds:[si].F4B_sector_count,0
;R12		mov	cx,ds:CDROM_EMUL_CYL_SEC
;R12		dec	ch
;R12		mov	ds:[si].F4B_cyl_count,ch
;R12		mov	ds:[si].F4B_sector,cl
;R12		mov	dh,ds:CDROM_EMUL_HEAD
;R12		dec	dh
;R12		mov	ds:[si].F4B_head,dh
;R12 start
		mov	ah,80h
		cmp	bp_al,1
		ja	Ext4B_exit
		test	byte ptr ds:[CDROM_ALLOCATE],0ch	;R37 have any emulation?
		jz	Ext4B_exit				;R37 No,then skip
		mov	si,bp_ds
		mov	es,si
		mov	si,bp_si
		mov	byte ptr es:[si].F4B_Packet_Size,size Func4B_Specify_Pkt

		mov	ah,40h
		mov	cl,CDROM_EMUL_NUM	;set Drive number for no emulation
		mov	al,ds:[CDROM_ALLOCATE]
		and	al,0ch			;isolate emulate bits
		cmp	al,0ch			;Is no emulation?
		je	short @F		;Yes,jump
		mov	cl,80h			;set Drive number for HD
		or	ah,4			;assume HD emulation
		cmp	al,8			;Is HD emulation?
		je	short @F		;Yes,jump
		xor	cl,cl			;set Drive number for FD
		dec	ah			;assume 2.88 emulation
		mov	al,byte ptr ds:[CDROM_EMUL_CYL_SEC]
		cmp	al,24h			;Is 2.88 emulation?
		je	short @F		;Yes,jump
		dec	ah			;assume 1.44 emulation
		cmp	al,12h			;Is 1.44 emulation?
		je	short @F		;Yes,jump
		dec	ah			;assume 1.2 emulation
@@:
;R28 start
		or	cl,cl
		jnz	short Not_Emul_Floppy
		test	byte ptr ds:Hardware,40h	;check have 2 floppy?
		jnz	short Have_2_Floppy		;Yes,jump
		and	byte ptr ds:Hardware,not 1	;set none any floppy
		jmp	short Terminate_Done
Have_2_Floppy:
		and	byte ptr ds:Hardware,not 40h	;set to 1 floppy
		jmp	short Terminate_Done
Not_Emul_Floppy:
		cmp	cl,80h				;emulate C drive?
		jne	short Terminate_Done		;No,skip
		dec	byte ptr ds:NumHDSKS		;decrease hard drive number
Terminate_Done:
;R28 end
		mov	byte ptr es:[si].F4B_media_type,ah
		mov	byte ptr es:[si].F4B_drive_num,cl
		mov	byte ptr ds:[si].F4B_controller_index,0	;?????
		mov	eax,ds:CDROM_EMUL_START_SECTOR
		mov	es:[si].F4B_LBA,eax
		mov	al,ds:[CDROM_ALLOCATE]
		mov	ah,al
		and	al,1
		shr	ah,1
		mov	es:[si].F4B_drive_specify,ax
		mov	es:[si].F4B_buffer_seg,2000h	;user buffer segment
		mov	es:[si].F4B_load_seg,7c0h
		mov	es:[si].F4B_sector_count,0
		mov	cx,ds:CDROM_EMUL_CYL_SEC
		dec	ch
		mov	es:[si].F4B_cyl_count,ch
		mov	es:[si].F4B_sector,cl
		mov	dh,ds:CDROM_EMUL_HEAD
		dec	dh
		mov	es:[si].F4B_head,dh

		cmp	bp_al,0
		jne	short @F
;R41		mov	byte ptr ds:[CDROM_ALLOCATE],0	;terminate emulation
		and	byte ptr ds:[CDROM_ALLOCATE],0f0h	;R41;terminate emulation
@@:
;R12 end
		xor	ah,ah
Ext4B_exit:
		ret
Extend_4B_func	endp

;R29 start
Get_Sense_Code:
		push	ax				;save AX
;R39		xor	cx,cx				;assume no additional sense code

		push	dword ptr CMD_Pkt_buffer	;---------------------------------------
		push	dword ptr CMD_Pkt_buffer.4	; Save original CMD_Pkt_buffer to stack
		push	dword ptr CMD_Pkt_buffer.8	;---------------------------------------

		call	Clear_CMD_Pkt_buffer		;R32
		mov	CMD_Pkt_buffer.OpCode,3		;Request sense command
;R32		mov	CMD_Pkt_buffer.CD_Reserved0,0
		mov	CMD_Pkt_buffer.S_LBA,0e0000h	;allocation length
;R32		mov	CMD_Pkt_buffer.CD_Reserved1,0
;R32		mov	CMD_Pkt_buffer.S_Length,0
;R32		mov	CMD_Pkt_buffer.CD_Reserved2,0
;R32		mov	CMD_Pkt_buffer.CD_Reserved3,0
;R32		mov	CMD_Pkt_buffer.CD_Reserved4,0
		call	Send_Pkt_Command		;issue command

		pop	dword ptr CMD_Pkt_buffer.8	;---------------------------------------
		pop	dword ptr CMD_Pkt_buffer.4	; Restore original CMD_Pkt_buffer from stack
		pop	dword ptr CMD_Pkt_buffer	;---------------------------------------

		mov	cx,0			;R39 assume no additional sense code
						;R39 Don't destroy flag
		jc	short GSC_Ret		;if error then return

;R35 start
		mov	ax,302h
		call	Get_CoD_IO
		jc	short GSC_Ret
		call	Get_DRQ
		jc	short GSC_Ret
		call	Get_Byte_Count		;SI = word count
		push	cx			;R39 push for balance stack
		push	cx			;R39 push for balance stack
		cmp	si,7			;R39 sense key below 7 bytes?
		jb	short Get_Remain_Key	;R39 Yes,skip
		pop	cx			;R39 balance stack
		pop	cx			;R39 balance stack
;R35 end
		mov	dx,CDROM_port		;data port
		in	ax,dx			;get first data from device
		newiodelay
		dec	si			;R35 decrease data count
;R34		and	al,7eh			;dont care bit 0 and 7
;R34		cmp	al,70h			;is 70h or 71h?
;R34		jne	short GSC_Ret		;No,means no error then skip
		in	ax,dx			;get second data
		newiodelay
		dec	si			;R35 decrease data count
		push	ax			;store to stack
		mov	cx,5			;get data count
@@:
		in	ax,dx			;get data ...
		newiodelay
		loop	@B			;loop
;R35 start
		push	ax			;save ASC and ASCQ
		sub	si,5
		jz	short GSC_over		;If no more data then skip
Get_Remain_Key:					;R39
		mov	cx,si			;remain data count
		pushf
		cli
@@:
		in	ax,dx			;get remain data
		newiodelay
		loop	@B
		popf
GSC_over:
		pop	cx			;restore ASC and ASCQ
;R35 end
;R35		mov	cx,ax			;CX=ASC and ASCQ code
;R35@@:
;R35		add	dl,7			;DX=1X7h
;R35		in	al,dx			;get status
;R35		test	al,8			;more data?
;R35		jz	short @F		;No,skip
;R35		sub	dl,7			;DX=1X0h(data port)
;R35		in	ax,dx			;read remain data
;R35		newiodelay
;R35		jmp	short @B		;check next
;R35@@:
		call	ATAPI_Wait_Int		;R33A
		pop	dx			;pop second data to DX
		and	dl,0fh			;isolate sense Key value
		clc				;R35 indicate no error
GSC_Ret:
		pop	ax			;restore AX
		ret
;R29 end

Send_Test_Unit_Ready:
		clc
		xor	ah,ah
;R08ifdef LS120_SUPPORT
;R08		test	INT13X_FLAG,Floptical_Exist
		test	INT13X_FLAG,Floptical_Exist+IOMEGA_ZIP_Exist	;R08
;R24		jz	short @F
		jz	@F					;R24
		push	bx
		call	Clear_CMD_Pkt_buffer		;R32
		mov	CMD_Pkt_buffer.OpCode,Test_Unit_Ready
;R32		mov	CMD_Pkt_buffer.CD_Reserved0,0
		mov	CMD_Pkt_buffer.S_LBA,0
;R32		mov	CMD_Pkt_buffer.CD_Reserved1,0
;R32		mov	CMD_Pkt_buffer.S_Length,0
;R32		mov	CMD_Pkt_buffer.CD_Reserved2,0
;R32		mov	CMD_Pkt_buffer.CD_Reserved3,0
;R32		mov	CMD_Pkt_buffer.CD_Reserved4,0
		call	Send_Pkt_Cmd
;R05 start
		pushf
		cmp	ah,6
;R33A		jne	short Drive_OK
;R33A start
		je	short Media_have_Changed
		or	ah,ah
		jz	short Drive_OK
;R41		call	ATAPI_Wait_Int
		jmp	short Drive_OK
Media_have_Changed:
;R33A end
ifdef LS120_SUPPORT					;R08
		test	INT13X_FLAG,Floptical_Exist	;R08
		jz	short Drive_OK			;R08
		push	ax
		mov	CMD_Pkt_buffer.OpCode,Read_Capacity_Cmd
		call	Send_Pkt_Cmd
		jc	short Drive_OK1
		mov	dx,CDROM_port
		in	eax,dx
		newiodelay
		in	eax,dx
		newiodelay
		call	Get_Media_Para
		call	ATAPI_Wait_Int			;R33A
Drive_OK1:
		pop	ax
endif ;LS120_SUPPORT					;R08
Drive_OK:
;R20A start
	test	INT13X_FLAG,Floptical_Exist
	jz	short Dont_Set_LS120_Para
	lea	bx,G_RAM:[Floptical0_EMUL_CYL_SEC]
	test	G_RAM:[ATAPI_Byte],30h
	jz	short Is_dirveA
	cmp	bp_dl,0
	je	short Is_dirveA
	lea	bx,G_RAM:[Floptical1_EMUL_CYL_SEC]
Is_dirveA:
	mov	dx,G_RAM:[bx]
	mov	LS120_EMUL_CYL_SEC,dx
	mov	dx,G_RAM:[bx+2]
	mov	LS120_EMUL_HEAD,dl
	mov	LS120_Medium_Type,dh
;R24 start
	cmp	dh,30h
	je	short Set_LS120_Para
	cmp	dh,31h
	jne	short Dont_Set_LS120_Para
Set_LS120_Para:
	mov	LS120_EMUL_CYL_SEC,0c3e0h
	mov	LS120_EMUL_HEAD,8
;R24 end
Dont_Set_LS120_Para:
;R20A end
		popf
;R05 end
		pop	bx
@@:
;R08endif ;LS120_SUPPORT
		ret

;=============================================================================
;Func:  STD_ATAPI_ACCESS
;Desc:  Translate standard int 13 call parameters and read atapi
;Entry: AH = 2 (read function)
;       AL = number of sectors
;       CH = cyl low
;       CL = cyl high(2 bits) / sector(low 6 bits)
;       DH = heads
;       DL = drive
;       ES:BX = buffer
;=============================================================================
std_atapi_access	proc	near
		call	Send_Test_Unit_Ready
		jc	exit
		mov	CMD_Pkt_buffer.OpCode,bl
		mov	ax,BP_CX
		xchg	al,ah
		shr	ah,6
		mov	cl,ds:CDROM_EMUL_HEAD
ifdef LS120_SUPPORT
		test	INT13X_FLAG,Floptical_Exist
		jz	short @F
;R07		mov	cl,ds:Floptical_EMUL_HEAD
		mov	cl,LS120_EMUL_HEAD		;R07
@@:
endif ;LS120_SUPPORT
;R08 start
ifdef IOMEGA_ZIP_Support
		test	INT13X_FLAG,IOMEGA_ZIP_Exist
		jz	short @F
		mov	cl,IOMEGA_ZIP_Heads
@@:
endif ;IOMEGA_ZIP_Support
;R08 end
		xor	ch,ch
		mul	cx				;ax = cyl. x HEAD
		add	al,BP_DH
		adc	ah,0
		mov	cl,byte ptr ds:CDROM_EMUL_CYL_SEC
ifdef LS120_SUPPORT
		test	INT13X_FLAG,Floptical_Exist
		jz	short @F
;R07		mov	cl,byte ptr ds:Floptical_EMUL_CYL_SEC
		mov	cx,LS120_EMUL_CYL_SEC	;R07
		xor	ch,ch			;R07
@@:
endif ;LS120_SUPPORT
;R08 start
ifdef IOMEGA_ZIP_Support
		test	INT13X_FLAG,IOMEGA_ZIP_Exist
		jz	short @F
		mov	cl,IOMEGA_ZIP_Sectors
@@:
endif ;IOMEGA_ZIP_Support
;R08 end
		and	cl,3fh
		mul	cx
		mov	cl,BP_CL
		and	cl,3fh
		dec	cx
;R08 start
ifdef IOMEGA_ZIP_Support
		test	INT13X_FLAG,IOMEGA_ZIP_Exist
		jz	short @F
;R23 start
		mov	bl,1
		cmp	CDROM_port,1f0h
		jae	short _Pri
		shl	bl,2
_Pri:
		cmp	CDROM_drive,0a0h
		je	short _Master
		shl	bl,1
_Master:
		test	byte ptr DGROUP:[IoMegaZip_Flag],bl	;test is floppy mode ZIP?
		jnz	short @F			;Yes,skip to adjust sectores
;R23 end
		add	cx,IOMEGA_ZIP_Sectors
@@:
endif ;IOMEGA_ZIP_Support
;R08 end
		add	ax,cx
		adc	dx,0				;dx/ax = LBA number (physical sector)
		test	INT13X_FLAG,Sector_200b
		jnz	short @F
		mov	cl,al
		and	cl,3
		mov	Start_Capt_Sec,cl
		shr	dx,1
		rcr	ax,1
		shr	dx,1
		rcr	ax,1				;dx/ax = CDROM LBA number
		add	ax,word ptr ds:CDROM_EMUL_START_SECTOR
		adc	dx,word ptr ds:CDROM_EMUL_START_SECTOR+2
@@:
		xchg	al,ah
		shl	eax,16
		xchg	dl,dh
		mov	ax,dx
		mov	DAP_Block_Count_hi,0
Set_ATAPI_Parm:
		mov	CMD_Pkt_buffer.S_LBA,eax

		mov	ah,BP_AL
		test	INT13X_FLAG,Sector_200b
		jnz	short @F
		add	ah,cl
		add	ah,3
		shr	ah,2
@@:
		mov	al,DAP_Block_Count_hi
		mov	CMD_Pkt_buffer.S_Length,ax

;R32 start
		mov	di,BP_ES		;---------
		mov	es,di			;get transfer address to ES:DI
		mov	di,BP_BX		;---------

		test	INT13X_FLAG,Sector_200b	;LS120 or ZIP?
		jz	short Not_Sector_200b	;No,jump
;----------- for LS120/ZIP access ------------
ifdef IOMEGA_ZIP_Support
;--- for write BPB (sector 0) modify
		xor	al,al
		call	Change_BPB_data
		jc	short @F
;R40A		mov	byte ptr es:[di+26],64
		mov	byte ptr es:[di+28],32
		mov	byte ptr es:[di+36],80h
@@:
endif ;IOMEGA_ZIP_Support

		call	Send_Pkt_Cmd
		jc	exit
ifdef IOMEGA_ZIP_Support
;--- for read BPB (sector 0) modify
		mov	al,RW_Flag
		call	Change_BPB_data
		jc	short @F
;R40A		mov	byte ptr es:[di+26],12
		mov	byte ptr es:[di+28],0
		mov	byte ptr es:[di+36],0
@@:
endif ;IOMEGA_ZIP_Support
		xor	ah,ah
		jmp	exit

;----------- for CDROM access ------------
ATAPI_RW_MAX_BLOCK	equ	1fh
Not_Sector_200b:
		mov	cl,BP_AL			;get R/W sector
		push	cx				;store it
		mov	bx,CMD_Pkt_buffer.S_Length	;get transfer length
		xchg	bl,bh
		mov	ax,bx
		cmp	bx,20h				;over or equ 64K?
							;(1 block = 800h bytes,
							;so 20h = 64K bytes)
		mov	bx,0				;assume no exceed block
		jb	short @F			;No,skip
		mov	bx,ax
		mov	ax,ATAPI_RW_MAX_BLOCK
		sub	bx,ax				;remain block length
		xchg	al,ah
		mov	CMD_Pkt_buffer.S_Length,ax	;first read block length
		xchg	al,ah

		shl	al,2				;1 block = sector*4
		sub	al,Start_Capt_Sec		;first read scetor number
		mov	BP_AL,al			;store to stack
@@:
		push	bx				;keep remain block
;R32 end
		call	Send_Pkt_Cmd
;R32		jc	exit

;R32 start
		pop	bx
		pop	cx
		jnc	short RW_OK			;access no error then jump
RW_Over:
		mov	BP_AL,cl			;restore AL of stack
		jmp	exit
RW_OK:
		or	bx,bx				;have any remain data?
		jz	short RW_Over1			;no,skip
		push	cx
		sub	cl,BP_AL			;remain sector
		mov	BP_AL,cl			;store to stack
		mov	eax,CMD_Pkt_buffer.S_LBA	;get first block address
		xchg	al,ah				;-----
		rol	eax,16				;change style
		xchg	al,ah				;-----
		add	eax,ATAPI_RW_MAX_BLOCK		;point to second block address
		xchg	al,ah				;-----
		rol	eax,16				;change style
		xchg	al,ah				;-----
		mov	CMD_Pkt_buffer.S_LBA,eax	;set to second block address
		xchg	bl,bh
		mov	CMD_Pkt_buffer.S_Length,bx	;set transfer length
		call	Send_Pkt_Cmd
		pop	cx
		jc	short RW_Over
RW_Over1:
		mov	BP_AL,cl
;------------------------------------------
;R32 end

;R32		cmp	CMD_Pkt_buffer.OpCode,ATAPI_Verify
;R32		je	atapi_access_over
;R32		cmp	CMD_Pkt_buffer.OpCode,ATAPI_Format
;R32		je	atapi_access_over

;R32		test	INT13X_FLAG,Sector_200b
;R32		jnz	short Read_Capture_Sector
;R32
;R32		mov	cl,Start_Capt_Sec
;R32		xor	ch,ch
;R32		shl	cx,8
;R32		mov	bx,cx
;R32		jcxz	short Read_Capture_Sector
;R32		call	CTLR_BUSY	;R10
;R32		mov	dx,CDROM_port
;R32		cli
;R32		align	4
;R32@@:
;R32		in	ax,dx
;R32		loop	@B
;R32		sti
;R32		call	Wait_Drq_Clear	;R10
;R32		call	Wait_BSY	;R10
;R32
;R32Read_Capture_Sector:
;R32;R08 start 
;R32ifdef IOMEGA_ZIP_Support
;R32;--- for write BPB (sector 0) modify
;R32		xor	al,al
;R32		call	Change_BPB_data
;R32		jc	short @F
;R32		mov	byte ptr es:[di+26],64
;R32		mov	byte ptr es:[di+28],32
;R32		mov	byte ptr es:[di+36],80h
;R32@@:
;R32endif ;IOMEGA_ZIP_Support
;R32;R08 end
;R32		test	INT13X_FLAG,Sector_200b
;R32		jnz	short @F
;R32		mov	cx,400h
;R32		sub	cx,bx
;R32@@:
;R32		mov	di,BP_ES
;R32		mov	es,di
;R32		mov	di,BP_BX
;R32		mov	bl,BP_AL
;R32		mov	bh,DAP_Block_Count_hi
;R32		shl	bx,8
;R32		test	INT13X_FLAG,Sector_200b
;R32		jnz	short Access_loop
;R32		cmp	cx,bx
;R32		jbe	short @F
;R32		mov	cx,bx
;R32		jmp	short @F
;R32Access_loop:
;R32		call	CTLR_BUSY
;R32		jc	exit
;R32
;R32		mov	ah,3
;R32		mov	al,INT13X_FLAG
;R32		and	al,RW_Flag
;R32		call	Get_CoD_IO
;R32		jc	With_Error
;R32		jnz	With_Error
;R32@@:
;R32		test	INT13X_FLAG,Sector_200b
;R32		jnz	short @F
;R32		sub	bx,cx
;R32		jnc	short @F
;R32		add	bx,cx
;R32		mov	cx,bx
;R32		xor	bx,bx
;R32@@:
;R32		call	CTLR_BUSY
;R32		jc	With_Error
;R32		test	INT13X_FLAG,Sector_200b
;R32		jz	short @F
;R32		mov	cx,100h
;R32@@:
;R32		mov	dx,CDROM_port
;R32		cli
;R32		test	INT13X_FLAG,RW_Flag
;R32		jnz	short Read_Data
;R32		align	4
;R32@@:
;R32		mov	ax,es:[di]
;R32		add	di,2
;R32		out	dx,ax
;R32		loop	@B
;R32		sti
;R32		jmp	short Transfer_Date_Over
;R32Read_Data:
;R32		align	8
;R32@@:
;R32		in	ax,dx
;R32		stosw
;R32		loop	@B
;R32		sti
;R32;R21		call	Wait_Drq_Clear
;R32;R21		call	Wait_BSY	;R10
;R32Transfer_Date_Over:
;R32		test	INT13X_FLAG,Sector_200b
;R32		jz	short @F
;R32		sub	bx,100h
;R32		jz	short Read_Over
;R32		jmp	short Access_loop
;R32@@:
;R32		or	bx,bx
;R32		jz	short Read_Others
;R32		call	Wait_BSY	;R31
;R32		mov	cx,400h
;R32		jmp	Access_loop
;R32Read_Others:
;R32		test	INT13X_FLAG,Sector_200b
;R32		jnz	short Read_Over
;R32		mov	al,Start_Capt_Sec
;R32		add	al,BP_AL
;R32		and	al,3
;R32		mov	cl,4
;R32		sub	cl,al
;R32		mov	ch,DAP_Block_Count_hi
;R32		jcxz	short Read_Over
;R32		call	CTLR_BUSY	;R10
;R32		shl	cx,8
;R32		mov	dx,CDROM_port
;R32		cli
;R32		align	4
;R32@@:
;R32		in	ax,dx
;R32		loop	@B
;R32		sti
;R32Read_Over:
;R32		call	Wait_Drq_Clear
;R32		call	Wait_BSY	;R10
;R32
;R32atapi_access_over:
;R32;R08 start 
;R32ifdef IOMEGA_ZIP_Support
;R32;--- for read BPB (sector 0) modify
;R32		mov	al,RW_Flag
;R32		call	Change_BPB_data
;R32		jc	short @F
;R32		mov	byte ptr es:[di+26],12
;R32		mov	byte ptr es:[di+28],0
;R32		mov	byte ptr es:[di+36],0
;R32@@:
;R32endif ;IOMEGA_ZIP_Support
;R32;R08 end
;R32		clc
		xor	ah,ah
exit:
		ret
std_atapi_access	endp

;R08 start
ifdef IOMEGA_ZIP_Support
Change_BPB_data:
	test	INT13X_FLAG,IOMEGA_ZIP_Exist
	jz	short Dont_trans_BPB
	test	INT13X_FLAG,IOMEGA_ZIP_RW
	jz	short Dont_trans_BPB
	cmp	BP_CX,1
	jne	short Dont_trans_BPB
	cmp	BP_DH,0
	jne	short Dont_trans_BPB
	mov	ah,INT13X_FLAG
	and	ah,RW_Flag
	cmp	al,ah
	jne	short Dont_trans_BPB
	mov	di,BP_ES
	mov	es,di
	mov	di,BP_BX
	clc
	ret
Dont_trans_BPB:
	stc
	ret
endif ;IOMEGA_ZIP_Support
;R08 end

;=============================================================================
;Func:  GET_ATAPI_PARM
;Desc:  Get parameters for ATAPI disk
;Entry: DL = drive
;Exit:  DH = max head number
;       DL = number of drives
;       CH = max cyl number (low 8 bits)
;       CL = 7:6 max cyl number high bits, 5:0 max sector number
;=============================================================================
get_atapi_parm proc	near
		mov	dh,ds:CDROM_EMUL_HEAD
		dec	dh
		cmp	bp_dl,80h		;R30
		jb	short Is_Floppy		;R30
		mov	dl,ds:NUMHDSKS
		jmp	short None_floppy	;R30
Is_Floppy:					;R30
		mov	cl,byte ptr ds:HARDWARE
		test	cl,1
		jz	short None_floppy
		rol	cl,2			; bit 6 to bit 0.
		and	cl,1			; isolate
		inc	cl			; 0->1, 1->2
;R30		add	dl,cl
		mov	dl,cl			;R30
None_floppy:
		mov	cx,ds:CDROM_EMUL_CYL_SEC
		dec	ch
		ret
get_atapi_parm endp

Send_Pkt_Cmd:
;R29 start
		call	Send_Pkt_Command
		jnc	short Send_Pkt_Cmd_ret
;R29B;R29A start
;R29Bifdef IOMEGA_ZIP_Support
;R29B		test	INT13X_FLAG,IOMEGA_ZIP_Exist
;R29B		jnz	short Send_Pkt_Cmd_ret1
;R29Bendif ;IOMEGA_ZIP_Support
;R29B;R29A end
;R34		cmp	ah,80h			;time out error?
		cmp	ah,Get_SenseKey_Code	;R34 Get SenseKey error?
		jne	short Send_Pkt_Cmd_ret1	;No,skip
		mov	ah,80h			;R34 time out
;R39A		cmp	CMD_Pkt_buffer.OpCode,Test_Unit_Ready	;R39
;R39A		je	short Send_Pkt_Cmd_ret1			;R39
		call	Get_Sense_Code		;get sense code
		jc	short Send_Pkt_Cmd_ret1	;R35 have some error then skip
		mov	G_RAM:[FDC_RET_CODES],dl		;R34
		mov	word ptr G_RAM:[FDC_RET_CODES+1],cx	;R34
;R39A		cmp	dl,0bh			;R39 sense key = 0bh?
;R39A		je	short Send_Pkt_Cmd	;R39 Yes,resend command again
		cmp	dl,2			;sense key = 2?
		jne	short Send_Pkt_Cmd_ret1	;no,skip
		cmp	cx,104h			;ASC=4 and ASCQ=1?
		je	short Send_Pkt_Cmd	;Yes,resend command again
Send_Pkt_Cmd_ret1:
		stc
Send_Pkt_Cmd_ret:
		ret
Send_Pkt_Command:
;R29 end
		call	Drive_Ready
		jc	With_Error
		dec	dl
		mov	al,CDROM_drive
		out	dx,al
		newiodelay
;R04		call	Ctlr_Drive_Ready
;R04A		call	Drive_Ready		;R04
;R04B		call	Ctlr_Drive_Ready	;R04A
		call	Drive_Ready		;R04B
		jc	With_Error

;----- Issue Packet Command
		sub	dx,6			;dx = 1X1h
		xor	al,al
		out	dx,al
		newiodelay

		add	dx,3			;dx = 1X4h
;R32 start
;R29B		mov	ax,ss:CMD_Pkt_Buffer.S_Length
;R29B		shl	ax,1			;assume 200h bytes/sector
;R29B		test	INT13X_FLAG,Sector_200b	;200 bytes/sector device?
;R29B		jnz	short @F		;Yes,jump
;R29B		shl	ax,2			;800h bytes/sector for CDROM
;R29B@@:
;R32 end
		mov	al,0feh			;R29B
		out	dx,al			;send total bytes (low byte) of transfer
		newiodelay

;R29B		mov	al,ah			;R32 get byte count hi byte
		inc	dx			;dx = 1X5h
;R17		mov	al,Size ATAPI_CmdPkt
;R32		mov	al,8			;R17 800h bytes per sector of CDROM
;R32;R17A start
;R32		test	INT13X_FLAG,Sector_200b
;R32		jz	short @F
;R32		mov	al,2			;200h bytes per sector for LS120/ZIP
;R32@@:
;R32;R17A end
;R32		mul	byte ptr ss:[CMD_Pkt_Buffer+8]	;R17 send total bytes (high byte) of transfer
;R32;R17B start
;R32		or	al,al
;R32		jnz	short @F
;R32		mov	al,0ffh
;R32		dec	dx
;R32		out	dx,al
;R32		inc	dx
;R32@@:
;R32;R17B end
		mov	al,0ffh			;R29B
		out	dx,al
		newiodelay

		inc	dx			;dx = 1X6h
		mov	al,CDROM_drive
		out	dx,al
		newiodelay

;R04		call	Drive_Ready
;R04B		call	Ctlr_Drive_Ready	;R04
		call	Drive_Ready		;R04B
;R32		call	Wait_Drq_Clear

		mov	al,ATAPI_Pkt_Cmd
		out	dx,al
		newiodelay

		call	CTLR_BUSY
		jc	With_Error

		mov	ax,301h			;R32
		call	Get_CoD_IO		;R32
		jc	With_Error		;R32
		call	Get_DRQ
		jc	With_Error

;----- Write Command Packet Bytes
		mov	dx,CDROM_port
		mov	cx,Size ATAPI_CmdPkt
		shr	cx,1
		lea	si,CMD_Pkt_Buffer
;R39		cli
;R39		align	4
;R39@@:
;R39		mov	ax,ss:[si]
;R39		out	dx,ax
;R39		add	si,2
;R39		loop	@B
;R39		sti
;R39 start
		pushf				;store flag to stack
		cli
		push	ds

		push	ss			;DS=SS
		pop	ds
		rep	outsw			;send out packet command

		pop	ds
		popf
;R39 end
;R32		call	Wait_Drq_Clear
		call	Wait_BSY			;R36

		call	CTLR_BUSY
;R34		jc	With_Error
		jc	Get_SenseKey_Err		;R34
		cmp	CMD_Pkt_buffer.OpCode,ATAPI_Verify
		je	short Check_Error
		cmp	CMD_Pkt_buffer.OpCode,ATAPI_Format
		je	short Check_Error
		cmp	CMD_Pkt_buffer.OpCode,Read_Capacity_Cmd	;R05
		je	short Check_Error			;R05
ifndef ZIP_Floppy_Depand_on_Jumper				;R23A
		cmp	CMD_Pkt_buffer.OpCode,0dh		;R23 misc command code?
		je	short Check_Error			;R23 Yes,jump
endif ;ZIP_Floppy_Depand_on_Jumper				;R23A
;R32A start
		cmp	CMD_Pkt_buffer.OpCode,3		;Request sense command
		je	short Check_Error
;R32A end
		cmp	CMD_Pkt_buffer.OpCode,Test_Unit_Ready
		jne	short Get_Trans_Status
Check_Error:
		call	Ctlr_Drive_Ready
;R34		jc	With_Error
		jc	Get_SenseKey_Err		;R34
		in	al,dx			;dx = 1X7h
		newiodelay
		test	al,1
		jnz	short Get_Error
		jmp	No_Error
Get_Trans_Status:
;R32A;R32 start
;R32A		call	ReadWrite_Action
;R32A		jc	With_Error
;R32A		mov	ax,303h
;R32A		call	Get_CoD_IO
;R32A		call	Wait_Drq_Clear
;R32A;R32 end
;R32		mov	ah,3
;R32		mov	al,INT13X_FLAG
;R32		and	al,RW_Flag
;R32		call	Get_CoD_IO
;R32		jc	short @F
;R32		jz	No_Error
;R32@@:
		mov	dx,CDROM_port
		add	dx,7
		in	al,dx			;dx = 1X7h
		newiodelay
		test	al,1
;R32		jz	Send_Pkt_Cmd
;R32A		jz	No_Error		;R32
;R32A start
		jnz	short Get_Error
		call	ReadWrite_Action
;R34		jc	With_Error
		jc	Get_SenseKey_Err	;R34
;R39		mov	ax,303h
;R39		call	Get_CoD_IO
;R33		call	Wait_Drq_Clear
		test	INT13X_FLAG,Sector_200b	;R39A Is sector 200h?
		jz	No_Error		;R39A
		call	Get_Sense_Code		;R39 get sense code
		jmp	No_Error
;R32A end
Get_Error:
		sub	dx,6			;dx = 1X1h
		in	al,dx
		newiodelay
		shr	al,4
		cmp	al,2			;Not Ready... Retry
;R34		je	With_Error
		je	Get_SenseKey_Err	;R34
		cmp	al,4
;R34		je	With_Error
		je	Get_SenseKey_Err	;R34
;R19 - start
		cmp	al,5			;
		jne	short @F
		mov	ah,32h			;return Media type not supported by drive
		jmp	Error_Ret
@@:
;R19 -end
		cmp	al,7			;write protect
		jne	short @F
		mov	ah,3			;return write protect status
		jmp	Error_Ret
@@:
		cmp	al,6			;Unit Attention... Retry
;R34		jne	With_Error
		jne	Get_SenseKey_Err	;R34
		test	INT13X_FLAG,IOMEGA_ZIP_Exist	;R08
		jnz	Media_change			;R08
		test	INT13X_FLAG,Floptical_Exist
;R29		jz	With_Error
		jz	Media_change			;R29
ifdef LS120_SUPPORT
Get_Media_Para:					;R05
		xor	bh,bh
Resend_Id_Cmd:
;----- media have changed so redetect media type for floptical parameter
		call	Ctlr_Drive_Ready
		jc	With_Error
		mov	dx,CDROM_port
		add	dx,7			;dx = 1X7h
		mov	al,ATAPI_Identify_Cmd
		out	dx,al			;Send CDROM identify command
		call	Ctlr_Drive_Ready
		jc	With_Error
		call	Get_DRQ
		jc	With_Error
		mov	dx,CDROM_port
		in	ax,dx			;discard word 0
		in	ax,dx			;get word 1
		mov	di,ax			;get cylinders
		in	ax,dx			;discard word 2
		in	ax,dx			;get word 3
		mov	cl,al			;get heads
		in	ax,dx			;get word 4
		or	al,al			;have any media in drive?
		jnz	short Media_Exist
		mov	cx,0ffh-4		;read remain word
@@:
		in	ax,dx
		loop	@B
		dec	bh
		jnz	Resend_Id_Cmd
		jmp	short With_Error
Media_Exist:
;R07		mov	G_RAM:[Floptical_Medium_Type],al
;R07 start
		lea	si,G_RAM:[Floptical0_EMUL_CYL_SEC]
		test	G_RAM:[ATAPI_Byte],30h			;R14A
		jz	short @F				;R14A
		cmp	BP_DL,0
		je	short @F
		lea	si,G_RAM:[Floptical1_EMUL_CYL_SEC]
@@:
		mov	G_RAM:[si+3],al
;R07 end
		in	ax,dx			;discard word 5
		in	ax,dx			;get word 6
		mov	ch,al			;get heads
		mov	bl,53-7+1		;discard word 7-53
@@:
		in	ax,dx
		dec	bl
		jnz	@B
		in	ax,dx			;get word 54
		cmp	ax,di			;cylinders is equal with word 54?
		je	short @F
		in	ax,dx			;discard word 55
		in	ax,dx			;discard word 56
		jmp	short Discard_remain_word
@@:
		in	ax,dx			;get word 55
		cmp	cl,al			;Heads is equal with word 55?
		je	short @F
		in	ax,dx			;discard word 56
		jmp	short Discard_remain_word
@@:
		in	ax,dx			;get word 56
		cmp	ch,al			;Sectors is equal with word 56?
		jne	short Discard_remain_word
		mov	ax,di			;restore cylinders to AX
;R07		mov	G_RAM:[Floptical_EMUL_HEAD],cl
		mov	G_RAM:[si+2],cl		;R07
		shl	ah,6
		and	ch,3fh
		or	ah,ch
		xchg	al,ah
;R07		mov	G_RAM:[Floptical_EMUL_CYL_SEC],ax
		mov	G_RAM:[si],ax		;R07
Discard_remain_word:
		mov	cx,0ffh-56		;read remain word
@@:
		in	ax,dx
		loop	@B
endif ;LS120_SUPPORT
Media_change:					;R08
		mov	ah,6			;media changed
		jmp	short Error_Ret
;R34 start
Get_SenseKey_Err:
		mov	ah,Get_SenseKey_Code
		jmp	short Error_Ret
;R34 end
With_Error:
		mov	ah,80h
Error_Ret:
		stc
		ret
No_Error:
		clc
		xor	ah,ah
		ret

;-------------------------------------------
;input  : None
;output : CY = error
;	  NC = OK
;-------------------------------------------
Drive_Ready:
;R03		test	INT13X_FLAG,RW_Flag
;R03		jnz	short CTLR_BUSY
		test	INT13X_FLAG,RW_Flag		;R04
		jnz	short CTLR_BUSY			;R04
Ctlr_Drive_Ready:
;R03		test	INT13X_FLAG,Floptical_Exist
;R03		jz	short CTLR_BUSY
;R03		mov	ax,0c040h
;R03		jmp	short Check_Status_Port
		test	INT13X_FLAG,Floptical_Exist	;R04
		jz	short CTLR_BUSY			;R04
		mov	ax,0c040h			;R04
		jmp	short Check_Status_Port		;R04

CTLR_BUSY	PROC	NEAR
		mov	ax,8000h
Check_Status_Port:
		push	bx
		push	cx

		mov	dx,CDROM_port
		add	dx,7			;dx = 1X7h
		mov	bh,WAIT_UHD_BUSY_HI
		mov	cx,WAIT_UHD_BUSY_LO
		call	WAIT_FOR_PORT
		clc
		or	ah,ah
		jz	short @F
		stc
@@:
		pop	cx
		pop	bx
		ret
CTLR_BUSY	ENDP

;-------------------------------------------
;input  : None
;output : CY = error
;	  NC = OK
;-------------------------------------------
Get_DRQ		PROC	NEAR
		push	bx
		push	cx

		mov	dx,CDROM_port
		add	dx,7			;dx = 1X7h
		mov	bh,WAIT_UHD_DRQ_HI
		mov	cx,WAIT_UHD_DRQ_LO
;R39Get_Drq_Loop:
;R39		push	bx
;R39		push	cx
		mov	ax,808h			;wait for top bit to be 0
;R39		xor	bh,bh
;R39		mov	cx,20h
		call	WAIT_FOR_PORT
;R39		pop	cx
;R39		pop	bx
;R39		clc
		or	ah,ah
		jz	short Get_Drq_Exit
;R39		in	al,dx
;R39		test	al,1
;R39		jnz	short Get_Drq_Err
;R39		loop	Get_Drq_Loop
;R39		or	bh,bh
;R39		jz	short Get_Drq_Err
;R39		dec	bh
;R39		jmp	short Get_Drq_Loop
;R39Get_Drq_Err:
		stc
Get_Drq_Exit:
		pop	cx
		pop	bx
		ret
Get_DRQ		ENDP

;-------------------------------------------
;input  : AX = Get pattern
;output : CY = error
;	  NC = OK
;R32;	  NZ = Resend command
;-------------------------------------------
Get_CoD_IO	PROC	NEAR
		push	bx
		push	cx

		mov	dx,CDROM_port
		add	dx,2			;dx = 1X2h
		mov	bh,WAIT_UHD_DRQ_HI
		mov	cx,WAIT_UHD_DRQ_LO
		call	WAIT_FOR_PORT		;R39
		or	ah,ah			;R39
		jz	short Got_Pattern	;R39

;R39		mov	bl,al
;R39G_CoD_IO_Loop:
;R39		in	al,dx			;get status
;R39		and	al,ah			;isolate bits.
;R39		cmp	al,bl			;check for match.
;R39		je	short Got_Pattern	;got the bit
;R39;R32		cmp	al,3
;R39;R32		je	short Resend_Cmd
;R39;R34 start
;R39		add	dl,5			;DX = 1x7h
;R39		in	al,dx			;get status
;R39		newiodelay
;R39		sub	dl,5			;DX = 1x2h
;R39		test	al,1			;error bit?
;R39		stc
;R39		jnz	short G_CoD_IO_Exit
;R39;R34 end
;R39
;R39		ALIGN	4
;R39R_Hi:		in	al,SYS1			;wait for hi to lo
;R39		test	al,10h			;transition on memory
;R39		jnz	short R_Hi		;refresh.
;R39
;R39		ALIGN	4
;R39R_Lo:
;R39		in	al,SYS1
;R39		test	al,10h
;R39		jz	short R_Lo
;R39
;R39		loop	short G_CoD_IO_Loop
;R39;R32		stc
;R39		or	bh,bh
		stc				;R32
;R39		jz	short G_CoD_IO_Exit
;R39		dec	bh
;R39		jmp	short G_CoD_IO_Loop

Got_Pattern:
;R32		call	Get_DRQ					;R00
;R32		jc	short G_CoD_IO_Exit			;R00
;R32		xor	ah,ah			;success
;R32		jmp	short @F
;R32Resend_Cmd:
;R32		or	ah,1			;Resend Command
;R32@@:
;R39		clc
;R39G_CoD_IO_Exit:
		pop	cx
		pop	bx
		ret
Get_CoD_IO	ENDP

;R34 start
;-------------------------------------------
;	Wait_Drq_Clear
;input  : None
;output : None
;-------------------------------------------
Wait_Drq_Clear:
		push	bx
		push	cx

		mov	dx,CDROM_port
		add	dx,7			;dx = 1X7h
		xor	bh,bh
		mov	cx,1000			;timer count
		mov	ax,800h			;wait for DRQ = 0
		call	WAIT_FOR_PORT
		call	CTLR_BUSY

		pop	cx
		pop	bx
		ret
;R34 end

;R32;R10 start
;R36 start
Wait_BSY:
		push	bx
		push	cx

		mov	dx,CDROM_port
		add	dx,7			;dx = 1X7h
		xor	bh,bh
;R39		mov	cx,3			;90 us
		mov	cx,4000			;R39 120 ms
		mov	ax,8080h
		call	WAIT_FOR_PORT

		pop	cx
		pop	bx
		ret
;R36 end
;R32;R10 end

;R32 start
ReadWrite_Action:

		mov	bh,BP_AL		;get R/W sectors change to word
		xor	bl,bl
Access_loop:
		mov	ah,3
		mov	al,INT13X_FLAG
		and	al,RW_Flag
		call	Get_CoD_IO
		jc	short RWA_Exit
		call	Get_DRQ
		jc	short RWA_Exit
		call	Get_Byte_Count		;SI = word count

		mov	ch,Start_Capt_Sec	;discard front garbare data
		xor	cl,cl
		call	Discard_Unuse_Data	;discard front garbare data
		mov	Start_Capt_Sec,0

		mov	cx,si
		sub	bx,si			;subtract total word
		jnc	short Capture_Start	;not final then jump
		add	cx,bx			;remain transfer data word
		xor	bx,bx			;indicate no more data
Capture_Start:
		pushf
		jcxz	short Transfer_Data_Done	;no more data then skip
		sub	si,cx			;subtract word count
		mov	dx,CDROM_port
		cli
		test	INT13X_FLAG,RW_Flag
		jnz	short Read_Data
		push	ds

		push	es
		pop	ds
		xchg	si,di
		rep	outsw			;write data
		xchg	di,si

		pop	ds
		jmp	short Transfer_Data_Done
Read_Data:
		rep	insw			;read data
Transfer_Data_Done:
		popf
		mov	cx,si
		call	Discard_Unuse_Data	;discard remain garbare data
;R33 start
;R33A		push	es
;R33A		push	bx
;R33A		push	di
;R33A		call	WAIT_INT
;R33A		pop	di
;R33A		pop	bx
;R33A		pop	es
		call	ATAPI_Wait_Int		;R33A
;R33 end
		or	bx,bx
;R34		jnz	short Access_loop	;R33
;R34 start
		jz	short Access_Over
		test	INT13X_FLAG,Sector_200b	;R39 Is sector 200h?
		jnz	Access_loop		;R39
		call	Wait_Drq_Clear
		jmp	short Access_loop
Access_Over:
;R34 end
		clc
RWA_Exit:
		ret

;R33A start
;-------------------------------------------
;-------------------------------------------
ATAPI_Wait_Int:
ifndef COMPILE_FOR_BTINT13X			;R41
		push	es
;R33B		push	ax
;R33B		push	bx
;R33B		push	di
		pusha				;R33B
		pushf
;R38 start
		mov	ax,SEG_0		;get vector segment
		mov	es,ax
		lea	di,HD_INT		;get IRQ14 vector
		cmp	CDROM_PORT,1f0h		;Is primary channel?
		je	short @F		;Yes,skip
		lea	di,INT77		;get IRQ15 vector
@@:
		cmp	es:[di+2],0f000h	;Is our vector?
		jne	short HD_int_Replaced	;No,skip and dont wait int
;R38 end
		sti
		call	WAIT_INT
HD_int_Replaced:				;R38
		popf
		popa				;R33B
;R33B		pop	di
;R33B		pop	bx
;R33B		pop	ax
		pop	es
endif ;COMPILE_FOR_BTINT13X			;R41
		ret
;R33A end

;-------------------------------------------
;input  : None
;output : SI = word count
;-------------------------------------------
Get_Byte_Count:
		mov	dx,CDROM_port
		add	dl,5			;port 1X5h
		in	al,dx			;get high byte
		newiodelay
		mov	ah,al			;store it
		dec	dx			;port 1X4h
		in	al,dx			;get high byte
		newiodelay
		shr	ax,1			;transfer to word unit
		mov	si,ax			;save it
		ret

;-------------------------------------------
;input  : CX = word count
;output : None
;-------------------------------------------
Discard_Unuse_Data:
		jcxz	short DUD_Ret		;count zero then skip
		test	INT13X_FLAG,Sector_200b	;Is sector 200h?
		jnz	short DUD_Ret		;Yes,skip
		sub	si,cx			;sub word count
		mov	dx,CDROM_port		;data port
		pushf
		cli
@@:
		in	ax,dx			;get data
		loop	@B
		popf
DUD_Ret:
		ret

;-------------------------------------------
;	Clear_CMD_Pkt_buffer
;input  : None
;output : None
;-------------------------------------------
Clear_CMD_Pkt_buffer:
		push	ax
		xor	ax,ax
		mov	CMD_Pkt_buffer.S_Length,ax
		mov	CMD_Pkt_buffer.CD_Reserved0,al
		mov	CMD_Pkt_buffer.CD_Reserved1,al
		mov	CMD_Pkt_buffer.CD_Reserved2,al
		mov	CMD_Pkt_buffer.CD_Reserved3,al
		mov	CMD_Pkt_buffer.CD_Reserved4,al
		pop	ax
		ret
;R32 end

endif ;ATAPI_COMMAND_SUPPORT

ifndef COMPILE_FOR_BTINT13X		;R41
ifdef Support_EDDS30						;R27A
;R27 - start
;=============================================================================
;Func	: Host_Bus_type
;input  : None
;output : CY = No found
;	  NC = found host bus   
;		al = function number
;		ah = device number	
;=============================================================================
public 	Host_Bus_type
Host_Bus_type		proc	near
		push	es
		pusha			;BH = Bus identification Number (0...255)
		xor	bx,bx		;BL = Device Number in upper 5 bits
		mov	es,bx		;     Function Number in lower 3 bits
Host_Bus_type_0:
		mov	ax,0b109h	;AH = PCI_FUNCTION_ID	(B1h)
					;AL = READ_CONFIG_WORD 	(09h)
		mov	di,0ah		;read class code
		int	01ah		;read PCI configure register
		jc	short not_found_host		
		cmp	cx,0101h	;test Mass storge controller &
					;IDE controller
		je	short Found_IDE_host
Host_Bus_type_1:
		inc	bl		;next function/decice number
		jnz	short	Host_Bus_type_0
		stc				;;;
		jmp	short not_found_host
Found_IDE_host:
		mov	ax,0b109h	;AH = PCI_FUNCTION_ID	(B1h)
					;AL = READ_CONFIG_WORD 	(09h)
		mov	di,04		;read command register
		int	01ah		;read PCI configure register
		jc	short not_found_host
		test	cx,1		;I/O access enable
		jz	short	Host_Bus_type_1
		mov	bh,bl
		and	bx,0F807H	;bl = function number
		shr	bh,3		;bh = device number
		mov	es,bx
		clc
not_found_host:
		popa
		mov	ax,es		;return value
		pop	es
		ret
Host_Bus_type	endp
;R27 - end
endif; Support_EDDS30						;R27A
endif ;COMPILE_FOR_BTINT13X		;R41

;R22;R01 start
;R22ifdef	Int13_Extensions
;R22		public	EXTEND_FUNC_MAX
;R22		public	EXTEND_FUNC
;R22		public	Get_DAP_Value
;R22Extend_Func:
;R22		DW	OFFSET	FUN41		;FUN41
;R22		DW	OFFSET	FUN42		;FUN42
;R22		DW	OFFSET	FUN43		;FUN43
;R22		DW	OFFSET	FUN44		;FUN44
;R22		DW	OFFSET	FUN45		;FUN45
;R22		DW	OFFSET	FUN46		;FUN46
;R22		DW	OFFSET	FUN47		;FUN47
;R22		DW	OFFSET	FUN48		;FUN48
;R22		DW	OFFSET	FUN49		;FUN49
;R22Extend_Func_MAX	EQU	($-offset Extend_Func)/2
;R22
;R22;[]------------------------------------------------------------------------[]
;R22;Function:   	Check for Extension support
;R22;Entry:  	INT 13h
;R22;Input:  	AH = 41h
;R22;		BX = 55AAh
;R22;               DL = Drive Number
;R22;Output: 	CF = 0 - operation successfully completed
;R22;		   AH - major version of extensions
;R22;		   AL - minor version of extensions
;R22;		   BX = 0AA55h
;R22;		   CX = Bits 15 to 2 - reserved (set to 0)
;R22;			Bits 1 = 0 - Removable-media control is not supported
;R22;			       = 1 - Removable-media control is supported
;R22;			Bits 0 = 0 - Extended disk access is not supported
;R22;			       = 1 - Extended disk access is supported
;R22;		CF = 1 - operation failed
;R22;		   AH - Status of operation
;R22;Description:
;R22;
;R22;[]------------------------------------------------------------------------[]
;R22FUN41:
;R22		cmp	word ptr +4[bp],55aah		;BX = 55aah?
;R22		jne	FUN10_2				;no,then return error
;R22		mov	word ptr +2[bp],2100h		;return AX
;R22		mov	word ptr +4[bp],0aa55h		;return BX
;R22;R18		mov	word ptr +6[bp],1		;return CX
;R22		mov	word ptr +6[bp],5		;return CX ;R18
;R22		jmp	GOOD_RET
;R22
;R22;[]------------------------------------------------------------------------[]
;R22;Function:   	Extended Read
;R22;Entry:  	INT 13h
;R22;Input:  	AH = 42h
;R22;               DL = Drive Number
;R22;		DS:SI = Disk-address packet
;R22;Output: 	CF = 0 - operation successfully completed
;R22;		     1 - operation failed
;R22;		   AH - Status of operation
;R22;Description:
;R22;
;R22;[]------------------------------------------------------------------------[]
;R22FUN42:
;R22		mov	HD_CMD,20h
;R22		jmp	cont_cmd
;R22
;R22;[]------------------------------------------------------------------------[]
;R22;Function:   	Extended Write
;R22;Entry:  	INT 13h
;R22;Input:  	AH = 43h
;R22;		AL = Bits 7 to 1 - reserved (set to 0)
;R22;		     Bit 0 = 0 - Write-verify off
;R22;		     	   = 1 - Write-verify on
;R22;               DL = Drive Number
;R22;		DS:SI = Disk-address packet
;R22;Output: 	CF = 0 - operation successfully completed
;R22;		CF = 1 - operation failed
;R22;		   AH - Status of operation
;R22;Description:
;R22;
;R22;[]------------------------------------------------------------------------[]
;R22FUN43:
;R22		mov	HD_CMD,30h
;R22		jmp	cont_cmd
;R22
;R22;[]------------------------------------------------------------------------[]
;R22;Function:   	Extended Verification
;R22;Entry:  	INT 13h
;R22;Input:  	AH = 44h
;R22;               DL = Drive Number
;R22;		DS:SI = Disk-address packet
;R22;Output: 	CF = 0 - operation successfully completed
;R22;		CF = 1 - operation failed
;R22;		   AH - Status of operation
;R22;Description:
;R22;
;R22;[]------------------------------------------------------------------------[]
;R22FUN44:
;R22		mov	HD_CMD,40h
;R22		jmp	cont_cmd
;R22
;R22;[]------------------------------------------------------------------------[]
;R22;Function:   	Lock/Unlock drive
;R22;Entry:  	INT 13h
;R22;Input:  	AH = 45h
;R22;               AL = 0 - Lock media in drive
;R22;                  = 1 - Unlock media in drive
;R22;                  = 2 - Return lock/unlock status
;R22;                  = 3 to 0ffh - reserved
;R22;               DL = Drive Number
;R22;Output: 	CF = 0 - operation successfully completed
;R22;		CF = 1 - operation failed
;R22;		   AH - Status of operation
;R22;		      =	1   - unsupported function or parameter
;R22;		      =	20h - general controller failure
;R22;		      =	80h - controller did not respond
;R22;		      =	B0h - media not locked in drive
;R22;		      =	B4h - lock count exceeded
;R22;		   AH - Lock/Unlock status
;R22;		      = 0 - drive is locked
;R22;		      = 1 - drive is unlocked
;R22;Description:
;R22;
;R22;[]------------------------------------------------------------------------[]
;R22FUN45:
;R22
;R22;[]------------------------------------------------------------------------[]
;R22;Function:   	Eject media from drive
;R22;Entry:  	INT 13h
;R22;Input:  	AH = 46h
;R22;               DL = Drive Number
;R22;Output: 	CF = 0 - operation successfully completed
;R22;		CF = 1 - operation failed
;R22;		   AH - Status of operation
;R22;		      =	1   - unsupported function or parameter
;R22;		      =	20h - general controller failure
;R22;		      =	80h - controller did not respond
;R22;		      =	B1h - media locked in drive
;R22;		      =	B2h - media not removable
;R22;		      =	B2h - media in use
;R22;		      =	B5h - valid eject request failed
;R22;Description:
;R22;
;R22;[]------------------------------------------------------------------------[]
;R22FUN46:
;R22		jmp	FUN10_2
;R22
;R22;[]------------------------------------------------------------------------[]
;R22;Function:   	Extended Seek
;R22;Entry:  	INT 13h
;R22;Input:  	AH = 47h
;R22;               DL = Drive Number
;R22;		DS:SI = Disk-address packet
;R22;Output: 	CF = 0 - operation successfully completed
;R22;		CF = 1 - operation failed
;R22;		   AH - Status of operation
;R22;Description:
;R22;
;R22;[]------------------------------------------------------------------------[]
;R22FUN47:
;R22		mov	HD_CMD,70h
;R22		jmp	cont_cmd
;R22
;R22;[]------------------------------------------------------------------------[]
;R22;Function:   	Extended Get Drive Parameters
;R22;Entry:  	INT 13h
;R22;Input:  	AH = 48h
;R22;               DL = Drive Number
;R22;		DS:SI = Disk-address packet
;R22;Output: 	CF = 0 - operation successfully completed
;R22;		CF = 1 - operation failed
;R22;		   AH - Status of operation
;R22;		DS:SI = Resulting buffer
;R22;Description:
;R22;
;R22;[]------------------------------------------------------------------------[]
;R22FUN48:
;R22	mov	si,+14[bp]
;R22	mov	ds,si
;R22	mov	si,+16[bp]
;R22;R18	mov	word ptr ds:[si],26		;buffer size
;R22;R18A	mov	word ptr ds:[si],30		;buffer size ;R18
;R22;R18A start
;R22	mov	ax,ds:[si]			;get buffer size
;R22	cmp	ax,26				;check buffer size
;R22	jae	short @F			;>= 26 then set parameter to buffer
;R22	mov	word ptr +2[BP],100h		;set status = bad command
;R22	jmp	AHDSK_ERROR_RET			;error return
;R22@@:
;R22	mov	word ptr ds:[si],26		;set buffer size = 26
;R22	cmp	ax,30				;check buffer size
;R22	jb	short @F			;< 26 then set parameter to buffer
;R22	mov	word ptr ds:[si],30		;set buffer size = 30
;R22@@:
;R22;R18A end
;R22	mov	word ptr ds:[si+2],00000010b	;information flags
;R22
;R22	mov	dx,2
;R22	mov	cl,14
;R22ifndef ExtInt13_LBA				;R01B
;R22	call	Detect_LBA_Mode
;R22	jne	short @F
;R22	mov	dx,90bh
;R22	mov	cl,4
;R22@@:
;R22endif ;ExtInt13_LBA				;R01B
;R22	xor	eax,eax
;R22	mov	al,dl
;R22	mov	dl,DRIVE
;R22	CALL	GETHPARM			;get heads
;R22	mov	ds:[si+8],eax			;store to buffer
;R22	mov	ch,al
;R22
;R22	mov	al,cl
;R22	CALL	GETHPARM			;get sectors
;R22	mov	ds:[si+0ch],eax			;store to buffer
;R22	mov	cl,al
;R22
;R22	mov	al,dh
;R22	CALL	GETHPARM			;get cylinders
;R22	mov	ds:[si+4],eax			;store to buffer
;R22	xchg	ax,cx
;R22	mul	ah
;R22	mul	cx
;R22	mov	word ptr ds:[si+16],ax
;R22	mov	word ptr ds:[si+18],dx
;R22	mov	word ptr ds:[si+20],0		;set high dword = 0
;R22	mov	word ptr ds:[si+22],0
;R22	mov	word ptr ds:[si+24],200h	;bytes in a sectors
;R22;R18 - start
;R22	cmp	word ptr ds:[si],30		;R18A check buffer size = 30?
;R22	jb	short @F			;R18A if< 30 then skip
;R22	movzx	dx,DRIVE
;R22	shl	dl,4
;R22	add	dx,offset cs:FDPTE_Drive0	;get FDPTE address	
;R22	mov	word ptr ds:[si+26],dx		;save FDPTE offset
;R22	mov	word ptr ds:[si+28],0f000h	;save segment
;R22@@:						;R18A
;R22;R18 - end
;R22
;R22	mov	byte ptr +3[BP],0		;no error return
;R22	jmp	GOOD_RET
;R22
;R22;[]------------------------------------------------------------------------[]
;R22;Function:   	Extended Disk-Change status
;R22;Entry:  	INT 13h
;R22;Input:  	AH = 49h
;R22;               DL = Drive Number
;R22;Output: 	CF = 0 - operation successfully completed
;R22;		CF = 1 - operation failed
;R22;		   AH = 0 - 'Change' line is inactive
;R22;		      =	1 - 'Change' line is active
;R22;Description:
;R22;
;R22;[]------------------------------------------------------------------------[]
;R22FUN49:
;R22		jmp	FUN10_2
;R22
;R22Get_DAP_Value:
;R22;R01A		cmp	byte ptr FUNC_CMD,41h		;function call(AH) below 41h
;R22;R01A		jb	short @F			;Yes,standard call
;R22		push	ds
;R22		push	si
;R22		mov	si,+14[bp]
;R22		mov	ds,si
;R22		mov	si,+16[bp]
;R22		mov	eax,dword ptr ds:[si][bx]
;R22		pop	si
;R22		pop	ds
;R22		clc
;R22;R01A @@:
;R22		ret
;R22endif	;Int13_Extensions
;R22;R01 end
;R22;R18 - start
;R22		align 	16
;R22FDPTE_Drive0	db	16 dup(0)
;R22FDPTE_Drive1	db	16 dup(0)
;R22FDPTE_Drive2	db	16 dup(0)
;R22FDPTE_Drive3	db	16 dup(0)
;R22;R18 - end
FCODE   ENDS
END 

