; !FIXIT ALL
;
;[]===========================================================[]



; FDD.CHANGE:
; 	LD	A,#01
; 	AND	A
; 	RET 



;[]===========================================================[]
;Function: Get Current Media Parameters
;	A - Disk
;Return:
;	H - Heads
;	L - Sectors
;      DE - Cylinders
;      IX - Capacity sector in bytes
;	B - Flags
;	    D7 - "1" - High Density, "0" - Double Density
;[]===========================================================[]
;!FIXIT всегда идет работа с данными для диска А
FDD_5x_GETMED:
	;!TEST FDD 720/1440
	IF FDD_NormalCount
	 LD	IY,FDD_INI_TABLE.FDD_0
	 DEC	A
	 JR	C,.getParams
	 LD	IY,FDD_INI_TABLE.FDD_1
.getParams:
	ENDIF

	IN	A,(SLOT3)
	EX	AF,AF'
	LD	A,SYS_PAGE
	OUT	(SLOT3),A
	;!TEST FDD 720/1440
	IF FDD_NormalCount
	 LD	L,(IY+1)	;SECTORS
	 LD	H,(IY+2)	;HEADS
	 LD	E,(IY+3)	;CYLINDL
	 LD	D,(IY+4)	;CYLINDH
	 LD	A,(IY+5)	;B_P_S low
	 LD	XL,A
	 LD	A,(IY+6)	;B_P_S High
	 LD	XH,A
	 LD	A,(IY+0)	;F144/720
	ELSE
	 LD	HL,(FDD_INI_TABLE.FDD_0.SECTORS)
	 LD	DE,(FDD_INI_TABLE.FDD_0.CYLINDL)
	 LD	IX,(FDD_INI_TABLE.FDD_0.BytesPerSector)
	 LD	A,(FDD_INI_TABLE.FDD_0.F144)
	ENDIF
	LD	B,A
	EX	AF,AF'
	OUT	(SLOT3),A
	EX	AF,AF'
	AND	A
	RET 

;[]===========================================================[]
;Function: Set Current Media Parameters
;	A - Disk
;	H - Heads
;	L - Sectors
;      DE - Cylinders
;      IX - Capacity sector in bytes
;	B - Flags
;	    D7 - "1" - High Density, "0" - Double Density
;Return: None
;[]===========================================================[]
FDD_5x_SETMED:	;!TEST FDD 720/1440
		IF FDD_NormalCount
		 LD	IY,FDD_INI_TABLE.FDD_0
		 DEC	A
		 JR	C,.setParams
		 LD	IY,FDD_INI_TABLE.FDD_1
		ENDIF
		;
.setParams:	IN	A,(SLOT3)
		EX	AF,AF'
		LD	A,SYS_PAGE
		OUT	(SLOT3),A
		;
		;!TEST FDD 720/1440
		IF FDD_NormalCount
		 LD	(IY+1),L	;SECTORS
		 LD	(IY+2),H	;HEADS
		 LD	(IY+3),E	;CYLINDL
		 LD	(IY+4),D	;CYLINDH
		 LD	A,XL
		 LD	(IY+5),A	;B_P_S low
		 LD	A,XH
		 LD	(IY+6),A	;B_P_S High
		 LD	(IY+0),B	;F144/720
		 LD	A,B
		ELSE
		 LD	A,B
		 LD	(FDD_INI_TABLE.FDD_0.SECTORS),HL
		 LD	(FDD_INI_TABLE.FDD_0.CYLINDL),DE
		 LD	(FDD_INI_TABLE.FDD_0.BytesPerSector),IX
		 LD	(FDD_INI_TABLE.FDD_0.F144),A
		ENDIF
		;
		EX	AF,AF'
		OUT	(SLOT3),A
		EX	AF,AF'
		;
		;!TEST FDD 720/1440
		IF FDD_NormalCount
		 AND	1
		 JP	Z,FN_TURBO.SET_FDD_720
		 JP	FN_TURBO..SET_FDD_1440
		ELSE
		 AND	A
		 RET 
		ENDIF

