;[BEGIN]
;//MODULE: AUTOIDE
;//CREATE: 27-07-2001	AUTHOR:	Denis Parinov
;-----------------------------------------------------------------------
;Rev	Date	   Name	 Description
;-----------------------------------------------------------------------
;R02 	17.08.2023  BAO	 New AUTODETECT ATA/ATAPI procedure 
;R01	01.08.2001  DNS	 FIX BUG INT "SELECT_IDE"
;R00	24.07.2001  DNS	 ADD SECONDARY IDE
;	24.07.2001  DNS	 INITIAL NEW VERSION 2.48
;=======================================================================

;	MODULE AUTOIDE
/*
;Write
HDW_3F7		EQU	#4155					;3F7H Command
HDW_3F6		EQU	#4154					;3F6H Device Control
;Read
HDR_3F7		EQU	#4055					;3F7H Drive Address
HDR_3F6		EQU	#4054					;3F6H Alt. Status

;Write
IDE.Write.Command		EQU	#4153					; #1F7 Command
HDW_DRV		EQU	#4152					; #1F6 Drive Control

HDW_CLH		EQU	#0155					; #1F5 Cylinder High
HDW_CLL		EQU	#0154					; #1F4 Cylinder Low
HDW_SEC		EQU	#0153					; #1F3 Sector
HDW_CNT		EQU	#0152					; #1F2 Counter
HDW_ERR		EQU	#0151					; #1F1 Error
HDW_DAT		EQU	#0150					; #1F0 Data

;Read
HDR_CTL		EQU	#4053					; #1F7 Status (Control)
HDR_DRV		EQU	#4052					; #1F6 Drive Control

HDR_CLH		EQU	#0055					; #1F5 Cylinder High
HDR_CLL		EQU	#0054					; #1F4 Cylinder Low
HDR_SEC		EQU	#0053					; #1F3 Sector
HDR_CNT		EQU	#0052					; #1F2 Counter
HDR_ERR		EQU	#0051					; #1F1 Error
HDR_DAT		EQU	#0050					; #1F0 Data

;Bits for HDR_CTL
;---[]
BSY			EQU	7
RDY			EQU	6
DRQ			EQU	3
ERR			EQU	0
;---[]

HDD			EQU	1
CDROM		EQU	2


;EQU FOR IY+
;---[]
DRVHD_H		EQU	0
SC_PT_H		EQU	1
IDE.HDD_INIT_TABLE.HeadsNumber		EQU	2
CYL_L_H		EQU	3
CYL_H_H		EQU	4
SPCLL_H		EQU	5
SPCLH_H		EQU	6
DTYPE_H		EQU	7
;---[]
;-------[ ;!!!!! hardcoded table]-------
IDE0		EQU	#C1C0
IDE1		EQU	#C1C8
IDE2		EQU	#C1D0
IDE3		EQU	#C1D8
;---------------------------------------
*/

;IDE0	 DB	 #FF	 ;DRIVE/HEAD REGISTER	      ;00
;	 DB	 #FF	 ;SECTORS PER TRACK	      ;01
;	 DB	 #FF	 ;HEADS			      ;02
;	 DB	 #FF	 ;CYLINDERS LOW		      ;03
;	 DB	 #FF	 ;CYLINDERS HIGH	      ;04
;	 DB	 #FF	 ;SECTOR PER CYLINDER LOW     ;05
;	 DB	 #FF	 ;SECTOR PER CYLINDER HIGH    ;06
;	 DB	 #FF	 ;DEVICE TYPE		      ;07

;IDE1	 DB	 #FF	 ;DRIVE/HEAD REGISTER	      ;00
;	 DB	 #FF	 ;SECTORS PER TRACK	      ;01
;	 DB	 #FF	 ;HEADS			      ;02
;	 DB	 #FF	 ;CYLINDERS LOW		      ;03
;	 DB	 #FF	 ;CYLINDERS HIGH	      ;04
;	 DB	 #FF	 ;SECTOR PER CYLINDER LOW     ;05
;	 DB	 #FF	 ;SECTOR PER CYLINDER HIGH    ;06
;	 DB	 #FF	 ;DEVICE TYPE		      ;07

	MODULE	CONFIGURE_IDE_DRIVES

 MODULE PAUSES
