;[x] 18/12/2023. добавление/допиливание API CD-ROM (ATAPI)
;██████████████████████████████████████████████████████████████████████████
;CD ROM DRIVE DRIVER
;---------------------------------------------------------------
;Rev	Date	   Name	Description
;---------------------------------------------------------------
;	02-08-2001 DNS	Initial this module
;---------------------------------------------------------------
;========================================================

;!TODO ;!TODO ;!TODO ;!TODO ;!TODO ;!TODO ;!TODO ;!TODO ;!TODO ;!TODO ;!TODO ;!TODO 
;
;	[ ] установка параметра максимального размера для чтения через DRV_SET_PAR
;
;----------------------------------------------------------------------------------
MAX_ATAPI_SEC_SIZE			EQU	4096/2
PACKET_SIZE				EQU	12	; !FIXIT брать из IDENTIFY PACKET DEVICE
RAM_ATAPI_PK 				EQU	SYS_PAGE.SHARED_BUFFER_32b
RAM_ATAPI_RW_CMD			EQU	SYS_PAGE.SHARED_BUFFER_32b+16
MAX_DATA_PACKET_FOR_REQUEST_SENSE	EQU	254

	ASSERT ((PACKET_SIZE % 4) = 0), "PACKET_SIZE must be an even number"

;[]================================================================[#51]
;!FIXIT сделать настоящий ресет
ATAPI_5x_RESET:	LD	C,IDE.Device.ATAPI
		CALL	SELECT_DRIVE
		RET	C
		LD	B,50
.loop:		PUSH	BC
		CALL	EXEC_TEST_CMD
		;!FIXIT ;[ ] sector size. сделать реинит HDD_INIT_TABLE
		POP	BC
		RET	NC
		;
		CALL	ATAPI_CHECK_MEDIA_CHANGED.noWait
		RET	C
		;
		EI 
		HALT 
		DJNZ  .loop
		RET 
;[]================================================================[#51]


;[]================================================================[#58]
;Function: Get Current Media Parameters
;	A - Disk
;Return:
;	H - Heads			; [ ] For ATAPI HL:DE - media size in sectors
;	L - Sectors per cylinder	;
;      DE - Cylinders			;
;      IX - Capacity sector in bytes
;	B - Flags: MASTER/SLAVE, LBA/CHS
; [ ]	A - HDD_INIT_TABLE.MediaParameters
;	IF media changed
; [ ]	CF' = 1, A' = error number UnitAttention
ATAPI_5x_GET_PAR:
		LD	C,IDE.Device.ATAPI
		CALL	SELECT_DRIVE
		RET	C
		;
.DriveSelected:	IN	A,(SLOT3)
		AND	A
		PUSH	AF
		EX	AF,AF'
		 LD	A,SYS_PAGE
		 OUT	(SLOT3),A
		 ;
		 ; [ ] sector size. media changed
		  CALL	ATAPI_CHECK_MEDIA_CHANGED
		  EX	AF,AF'
		   POP	AF
		  EX	AF,AF'
		  JR	NC,.get_data
		  ;
		  CP	BIOS.Error.ATAPI.UnitAttention
		  JR	Z,.UnitAttention
		  ;
		  ;CP	BIOS.Error.ATAPI.NotReady
		  ;SCF
		  ;RET	NZ
		  EX	AF,AF'
		   OUT	(SLOT3),A
		  EX	AF,AF
		  LD	HL,#FFFF
		  LD	D,H
		  LD	E,L
		  SCF
		  RET
		  ;
.UnitAttention:	  RES	1,(IY + IDE.HDD_INIT_TABLE.MediaParameters)	; [ ] removable media
		  EX	AF,AF'
		   SCF
		  EX	AF,AF'
.get_data:	 ;
		 LD	A,(IY+IDE.HDD_INIT_TABLE.MediaParameters)
		 LD	B,(IY+IDE.HDD_INIT_TABLE.DRV_Flags)
		 ; [ ] sector size
		 LD	E,(IY+IDE.HDD_INIT_TABLE.SectorSize)
		 LD	D,(IY+IDE.HDD_INIT_TABLE.SectorSize + 1)
		 LD	XL,E
		 LD	XH,D
		 ; [ ] media size
		 LD	L,(IY+IDE.HDD_INIT_TABLE.MediaSizeHigh)
		 LD	H,(IY+IDE.HDD_INIT_TABLE.MediaSizeHigh+1)
		 LD	E,(IY+IDE.HDD_INIT_TABLE.MediaSizeLow)
		 LD	D,(IY+IDE.HDD_INIT_TABLE.MediaSizeLow+1)
		;
		EX	AF,AF'
		 OUT	(SLOT3),A
		 LD	A,BIOS.Error.ATAPI.UnitAttention	; если CF, то номер ошибки
		EX	AF,AF
		RET 
;[]================================================================[#58]

;!TODO
; atapi.pdf стр. 24 запись/чтение могут быть максимальными блоками в несколько заходов
;[]================================================================[#55]
;Function: Read	Sectors
;	A - Disk
;   HL:IX - Sector
;      DE - Address
;	B - Sector counter
;Return:
;   HL:IX - Sector + Sector counter
;      DE - Address + (Sector counter *	Size sector)
;READ SECTOR(S)
ATAPI_5x_READ:	EX	AF,AF'
		 IN	A,(SLOT3)
		EX	AF,AF'
;[]================================================================[#52]
;Function: Long	Read Sectors
;	A - Disk
;   HL:IX - Sector
;      DE - Address
;	B - Sector counter
;	A'- Memory Page Number
;Return:
;   HL:IX - Sector + Sector counter
;      DE - Address + (Sector counter *	Size sector)
;LONG READ SECTOR(S)
ATAPI_5x_LONG_READ:
		AND	A
		;
		PUSH	IY
		SAFE_PORTY_2
		PUSH	BC
		PUSH	IX
		PUSH	HL
		;
		 EX	AF,AF'
		  AND	A	;read
		 EX	AF,AF'
		CALL	RW_ATAPI_SECTORs
		; [ ] sector size. media changed
		 JP	ATA_5x_LONG_READ.shared
		;  JP	NC,ATA_5x_LONG_READ.shared
		;  CP	BIOS.Error.UnitAttention
		;  JR	Z,ATAPI_MEDIA_ERROR
		;  SCF
;[]================================================================[#52]
; INPUT:
;	A - Disk
;   HL:IX - Sector
;      DE - Address
;	B - Sector counter
;	A'- Memory Page Number
;	CF'=1 - write, CF'=0 - read
;
; OUTPUT:
;	
RW_ATAPI_SECTORs:
		LD	C,IDE.Device.ATAPI
		CALL	SELECT_DRIVE
		RET	C
		;
		EXX
		 LD	C,SLOT3
		 IN	B,(C)
		 PUSH	BC
		 LD	A,SYS_PAGE
		 OUT	(C),A
		 ; [ ] media change
		  LD	A,(IY + IDE.HDD_INIT_TABLE.MediaParameters)
		  AND	%0000'0010
		  JR	NZ,.error_media
		 ;
		 LD	HL,ATAPI_CMD_PACKET.READ
		 EX	AF,AF'
		  JR	NC,.read_cmd
		  LD	HL,ATAPI_CMD_PACKET.WRITE
.read_cmd:	 EX	AF,AF'	 
		 LD	DE,RAM_ATAPI_RW_CMD
		 LD	BC,PACKET_SIZE
		 LDIR
		EXX
		;
		LD	A,H
		LD	H,L
		LD	L,A
		LD	(RAM_ATAPI_RW_CMD + ATAPI_PACKET.SECTOR+0),HL
		LD	A,XH
		LD	(RAM_ATAPI_RW_CMD + ATAPI_PACKET.SECTOR+2),A	;R01
		LD	A,XL
		LD	(RAM_ATAPI_RW_CMD + ATAPI_PACKET.SECTOR+3),A	;R01
		LD	A,B
		LD	(RAM_ATAPI_RW_CMD + ATAPI_PACKET.COUNTER+1),A	;R01
		;
		; EX	AF,AF'
		; OUT	(SLOT3),A
		;
		; POP	AF
		; OUT	(SLOT3),A
		LD	HL,RAM_ATAPI_RW_CMD
		CALL	EXEC_PACKET_COMMAND.start
		;
.exit:		POP	BC
		;LD	C,SLOT3
		OUT	(C),B
		RET
		;
.error_media:	EXX
		LD	A,BIOS.Error.ATAPI.UnitAttention
		SCF
		JR	.exit

;[]===========================================================[#52, #55]

;[]================================================================[#56]
;Function: Write Sectors
;	A - Disk
;   HL:IX - Sector
;      DE - Address
;	B - Sector counter
;Return:
;   HL:IX - Sector + Sector counter
;      DE - Address + (Sector counter *	Size sector)
;WRITE SECTOR(S)
ATAPI_5x_WRITE:	EX	AF,AF'
		 IN	A,(SLOT3)
		EX	AF,AF'
;[]================================================================[#53]
;Function: Long	Write Sectors
;	A - Disk
;   HL:IX - Sector
;      DE - Address
;	B - Sector counter
;	A'- Memory Page Number
;Return:
;   HL:IX - Sector + Sector counter
;      DE - Address + (Sector counter *	Size sector)
;WRITE SECTOR(S)
ATAPI_5x_LONG_WRITE:
		AND	A
		;
		PUSH	IY
		SAFE_PORTY_2
		PUSH	BC
		PUSH	IX
		PUSH	HL
		;
		 EX	AF,AF'
		  SCF		;write
		 EX	AF,AF'
		 CALL	RW_ATAPI_SECTORs
		;
		JP	ATA_5x_LONG_READ.shared

;[]================================================================[#57]
;Function: Detect Disk
;	   A - Disk
;Return:   CF=0 - A=Drive type 
;		  B=MediaParameters byte ; [ ] media change
;	   CF=1 - drive not present, A=#02
; ATAPI_5x_DETECT:	LD	C,IDE.Device.ATAPI
; 		AND	%1011'1111
; .shared:	LD	D,A
; 		LD	E,C
; 		PUSH	DE
; 		CALL	DRV_DETECT
; 		POP	DE
; 		RET	C
; 		;
; 		PUSH	AF
; 		LD	C,SLOT3
; 		IN	B,(C)
; 		LD	A,SYS_PAGE
; 		OUT	(C),A
; 		INC	HL			;!HARDCODE HDD_INIT_TABLE
; 		INC	HL
; 		INC	HL
; 		LD	A,(HL)
; 		OUT	(C),B
; 		LD	B,A
; 		AND	%0000'0011	;[ ] media change переделать логику тут и в ДСС? ; !FIXIT
; 		JR	NZ,.error
; 		;
; .exit:		POP	AF
; 		RET
; 		;
; .error:		AND	%0000'0010
; 		JR	NZ,.UnitAttention
; 		;
; 		LD	A,D
; 		LD	C,E
; 		CALL	SELECT_DRIVE
; 		CALL	ATAPI_CHECK_MEDIA_CHANGED
; 		JR	NC,.exit
; 		POP	BC
; 		RET
; 		;
; .UnitAttention:	POP	AF
; 		LD	A,BIOS.Error.ATAPI.UnitAttention
; 		SCF
; 		RET
;[]================================================================[#57]
;[]================================================================[#57]
;Function: Detect Disk
;	   A - Disk
;Return:   CF=0 - A=Drive type 
;		  B=MediaParameters byte ; [ ] media change
;	   CF=1 - drive not present, A=#02
ATAPI_5x_DETECT:
		LD	C,IDE.Device.ATAPI
		JP	ATA_5x_DETECT.shared
;[]================================================================[#57]

;[]================================================================[#5E]
; [ ]
;Function: Extended
;	   A - Disk
;	   B - SubFunction
;Return:   
;	   
ATAPI_5x_Extended:
	LD	C,IDE.Device.ATAPI
	CALL	SELECT_DRIVE
	RET	C
	;
	LD	A,B
	CP	2
	JR	C,TRAY_FN		; B = 0 или 1
	;
	JR	Z,ATAPI_REQUEST_SENSE	; B = 2
	; ...
	; ...
	;LD	A,#AA
	LD	A,BIOS.Error.InvalidSubFunction
	SCF
	RET
;[]================================================================[#5E]

;----------------------------------------------------------------------;!TODO сделать доступной через расширенную функцию API
; вход:	DE - адрес для данных
ATAPI_REQUEST_SENSE:
		LD	HL,ATAPI_CMD_PACKET.REQUEST_SENSE
		JR	EXEC_PACKET_COMMAND.start
;----------------------------------------------------------------------;

;[ ] media changed
;----------------------------------------------------------------------;
ATAPI_CHECK_MEDIA_CHANGED:
		CALL	EXEC_TEST_CMD	;!FIXIT а может и не надо
		RET	C
; .skip_nop:	EXX
; 		 CALL	ATAPI_WAITPRT
; 		EXX
; 		LD	A, high IDE.Read.Status
; 		IN	A,(low IDE.Read.Status)
; 		RRA
; 		;RET	NC
		;JR	C,.noWait
		;
		EXX
		 LD	C,SLOT3
		 IN	B,(C)
		 LD	A,SYS_PAGE
		 OUT	(C),A
		 ;
		 LD	A,(IY + IDE.HDD_INIT_TABLE.MediaParameters)
		 OUT	(C),B
		EXX
		RRA
		RRA
		LD	A,BIOS.Error.ATAPI.UnitAttention
		RET
		;
.noWait:	EXX
		 ;CALL	ATAPI_GET_ERROR
		 XOR	A			;LD	BC,IDE.Read.Error
		 IN	A,(IDE.Read.Error)	;IN	A,(C)
		 RRCA 
		 RRCA 
		 RRCA 
		 RRCA 
		 AND	#0F
		 OR	#70
		EXX
		CP	BIOS.Error.ATAPI.NoSence
		JP	Z,ATAPI_MEDIA_ERROR
		; !FIXIT скорее всего железо тут выдаст всегда Error.ATAPI.NoSence
		 CP	BIOS.Error.ATAPI.NotReady
		 JP	Z,ATAPI_MEDIA_ERROR
		 CP	BIOS.Error.ATAPI.UnitAttention
		 JP	Z,ATAPI_MEDIA_ERROR
		;
		SCF
		RET
;----------------------------------------------------------------------;

;----------------------------------------------------------------------;
TRAY_FN:	LD	HL,ATAPI_CMD_PACKET.CLOSE
		LD	DE,0	; маркер того, что не нужно читать с устройства в ОЗУ
		DEC	A
		JR	Z,EXEC_PACKET_COMMAND.start
		LD	HL,ATAPI_CMD_PACKET.OPEN
		;JR	EXEC_PACKET_COMMAND
		
; INPUT:  HL - AP packet (12bytes)
;	  DE - address for/with data if needed
;
; RETURN: CF - ERROR
;	!TODO CD ERRORS to INCLUDES
;	 #01 - RECOVERED ERROR
;	 #02 - NOT READY
;	 #03 - MEDIUM ERROR
;	 #04 - HARDWARE	ERROR
;	 #05 - ILLEGAL REQUEST
;	 #06 - UNIT ATTETION
;	 #07 - DATA PROTECT
;	 #0B - ABORTED COMMAND
;	 #80 - TIME OUT
EXEC_PACKET_COMMAND:
.error:		CP	#FF
.error_fail:	SCF
		LD	A,BIOS.Error.Failure
		RET	Z
		;
		LD	A,BIOS.Error.Busy
		RET
		;
.error_TimeOut:	CP	#FF
		JR	Z,.error_fail
		LD	A,BIOS.Error.ATAPI.TimeOut
		SCF
		RET
; .CMD_ERROR:	 CALL	ATAPI_GET_ERROR
; 		 OR	#70
; 		 CP	BIOS.Error.UnitAttention
; 		 CALL	Z,ATAPI_MEDIA_ERROR
; 		 ;LD	BC,IDE.Read.Error	;ERROR
; 		 ;IN	A,(C)
; 		 ;RRCA 
; 		 ;RRCA 
; 		 ;RRCA 
; 		 ;RRCA 
; 		 ;AND	#0F
; 		SCF 
; 		RET
		;
.start:		EXX 
		 CALL	ATAPI_WAITPRT
		EXX 
		JR	NC,.READY
		;
.reset:		LD	BC,IDE.Write.Command
		LD	A,IDE.ATAPI.Reset
		OUT	(C),A
		;
		LD	B,#80
.pause:		DJNZ	.pause
		;
		EXX 
		 CALL	ATAPI_WAITPRT
		EXX
		JR	C,.error
		;
.READY:		LD	C,SLOT3
		IN	B,(C)
		PUSH	DE
		PUSH	BC
		;
		LD	A,SYS_PAGE
		OUT	(C),A
		LD	DE,RAM_ATAPI_PK	;!FIXIT может на стеке выделять место?
		LD	BC,PACKET_SIZE
		LDIR
		;
		POP	BC
		POP	DE
		OUT	(C),B
		;
		XOR	A
		EXX
		 LD	BC,IDE.Write.Features
		 OUT	(C),A
		 LD	DE,MAX_ATAPI_SEC_SIZE	;SIZE BLOCK	;!HARDCODE доставать из переменной какой-нибудь
		 LD	BC,IDE.Write.ByteCountLow
		 OUT	(C),E
		 LD	BC,IDE.Write.ByteCountHigh
		 OUT	(C),D
		 LD	BC,IDE.Write.Command
		 LD	A,IDE.ATAPI.Packet
		 OUT	(C),A
		 CALL	ATAPI_WAITPRT
		EXX 
		JR	C,.error
		;
		EXX 
		 LD	DE,256*(IDE.CtrlByte.DataRequest+IDE.CtrlByte.Error)+IDE.CtrlByte.DataRequest
		 CALL	ATAPI_WAITPRT.Custom
		EXX 
		JR	C,.error_TimeOut
		;
		; EXEC ATAPI PACKET COMMAND
.YEP_DRQ:	LD	C,SLOT3
		IN	B,(C)
		PUSH	BC
		LD	A,SYS_PAGE
		OUT	(SLOT3),A
		LD	HL,RAM_ATAPI_PK
		LD	BC,IDE.Write.Data
		LD	A,PACKET_SIZE/4	; !FIXIT брать из IDENTIFY PACKET DEVICE
.OUTPKT:	OUTI 
		OUTI
		OUTI
		OUTI
		DEC	A
		JR	NZ,.OUTPKT
		;
		POP	BC
		OUT	(C),B
		;
		LD	B,#80
.pause2: 	DJNZ	.pause2
		;
		EX	AF,AF'
		 LD	XH,A	; страница для R/W_LONG
		 LD	XL,0
		EX	AF,AF'
		;
		EX	DE,HL
.AP_LOOP:	EX	DE,HL
		IN	A,(SLOT3)
		EX	AF,AF'		;>-----------> \
		;
		EXX 
		 CALL	ATAPI_WAITPRT
		EXX 
		JP	C,.error
		; [ ] media change. а надо ли тут? ;!FIXIT лучше блокировать носитель
		LD	A,high IDE.Read.Status
		IN	A,(low IDE.Read.Status)
		;
		AND	IDE.CtrlByte.DataRequest + IDE.CtrlByte.Error
		RET	Z	;NO DATA REQUEST. A = 0: BIOS.Error.NoErrors
		RRA		; Checking IDE.CtrlByte.CheckCondition
		JP	C,ATAPI_CHECK_MEDIA_CHANGED.noWait
	;
	;====== IF DATA REQUEST =======================================;
	;
		LD	A,XH
		OUT	(SLOT3),A
		EX	DE,HL
		LD	BC,IDE.Read.ByteCountLow
		IN	E,(C)
		INC	C	;LD BC,IDE.Read.ByteCountHigh
		IN	D,(C)	;TRANSFER BLOCK	SIZE
		;
		LD	A,D
		OR	E
		RET	Z	;BLOCK = 0
		;
		; уменьшаем счётчик загружаемых байтов в 2 раза. Читаем по 2 байта
		SRL	D
		RR	E
		;
		LD	BC,IDE.Read.InterruptReason
		IN	A,(C)
		AND	IDE.InterruptReasonByte.IO
		LD	BC,IDE.Read.Data
		JR	Z,.WRITE_DATA
	;READ
		; проверка на тупость кодера
		; CF=0
		; ADC	HL,DE
		; JR	Z,.good_buffer
		; JR	C,.error_buffer
		;
; .good_buffer:	AND	A
; 		SBC	HL,DE

.read_loop:	INI 
		INI 
		DEC	DE
		LD	A,D
		OR	E
		JR	NZ,.read_loop
		;
.return_rw:	INC	XL		;INC LOADED SECTORS
		EX	AF,AF'		;<-----------< /
		OUT	(SLOT3),A
		;
		LD	A,H
		OR	L
		JR	NZ,.AP_LOOP
		; next page in mem block
		LD	HL,#C000
		IN	A,(SLOT3)
		EX	AF,AF'		;>-----------> \
		 LD	A,SYS_PAGE
		 OUT	(SLOT3),A
		 LD	D,high SYS_PAGE.RAM_TABLE
		 LD	E,XH
		 LD	A,(DE)
		 LD	XH,A
		EX	AF,AF'		;<-----------< /
		OUT	(SLOT3),A
		JR	.AP_LOOP
	;WRITE
.WRITE_DATA:	INC	B ; LD	BC,IDE.Write.Data
.write_loop:	OUTI 
		OUTI 
		DEC	DE
		LD	A,D
		OR	E
		JR	NZ,.write_loop
		JR	.return_rw
		;
; !TODO	холостое чтение
; .error_buffer:	AND	A
; 		SBC	HL,DE
;.NULL:		
;.RD_N_CD:	IN	A,(C)
; 		DEC	B
; 		IN	A,(C)
; 		DEC	B
; 		DEC	DE
; 		DEC	DE
; 		LD	A,D
; 		OR	E
; 		JR	NZ,.RD_N_CD
; 		; DE = 0
; 		JR	.AP_LOOP
;----------------------------------------------------------------------;


;----------------------------------------------------------------------;
; ATAPI_GET_ERROR:	XOR	A			;LD	BC,IDE.Read.Error
; 		IN	A,(IDE.Read.Error)	;IN	A,(C)
; 		RRCA 
; 		RRCA 
; 		RRCA 
; 		RRCA 
; 		AND	#0F
; 		RET
;----------------------------------------------------------------------;



;----------------------------------------------------------------------;
; D - MASK, E - PATTERN
ATAPI_WAITPRT:	LD	DE,256*IDE.CtrlByte.Busy + 0
.Custom:	LD	B,100
		LD	HL,#0000
.LOOP:		LD	A,high IDE.Read.Status
		IN	A,(low IDE.Read.Status)
		CP	#FF
		JR	Z,.error
		AND	D
		CP	E
		;
		RET	Z
		;
.NEXT_TRY:	DEC	L
		JR	NZ,.LOOP
		DEC	H
		JR	NZ,.LOOP
		DJNZ	.LOOP
.error:		SCF 
		RET
;----------------------------------------------------------------------;


;----------------------------------------------------------------------;
; ATAPI_TEST:	LD	HL,ATAPI_CMD_PACKET.TEST_UNIT_READY
; 		LD	DE,0	; маркер того, что не нужно читать с устройства в ОЗУ
; 		JP	EXEC_PACKET_COMMAND
;----------------------------------------------------------------------;


;----------------------------------------------------------------------;
ATAPI_MEDIA_ERROR:
		IN	A,(SLOT3)
		PUSH	AF
		LD	A,SYS_PAGE
		OUT	(SLOT3),A
		;
		LD	DE,SYS_PAGE.SHARED_BUFFER_256b
		CALL	ATAPI_REQUEST_SENSE
		;
		LD	A,(SYS_PAGE.SHARED_BUFFER_256b + 2)		; SenceKey. 06 - UNIT ATTENTION
		CP	2						; SenceKey. 02 - NOT READY
		JR	Z,.Not_Ready
		CP	6
		JR	NZ,.unkn_error
		;
		LD	A,(SYS_PAGE.SHARED_BUFFER_256b + 12)		; AdditionalSenceKey. #28
		CP	#28		
		JR	NZ,.unkn_error
		;
		LD	A,(SYS_PAGE.SHARED_BUFFER_256b + 13)		; AdditionalSenseCodeQualifier. 0
		AND	A
		JR	NZ,.unkn_error
		;
		LD	A,(IY + IDE.HDD_INIT_TABLE.MediaParameters)
		OR	%0000'0011
		LD	(IY + IDE.HDD_INIT_TABLE.MediaParameters),A
		;
		LD	HL,ATAPI_CMD_PACKET.READ_CAPACITY_DATA
		LD	DE,SYS_PAGE.TMP_BUFFER
		CALL	EXEC_PACKET_COMMAND.start
		LD	HL,#FFFF
		LD	C,BIOS.Error.ATAPI.MediumError
		JR	C,.No_Media
		;
		 LD	HL,(SYS_PAGE.TMP_BUFFER)	; media size high
		 LD	(IY+IDE.HDD_INIT_TABLE.MediaSizeHigh),H
		 LD	(IY+IDE.HDD_INIT_TABLE.MediaSizeHigh+1),L
		 LD	HL,(SYS_PAGE.TMP_BUFFER + 2)	; media size low
		 LD	(IY+IDE.HDD_INIT_TABLE.MediaSizeLow),H
		 LD	(IY+IDE.HDD_INIT_TABLE.MediaSizeLow+1),L
		 LD	HL,(SYS_PAGE.TMP_BUFFER + 6)	; sector size
		;
		LD	C,BIOS.Error.ATAPI.UnitAttention
.No_Media:	LD	(IY+IDE.HDD_INIT_TABLE.SectorSize),H			;[ ] sector size
		LD	(IY+IDE.HDD_INIT_TABLE.SectorSize + 1),L		
		;
.exit:		POP	AF
		OUT	(SLOT3),A
		LD	A,C
		SCF
		RET
		;
.Not_Ready:	LD	A,(SYS_PAGE.SHARED_BUFFER_256b + 12)		; AdditionalSenceKey
		LD	C,BIOS.Error.ATAPI.MediumError			; нет носителя
		CP	4
		JR	NZ,.exit
		; [ ]  !(test for ZIP)
		 LD	A,(SYS_PAGE.SHARED_BUFFER_256b + 13)		; AdditionalSenseCodeQualifier
		 CP	1
		 JR	NZ,.exit
		;
		; идёт инициализация
		LD	C,BIOS.Error.ATAPI.NotReady
		JR	.exit
		;
.unkn_error:	LD	C,BIOS.Error.ATAPI.MediumError	
		JR	.exit
;----------------------------------------------------------------------;

; !!! SELECT_DRIVE должен отработать заранее
EXEC_TEST_CMD:	LD	HL,ATAPI_CMD_PACKET.TEST_UNIT_READY
		LD	DE,0	; маркер того, что не нужно читать с устройства в ОЗУ
		JP	EXEC_PACKET_COMMAND.start

////////////////////////////////////////////////////////////////////////
ATAPI_CMD_PACKET:
.TEST_UNIT_READY:	DUP	12
			 DB	#00
			EDUP
;
.OPEN:			DB	#1B
			DB	#00,#00,#00
			DB	#02
			DB	#00,#00,#00,#00,#00,#00,#00
;
.CLOSE:			DB	#1B
			DB	#00,#00,#00
			DB	#03
			DB	#00,#00,#00,#00,#00,#00,#00
;
.READ:			DB	#28,#00
			DB	#00,#00,#00,#00	; sector dword
			DB	#00
			DB	#00,#01,#00,#00	; counter dword
			DB	#00
;
.WRITE:			DB	#2E,#00
			DB	#00,#00,#00,#00	; sector dword
			DB	#00
			DB	#00,#01,#00,#00	; counter dword
			DB	#00
;
.READ_CAPACITY_DATA:	DB	#25
			BLOCK	11,0
;
.REQUEST_SENSE:		DB	#03
			DB	#00,#00,#00
			DB	MAX_DATA_PACKET_FOR_REQUEST_SENSE
			DB	#00,#00,#00,#00,#00,#00,#00
;

ATAPI_PACKET:
.SECTOR		EQU	2
.COUNTER	EQU	7
////////////////////////////////////////////////////////////////////////
;
; E - Second * 10
; PAUSE		LD	HL,#0000
; PAUSE1	DEC	L
; 		JR	NZ,PAUSE1
; 		DEC	H
; 		JR	NZ,PAUSE1
; 		DEC	E
; 		JR	NZ,PAUSE1
; 		RET 
;
/*
Если ловится ошибка media changed, то биос должен выставлять в HDD_INIT_TABLE.MediaParameters = 3
и затирать FF SectorSize.
Дос после получения такой ошибки должен вызывать BIOS.DRV_DETECT и если всё ОК, то ReScanDRV
*/