;[]===========================================================[]
;Function: Detect Disk Density
;	A - Disk
;Return:
;	A - Flag D7 - "1" - High Density, "0" -	Double Density
;[]===========================================================[]
FDD_5x_DETECT:	CALL	SAVE_INTERRUPTS.switch_off
		CALL	SET_DOS_ON
		CALL	DISK_ID
		PUSH	AF
		CALL	SET_DOS_OFF
		POP	AF
		JP	SAVE_INTERRUPTS.restore
		;RET 

;[]===========================================================[]
;Function: Reset Disk
;	A - Disk
;Return: None
;[]===========================================================[]
FDD_5x_RESET:	CALL	SAVE_INTERRUPTS.switch_off
		CALL	SET_DOS_ON
		CALL	S_FDD
		CALL	DISK_ID
		JR	C,.MOTOR_OFF
		;
		CALL	RESWG
		XOR	A
		OUT	(FDC_93.Track),A
		IN	A,(FDC_93.Command)
		LD	C,A
		CALL	SET_DOS_OFF
		LD	A,C
		AND	A
		JP	SAVE_INTERRUPTS.restore
		;RET 
.MOTOR_OFF:	;PUSH	AF
		LD	A,#D0
		OUT	(FDC_93.Command),A      ;STOP OPERATION
		LD	A,#00
		OUT	(FDC_93.DrvCTRL),A
		LD	A,#3C
		OUT	(FDC_93.DrvCTRL),A
		CALL	SET_DOS_OFF
		; CF=1
		LD	A,4	;NOT READY /NO DISK/
		;POP	AF
		JP	SAVE_INTERRUPTS.restore

;[]===========================================================[]
;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)
;[]===========================================================[]
FDD_5x_READ:
	EX	AF,AF'
	IN	A,(SLOT3)
	EX	AF,AF'
;[]===========================================================[]
;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)
;[]===========================================================[]
FDD_5x_LONG_READ:
		CALL	SAVE_INTERRUPTS.switch_off
		CALL	.Start
		JP	SAVE_INTERRUPTS.restore
		;
.Start:		PUSH	IY
		PUSH	BC
		PUSH	HL
		PUSH	IX
		EX	AF,AF'
		LD	C,A
		EX	AF,AF'
		PUSH	BC
		CALL	SET_DOS_ON
		CALL	S_FDD
		CALL	SPEED
		CALL	NTRACK
		POP	BC
		EX	DE,HL
;		LD	A,B
;		OR	A
;		JP	Z,RETDOS
		IN	A,(SLOT3)
		EX	AF,AF'
		LD	A,SYS_PAGE
		OUT	(SLOT3),A
		LD	IY,(FDD_INI_TABLE.FDD_0.BytesPerSector)
		LD	XH,C
		LD	A,(FDD_INI_TABLE.FDD_0.SECTORS)
		LD	C,A
		EX	AF,AF'
		OUT	(SLOT3),A
.DSK_LP:	LD	A,D
		EXX 
		CALL	SEEK
		EXX 
		PUSH	DE
		PUSH	BC
		PUSH	HL
		CALL	READ_SECTOR
		JP	C,ERRDOS
		LD	D,YH
		LD	E,YL
		POP	HL
		POP	BC
		ADD	HL,DE
		JR	NC,.THISRD
		IN	A,(SLOT3)
		EX	AF,AF'
		LD	A,SYS_PAGE
		OUT	(SLOT3),A
		LD	D,#C2
		LD	E,XH
		LD	A,(DE)
		LD	XH,A
		EX	AF,AF'
		OUT	(SLOT3),A
		SET	7,H
		SET	6,H
.THISRD:	POP	DE
		LD	A,C
		INC	E
		CP	E
		JP	NZ,.NINC_T
		LD	E,0
		INC	D
.NINC_T:	DJNZ	.DSK_LP
.RETDOS:	CALL	SET_DOS_OFF
		LD	A,XH
		EX	AF,AF'
		EX	DE,HL
		POP	IX
		POP	HL
		POP	BC
		POP	IY
		LD	A,B
		LD	C,B
		INC	B
		DEC	B
		LD	B,0
		JR	NZ,.ADD8BIT
		INC	B