HALT:
.Time_2s	EQU 100
.SMALL		EQU 200		; 04 сек
.BIG		EQU 1550	; 31 сек
WAIT:
.IDE		EQU #0000
.SMALL		EQU #0200
.ERROR		EQU #0400
 ENDMODULE

WAIT_IDE	EQU	#0000
WAIT_SML	EQU	#1000
WAIT_ERROR	EQU	#0400

M_CYLL	EQU	#12
M_CYLH	EQU	#13
M_HEAD	EQU	#14
M_SECT	EQU	#15

S_CYLL	EQU	#16
S_CYLH	EQU	#17
S_HEAD	EQU	#18
S_SECT	EQU	#19

SM_CYLL	EQU	#37
SM_CYLH	EQU	#38
SM_HEAD	EQU	#39
SM_SECT	EQU	#3A

SS_CYLL	EQU	#3B
SS_CYLH	EQU	#3C
SS_HEAD	EQU	#3D
SS_SECT	EQU	#3E

 MACRO PAUSE_DJNZ num
	IF num<255
	 LD	B,num
.loop:	 DJNZ	.loop
	ELSE
	 ASSERT 0, "WRONG PAUSE NUMBER!!!"
	ENDIF
 ENDM

/////////////////////////////////////////////////////////////////////[v]
START:	CALL	SetUP_CHANELS
	;
	IN	A,(SLOT3)
	EX	AF,AF'
	LD	A,SYS_PAGE
	OUT	(SLOT3),A
	LD	HL,IDE.INIT_TBL_IDE0
	LD	BC,256*(IDE.HDD_INIT_TABLE * 4) + #FF	;R02
;CLEAR HDD VARIABLE
.FILLIDE:
	LD	(HL),C		
	INC	HL
	DJNZ	.FILLIDE
	EX	AF,AF'
	OUT	(SLOT3),A

	LD	IY,IDE.INIT_TBL_IDE0
	XOR	A
	CALL	STEP1_GETCMOS

	LD	IY,IDE.INIT_TBL_IDE1
	LD	A,#01
	CALL	STEP1_GETCMOS

	LD	IY,IDE.INIT_TBL_IDE2
	LD	A,#02
	CALL	STEP1_GETCMOS

	LD	IY,IDE.INIT_TBL_IDE3
	LD	A,#03
	CALL	STEP1_GETCMOS

	;[x] save hdd parameters to cmos for "setup" in settings
	 CALL	WRITING
	;
	CALL	ScreenPOS.CRLF
	RET
/////////////////////////////////////////////////////////////////////[^]


/////////////////////////////////////////////////////////////////////[v]
AUTODETECT:
	LD	A,L		;DETECT	MESSAGE
	CALL	POSTMSG
	CALL	ScreenPOS.SUBNAME
	LD	A,(MasterSlave)
	;
	CALL	AUTODETECTING
.IDEJUMPBACK:
	CALL	NC,MODEL
	LD	A,(SKIP)
	INC	A
	LD	A,msgStrings.ideNone
	JR	Z,.NOSKIPKEY
	LD	A,msgStrings.ideSkiped
.NOSKIPKEY:
	CALL	C,POSTMSG
	CALL	ScreenPOS.CRLF
	RET
/////////////////////////////////////////////////////////////////////[^]


