Sprinter-Core/src/bios/exp/FUNC_4x.ASM

905 lines
15 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

;
MACRO WAIT_HDD
LD BC,IDE.Read.Status
.loop: IN A,(C)
BIT IDE.CtrlBit.Busy,A
JR NZ,.loop
ENDM
;______________________________________________________________________:
;
; GET_BPB_OFFSET:
; ;LD A,SYS_PAGE
; ;LD HL,MS_BPB
; PUSH AF
; PUSH HL
; LD B,1
; LD IX,#0000
; LD DE,#0000
; CALL FN_HDD_READ
; POP IX
; POP AF
; PUSH AF
; PUSH IX
; LD DE,#01BE ;!HARDCODE ᬥ饭¨¥ ®â ­ ç «  ᥪâ®à  ¤«ï â ¡«¨æë à §¤¥«®¢
; ADD IX,DE
; ;
; EX AF,AF'
; IN A,(SLOT3)
; EX AF,AF'
; OUT (SLOT3),A
; ;
; LD E,(IX+8) ; ¯¥à¢ë© ᥪâ®à (LBA) ­ ç «  à §¤¥«  (DWORD)
; LD D,(IX+9)
; LD L,(IX+10)
; LD H,(IX+11)
; ;
; EX AF,AF'
; OUT (SLOT3),A
; EX AF,AF'
; ;
; PUSH HL
; POP IX
; POP HL
; POP AF
; RET
HD_BPB_PREP:
; [x] 27/01/2024 ⥯¥àì ०¨¬ ᯥªâà㬠 à ¡®â ¥â á «î¡ë¬ à §¤¥«®¬ HDD
;LD D,A
;IN A,(SLOT3)
;EX AF,AF'
; LD A,SYS_PAGE
; OUT (SLOT3),A
; LD A,(SYS_PAGE.HD_IDF_ADR.sectors)
; LD E,A
;EX AF,AF'
;OUT (SLOT3),A
;LD A,D
;LD D,#00
;LD IX,#0000
;LD B,#01
LD B,A
IN A,(SLOT3)
EX AF,AF'
LD A,SYS_PAGE
OUT (SLOT3),A
LD A,(SYS_PAGE.CURRENT_HDD)
INC A
JR NZ,.configured
;
LD A,(SYS_PAGE.HD_IDF_ADR.sectors)
LD E,A
LD D,#00
LD IX,#0000
JR .done
;
.configured:
LD IX,(SYS_PAGE.HDD_PARTITION_OFFSET+2)
LD DE,(SYS_PAGE.HDD_PARTITION_OFFSET)
.done: EX AF,AF'
OUT (SLOT3),A
LD A,B
LD B,#01
;
HD_PREPARE:
PUSH AF
PUSH HL
CALL HD_CALC_SECS
JR C,.error
;
LD A,B
LD BC,IDE.Write.Counter ; “áâ ­®¢¨âì ç¨á«® ᥪâ®à®¢ ¤«ï § ¯¨á¨
OUT (C),A
IF IDE_Optimization
INC C
OUT (C),L
INC C
OUT (C),E
INC C
OUT (C),D
ELSE
LD BC,IDE.Write.Sector
OUT (C),L ; …ŠŽ<E28099>
LD BC,IDE.Write.CylinderLow
OUT (C),E ; ¤®à®¦ª  low
LD BC,IDE.Write.CylinderHigh
OUT (C),D ; ¤®à®¦ª  high
ENDIF
LD BC,IDE.Read.Control
IN A,(C)
AND #F0 ; !!!!! ¯®á¬®âà¥âì
OR H
INC B ; IDE.Write.DeviceHead
OUT (C),A
POP HL ; BUFER & PAGE
POP AF
AND A
RET
;
.error: POP HL
POP AF
SCF
RET
NEXT_ADD_SEC:
PUSH AF
LD A,B
LD BC,IDE.Write.Counter ; “áâ ­®¢¨âì ç¨á«® ᥪâ®à®¢ ¤«ï § ¯¨á¨
OUT (C),A
IF IDE_Optimization
DEC B
INC C
IN A,(C) ; IDE.Read.Sector
ADC A,E
INC B
OUT (C),A ; IDE.Write.Sector
DEC B
INC C
IN A,(C) ; IDE.Read.CylinderLow
ADC A,D
INC B
OUT (C),A ; IDE.Write.CylinderLow
DEC B
INC C
IN A,(C) ; IDE.Read.CylinderHigh
ADC A,0
INC B
OUT (C),A ; IDE.Write.CylinderHigh
LD BC,IDE.Read.Control
IN A,(C)
ELSE
LD BC,IDE.Read.Sector
IN A,(C)
ADC A,E
INC B
OUT (C),A ; IDE.Write.Sector
LD BC,IDE.Read.CylinderLow
IN A,(C)
ADC A,D
INC B
OUT (C),A ; IDE.Write.CylinderLow
LD BC,IDE.Read.CylinderHigh
IN A,(C)
ADC A,0
INC B
OUT (C),A ; IDE.Write.CylinderHigh
LD BC,IDE.Read.Control
IN A,(C)
ENDIF
LD D,A
ADC A,0
AND #0F
LD E,A
LD A,D
AND #F0
OR E
INC B
OUT (C),A ; IDE.Write.DeviceHead
POP AF
RET
; <20>ਠ¨á¯®«­¥­¨¨ ¯à®¨§¢®¤¨âáï ¢áï ¯®¤£®â®¢ª  ª
; ®¯¥à æ¨ï¬ ç⥭¨ï/§ ¯¨á¨ ¢ëç¨á«¥­¨¥
; 樫¨­¤à®¢/£®«®¢®ª/ᥪâ®à®¢ ¨ § ­¥á¥­¨¥ ¨å ¢ ॣ¨áâàë ¢¨­ç¥áâ¥à 
; ¤ «¥¥ ¯à®£à ¬¬  ¬®¦¥â á ¬  ⮫쪮 ¯®¤ âì ª®¬ ­¤ã ç¨â âì/¯¨á âì ¨
; á ¬®áâ®ï⥫쭮 ¯à®¨§¢®¤¨âì áç¨â뢠­¨¥/§ ¯¨áì ¤ ­­ëå ¢ ¢¨­ç¥áâ¥à.
; Š®¬ ­¤  㤮¡­  ¤«ï à ¡®âë ¯à®£à ¬¬ ¢ ॠ«ì­®¬ ¢à¥¬¥­¨, ª®£¤  ­¥®¡å®¤¨¬®
; ªà®¬¥ ç⥭¨ï/§ ¯¨á¨ ¤ ­­ëå ¯à®¨§¢®¤¨âì ª ª¨¥ «¨¡® ¨­ë¥ ¤¥©á⢨ï.
FN_HDD_PREPARE: ; <20>Ž„ƒŽŽŠ€ Š <>˜<E280A6>ˆŒ Ž<><EFBFBD>ˆŸŒ R/W
AND A ; ç⮡ á¡à®á¨âì CF ¥á«¨ ®­ á⮨⠨ B=0
INC B
DEC B
RET Z
CALL HD_WAIT
RET C
CALL HD_PREPARE
RET C
; [x]
EX AF,AF'
LD A,#BF ; check buffer address in SLOT3
SUB H
JR C,.SetCommand
EX AF,AF'
SAFE_PORTY
EXX
LD C,SLOT3
IN B,(C)
EXX
OUT (SLOT3),A
EX AF,AF'
.SetCommand:
LD BC,IDE.Write.Command
LD A,IDE.CMD.ATA.ReadSectorsWithRetry
; OUT (C),A
AND A
RET
FN_HDD_READ_BPB:
CALL HD_WAIT
RET C
CALL HD_BPB_PREP
JR NC,FN_HDD_READ.L1
RET
; FOR LBA ONLY - NEXT_READ
; HL - bufer, A - page
; B - numer of sectors
; DE - add_par (next+DE) (d.b. 1 for NEXT)
FN_HDD_READ_NEXT:
AND A
INC B
DEC B
RET Z ; ret if 0 sectors
CALL HD_WAIT
RET C
CALL NEXT_ADD_SEC
JR FN_HDD_READ.L1
;
; HL - BUFER, A - PAGE
FN_HDD_READ:
AND A
INC B
DEC B
RET Z
CALL HD_WAIT
CALL NC,HD_PREPARE
RET C
.L1: EXX
LD C,SLOT3
IN B,(C)
EXX
OUT (SLOT3),A
EX AF,AF'
;
SAFE_PORTY
;
LD BC,IDE.Write.Command
LD A,IDE.CMD.ATA.ReadSectorsWithRetry
OUT (C),A
.L2: WAIT_HDD
;BIT IDE.CtrlBit.DataRequest,A
AND IDE.CtrlByte.DataRequest
JR Z,.RET_PortY
;
;HD_READ_CONT
LD BC,IDE.Read.Data
.loop_read1:
DUP 16
INI ; ¢á¥£® 16 à § INI - ®¯â¨¬ «ì­®.
EDUP
JR NZ,.loop_read1
.loop_read2:
DUP 16
INI ; ¢á¥£® 16 à § INI - ®¯â¨¬ «ì­®.
EDUP
JR NZ,.loop_read2
;
LD A,H
OR L
JR NZ,.L2
;
LD A,SYS_PAGE
OUT (SLOT3),A
EX AF,AF'
LD H,high SYS_PAGE.RAM_TABLE
LD L,A
LD A,(HL)
OUT (SLOT3),A
EX AF,AF'
LD HL,#C000
JR .L2
;
.RET_PortY:
ZERO_PORTY
;
HD_RET: EXX
OUT (C),B
EXX
LD BC,IDE.Read.Error
IN A,(C)
AND A
SCF
RET NZ
;
EX AF,AF'
AND A
RET
; HL - BUFER, A - PAGE
FN_HDD_WRITE:
AND A
INC B
DEC B
RET Z
CALL HD_WAIT
RET C
CALL HD_PREPARE
RET C
EXX
LD C,SLOT3
IN B,(C)
EXX
OUT (SLOT3),A
EX AF,AF'
LD BC,IDE.Write.Command
LD A,IDE.CMD.ATA.WriteSectorsWithRetry
OUT (C),A
HD_WR_L2:
WAIT_HDD
BIT IDE.CtrlBit.DataRequest,A
JR Z,HD_RET
LD BC,IDE.Write.Data
LD D,32 ;!HARDCODE § ¢¨á¨â ®â áçñâ稪  DUP ¢ HD_WR_LOOP
HD_WR_LOOP:
DUP 16
OUTI ; ¢á¥£® 16 à § OUTI - ®¯â¨¬ «ì­®.
EDUP
DEC D
JR NZ,HD_WR_LOOP
LD A,H
OR L
JR NZ,HD_WR_L2
LD A,SYS_PAGE
OUT (SLOT3),A
EX AF,AF'
LD H,high SYS_PAGE.RAM_TABLE
LD L,A
LD A,(HL)
OUT (SLOT3),A
EX AF,AF'
LD HL,#C000 ; !HARDCODE
JR HD_WR_L2
;!FIXIT ¯®ª  à ¡®â ¥â ⮫쪮 á ®¤­¨¬ ª ­ «®¬ (¯®-áâ à®¬ã)
FN_HDD_RECAL:
LD A,IDE.Drive.Master
LD BC,IDE.Write.DeviceHead
OUT (C),A
LD A,IDE.CMD.ATA.ExecuteDeviceDiagnostic
CALL HD_CMD_EXE
;AND A
CP IDE.CtrlByte.Error
RET Z
LD BC,IDE.Read.Error
IN A,(C)
CP 1 ; !HARDCODE
RET Z
SCF
RET
;????? £«ï­ãâì
; RET C
; LD A,#1F ; RECALIBRATE
; CALL HD_CMD_EXE
; RET
; [x] 28/01/2024 à ¡®â ¥â á® ¢á¥¬¨ ª ­ « ¬¨
FN_HDD_TEST_IDE:
LD E,#00
; TEST Secondary Chanel
LD A,IDE.Chanel.Secondary
OUT (IDE.Chanel.Set),A
CALL .TEST_CHANEL
SLA E
SLA E
; TEST Primary Chanel
LD A,IDE.Chanel.Primary
OUT (IDE.Chanel.Set),A
CALL .TEST_CHANEL
; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; LD BC,IDE.Write.DeviceHead
; LD A,IDE.Drive.Master
; OUT (C),A
; ;
; CALL TEST_HDD_DRV
; ;
; JR NZ,.NO_HDD1
; SET 0,E
; .NO_HDD1:
; LD BC,IDE.Write.DeviceHead
; LD A,IDE.Drive.Slave
; OUT (C),A
; ;
; CALL TEST_HDD_DRV
; ;
; JR NZ,.NO_HDD2
; SET 1,E
; .NO_HDD2:
; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LD C,SLOT3
IN B,(C)
LD A,SYS_PAGE
OUT (SLOT3),A
;
LD A,(SYS_PAGE.CURRENT_HDD)
OUT (C),B
CP #FF
JR Z,.exit
AND 1
JR Z,.exit
LD A,IDE.Chanel.Secondary
OUT (IDE.Chanel.Set),A
; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.exit: LD A,E
AND A
SCF
RET Z ; HDD absent !
AND A
RET
.TEST_CHANEL:
LD BC,IDE.Write.DeviceHead
LD A,IDE.Drive.Master
OUT (C),A
;
CALL TEST_HDD_DRV
;
JR NZ,.NO_HDD1
SET 0,E
.NO_HDD1:
LD BC,IDE.Write.DeviceHead
LD A,IDE.Drive.Slave
OUT (C),A
;
CALL TEST_HDD_DRV
;
RET NZ
SET 1,E
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;-----------------------------------[DIFFERENT]
; <20>¥ ¤®«¦­  ¯®àâ¨âì ॣ¨áâà E!!!
TEST_HDD_DRV:
; EXP_HDD.ASM variant
LD HL,#01FE
LD BC,IDE.Write.Counter
OUT (C),L
IF IDE_Optimization
INC C
OUT (C),H ; IDE.Write.Sector
;
DEC C
DEC B
IN A,(C) ; IDE.Read.Counter
CP L
RET NZ
INC C
ELSE
LD BC,IDE.Write.Sector
OUT (C),H
LD BC,IDE.Read.Counter
IN A,(C)
CP L
RET NZ
LD BC,IDE.Read.Sector
ENDIF
IN A,(C) ; IDE.Read.Sector
CP H
RET
; TEST_HDD_DRV:
; ; EXTENDED.ASM variant
; LD HL,#00FF
; LD BC,IDE.Write.CylinderLow
; OUT (C),L
; IF IDE_Optimization
; INC C
; OUT (C),H ; IDE.Write.CylinderHigh
; INC B
; DEC C
; IN A,(C) ; ’ãâ ॣ¨áâà BC = #0254 - .CylinderLow
; CP L
; RET NZ
; INC C
; ELSE
; LD BC,IDE.Write.CylinderHigh
; OUT (C),H
; LD BC,#0254
; IN A,(C)
; CP L
; RET NZ
; LD BC,#0255
; ENDIF
; IN A,(C) ; ’ãâ ॣ¨áâà BC = #0255 - .CylinderHigh
; CP H
; RET
; [x] 07/01/2024 bit0 - master/slave, bit1: Primary/Secondary, bit2..3: ¨á¯®«ì§ãî騩áï à §¤¥« ¢ MBR
; !TODO ᤥ« âì à ¡®âã á ¯¥à¥¬¥­­ë¬¨ ¡¨®á  SYS_PAGE.IDE_0..3
FN_HDD_PART:
DI
PUSH BC
PUSH HL
;
EX AF,AF'
IN A,(SLOT3)
EX AF,AF'
;
LD C,A
AND 2
LD A,IDE.Chanel.Primary
JR Z,.SET_CH
LD A,IDE.Chanel.Secondary
.SET_CH:
OUT (IDE.Chanel.Set),A
;
LD A,C
PUSH AF
AND 1
;
LD A,IDE.Drive.Slave
JR NZ,.SET_Master_Slave
;
LD A,IDE.Drive.Master
.SET_Master_Slave:
LD BC,IDE.Write.DeviceHead
OUT (C),A
CALL TEST_HDD_DRV
JR NZ,.Error
;
CALL FN_HDD_INIT.L3
JR C,.Error
;
POP BC
LD A,SYS_PAGE
OUT (SLOT3),A
;
LD A,B
LD (SYS_PAGE.CURRENT_HDD),A
;
EX AF,AF'
OUT (SLOT3),A
;
CALL SET_BPB_OFFSET
.exit: POP HL
POP BC
EI
RET
;
.Error: POP AF
SCF
JR .exit
; [x] 27/01/2024  ¤ ¯â¨à®¢ ­  ¤«ï ª®à४⭮© à ¡®âë á FN_HDD_PART
FN_HDD_INIT:
LD C,SLOT3
IN B,(C)
LD A,SYS_PAGE
OUT (SLOT3),A
;
LD A,(SYS_PAGE.CURRENT_HDD)
OUT (C),B
INC A
JR Z,FN_HDD_PART
; !FIXIT ᤥ« âì âãâ ¢ë¡®à ¯¥à¢®£® ¯®¯ ¢è¥£®áï ¨§ SYS.IDE_0-3
CALL TEST_HDD_DRV
SCF
RET NZ
; LD BC,IDE.Write.DeviceHead
; LD A,IDE.Drive.Master
; OUT (C),A
; CALL TEST_HDD_DRV
; JR NZ,.ABSENT
;
.L3: WAIT_HDD
LD BC,IDE.Write.Command
LD A,IDE.CMD.ATA.IdentifyDevice ;!FIXIT ¯¥à¥¤¥« âì
OUT (C),A
WAIT_HDD
AND IDE.CtrlByte.DataRequest
;JR NZ,.L2
SCF
RET Z
;JR NZ,.L2
;SCF
;RET
; .ABSENT:
; LD BC,IDE.Write.DeviceHead
; LD A,IDE.Drive.Slave
; OUT (C),A
; CALL TEST_HDD_DRV
; JR Z,.L3
; SCF
; RET
;
;.L2:
LD BC,IDE.Read.Data
LD HL,SYS_PAGE.HD_IDF_ADR
IN A,(SLOT3)
LD D,A
LD A,SYS_PAGE
OUT (SLOT3),A
INIR
INIR
; B = 0
LD H,B
LD L,B
LD A,(SYS_PAGE.HD_IDF_ADR.sectors) ; ç¨á«® ᥪâ®à®¢
LD C,A
;LD HL,0
;LD B,H
LD A,(SYS_PAGE.HD_IDF_ADR.heads) ; ç¨á«® £®«®¢®ª
.loop: ADD HL,BC
DEC A
JR NZ,.loop
LD (SYS_PAGE.HD_IDF_ADR.sec_cyl),HL
WAIT_HDD
LD BC,IDE.Read.Control
IN A,(C)
AND #10
LD B,A
LD A,(SYS_PAGE.HD_IDF_ADR.heads) ; ç¨á«® £®«®¢®ª
DEC A
AND #0F
OR IDE.Drive.Master
OR B
LD H,A
LD A,(SYS_PAGE.HD_IDF_ADR.LBA_CHS)
;BIT 1,A
AND %0000'0010
JR Z,.NO_LBA
SET 6,H
.NO_LBA:
LD BC,IDE.Write.DeviceHead
OUT (C),H
LD A,(SYS_PAGE.HD_IDF_ADR.sectors) ; ç¨á«® ᥪâ®à®¢
.HDD_CONFIGURED:
LD BC,IDE.Write.Counter
OUT (C),A
LD A,D
OUT (SLOT3),A
LD A,IDE.CMD.ATA.InitializeDeviceParameters ; SET HDD PARAMETERS
;CALL HD_CMD_EXE
;RET
HD_CMD_EXE:
CALL HD_WAIT
RET C
LD BC,IDE.Write.Command
OUT (C),A
HD_WAIT:
PUSH DE
PUSH BC
PUSH AF
LD DE,0
.loop: LD BC,IDE.Read.Status
IN A,(C)
AND IDE.CtrlByte.Busy
JR Z,.EXIT
DEC DE
LD A,D
OR E
JR NZ,.loop
POP AF
POP BC
POP DE
SCF
RET
;
.EXIT: POP AF
POP BC
POP DE
AND A
RET
; ;EXTENDED.ASM Version
; HDD_LBA: ;???!!!!
; POP BC
; LD L,E
; LD E,D
; LD D,XL
; XOR A
; LD H,A
; RET
; HD_CALC_SECS:
; LD A,XH
; AND A
; SCF
; RET NZ ; ®è¨¡ª , ᫨誮¬ ¡®«ì让 HDD
; PUSH BC
; LD BC,IDE.Write.DeviceHead
; DEC B
; IN A,(C)
; BIT 6,A
; JR NZ,HDD_LBA
; ; POP BC
;EXP_HDD.ASM Version
HD_CALC_SECS:
PUSH BC
LD BC,IDE.Read.Control
IN A,(C)
AND %0100'0000
POP BC
JR Z,.CHS
; LBA
LD L,E
LD E,D
LD D,XL
LD A,XH
AND #0F ; LBA 28
LD H,A
RET
; CHS
.CHS: LD A,XH
AND A
SCF
RET NZ ; ®è¨¡ª , ᫨誮¬ ¡®«ì让 HDD
; IX,DE -  ¡á®«îâ­ë© ­®¬¥à ᥪâ®à 
PUSH IX
POP HL
;
IN A,(SLOT3)
LD C,A
LD A,SYS_PAGE
OUT (SLOT3),A
LD A,C
LD (SYS_PAGE.COPY_SLOT3),A
; HL,DE - ­®¬¥à ᥪâ®à 
; BC - ç¨á«® ᥪâ®à®¢ ­  樫¨­¤à¥
LD BC,(SYS_PAGE.HD_IDF_ADR.sec_cyl) ; ç¨á«® ᥪâ®à®¢ ­  樫¨­¤à¥
LD A,16 ; HL,DE à §¤¥«¨âì ­  BC
SCF
.DIV_LOOP:
EX DE,HL
ADD HL,HL
EX DE,HL
ADC HL,HL
;
SBC HL,BC ; áà ¢­¨âì HL ¨ BC
JR NC,.NO_ADD ; ¯¥à¥­®á  ­¥ ¡ë«® - +1!
ADD HL,BC
DEC A
JR NZ,.DIV_LOOP
JR .DIV_END
.NO_ADD:
INC DE
DEC A
JR NZ,.DIV_LOOP
.DIV_END:
; DE - १ã«ìâ â, HL - ®áâ â®ª
; DE - 樫¨­¤à
LD A,(SYS_PAGE.HD_IDF_ADR.sectors)
; A - ç¨á«® ᥪâ®à®¢ ­  ¤®à®¦ª¥
; HL - ­®¬¥à ᥪâ®à  ¢ 樫¨­¤à¥
LD C,A
;LD BC,(MS_BPB+S_P_T) ; —ˆ‘‹Ž …ŠŽ<E28099>Ž <20>€ „Ž<E2809E>ކЅ
XOR A
LD B,A
.LOOP: SBC HL,BC
INC A
JR NC,.LOOP
;
DEC A ; A - £®«®¢ª 
ADD HL,BC ; L - ᥪâ®à
INC L
LD H,A ; HL - HEAD,SEC
;
LD A,(SYS_PAGE.COPY_SLOT3)
OUT (SLOT3),A
AND A
RET
; [x] 27/01/2024 ⥯¥àì ०¨¬ ᯥªâà㬠 à ¡®â ¥â á «î¡ë¬ à §¤¥«®¬ HDD
SET_BPB_OFFSET:
LD A,SYS_PAGE
LD HL,SYS_PAGE.MS_BPB
LD IX,#0000
LD DE,#0000
LD B,1
CALL FN_HDD_READ
;
EX AF,AF'
IN A,(SLOT3)
EX AF,AF'
OUT (SLOT3),A
;
LD A,(SYS_PAGE.CURRENT_HDD)
RRCA
RRCA
AND 3
INC A
LD B,A
;
; ; ᬥ饭¨¥ ®â ­ ç «  ᥪâ®à  ¤«ï â ¡«¨æë à §¤¥«®¢ c ¯¥à¢ë¬ ᥪâ®à®¬ LBA ¤«ï ¯¥à¢®£® à §¤¥« 
LD HL,SYS_PAGE.MS_BPB - _sMBR_PARTITION_RECORD + _sBOOT_SECTOR.PARTITION_TABLE
LD DE,_sMBR_PARTITION_RECORD
.loop: ADD HL,DE
DJNZ .loop
;
LD A,_sMBR_PARTITION_RECORD.Start_LBA
ADD L
LD L,A
LD DE,SYS_PAGE.HDD_PARTITION_OFFSET
LD C,_sMBR_PARTITION_RECORD.Size_LBA - _sMBR_PARTITION_RECORD.Start_LBA
LDIR
; [x] 07/07/2024 fix bug with select empty partition record
EX DE,HL
XOR A
LD B,_sMBR_PARTITION_RECORD.Size_LBA - _sMBR_PARTITION_RECORD.Start_LBA
.loop2: DEC HL
OR (HL)
DJNZ .loop2
SUB 1
;
EX AF,AF'
OUT (SLOT3),A
EX AF,AF'
RET
; ENDMODULE
;************************************************
; ?????
; DB 'HDD_DRV_END'
; ‚室:
; C - ª®¬ ­¤ 
; 0 - INIT - ¢å®¤­ëå ¯ à ­¥â => A - ç¨á«® ¯®¤¤¥à¦¨¢ ¥¬ëå ¤¨áª®¢.
; 1 - RESET - ¢ë¡®à ¤¨áª  A - ­®¬¥à ¤¨áª  ®â 0 =>
; 2 - (STATUS) !!!!! TEST?
; 3 - MEDIA CHECK - A - ­®¬¥à ¤¨áª  => A = 0 - old. #FF - new (¢á¥£¤  #FF) !!!!! PREPARE???
; 4 - READ BPB - A - ¤¨áª HL -  ¤à¥á ¢ ⥪ã饩 áâà ­¨æ¥.
; 5 - READ - A - ¤¨áª, IX:DE ᥪâ®à, HL -  ¤à¥á, B - ç¨á«® ᥪâ®à®¢
; 6 - WRITE - '' -
; 7 - PART
; 8 - READ_NEXT
;
; ®è¨¡ª¨ - CF - A - ®è¨¡ª 
;
; 0 - ­¥â ®è¨¡ª¨
; 1 - ­¥¢¥à­ ï ª®¬ ­¤ 
; 2 - ­¥¢¥à­ë© ­®¬¥à ¤¨áª 
; 3 - ­¥¢¥à­ë© ä®à¬ â (­¥ MS-DOS)
; 4 - ­¥â £®â®¢­®áâ¨
; 5 - ®è¨¡ª  ¯®§¨æ¨®­¨à®¢ ­¨ï
; 6 - ᥪâ®à ­¥ ­ ©¤¥­
; 7 - ®è¨¡ª  CRC
; 8 - § é¨â  § ¯¨á¨
; 9 - ®è¨¡ª  ç⥭¨ï
; 10 - ®è¨¡ª  § ¯¨á¨
; 11 - ƒ‹žŠ
;