.ADD8BIT:	ADD	IX,BC
		LD	BC,0
		ADC	HL,BC
		LD	B,A
		XOR	A
		RET 
	;
ERRDOS:		POP	HL
		POP	BC
		POP	DE
		CALL	SET_DOS_OFF
		EX	DE,HL
		EX	AF,AF'
		EXX 
		LD	C,XH
		EXX 
		LD	A,B
		POP	IX
		POP	HL
		POP	BC
		POP	IY
		PUSH	AF
		LD	C,A
		LD	A,B
		SUB	C
		LD	C,A
		LD	B,0
		ADD	IX,BC
		LD	C,B
		ADC	HL,BC
		POP	BC
		EXX 
		LD	A,C
		EXX 
		EX	AF,AF'
		SCF 
		RET 

;[]===========================================================[]
;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)
;[]===========================================================[]
FDD_5x_WRITE:
	EX	AF,AF'
	IN	A,(SLOT3)
	EX	AF,AF'
;[]===========================================================[]
;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)
;[]===========================================================[]
FDD_5x_LONG_WRITE:
		CALL	SAVE_INTERRUPTS.switch_off
		CALL	.Start
		JP	SAVE_INTERRUPTS.restore
		;
.Start:		PUSH	IY
		PUSH	BC
		PUSH	HL
		PUSH	IX
		EX	AF,AF'
		LD	C,A
		EX	AF,AF'
		PUSH	BC
		CALL	SET_DOS_ON
		CALL	S_FDD
		CALL	SPEED
		CALL	NTRACK
		POP	BC
		EX	DE,HL
;		LD	A,B
;		OR	A
;		JP	Z,RETDOS
		IN	A,(SLOT3)
		EX	AF,AF'
		LD	A,SYS_PAGE
		OUT	(SLOT3),A
		LD	IY,(FDD_INI_TABLE.FDD_0.BytesPerSector)
		LD	XH,C
		LD	A,(FDD_INI_TABLE.FDD_0.SECTORS)
		LD	C,A
		EX	AF,AF'
		OUT	(SLOT3),A
.DSK_LP2:	LD	A,D
		EXX 
		CALL	SEEK
		EXX 
		PUSH	DE
		PUSH	BC
		PUSH	HL
		CALL	WR_SEC
		JP	C,ERRDOS
		LD	D,YH
		LD	E,YL
		POP	HL
		POP	BC
		ADD	HL,DE
		JR	NC,.THISWR
		IN	A,(SLOT3)
		EX	AF,AF'
		LD	A,SYS_PAGE
		OUT	(SLOT3),A
		LD	D,#C2
		LD	E,XH
		LD	A,(DE)
		LD	XH,A
		EX	AF,AF'
		OUT	(SLOT3),A
		SET	7,H
		SET	6,H
.THISWR:	POP	DE
		LD	A,C
		INC	E
		CP	E
		JP	NZ,.NINC_T2
		LD	E,0
		INC	D
.NINC_T2:	DJNZ	.DSK_LP2
		CALL	SET_DOS_OFF
		LD	A,XH
		EX	AF,AF'
		EX	DE,HL
		POP	IX
		POP	HL
		POP	BC
		POP	IY
		LD	A,B
		LD	C,B
		INC	B
		DEC	B
		LD	B,0
		JR	NZ,.ADW8BIT
		INC	B
.ADW8BIT:	ADD	IX,BC
		LD	BC,0
		ADC	HL,BC
		LD	B,A
		XOR	A
		RET 

;
;-------------------------------
;READ SECTOR
;-------------------------------
READ_SECTOR:	LD	D,5			;RETRY COUNT
.RRETRY:	;DI 
		PUSH	DE
		LD	A,E
		INC	A
		OUT	(FDC_93.Sector),A