/////////////////////////////////////////////////////////////////////[v]
; !HARDCODE заменить числа на метки в этой процедуре
STEP1_GETCMOS:
	LD	(MasterSlave),A
	LD	H,A		;SAVE DRIVE NUMBER
	CALL	SELECT_IDE
	LD	A,IDE.Device.NONE
	LD	(IDEDEV),A
	LD	(SKIP),A
	LD	A,H
	;
	AND	A
	LD	BC,CMOS_CELL.DrivesSetup_1.Mask.PriIDEmaster		;#3011
	LD	L,msgStrings.detectIdePrMA
	JR	Z,.choose
	;
	DEC	A
	LD	BC,CMOS_CELL.DrivesSetup_1.Mask.PriIDEslave		;#C011
	LD	L,msgStrings.detectIdePrSL
	JR	Z,.choose
	;
	DEC	A
	LD	BC,CMOS_CELL.DrivesSetup_2.Mask.SecIDEmaster
	LD	L,msgStrings.detectIdeSecMA
	JR	Z,.choose
	;
	DEC	A
	LD	BC,CMOS_CELL.DrivesSetup_2.Mask.SecIDEslave
	LD	L,msgStrings.detectIdeSecSL
	JR	Z,.choose
	SCF
	RET
	;0 - AUTODETECT
	;1 - GETTING FROM SETUP
	;2 - CD-ROM (ATAPI device)
	;3 - DISABLED
.choose:
	EI
	;
	CALL	G_VALUE
	OR	A
	JR	Z,AUTODETECT		;AUTO DETECT
	;
	DEC	A
	JR	Z,SETUP_FROM_CMOS	;Get from CMOS (SETUP)
	;
	DEC	A
	RET	NZ			;DON'T CHECK THIS DEVICE
	;JR	Z,IT_IS_ATAPI		;CD-ROM
/////////////////////////////////////////////////////////////////////[^]
/////////////////////////////////////////////////////////////////////[v]
IT_IS_ATAPI:
	LD	A,L		;DETECT	MESSAGE
	CALL	POSTMSG
	CALL	ScreenPOS.SUBNAME

	LD	HL,PAUSES.HALT.BIG
	CALL	BITS_WAITS.Clear_BUSY
	JR	C,AUTODETECTING.IDE_ABSENT

	CALL	AUTODETECTING.Its_ATAPI
	JP	AUTODETECT.IDEJUMPBACK
/////////////////////////////////////////////////////////////////////[^]


/////////////////////////////////////////////////////////////////////[v]
AUTODETECTING:	CALL	DETECTORS.CheckChanel
		JR	C,.IDE_ABSENT

		CALL	Bug31SecCheck
		JR	C,.next

		LD	HL,PAUSES.HALT.BIG
		CALL	BITS_WAITS.Clear_BUSY
		JR	C,.IDE_ABSENT

.next:		CALL	DETECTORS.Counter
		JR	C,.IDE_ABSENT

		CALL	DETECTORS.NOP_Check
		JR	C,.IDE_ABSENT

		; CALL	DISABLE_8bit	; DISABLE 8 bit data transfer

		CALL	DETECTORS.IdentDevCheck
		JR	C,.IDE_ABSENT
		JR	Z,.Its_ATA

		; enter point for ATAPI in setup		
.Its_ATAPI:	CALL	DETECTORS.IdentPDevChk
		JR	C,.IDE_ABSENT
		LD	A,IDE.Device.CDROM
		LD	(IDEDEV),A
		JR	.get

.Its_ATA:	LD	A,IDE.Device.HDD
		LD	(IDEDEV),A
.get:		CALL	GETPARAM
		JR	C,.IDE_ABSENT
		;CALL	DisableWriteCache
		;CALL	DisableStandBy
		AND	A
		RET
		;	
.IDE_ABSENT:	LD	A,IDE.Device.NONE
		LD	(IDEDEV),A	
		LD	A,IDE.ATA.Nop
 		LD	BC,IDE.Write.Command
 		OUT	(C),A
		DEC	B
		IN	A,(C)			; IDE.Read.Status
		SCF 
		RET 
/////////////////////////////////////////////////////////////////////[^]


