Sprinter-BIOS/bios/exp/EXTENDED/IDE/ATA_DRV.ASM
2026-05-19 19:46:03 +10:00

671 lines
14 KiB
NASM
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;========================================================
;R03 !25.07.2001! BUG FIX WITH RETURN ERROR CODE
;R02 !24.07.2001! ADD SECONDARY CHANEL
;R01 !16.08.2000! REMOVED "DI"
/*
;Write
IDE.Write.Command EQU #4153 ; #1F7 Command
IDE.Write.DeviceHead 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
IDE.Read.Status 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 IDE.Read.Status
;---[]
BSY EQU 7
RDY EQU 6
DRQ EQU 3
ERR EQU 0
;---[]
HDD EQU 1
CDROM EQU 2
;EQU FOR IY+
IDE.HDD_INIT_TABLE.DRV_Flags EQU 0
IDE.HDD_INIT_TABLE.SectorsPerTrack EQU 1
IDE.HDD_INIT_TABLE.HeadsNumber EQU 2
IDE.HDD_INIT_TABLE.CylinderNumberLow EQU 3
IDE.HDD_INIT_TABLE.CylinderNumberHigh EQU 4
IDE.HDD_INIT_TABLE.SectorsPerCylinderLow EQU 5
IDE.HDD_INIT_TABLE.SectorsPerCylinderHigh EQU 6
DTYPE_H EQU 7
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 ;RESERVED ;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 ;RESERVED ;07
WRITE_OUTI_DUPs EQU 32 ; bytes
;[]================================================================[#50]
; IN: A - <20><><EFBFBD> 4..7 - <20><><EFBFBD><EFBFBD>⢠, <20><><EFBFBD> 0..3 - <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
; B - <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>㭪樨:
; 1 - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 512 <20><><EFBFBD>⮢ Identify Device
; 2 - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><E0A8A9><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E8A8A2> <20><><EFBFBD><EFBFBD>
; HL - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 71 <20><><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
; OUT: NC - <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E8A8A2><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; <09>F - <20> A <20><><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><E8A8A1>
ATA_5x_GET_DRIVE_NAME:
LD C,IDE.Device.HDD
LD E,IDE.CMD.ATA.IdentifyDevice
JP ATAxx_IdentifyDevice
;[]================================================================[#50]
;[]================================================================[#51]
;Function: Reset drive
ATA_5x_RESET: ; !FIXIT <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
;For non-ATAPI drives, the only method a driver has of resetting a drive
; after a major error is to do a "software reset" on the bus.
; Set bit 2 (SRST, value = 4) in the proper Control Register for the
; bus. This will reset both ATA devices on the bus. Then, you have to
; clear that bit again, yourself. The master drive on the bus is
; automatically selected.
XOR A
RET
;[]================================================================[#51]
;[]================================================================[#58]
;Function: Get Current Media Parameters
; A - Disk
;Return:
; H - Heads
; L - Sectors per cylinder
; DE - Cylinders
; IX - Capacity sector in bytes
; B - Flags: MASTER/SLAVE, LBA/CHS
ATA_5x_GET_PAR:
LD C,IDE.Device.HDD
CALL SELECT_DRIVE
RET C
IN A,(SLOT3)
EX AF,AF'
LD A,SYS_PAGE
OUT (SLOT3),A
LD A,(IY+IDE.HDD_INIT_TABLE.MediaParameters)
LD L,(IY+IDE.HDD_INIT_TABLE.SectorsPerTrack)
LD H,(IY+IDE.HDD_INIT_TABLE.HeadsNumber)
LD E,(IY+IDE.HDD_INIT_TABLE.CylinderNumberLow)
LD D,(IY+IDE.HDD_INIT_TABLE.CylinderNumberHigh)
LD B,(IY+IDE.HDD_INIT_TABLE.DRV_Flags)
LD IX,512 ;!HARDCODE ; [ ] sector size
EX AF,AF'
OUT (SLOT3),A
EX AF,AF'
AND A
RET
;[]================================================================[#58]
;[]================================================================[#59]
;Function: Set Current Media Parameters
; A - Disk
; H - Heads
; L - Sectors
; DE - Cylinders
; IX - Capacity sector in bytes
; B - Flags
;Return: None
ATA_5x_SET_PAR:
LD C,IDE.Device.HDD
CALL SELECT_DRIVE
RET C
IN A,(SLOT3)
EX AF,AF'
LD A,SYS_PAGE
OUT (SLOT3),A
LD (IY+IDE.HDD_INIT_TABLE.SectorsPerTrack),L
LD (IY+IDE.HDD_INIT_TABLE.HeadsNumber),H
LD (IY+IDE.HDD_INIT_TABLE.CylinderNumberLow),E
LD (IY+IDE.HDD_INIT_TABLE.CylinderNumberHigh),D
LD (IY+IDE.HDD_INIT_TABLE.DRV_Flags),B
;!TODO ; [ ] sector size
;!TODO ; [ ] UnitAttention
EX AF,AF'
OUT (SLOT3),A
;EX AF,AF'
;AND A
RET
;[]================================================================[#59]
;[]================================================================[#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)
ATA_5x_READ: ;PUSH IY ; !FIXIT <20><>祬?
LD C,0 ; <20><EFBFBD><E0A8A7><EFBFBD> short
EX AF,AF'
IN A,(SLOT3)
EX AF,AF'
JP ATA_5x_LONG_READ.main
;[]================================================================[#52]
;Function: Long Read Sectors
; A - Disk
; HL:IX - Sector
; DE - Address
; B - Sector counter, 0 = 256
; A'- Memory Page Number
;Return:
; HL:IX - Sector + Sector counter
; DE - Address + (Sector counter * Size sector)
; A' - Last mem page in RAM Block used for readed data
;LONG READ SECTOR(S)
ATA_5x_LONG_READ:
;PUSH IY ; !FIXIT <20><>祬?
LD C,1 ; <20><EFBFBD><E0A8A7><EFBFBD> long
.main: SAFE_PORTY_2
PUSH BC
PUSH IX
PUSH HL
;
EX AF,AF'
AND A ;read
EX AF,AF'
CALL RW_ATA_SECTORs
;
.shared: EX DE,HL
JR C,.error
LD A,XH ; current page in mem block for SLOT3
EX AF,AF'
;
POP HL
POP IX
POP BC
; HL:IX + B. <20>᫨ B=0, <20><> B=256
XOR A
CP B
LD C,B
CCF
RLA
LD B,A
ADD IX,BC
JR NC,.exit
INC HL
CCF
;
.exit: RESTORE_PORTY
;POP IY
RET
;
.error: LD B,A ; A - <20><><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><E8A8A1>
LD C,XL
LD A,XH ; current page in mem block for SLOT3
EX AF,AF'
POP HL
POP IX
PUSH BC
LD B,0
ADD IX,BC
;
;LD C,B
;ADC HL,BC
JR NC,.no_inc_hl
INC HL
.no_inc_hl: ;
POP BC
POP AF
SUB C
LD C,A
LD A,B
LD B,C
SCF ;R03
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)
ATA_5x_WRITE: ;PUSH IY ; !FIXIT <20><>祬?
LD C,0 ; <20><EFBFBD><E0A8A7><EFBFBD> short
EX AF,AF'
IN A,(SLOT3)
EX AF,AF'
JP ATA_5x_LONG_WRITE.main
;[]================================================================[#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)
ATA_5x_LONG_WRITE:
;PUSH IY ; !FIXIT <20><>祬?
LD C,1 ; <20><EFBFBD><E0A8A7><EFBFBD> long
.main: SAFE_PORTY_2
PUSH BC
PUSH IX
PUSH HL
;
EX AF,AF'
SCF ;write
EX AF,AF'
CALL RW_ATA_SECTORs
;
JP ATA_5x_LONG_READ.shared
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
; !TODO <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 8-bit data transfer mode <20><><EFBFBD> <20><EFBFBD><E0A5A2><EFBFBD> <20><><EFBFBD>
; A - Disk
; HL:IX - Sector
; DE - Address
; B - Sector counter
; C - short/long
; A'- Memory Page Number
; CF'=1 - write, CF'=0 - read
RW_ATA_SECTORs: PUSH BC ; <20><EFBFBD><E0A8A7><EFBFBD> short/long <20> C
LD C,IDE.Device.HDD
CALL SELECT_DRIVE
POP BC ; <20><EFBFBD><E0A8A7><EFBFBD> short/long <20> C
RET C
;
EXX
LD DE,256*(IDE.CtrlByte.Busy+IDE.CtrlByte.Ready) + IDE.CtrlByte.Ready
CALL WAITPRT.custom_DE
EXX
RET C
;
EX AF,AF'
PUSH AF ; memory page number
PUSH BC ; <20><EFBFBD><E0A8A7><EFBFBD> short/long <20> C
PUSH DE ; Address
CALL PRESET
; IY <20><> SELECT_DRIVE <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><EFBFBD>
;
POP HL ; Address
POP IY ; <20><EFBFBD><E0A8A7><EFBFBD> short/long <20> YL
POP AF ; memory page number
LD XL,0
LD XH,A ; memory page number
LD BC,IDE.Write.Command
LD A,IDE.CMD.ATA.WriteSectorsWithRetry
JR C,.set_command ; CF = r/w
;
LD A,IDE.CMD.ATA.ReadSectorsWithRetry
.set_command: OUT (C),A
EX AF,AF'
EXX
LD DE,256*(IDE.CtrlByte.Busy+IDE.CtrlByte.DataRequest+IDE.CtrlByte.Error)+IDE.CtrlByte.DataRequest
CALL WAITPRT.custom_DE
EXX
RET C
;DI ;R01 REMOVED "DI"
.big_loop: IN A,(SLOT3)
EX AF,AF' ;>-----------> \
LD A,XH
OUT (SLOT3),A
LD BC,IDE.Read.Data
JR C,.write_sector
;
; READ SECTOR 512 bytes ;!HARDCODE sector size
.loop_256_1: DUP 16
INI
EDUP
JP NZ,.loop_256_1
.loop_256_2: DUP 16
INI
EDUP
JP NZ,.loop_256_2
AND A
;EX AF,AF'
; ; ; ; ;
; CF=0
.return_rw: EX AF,AF' ;<-----------< /
INC XL ;INC LOADED SECTORS
OUT (SLOT3),A
;
LD A,H
OR L
JR NZ,.end_pass
; short/long
; A = 0
SUB YL
JR NC,.END_BUFFER
; next page in mem block
CALL CHANGE_MEM_BLK
; 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
;
.end_pass: ;INC XL ;INC LOADED SECTORS
EXX
CALL WAITPRT
EXX
RET C
;
;INC XL ;INC LOADED SECTORS
LD BC,IDE.Read.Status
IN A,(C)
BIT IDE.CtrlBit.DataRequest,A
RET Z
;
JP .big_loop
;
.write_sector: ; WRITE SECTOR 512 bytes ;!HARDCODE sector size
INC B ; LD BC,IDE.Write.Data
LD D,512/WRITE_OUTI_DUPs ;!HARDCODE sector size
.loop: DUP WRITE_OUTI_DUPs
OUTI
EDUP
DEC D
JR NZ,.loop
SCF
JP .return_rw
; ;
.END_BUFFER: CALL ATA_IdlePasses.CHECK_DRV
JR NZ,ATA_IdlePasses.Enter
RET
;;;;;;;;;;;;;;;;;
ATA_IdlePasses: CALL .CHECK_DRV
JR NZ,.Enter
;
RET C
LD A,BIOS.Error.Failure
SCF
RET
;
.Enter: XOR A ; <20><><EFBFBD><EFBFBD><20><><EFBFBD> READ_ZEROS, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> .WrZeros
EX AF,AF'
LD BC,IDE.Read.Data
JR C,.WrZeros
; READ > /dev/null
EX AF,AF'
.RdLoop: IN F,(C) ; <20><><EFBFBD> <20><> 1 ࠧ<> <20> <20><><EFBFBD><E2ADAE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><E2A0A5><EFBFBD> WORD
DEC A
JR NZ,.RdLoop
JR ATA_IdlePasses
; WRITE ZEROS
.WrZeros: EX AF,AF'
;
.WrLoop: OUT (C),A
DJNZ .WrLoop
;
.WrLoop2: OUT (C),A
DJNZ .WrLoop2
JR ATA_IdlePasses
;
.CHECK_DRV: EXX
CALL WAITPRT
EXX
RET C
;
LD BC,IDE.Read.Status
IN A,(C)
BIT IDE.CtrlBit.DataRequest,A
RET
;!TODO <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><E0AEA9><EFBFBD>
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
;[]================================================================[#54]
;Function: Verify Sectors
; A - Disk
; HL:IX - Sector
; B - Sector counter
;Return: CF - error
;VERIFY SECTOR(S)
ATA_5x_VERIFY: ;PUSH IY ; !FIXIT <20><>祬?
SAFE_PORTY_2
PUSH IX
PUSH HL
CALL .VERIFY
POP HL
POP IX
RESTORE_PORTY
;POP IY
RET
;VERIFY SECTOR(S)
.VERIFY: LD C,IDE.Device.HDD
CALL SELECT_DRIVE
RET C
EXX
LD DE,256*(IDE.CtrlByte.Busy+IDE.CtrlByte.Ready) + IDE.CtrlByte.Ready
CALL WAITPRT.custom_DE
EXX
RET C
;PUSH DE
; IN A,(SLOT3)
; PUSH AF
CALL PRESET
; POP AF
; OUT (SLOT3),A
;POP HL
LD BC,IDE.Write.Command
LD A,IDE.CMD.ATA.ReadVerifySectorsWithRetry
OUT (C),A
LD BC,IDE.Read.Status
IN A,(C)
RRA ;BIT IDE.CtrlBit.Error,A : SCF : RET NZ
RET C
;
JP WAITPRT
;RET C
;XOR A
;RET
;[]================================================================[#54]
; HL:IX - LBA SECTOR
; B - SECTOR COUNTER
; <20><>室: SLOT3 = SYS_PAGE
PRESET: LD A,B
LD BC,IDE.Write.Counter
OUT (C),A
;
IN A,(SLOT3)
EX AF,AF'
LD A,SYS_PAGE
OUT (SLOT3),A
LD A,(IY+IDE.HDD_INIT_TABLE.DRV_Flags)
LD BC,IDE.Write.DeviceHead
OUT (C),A
;<3B><><EFBFBD> CHS/LBA ;!FIXIT ᤥ<><E1A4A5><EFBFBD><EFBFBD> <20><><EFBFBD><E2AAA0> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
AND %0100'0000
LD E,XL
LD D,XH
CALL Z,LBA_CHS
LD BC,IDE.Write.Sector
OUT (C),E ;LBA 0..7
;
INC C ; LD BC,IDE.Write.CylinderLow
OUT (C),D ;LBA 8..15
INC C ; LD BC,IDE.Write.CylinderHigh
OUT (C),L ;LBA 16..23
LD BC,IDE.Read.Control
IN A,(C)
AND #F0 ;!HARDCODE DRIVE/HEAD REGISTER PHISICAL DISK bitmask
OR H ;LBA 24..27
INC B ; LD BC,IDE.Write.DeviceHead
;
OUT (C),A
EX AF,AF'
OUT (SLOT3),A
;AND A
RET
;PRESET ;
; HL:DE - SECTOR OFFSET
LBA_CHS: LD C,(IY+IDE.HDD_INIT_TABLE.SectorsPerCylinderLow)
LD B,(IY+IDE.HDD_INIT_TABLE.SectorsPerCylinderHigh)
;
DIV32X: ;HL:DE / BC => DE:IX HL-OSTATOK
LD XH,D
LD XL,E
EX DE,HL
LD HL,0
LD A,#20
;
.loop: ADD IX,IX
EX DE,HL
ADC HL,HL
EX DE,HL
ADC HL,HL
SBC HL,BC
JR NC,.DIV012
;
ADD HL,BC
DEC A
JR NZ,.loop
;
JR .DIV014
;
.DIV012: INC IX
DEC A
JR NZ,.loop
;
.DIV014: LD E,(IY+IDE.HDD_INIT_TABLE.SectorsPerTrack)
LD D,0
XOR A
;
.loop2: INC A
SBC HL,DE
JR NC,.loop2
;
ADD HL,DE
DEC A
LD H,A
LD E,L
INC E
LD D,XL
LD A,XH
LD L,A
RET
;----------------------------------------------------------------------;
; D - MASK
; E - PATTERN
; !!! <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>㭪樨 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><> <20><><EFBFBD> <20><EFBFBD><E1A5A3> ZF
WAITPRT: LD DE,256*(IDE.CtrlByte.Busy+IDE.CtrlByte.Ready+IDE.CtrlByte.Error) + IDE.CtrlByte.Ready
.custom_DE: LD HL,#0000 ; <20><><EFBFBD><EFBFBD><EFBFBD> ;!HARDCODE
.custom: LD BC,IDE.Read.Status
;
.loop: PUSH HL ; 11
; ;;;;;;;;;
.loop2: IN A,(C) ; 12
AND D ; 4
CP E ; 4
JR Z,.ok ; 7
;
DEC HL ; 6
LD A,L ; 4
OR H ; 4
JP NZ,.loop2 ; 10
; ;;;;;;;;; 51
POP HL ; 10
DEC L ; 4
JR NZ,.loop ; 12
; error ;;;;;;;;; 37
LD A,BIOS.Error.NotReady
SCF
RET
;
.ok: POP HL
RET
;----------------------------------------------------------------------;
;[]================================================================[#57]
;[x] 18/12/2023. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> API CD-ROM (ATAPI)
; [ ] media change
;Function: Detect Disk
; A - Disk
;Return: CF=0 - A=Drive type
; CF=1 - error
ATA_5x_DETECT: LD C,IDE.Device.HDD
.shared: CALL SELECT_DRIVE
RET C
;
LD B,A
AND %0000'0011 ;[ ] media change <20><><EFBFBD><E0A5A4><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20> <20> <20><><EFBFBD>? ; !FIXIT
JR NZ,.notZero
LD A,C
RET
;
.notZero: AND %0000'0010
JR NZ,.UnitAttention
; C = DriveType
LD A,C
CP IDE.Device.ATAPI
JR Z,.AtapiCheckMedia
;!FIXIT AtaCheckMedia - <20><><><E1A4A5><EFBFBD><EFBFBD> ; [ ] media change
AND A
RET
;
.AtapiCheckMedia:
PUSH BC ; B - MediaParameters, C - DriveType
CALL ATAPI_CHECK_MEDIA_CHANGED
POP BC ; B - MediaParameters, C - DriveType
RET C
LD A,C
RET
;
.UnitAttention: LD A,BIOS.Error.ATAPI.UnitAttention
SCF
RET
;[]================================================================[#57]