.FDREAD:	IN	A,(SLOT3)
		EX	AF,AF'
		LD	A,XH
		OUT	(SLOT3),A
		LD	B,4
		LD	C,FDC_93.Data
		LD	A,#80			;COMMAND READ
		OUT	(FDC_93.Command),A
.FDR001:	IN	A,(FDC_93.DrvCTRL)	;WAIT INTRQ or DRQ
		AND	#C0
		JR	NZ,.FDR004
		INC	DE
		LD	A,E
		OR	D
		JR	NZ,.FDR001
		DJNZ	.FDR001
		SCF 
		JR	.FDR005
		;
.FDR004:	INI				;READ BYTE
.FDR002:	IN	A,(FDC_93.DrvCTRL)
		AND	#C0
		JR	Z,.FDR002
		JP	P,.FDR004
.FDR005:	EX	AF,AF'
		OUT	(SLOT3),A
		EX	AF,AF'
		;
		POP	DE
		;EI 
		IN	A,(FDC_93.Command)
		LD	C,A
;R01		; JP	C,ERRRD			;READ ERROR
		; !TEST 29/06/2024
		 ;JP	C,.ERR_XRD
		 JP	NC,.NO_ERR_XRD
		 DEC	D
		 JR	Z,.RSTOP
		 JR	.RRETRY
		;
.NO_ERR_XRD:	; 
		AND	#7F
		RET	Z
		BIT	2,C
		JR	NZ,.ERDATA
		LD	A,5			;SEEK ERROR
		DEC	D
		JR	Z,.RSTOP
		PUSH	DE
		CALL	RESWG			; RESET_WG
		LD	A,XL
		CALL	SEEK	  ; !!!!!  посмотреть
.ERR_XRD:	POP	DE
		JR	.RRETRY
		;
.ERDATA:	DEC	D			; POTERIA DANNYH
		JR	NZ,.RRETRY
.ERRRD:		LD	A,9	;READ ERROR
.RSTOP:		EX	AF,AF'
		LD	A,#D0
		OUT	(FDC_93.Command),A      ;STOP OPERATION
		EX	AF,AF'
		BIT	0,C
		SCF 
		RET	Z
		LD	A,6			;SECTOR	NOT FOUND /NO DISK/
		RET 
;	;	;

;
;-------------------------------
;WRITE SECTOR
;-------------------------------
WR_SEC:	LD	D,5	;RETRY COUNT
.WRETRY:
	;DI 
	PUSH	DE
	LD	A,E
	INC	A
	OUT	(FDC_93.Sector),A
.FDWRITE:
	IN	A,(SLOT3)
	EX	AF,AF'
	LD	A,XH
	OUT	(SLOT3),A
	LD	B,4
	LD	C,FDC_93.Data
	LD	A,#A0		;COMMAND WRITE
	OUT	(FDC_93.Command),A
.FDW001:
	IN	A,(FDC_93.DrvCTRL)	;WAIT INTRQ or DRQ
	AND	#C0
	JR	NZ,.FDW004
	INC	DE
	LD	A,E
	OR	D
	JR	NZ,.FDW001
	DJNZ	.FDW001
	SCF 
	JR	.FDW005
.FDW004:
	OUTI			;WRITE BYTE
.FDW002:
	IN	A,(FDC_93.DrvCTRL)
	AND	#C0
	JR	Z,.FDW002
	JP	P,.FDW004
.FDW005:
	EX	AF,AF'
	OUT	(SLOT3),A
	EX	AF,AF'
;-------------------------------
	POP	DE
	;EI 
	IN	A,(FDC_93.Command)
	LD	C,A
;R01
	JP	C,.ERR_XWR
;	JP	C,ERRWR	;WRITE ERROR
	AND	#7F
	RET	Z
	BIT	6,C
	LD	A,8	;WRITE PROTECT
	JR	NZ,.WSTOP
	BIT	2,C
	JR	NZ,.EWDATA
	LD	A,5	;SEEK ERROR
	DEC	D
	JP	Z,.WSTOP
.ERR_XWR:
	PUSH	DE
	CALL	RESWG		; RESET_WG
	LD	A,XL
	CALL	SEEK	  ; !!!!!  посмотреть
	POP	DE
	JR	.WRETRY