/////////////////////////////////////////////////////////////////////[v]
SETUP_FROM_CMOS:
	LD	A,H
	LD	IX,PRIM_MASTER_CMOS_T
	OR	A
	JR	Z,.step1
	;
	LD	IX,PRIM_SLAVE_CMOS_T
	CP	1
	JR	Z,.step1
	;
	LD	IX,SEC_MASTER_CMOS_T
	CP	2
	JR	Z,.step1
	;
	LD	IX,SEC_SLAVE_CMOS_T
.step1:	LD	HL,TEMP
	LD	DE,TEMP+1
	LD	BC,511
	LD	(HL),0
	LDIR 
	;
	CALL	Bug31SecCheck
	JR	C,.step2
	;
	LD	HL,PAUSES.HALT.BIG
	CALL	BITS_WAITS.Clear_BUSY
	JR	C,AUTODETECTING.IDE_ABSENT
	;
.step2:	LD	A,(IX+2)	;M_HEAD
	CALL	READCMS
	LD	(TEMP+3*2),A                            ; !TODO сделать через структуру. HEADS PER TRACK
	;
	LD	A,(IX+1)	;M_CYLH
	CALL	READCMS
	PUSH	AF
	;
	LD	A,(IX+0)	;M_CYLL
	CALL	READCMS
	POP	HL
	LD	L,A
	LD	(TEMP+1*2),HL                           ; !TODO сделать через структуру. CYLINDERS
	;
	LD	A,(IX+3)	;M_SECT
	CALL	READCMS
	LD	(TEMP+6*2),A                            ; !TODO сделать через структуру. SECTOR PER TRACK
	;
	LD	A,IDE.Device.HDD
	LD	(IDEDEV),A
	CALL	IDESPEC
	RET
/////////////////////////////////////////////////////////////////////[^]


