mirror of
https://github.com/Tolik-Trek/Sprinter-BIOS.git
synced 2026-06-15 09:21:46 +03:00
671 lines
14 KiB
NASM
671 lines
14 KiB
NASM
|
||
;========================================================
|
||
;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] |