.EWDATA:
	DEC	D	       ; POTERIA DANNYH
	JR	NZ,.WRETRY
.ERRWR: LD	A,10	;WRITE ERROR
.WSTOP:	EX	AF,AF'
	LD	A,#D0
	OUT	(FDC_93.Command),A      ;STOP OPERATION
	EX	AF,AF'
	BIT	0,C
	SCF 
	RET	Z
	LD	A,6	;SECTOR	NOT FOUND /NO DISK/
	RET 




;
; Врубает третью карту портов
SET_DOS_ON:
	EX	AF,AF'
	LD	A,CNF_PORT.CNF_3 + ROM.BIOS
	OUT	(SYS_PORT.ROM),A	                ; - OPEN
	EX	AF,AF'
	RET 
; Врубает нулевую карту портов
SET_DOS_OFF:
	EX	AF,AF'
	LD	A,CNF_PORT.CNF_0 + ROM.BIOS
	OUT	(SYS_PORT.ROM),A	                ; - CLOSE
	EX	AF,AF'
	RET 
;

;
FDD.SET720:
        LD A,FDD_Density.SET_720
        OUT (FDD_Density),A
        RET
;

;
FDD.SET1440:
        LD A,FDD_Density.SET_1440
        OUT (FDD_Density),A
        RET
;

;
S_FDD:	PUSH	BC
	AND	1
	LD	B,A
	OR	#3C
	OUT	(FDC_93.DrvCTRL),A
	IN	A,(SLOT3)
	EX	AF,AF'
	LD	A,SYS_PAGE
	OUT	(SLOT3),A
	LD	A,(FDD_INI_TABLE.FDD_0.DISK)
	AND	#FE
	OR	B
	LD	(FDD_INI_TABLE.FDD_0.DISK),A
	EX	AF,AF'
	OUT	(SLOT3),A
	POP	BC
	RET 
;

;
; MOTOR_OFF:
; 	PUSH	AF
; 	LD	A,#D0
; 	OUT	(FDC_93.Command),A      ;STOP OPERATION
; 	LD	A,#00
; 	OUT	(FDC_93.DrvCTRL),A
; 	LD	A,#3C
; 	OUT	(FDC_93.DrvCTRL),A
; 	CALL	SET_DOS_OFF
; 	POP	AF
; 	RET 
;

;
TURNSPD:
	IN	A,(SLOT3)
	EX	AF,AF'
	LD	A,SYS_PAGE
	OUT	(SLOT3),A
	LD	A,(FDD_INI_TABLE.FDD_0.F144)
	XOR	#80
	LD	(FDD_INI_TABLE.FDD_0.F144),A
	AND	#80
	EX	AF,AF'
	OUT	(SLOT3),A
	EX	AF,AF'
	JP	Z,FDD.SET720
	JP	FDD.SET1440	;NZ
;

;
SPEED:	IN	A,(SLOT3)
	EX	AF,AF'
	LD	A,SYS_PAGE
	OUT	(SLOT3),A
	LD	A,(FDD_INI_TABLE.FDD_0.F144)
	AND	#80
	EX	AF,AF'
	OUT	(SLOT3),A
	EX	AF,AF'
	JP	Z,FDD.SET720
	JP	FDD.SET1440	;NZ
;

; прерывания должны быть отключены
DISK_ID:
	;DI 
	EXX 
	CALL	SPEED
	IN	A,(FDC_93.Track)
	OUT	(FDC_93.Data),A
	LD	A,#18              ;!TODO выписать комманды ВГ          ;SEARCH         ; !HARDCODE
	CALL	EXECOM
	LD	C,4
.ID_LP0:
	LD	A,#C0
	OUT	(FDC_93.Command),A
	LD	HL,#F000
.ID_LP1:
	IN	A,(FDC_93.DrvCTRL)
	AND	#C0
	JR	Z,.ID_LP4
.ID_LP2:
	IN	A,(FDC_93.Data)