/////////////////////////////////////////////////////////////////////[v]
IDESPEC:
	IN	A,(SLOT3)
	EX	AF,AF'
	LD	A,SYS_PAGE
	OUT	(SLOT3),A
	LD	A,(IDEDEV)
	LD	(IY+IDE.HDD_INIT_TABLE.DriveType),A	
	CP	IDE.Device.CDROM
	JP	Z,.FOR_CDR
	;
	LD	BC,IDE.Read.Control
	IN	A,(C)
	AND	#F0
	LD	B,A
	LD	A,(TEMP+#06)                                            ; !TODO сделать через структуру. HEADS PER TRACK	
	LD	(IY+IDE.HDD_INIT_TABLE.HeadsNumber),A
	DEC	A
	AND	#0F
	OR	B
	LD	B,A
	LD	A,(TEMP+#63)                                            ; !TODO сделать через структуру. LBA/NON-LBA bit 1 (FROM ZERO!)
	BIT	1,A
	JR	Z,.NONLBA
	;
	SET	6,B
.NONLBA: LD	A,B
	LD	BC,IDE.Write.DeviceHead
	OUT	(C),A
	AND	#F0		;!HARDCODE DRIVE/HEAD REGISTER PHISICAL DISK bitmask
	LD	HL,ICHANEL
	OR	(HL)
	LD	(IY+IDE.HDD_INIT_TABLE.DRV_Flags),A
	LD	HL,(TEMP+#02)                                           ; !TODO сделать через структуру. CYLINDERS
	LD	(IY+IDE.HDD_INIT_TABLE.CylinderNumberLow),L
	LD	(IY+IDE.HDD_INIT_TABLE.CylinderNumberHigh),H
	LD	A,(TEMP+#0C)                                            ; !TODO сделать через структуру. SECTOR PER TRACK
	LD	(IY+IDE.HDD_INIT_TABLE.SectorsPerTrack),A
	IF IDE_Optimization
	 LD	B,high IDE.Write.Counter	
	ELSE
 	 LD	BC,IDE.Write.Counter
	ENDIF
	OUT	(C),A
	LD	A,IDE.ATA.InitializeDeviceParameters
	CALL	IDE_CMD
	LD	C,(IY+IDE.HDD_INIT_TABLE.SectorsPerTrack)               ; Sector per track
	LD	B,0
	LD	H,B
	LD	L,B
	LD	A,(IY+IDE.HDD_INIT_TABLE.HeadsNumber)                   ; Head per HDD

.loop:	ADD	HL,BC
	DEC	A
	JR	NZ,.loop

	LD	(IY+IDE.HDD_INIT_TABLE.SectorsPerCylinderLow),L
	LD	(IY+IDE.HDD_INIT_TABLE.SectorsPerCylinderHigh),H
.END:	; [x] save hdd parameters to cmos for "setup" in settings
	 LD	A,(IY+IDE.HDD_INIT_TABLE.DRV_Flags)	; for save to cmos in GETPARM
	;
	EX	AF,AF'
	OUT	(SLOT3),A
	AND	A
	RET
	;
.FOR_CDR: LD	BC,IDE.Read.Control
	IN	A,(C)
	AND	#F0
	LD	HL,ICHANEL
	OR	(HL)
	LD	(IY+IDE.HDD_INIT_TABLE.DRV_Flags),A
	JR	IDESPEC.END
/////////////////////////////////////////////////////////////////////[^]


/////////////////////////////////////////////////////////////////////[v]
IDE_CMD:
	PUSH	AF
	LD	HL,PAUSES.WAIT.IDE
	LD	DE,256*IDE.ControlByte.Busy + 0
	CALL	BITS_WAITS.WAIT_PRT
	POP	HL
	RET	C
	INC	B			; LD BC,IDE.Write.Command 
	OUT	(C),H
	LD	HL,PAUSES.WAIT.IDE
	;LD	DE,256*IDE.ControlByte.Busy + 0
	JR	BITS_WAITS.WAIT_PRT
/////////////////////////////////////////////////////////////////////[^]


/////////////////////////////////////////////////////////////////////[v]
MODEL:	LD	HL,TEMP+27*2                                            ; !TODO сделать через структуру. 
	LD	A,(HL)
	OR	A
	JR	Z,.unknown
	LD	B,20							;!HARDCODE
	CALL	DWPRINT
	AND	A
	RET 
.unknown:
	LD	A,msgStrings.ideUnknown
	CALL	POSTMSG
	AND	A
	RET
/////////////////////////////////////////////////////////////////////[^]


/////////////////////////////////////////////////////////////////////[v]
BITS_WAITS:
; IN:
;  HL - Waiting delay
;  DE - MASK : PATTERN
; OUT:
;  NC: (PORT & D)-E = 0
;  CF: waiting delay exceeded 
.WAIT_PRT:
	LD	BC,IDE.Read.Status
	;
.loop:	IN	A,(C)
	AND	D
	CP	E
	 RET	Z
	DEC	HL
	CALL	SKIPKEY
	RET	C
	LD	A,L
	OR	H
	JP	NZ,.loop
	;
	SCF 
	RET 
	;

; Pause for clear BUSY and DATA REQUEST
.Clear_BUSY:	LD	BC,IDE.Read.Status
		IN	A,(C)
		;!TEST for normal bus with pull-ups
		 ;CP	#FF
		 ;SCF
		 ;RET	Z
		;
		AND	IDE.ControlByte.Busy; + IDE.ControlByte.DataRequest
		RET	Z
		;
		HALT 
		DEC	HL
		LD	A,H
		OR	L
		SCF
		RET	Z
		;
		CALL	SKIPKEY
		RET	C
		;
		JR	.Clear_BUSY
/////////////////////////////////////////////////////////////////////[^]


/////////////////////////////////////////////////////////////////////[v]
SELECT_IDE:
	AND	A	;%0000'0011
	LD	B,IDE.Drive.Master
	JR	Z,.AUTO_0
	;
	DEC	A
	LD	B,IDE.Drive.Slave
	JR	Z,.AUTO_0
	;
	DEC	A
	;R00
	 LD	B,IDE.Drive.Master
	 JR	Z,.AUTO_1
	 ;		
	 DEC	A			
	 LD	B,IDE.Drive.Slave		
.AUTO_1: LD	A,IDE.Chanel.Secondary	 ;SELECT SECONDARY
	 OUT	(IDE.Chanel.Set),A	
	 JP	.AUTO
	 ;		
.AUTO_0: LD	A,IDE.Chanel.Primary	 ;SELECT PRIMARY
	 OUT	(IDE.Chanel.Set),A	
	;
	XOR	A
.AUTO:	LD	(ICHANEL),A
	;R01
	 LD	A,B
	 LD	BC,IDE.Write.DeviceHead
	 OUT	(C),A
	;
	RET
/////////////////////////////////////////////////////////////////////[^]


/////////////////////////////////////////////////////////////////////[v]
SKIPKEY:
	EXX 
	 CALL	SCANKEY
	EXX 
	SCF 
	CCF 
	RET	Z
	EXX 
	 LD	HL,#3E00        ;!HARDCODE
	 AND	A
	 SBC	HL,DE
	EXX 
	SCF 
	CCF 
	RET	NZ
	LD	A,0
	LD	(SKIP),A
	SCF 
	RET 
/////////////////////////////////////////////////////////////////////[^]


/////////////////////////////////////////////////////////////////////[v]
; [x] save hdd parameters to cmos for "setup" in settings
; IN: A' = DRV_Flags
SaveToCMOS:
	LD	A,(IDEDEV)
	CP	IDE.Device.HDD
	RET	NZ

	EX	AF,AF'
	;LD	A,(IY+IDE.HDD_INIT_TABLE.DRV_Flags)
	AND	%0001'0001
	LD	IX,PRIM_MASTER_CMOS_T
	JR	Z,.save_to_cmos
	;
	DEC	A
	LD	IX,SEC_MASTER_CMOS_T
	JR	Z,.save_to_cmos	 
	;
	CP	%0001'0000
	LD	IX,SEC_SLAVE_CMOS_T
	JR	Z,.save_to_cmos	
	;
	LD	IX,PRIM_SLAVE_CMOS_T
.save_to_cmos:
	LD	HL,(TEMP+1*2)
	LD	B,L
	LD	A,(IX+0)
	CALL	WRITCMS			; Cylinder low

	LD	B,H
	LD	A,(IX+1)
	CALL	WRITCMS			; Cylinder high

	LD	A,(TEMP+3*2)
	LD	B,A
	LD	A,(IX+2)
	CALL	WRITCMS			; Heads

	LD	A,(TEMP+6*2)
	LD	B,A
	LD	A,(IX+3)
	JP	WRITCMS			; Heads	 
/////////////////////////////////////////////////////////////////////[^]


/////////////////////////////////////////////////////////////////////[v]
RESET_Slave_ATAPI:
		LD	A,IDE.Drive.Slave
		LD	BC,IDE.Write.DeviceHead
		OUT	(C),A
		PAUSE_DJNZ 16
		LD	BC,IDE.Write.Command
		LD	A,IDE.ATAPI.Reset
		OUT	(C),A
		PAUSE_DJNZ 16
		LD	A,IDE.Drive.Master
		LD	BC,IDE.Write.DeviceHead
		OUT	(C),A
		RET
/////////////////////////////////////////////////////////////////////[^]


/////////////////////////////////////////////////////////////////////[v]
; Check bug with 31 sec freeze
Bug31SecCheck:	LD	A,(MasterSlave)
		AND	1
		RET	NZ
		;
		LD	HL,PAUSES.HALT.Time_2s
		CALL	BITS_WAITS.Clear_BUSY
		CCF
		RET	C
		;
		JP	RESET_Slave_ATAPI
/////////////////////////////////////////////////////////////////////[^]


/////////////////////////////////////////////////////////////////////[v]
GETPARAM:
	LD	HL,PAUSES.WAIT.IDE
	LD	DE,IDE.ControlByte.DataRequest * 256 + IDE.ControlByte.DataRequest
	CALL	BITS_WAITS.WAIT_PRT
	RET	C
	LD	BC,IDE.Read.Data
	LD	HL,TEMP
	INIR 
	INIR 
	CALL	IDESPEC
	; [x] save hdd parameters to cmos for "setup" in settings
	 CALL	SaveToCMOS
	;
	AND	A
	RET 
/////////////////////////////////////////////////////////////////////[^]


/////////////////////////////////////////////////////////////////////[v]
DETECTORS:
;-------;
	; CHECK BY COUNTER PORT.
	; Exit:	CF - No device
.test_counter	EQU	5
.Counter:	LD	A,.test_counter
		LD	BC,IDE.Write.Counter
		OUT	(C),A
 		LD	HL,PAUSES.WAIT.SMALL
		LD	DE,IDE.ControlByte.Busy*256 + 0
 		CALL	BITS_WAITS.WAIT_PRT
		RET	C
		;
 		LD	BC,IDE.Read.Counter	; LD BC,IDE.Read.Counter
 		IN	A,(C)
 		CP	.test_counter
 		RET	Z
		SCF
		RET
;-------;

;-------;
	; CHECK BY EXECUTING NOP COMMAND AND WAIT.
	; Exit:	CF - No device
.NOP_Check:	LD	E,IDE.ATA.Nop
		LD	BC,IDE.Write.Command
		OUT	(C),E
		
		PAUSE_DJNZ 0
		
		LD	HL,PAUSES.HALT.SMALL
		LD	BC,IDE.Read.Status
		;DEC	B
		;
.loop:		IN	A,(C)
		SCF
		RET	Z
		;
		AND	IDE.ControlByte.Busy + IDE.ControlByte.DataRequest + IDE.ControlByte.Error
		CP	IDE.ControlByte.Error
		RET	Z
		;
		HALT 
		DEC	HL
		LD	A,H
		OR	L
		SCF
		RET	Z			; Absent
		;
		CALL	SKIPKEY
		RET	C			; Skipped = Absent
		;
		JR	.loop
;-------;

;-------;
	; CHECK WITH Identify Device.
	; Exit:	       CF - No device
	;	NC and ZF - ATA
	;	NC and NZ - ATAPI
.IdentDevCheck: LD	E,IDE.ATA.IdentifyDevice 
		LD	BC,IDE.Write.Command
		OUT	(C),E
		;
		LD	DE,IDE.ControlByte.Busy * 256 + 0
		LD	HL,PAUSES.WAIT.IDE
		CALL	BITS_WAITS.WAIT_PRT
		RET	C			; Absent
		;
		LD	BC,IDE.Read.Status
		IN	A,(C)
		RRCA
		JR	C,.non_ATA
		;
		AND	(IDE.ControlByte.DataRequest + IDE.ControlByte.Ready) / 2
		SCF
		RET	Z
		;
		XOR	A
		RET				; ATA
		;
.non_ATA:	LD	BC,IDE.Read.Error
		IN	A,(C)
		AND	IDE.ErrorByte.Abort
		RET	NZ			; ATAPI
		;
		SCF				; Absent
		RET
;-------;

;-------;
	; ATAPI or Absent
	; Exit:	CF - No device
	;	NC - ATAPI
.IdentPDevChk:	LD	E,IDE.ATAPI.IdentifyPackedDevice
		LD	BC,IDE.Write.Command
		OUT	(C),E
		LD	HL,PAUSES.WAIT.IDE
		LD	DE,IDE.ControlByte.Busy*256 + 0
		CALL	BITS_WAITS.WAIT_PRT
		RET	C
		;
		LD	BC,IDE.Read.Status
		IN	A,(C)
		RRCA
		RET	C
		XOR	A
		RET
;-------;

;-------;
; если канал пустой, то читается из порта то, что было выставлено
; последним на шину c чётного адреса в памяти а это первый или второй
; байт кода команды
 ALIGN	2 ; тут нужно выравнивание по задуманным адресам для команд чтения из портов
.CheckChanel:	LD	BC,IDE.Read.Status
		IN	A,(C)			;#ED78	A=#78
		IN	L,(C)			;#ED68	L=#68
		LD	D,A
		IN	A,(C)			;#ED60	A=#ED
		LD	E,L
		LD	HL,#7868 + #ED
		SBC	HL,DE
		XOR	L
		RET	NZ			; not absent
		SCF
		RET				; absent
;-------;
/////////////////////////////////////////////////////////////////////[^]


/////////////////////////////////////////////////////////////////////[v]
SetUP_CHANELS:
	LD	A,1
	CALL	.CMD
	LD	A,3
	CALL	.CMD
	LD	A,0
	CALL	.CMD
	LD	A,2
.CMD:	CALL	SELECT_IDE
	LD	BC,IDE.Write.Command
	LD	H,IDE.ATA.Nop
	OUT	(C),H
	PAUSE_DJNZ 32
	; Disable INTRQ
	; LD	BC,IDE.Write.DeviceControl
	; LD	A,%0000'0010
	; OUT	(C),A
	; PAUSE_DJNZ 32
	; ;
	; CALL	DisableStandBy
	; PAUSE_DJNZ 32
	RET
/////////////////////////////////////////////////////////////////////[^]


/////////////////////////////////////////////////////////////////////[v]
; DisableWriteCache:
; 	LD	BC,IDE.Write.Features
; 	LD	A,IDE.ATA.SetFeatures.DisableWriteCache
; 	OUT	(C),A
; 	LD	A,IDE.ATA.SetFeatures
; 	JP	IDE_CMD
/////////////////////////////////////////////////////////////////////[^]


/////////////////////////////////////////////////////////////////////[v]
;Disable StandBy timer
; DisableStandBy:
; 	LD	BC,IDE.Write.Counter
; 	XOR	A
; 	OUT	(C),A
; 	LD	A,IDE.ATA.Idle
; 	JP	IDE_CMD
/////////////////////////////////////////////////////////////////////[^]


/////////////////////////////////////////////////////////////////////[v]
; DISABLE_8bit:
; 	LD	BC,IDE.Write.Features
; 	LD	A,IDE.ATA.SetFeatures.Disable8bit
; 	OUT	(C),A
; 	LD	A,IDE.ATA.SetFeatures
; 	JP	IDE_CMD
/////////////////////////////////////////////////////////////////////[^]


;!FIXIT CMOS переделать под названия ячеек из SP2000.inc
PRIM_MASTER_CMOS_T:
	DB	M_CYLL,M_CYLH,M_HEAD,M_SECT
PRIM_SLAVE_CMOS_T:
	DB	S_CYLL,S_CYLH,S_HEAD,S_SECT
SEC_MASTER_CMOS_T:
	DB	SM_CYLL,SM_CYLH,SM_HEAD,SM_SECT	
SEC_SLAVE_CMOS_T:
	DB	SS_CYLL,SS_CYLH,SS_HEAD,SS_SECT


SKIP:		BYTE #FF
IDEDEV:		BYTE #FF
ICHANEL:	BYTE #00
MasterSlave	BYTE #00


;WAITHDD DEC	 L
;	 RET	 NZ
;	 DEC	 H
;	 RET	 NZ
;	 DEC	 E
;	 RET	 NZ
;	 SCF
;	 RET

; E - Second * 10

;PAUSE	 LD	 HL,#0000
;PAUSE1	 DEC	 L
;	 JR	 NZ,PAUSE1
;	 DEC	 H
;	 JR	 NZ,PAUSE1
;	 DEC	 E
;	 JR	 NZ,PAUSE1
;	 RET

	ENDMODULE
;