.ID_LP3:
	IN	A,(FDC_93.DrvCTRL)
	AND	#C0
	JR	Z,.ID_LP3
	JP	P,.ID_LP2
	EXX 
	IN	A,(SLOT3)
	EX	AF,AF'
	LD	A,SYS_PAGE
	OUT	(SLOT3),A
	LD	A,(FDD_INI_TABLE.FDD_0.F144)
	EX	AF,AF'
	OUT	(SLOT3),A
	EX	AF,AF'
	AND	#80
	;EI 
	RET 
.ID_LP4:
	DEC	HL
	LD	A,H
	OR	L
	JP	NZ,.ID_LP1
	CALL	TURNSPD
	DEC	C
	JP	NZ,.ID_LP0
	EXX 
	SCF 
	;EI 
	RET
;

;
SEEK:	LD	XL,A
	LD	C,A
	IN	A,(SLOT3)
	EX	AF,AF'
	LD	A,SYS_PAGE
	OUT	(SLOT3),A
	LD	A,(FDD_INI_TABLE.FDD_0.DISK)
	AND	1
	EX	AF,AF'
	OUT	(SLOT3),A
	EX	AF,AF'
	SRL	C
	JR	C,.GT001
	OR	#3C
.GT001:	OR	#2C
	OUT	(FDC_93.DrvCTRL),A
	IN	A,(FDC_93.Track)
	CP	C
	PUSH	BC
	CALL	NZ,P50ms
	POP	BC
	LD	A,C
	OUT	(FDC_93.Data),A
	IN	A,(FDC_93.Track)
	CP	C
	EX	AF,AF'	;R.TRACK==PHISICAL TRACK
	LD	A,#18
	CALL	EXECOM
	RET	C
	EX	AF,AF'
	LD	A,C
	OUT	(FDC_93.Track),A
	RET	Z
.STOL:	PUSH	BC
	CALL	P50ms
	POP	BC
	RET 
;
;P750ms	 LD	 B,3
;PMS2	 LD	 A,255
;	 CALL	 P1ms
;	 DJNZ	 PMS2
;	 RET
P50ms:	LD	A,12
.P1ms:	LD	C,255
.PMS:	DEC	C
	JR	NZ,.PMS
	DEC	A
	JR	NZ,.P1ms
	RET 
;

;
RESWG:	LD	A,8
EXECOM:	OUT	(FDC_93.Command),A
	LD	HL,#0000
.WREST:	DEC	HL
	LD	A,H
	OR	L
	SCF 
	RET	Z
	IN	A,(FDC_93.DrvCTRL)
	AND	#80
	JR	Z,.WREST
	AND	A
	RET 
;

;
;-------------------------------
; HL:IX	- SECTOR
;  H - TRACK, L	- SECTOR
;HL:IX/SECTOR_PER_TRACK
NTRACK:
	PUSH	HL
	EX	(SP),IX
	POP	HL
	IN	A,(SLOT3)
	EX	AF,AF'
	LD	A,SYS_PAGE
	OUT	(SLOT3),A
	LD	A,(FDD_INI_TABLE.FDD_0.SECTORS)
	LD	C,A
	LD	B,0
	EX	AF,AF'
	OUT	(SLOT3),A
	XOR	A
.NTRK:	INC	A
	SBC	HL,BC
	JR	NC,.NTRK
	EX	AF,AF'
	LD	A,XL
	OR	XH
	JR	Z,.NTRK3
	EX	AF,AF'
	DEC	IX
	JR	.NTRK
.NTRK3:	EX	AF,AF'
	ADD	HL,BC
	DEC	A
	LD	H,A
	RET
;
SAVE_INTERRUPTS:
.switch_off:	PUSH AF
		LD A,R
		LD A,#80
		JP PE,.set_R
		XOR A
.set_R: 	LD R,A
		DI
		POP AF
		RET
	;	;
.restore:	PUSH AF
		LD A,R
		BIT 7,A
		JR Z,.set_di
		EI
		POP AF	; PE
		RET
		;
.set_di:	DI
		POP AF	; PO
		RET
;[]===========================================================[]