Sprinter-BIOS/src/bios/exp/EXTENDED/IDE/ATAPI_DRV.ASM
Tolik 4caee04133 5x Read/Write отличаются от R/W Long тем, что R/W
теперь при HL=0 не переключают страницу. Вместо
этого выдаётся ошибка. В случае записи пишутся 0 в
оставшиеся сектора. Мелкие фиксы.
2025-04-14 00:57:06 +10:00

1006 lines
23 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.

;[x] 18/12/2023. ¤®¡ ¢«¥­¨¥/¤®¯¨«¨¢ ­¨¥ API CD-ROM (ATAPI)
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;CD ROM DRIVE DRIVER
;---------------------------------------------------------------
;Rev Date Name Description
;---------------------------------------------------------------
; 02-08-2001 DNS Initial this module
;---------------------------------------------------------------
;========================================================
;!TODO ;!TODO ;!TODO ;!TODO ;!TODO ;!TODO ;!TODO ;!TODO ;!TODO ;!TODO ;!TODO ;!TODO
;
; [ ] ãáâ ­®¢ª  ¯ à ¬¥âà  ¬ ªá¨¬ «ì­®£® à §¬¥à  ¤«ï ç⥭¨ï ç¥à¥§ DRV_SET_PAR
;
;----------------------------------------------------------------------------------
MAX_ATAPI_SEC_SIZE EQU 4096/2
PACKET_SIZE EQU 12 ; !FIXIT ¡à âì ¨§ IDENTIFY PACKET DEVICE
RAM_ATAPI_PK EQU SYS_PAGE.SHARED_BUFFER_32b
RAM_ATAPI_RW_CMD EQU SYS_PAGE.SHARED_BUFFER_32b+16
MAX_DATA_PACKET_FOR_REQUEST_SENSE EQU 254
ASSERT ((PACKET_SIZE % 4) = 0), "PACKET_SIZE must be an even number"
;[]================================================================[#51]
;!FIXIT ᤥ« âì ­ áâ®ï騩 à¥á¥â
ATAPI_5x_RESET: LD C,IDE.Device.ATAPI
CALL SELECT_DRIVE
RET C
LD B,50
.loop: PUSH BC
CALL EXEC_TEST_CMD
;!FIXIT ;[ ] sector size. ᤥ« âì २­¨â HDD_INIT_TABLE
POP BC
RET NC
;
;CALL ATAPI_CHECK_MEDIA_CHANGED.noWait
;RET C
CP BIOS.Error.ATAPI.UnitAttention
SCF
RET Z
;!FIXIT ­¥ âண âì ¯à¥à뢠­¨ï
EI
HALT
DJNZ .loop
RET
;[]================================================================[#51]
;[]================================================================[#58]
;Function: Get Current Media Parameters
; A - Disk
;Return:
; H - Heads ; [ ] For ATAPI HL:DE - media size in sectors
; L - Sectors per cylinder ;
; DE - Cylinders ;
; IX - Capacity sector in bytes
; B - Flags: MASTER/SLAVE, LBA/CHS
; [ ] A - HDD_INIT_TABLE.MediaParameters
; IF media changed
; [ ] CF' = 1, A' = error number UnitAttention
ATAPI_5x_GET_PAR:
LD C,IDE.Device.ATAPI
CALL SELECT_DRIVE
RET C
;
.DriveSelected: IN A,(SLOT3)
AND A
PUSH AF
EX AF,AF'
LD A,SYS_PAGE
OUT (SLOT3),A
;
; [ ] sector size. media changed
CALL ATAPI_CHECK_MEDIA_CHANGED
EX AF,AF'
POP AF
EX AF,AF'
JR NC,.get_data
;
CP BIOS.Error.ATAPI.UnitAttention
JR Z,.UnitAttention
;
;CP BIOS.Error.ATAPI.NotReady
;SCF
;RET NZ
EX AF,AF'
OUT (SLOT3),A
EX AF,AF
LD HL,#FFFF
LD D,H
LD E,L
SCF
RET
;
.UnitAttention: RES 1,(IY + IDE.HDD_INIT_TABLE.MediaParameters) ; [ ] removable media
EX AF,AF'
SCF
EX AF,AF'
.get_data: ;
LD A,(IY+IDE.HDD_INIT_TABLE.MediaParameters)
LD B,(IY+IDE.HDD_INIT_TABLE.DRV_Flags)
; [ ] sector size
LD E,(IY+IDE.HDD_INIT_TABLE.SectorSize)
LD D,(IY+IDE.HDD_INIT_TABLE.SectorSize + 1)
LD XL,E
LD XH,D
; [ ] media size
LD L,(IY+IDE.HDD_INIT_TABLE.MediaSizeHigh)
LD H,(IY+IDE.HDD_INIT_TABLE.MediaSizeHigh+1)
LD E,(IY+IDE.HDD_INIT_TABLE.MediaSizeLow)
LD D,(IY+IDE.HDD_INIT_TABLE.MediaSizeLow+1)
;
EX AF,AF'
OUT (SLOT3),A
LD A,BIOS.Error.ATAPI.UnitAttention ; ¥á«¨ CF, â® ­®¬¥à ®è¨¡ª¨
EX AF,AF
RET
;[]================================================================[#58]
;[]================================================================[#59]
; [ ] media changed
ATAPI_5x_SET_PAR:
LD L,B
LD C,IDE.Device.ATAPI
CALL SELECT_DRIVE
RET C
;
IN A,(SLOT3)
EX AF,AF'
LD A,SYS_PAGE
OUT (SLOT3),A
;
LD (IY+IDE.HDD_INIT_TABLE.MediaParameters),B
EX AF,AF
OUT (SLOT3),A
RET
;[]================================================================[#59]
;!TODO
; atapi.pdf áâà. 24 § ¯¨áì/ç⥭¨¥ ¬®£ãâ ¡ëâì ¬ ªá¨¬ «ì­ë¬¨ ¡«®ª ¬¨ ¢ ­¥áª®«ìª® § å®¤®¢
;[]================================================================[#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)
ATAPI_5x_READ: PUSH IY
LD C,0 ; ¯à¨§­ ª short
EX AF,AF'
IN A,(SLOT3)
EX AF,AF'
JP ATAPI_5x_LONG_READ.main
;[]================================================================[#52]
;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)
;LONG READ SECTOR(S)
ATAPI_5x_LONG_READ:
;AND A
;
PUSH IY
LD C,1 ; ¯à¨§­ ª long
.main: SAFE_PORTY_2
PUSH BC
PUSH IX
PUSH HL
;
EX AF,AF'
AND A ;read
EX AF,AF'
CALL RW_ATAPI_SECTORs
; [ ] sector size. media changed
JP ATA_5x_LONG_READ.shared
; JP NC,ATA_5x_LONG_READ.shared
; CP BIOS.Error.UnitAttention
; JR Z,ATAPI_MEDIA_ERROR
; SCF
;[]================================================================[#52]
; INPUT:
; A - Disk
; HL:IX - Sector
; DE - Address
; B - Sector counter
; A'- Memory Page Number
; CF'=1 - write, CF'=0 - read
;
; OUTPUT:
;
RW_ATAPI_SECTORs:
PUSH BC
LD C,IDE.Device.ATAPI
CALL SELECT_DRIVE
POP BC
RET C
;
EXX
LD C,SLOT3
IN B,(C)
PUSH BC
LD A,SYS_PAGE
OUT (C),A
; [ ] media change
LD A,(IY + IDE.HDD_INIT_TABLE.MediaParameters)
AND %0000'0010
JR NZ,.error_media
;
LD HL,ATAPI_CMD_PACKET.READ
EX AF,AF'
JR NC,.read_cmd
LD HL,ATAPI_CMD_PACKET.WRITE
.read_cmd: EX AF,AF'
LD DE,RAM_ATAPI_RW_CMD
LD BC,PACKET_SIZE
LDIR
EXX
;
LD A,H
LD H,L
LD L,A
LD (RAM_ATAPI_RW_CMD + ATAPI_PACKET.SECTOR+0),HL
LD A,XH
LD (RAM_ATAPI_RW_CMD + ATAPI_PACKET.SECTOR+2),A ;R01
LD A,XL
LD (RAM_ATAPI_RW_CMD + ATAPI_PACKET.SECTOR+3),A ;R01
LD A,B
LD (RAM_ATAPI_RW_CMD + ATAPI_PACKET.COUNTER+1),A ;R01
;
LD YL,C ; ¯à¨§­ ª short/long ¨§ C ¢ YL
LD HL,RAM_ATAPI_RW_CMD
CALL EXEC_PACKET_COMMAND.start
;
.exit: POP BC
OUT (C),B
RET
;
.error_media: EXX
LD A,BIOS.Error.ATAPI.UnitAttention
SCF
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)
ATAPI_5x_WRITE: PUSH IY
LD C,0 ; ¯à¨§­ ª short
EX AF,AF'
IN A,(SLOT3)
EX AF,AF'
JP ATAPI_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)
ATAPI_5x_LONG_WRITE:
;AND A
;
PUSH IY
LD C,1 ; ¯à¨§­ ª long
.main: SAFE_PORTY_2
PUSH BC
PUSH IX
PUSH HL
;
EX AF,AF'
SCF ;write
EX AF,AF'
CALL RW_ATAPI_SECTORs
;
JP ATA_5x_LONG_READ.shared
;[]================================================================[#57]
;Function: Detect Disk
; A - Disk
;Return: CF=0 - A=Drive type
; B=MediaParameters byte ; [ ] media change
; CF=1 - drive not present, A=#02
; ATAPI_5x_DETECT: LD C,IDE.Device.ATAPI
; AND %1011'1111
; .shared: LD D,A
; LD E,C
; PUSH DE
; CALL DRV_DETECT
; POP DE
; RET C
; ;
; PUSH AF
; LD C,SLOT3
; IN B,(C)
; LD A,SYS_PAGE
; OUT (C),A
; INC HL ;!HARDCODE HDD_INIT_TABLE
; INC HL
; INC HL
; LD A,(HL)
; OUT (C),B
; LD B,A
; AND %0000'0011 ;[ ] media change ¯¥à¥¤¥« âì «®£¨ªã âãâ ¨ ¢ „‘‘? ; !FIXIT
; JR NZ,.error
; ;
; .exit: POP AF
; RET
; ;
; .error: AND %0000'0010
; JR NZ,.UnitAttention
; ;
; LD A,D
; LD C,E
; CALL SELECT_DRIVE
; CALL ATAPI_CHECK_MEDIA_CHANGED
; JR NC,.exit
; POP BC
; RET
; ;
; .UnitAttention: POP AF
; LD A,BIOS.Error.ATAPI.UnitAttention
; SCF
; RET
;[]================================================================[#57]
;[]================================================================[#57]
;Function: Detect Disk
; A - Disk
;Return: CF=0 - A=Drive type
; B=MediaParameters byte ; [ ] media change
; CF=1 - drive not present, A=#02
ATAPI_5x_DETECT:
LD C,IDE.Device.ATAPI
JP ATA_5x_DETECT.shared
;[]================================================================[#57]
;[]================================================================[#5E]
; [ ]
;Function: Extended
; A - Disk
; B - SubFunction
;Return:
; [ ] à á¯¨á âì ¢ ¤®ª¥
ATAPI_5x_Extended:
LD C,IDE.Device.ATAPI
CALL SELECT_DRIVE
RET C
;
LD A,B
CP 2
JR C,TRAY_FN ; B = 0 ¨«¨ 1
;
JR Z,ATAPI_REQUEST_SENSE ; B = 2
;
CP 3
JR Z,ATAPI_CUSTOM_CMD
; ...
LD A,BIOS.Error.InvalidSubFunction
SCF
RET
;[]================================================================[#5E]
;----------------------------------------------------------------------;!TODO ᤥ« âì ¤®áâ㯭®© ç¥à¥§ à áè¨à¥­­ãî äã­ªæ¨î API
; ¢å®¤: DE -  ¤à¥á ¤«ï ¤ ­­ëå
ATAPI_REQUEST_SENSE:
IN A,(SLOT3)
EX AF,AF'
.FN: LD HL,ATAPI_CMD_PACKET.REQUEST_SENSE
JR EXEC_PACKET_COMMAND.start
;----------------------------------------------------------------------;
;[ ] media changed
;----------------------------------------------------------------------;
ATAPI_CHECK_MEDIA_CHANGED:
CALL EXEC_TEST_CMD ;!FIXIT   ¬®¦¥â ¨ ­¥ ­ ¤®
RET C
; .skip_nop: EXX
; CALL ATAPI_WAITPRT
; EXX
; LD A, high IDE.Read.Status
; IN A,(low IDE.Read.Status)
; RRA
; ;RET NC
;JR C,.noWait
;
EXX
LD C,SLOT3
IN B,(C)
LD A,SYS_PAGE
OUT (C),A
;
LD A,(IY + IDE.HDD_INIT_TABLE.MediaParameters)
OUT (C),B
EXX
RRA
RRA
LD A,BIOS.Error.ATAPI.UnitAttention
RET
;----------------------------------------------------------------------;
;[ ] media changed
;----------------------------------------------------------------------;
ATAPI_CHECK_ERROR:
CALL ATAPI_GET_ERROR_REG
;CP BIOS.Error.ATAPI.NoSence
;JP Z,ATAPI_MEDIA_ERROR
CP BIOS.Error.ATAPI.NotReady
JP Z,ATAPI_MEDIA_ERROR
CP BIOS.Error.ATAPI.UnitAttention
JP Z,ATAPI_MEDIA_ERROR
;
SCF
RET
;----------------------------------------------------------------------;
;----------------------------------------------------------------------;
; HL - 㪠§ â¥«ì ­  ¯ ª¥â­ãî ª®¬ ­¤ã (¯¥à¢ë© ¨«¨ ¢â®à®© á«®â)
; DE - 㪠§ â¥«ì ­  ¡ãää¥à ¤«ï ª®¬ ­¤ë
ATAPI_CUSTOM_CMD:
IN A,(SLOT3)
EX AF,AF'
LD A,1 ; ¯à¨§­ ª, çâ® ®è¨¡ª  ᬥ­ë ­®á¨â¥«ï <20>… ®¡à ¡ â뢠âìáï ¢ EXEC_PACKET_COMMAND
JP EXEC_PACKET_COMMAND.start_custom
;----------------------------------------------------------------------;
;----------------------------------------------------------------------;
TRAY_FN: LD HL,ATAPI_CMD_PACKET.CLOSE
LD DE,0 ; ¬ àª¥à ⮣®, çâ® ­¥ ­ã¦­® ç¨â âì á ãáâனá⢠ ¢ އ“
DEC A
JR Z,EXEC_PACKET_COMMAND.start
LD HL,ATAPI_CMD_PACKET.OPEN
;JR EXEC_PACKET_COMMAND
; INPUT: HL - AP packet (12bytes)
; DE - address for/with data if needed
; A' - ­ ç «ì­ ï áâà ­¨æ  ¤«ï R/W Long
;
; RETURN: CF - ERROR
; !TODO CD ERRORS to INCLUDES
; #01 - RECOVERED ERROR
; #02 - NOT READY
; #03 - MEDIUM ERROR
; #04 - HARDWARE ERROR
; #05 - ILLEGAL REQUEST
; #06 - UNIT ATTETION
; #07 - DATA PROTECT
; #0B - ABORTED COMMAND
; #80 - TIME OUT
EXEC_PACKET_COMMAND:
.error_ex: EX DE,HL
.error: CP #FF
.error_fail: SCF
LD A,BIOS.Error.Failure
RET Z
;
LD A,BIOS.Error.Busy
RET
;
.error_TimeOut: CP #FF
EX DE,HL
JR Z,.error_fail
LD A,BIOS.Error.ATAPI.TimeOut
SCF
RET
;
; .start_sys_page:
; LD A,SYS_PAGE
; EX AF,AF'
;
.start: XOR A ; ¯à¨§­ ª ⮣®, çâ® ®è¨¡ª  ᬥ­ë ­®á¨â¥«ï ¤®«¦­  ®¡à ¡ â뢠âìáï ¢ EXEC_PACKET_COMMAND
.start_custom: EXX
LD C,A ; ¯à¨§­ ª ⮣®, çâ® ®è¨¡ª  ᬥ­ë ­®á¨â¥«ï ¤®«¦­  ®¡à ¡ â뢠âìáï ¢ EXEC_PACKET_COMMAND
CALL ATAPI_WAITPRT
EXX
JR NC,.READY
;
.reset: LD BC,IDE.Write.Command
LD A,IDE.CMD.ATAPI.Reset
OUT (C),A
;
LD B,#80
.pause: DJNZ .pause
;
EXX
CALL ATAPI_WAITPRT
EXX
JR C,.error_ex
;
.READY: LD C,SLOT3
IN B,(C)
PUSH DE
PUSH BC
;
LD A,SYS_PAGE
OUT (C),A
LD DE,RAM_ATAPI_PK ;!FIXIT ¬®¦¥â ­  á⥪¥ ¢ë¤¥«ïâì ¬¥áâ®?
LD BC,PACKET_SIZE
LDIR
;
POP BC
POP DE
OUT (C),B
;
XOR A
EXX
LD H,C ; ¯à¨§­ ª ⮣®, çâ® ®è¨¡ª  ᬥ­ë ­®á¨â¥«ï ¤®«¦­  ®¡à ¡ â뢠âìáï ¢ EXEC_PACKET_COMMAND
LD BC,IDE.Write.Features
OUT (C),A
LD DE,MAX_ATAPI_SEC_SIZE ;SIZE BLOCK ;!HARDCODE ¤®áâ ¢ âì ¨§ ¯¥à¥¬¥­­®© ª ª®©-­¨¡ã¤ì
LD BC,IDE.Write.ByteCountLow
OUT (C),E
LD BC,IDE.Write.ByteCountHigh
OUT (C),D
LD BC,IDE.Write.Command
LD A,IDE.CMD.ATAPI.Packet
OUT (C),A
LD C,H ; ¯à¨§­ ª ⮣®, çâ® ®è¨¡ª  ᬥ­ë ­®á¨â¥«ï ¤®«¦­  ®¡à ¡ â뢠âìáï ¢ EXEC_PACKET_COMMAND
CALL ATAPI_WAITPRT
EXX
JR C,.error_ex
;
EXX
LD DE,256*(IDE.CtrlByte.DataRequest+IDE.CtrlByte.Error)+IDE.CtrlByte.DataRequest
CALL ATAPI_WAITPRT.Custom
EXX
JR C,.error_TimeOut
;
; EXEC ATAPI PACKET COMMAND
.YEP_DRQ: LD C,SLOT3
IN B,(C)
PUSH BC
LD A,SYS_PAGE
OUT (SLOT3),A
LD HL,RAM_ATAPI_PK
LD BC,IDE.Write.Data
LD A,PACKET_SIZE/4 ; !FIXIT ¡à âì ¨§ IDENTIFY PACKET DEVICE
.OUTPKT: OUTI
OUTI
OUTI
OUTI
DEC A
JR NZ,.OUTPKT
;
POP BC
OUT (C),B
;
LD B,#80
.pause2: DJNZ .pause2
;
EX AF,AF'
LD XH,A ; áâà ­¨æ  ¤«ï R/W_LONG
LD XL,0
EX AF,AF'
EX DE,HL
;
.AP_LOOP: CALL ATAPI_CHECK_DRV
JP C,.error
RET Z
;====== IF DATA REQUEST ===============================================;
.data_request: IN A,(SLOT3)
EX AF,AF' ;>-----------> \
;
LD A,XH
OUT (SLOT3),A
;
;LD BC,IDE.Read.ByteCountLow
;IN E,(C)
;INC C ;LD BC,IDE.Read.ByteCountHigh
;IN D,(C) ;TRANSFER BLOCK SIZE
;;
;LD A,D
;OR E
;RET Z ;BLOCK = 0
;; 㬥­ìè ¥¬ áçñâ稪 § £à㦠¥¬ëå ¡ ©â®¢ ¢ 2 à § . —¨â ¥¬ ¯® 2 ¡ ©â 
;SRL D
;RR E
;;
;LD BC,IDE.Read.InterruptReason
;IN A,(C)
;AND IDE.InterruptReasonByte.IO
;LD BC,IDE.Read.Data
CALL ATAPI_PREPARE_RW
RET NC
JR Z,.WRITE_DATA
;READ
.read_loop: INI
INI
DEC DE
LD A,D
OR E
JR NZ,.read_loop
;
.return_rw: EX AF,AF' ;<-----------< /
INC XL ;INC LOADED SECTORS
OUT (SLOT3),A
;
LD A,H
OR L
JR NZ,.AP_LOOP
; short/long
; A = 0
SUB YL
JR NC,.END_BUFFER
; next page in mem block
CALL CHANGE_MEM_BLK
JR .AP_LOOP
;WRITE
.WRITE_DATA: INC B ; LD BC,IDE.Write.Data
.write_loop: OUTI
OUTI
DEC DE
LD A,D
OR E
JR NZ,.write_loop
JR .return_rw
; ;
.END_BUFFER: CALL ATAPI_CHECK_DRV
JP C,.error
JR NZ,ATAPI_IdlePasses.Enter
RET
;;;;;;;;;;;;;;;;;
ATAPI_IdlePasses:
CALL ATAPI_CHECK_DRV
JP C,EXEC_PACKET_COMMAND.error
JP Z,EXEC_PACKET_COMMAND.error_fail
;
.Enter: ;LD BC,IDE.Read.ByteCountLow
;IN E,(C)
;INC C ;LD BC,IDE.Read.ByteCountHigh
;IN D,(C) ;TRANSFER BLOCK SIZE
;;
;LD A,D
;OR E
;RET Z ;BLOCK = 0
;;
;; 㬥­ìè ¥¬ áçñâ稪 § £à㦠¥¬ëå ¡ ©â®¢ ¢ 2 à § . —¨â ¥¬ ¯® 2 ¡ ©â 
;SRL D
;RR E
;;
;LD BC,IDE.Read.InterruptReason
;IN A,(C)
;AND IDE.InterruptReasonByte.IO
;LD BC,IDE.Read.Data
CALL ATAPI_PREPARE_RW
RET NC
JR Z,.write_data
;
.read_loop: IN F,(C) ; ç¨â ¥¬ ¯® 1 à §ã á çñâ­®£®  ¤à¥á , ç¨â ¥âáï WORD
DEC DE
LD A,D
OR E
JR NZ,.read_loop
JR ATAPI_IdlePasses
;
.write_data: ; A = 0
OUT (C),A ; ª¨¤ ¥¬ 0 ¢ ॣ¨áâà § éñ«ªã IDE
INC B
.write_loop: XOR A
OUT (C),A ; ¯¨è¥¬ ¯® 1 à §ã ¢ ­¥çñâ­ë©  ¤à¥á, ¯¨è¥âáï WORD
DEC DE
LD A,D
OR E
JR NZ,.write_loop
JR ATAPI_IdlePasses
;
; ¢ë室:
; CF,ZF ATAPI_WAITPRT Error ¨«¨ Check Condition á® ¢­¥è­¥© ®¡à ¡®âª®©
; ZF No errors, no data request
; NZ,NC DATA REQUEST
; CF Error
ATAPI_CHECK_DRV:
;EX DE,HL
EXX
CALL ATAPI_WAITPRT
EXX
; ZF=1
;JP C,.error
RET C
;
; [ ] media change.   ­ ¤® «¨ âãâ? ;!FIXIT «ãçè¥ ¡«®ª¨à®¢ âì ­®á¨â¥«ì
LD A,high IDE.Read.Status
IN A,(low IDE.Read.Status)
;
AND IDE.CtrlByte.DataRequest + IDE.CtrlByte.Error
RET Z ;NO DATA REQUEST. A = 0: BIOS.Error.NoErrors
RRA ; Checking IDE.CtrlByte.CheckCondition
;JR NC,.data_request
RET NC
; ¯à¨§­ ª ⮣®, çâ® ®è¨¡ª  ᬥ­ë ­®á¨â¥«ï ¤®«¦­  ®¡à ¡ â뢠âìáï ¢ EXEC_PACKET_COMMAND
EXX
DEC C ; ¯à¨§­ ª ⮣®, çâ® ®è¨¡ª  ᬥ­ë ­®á¨â¥«ï ¤®«¦­  ®¡à ¡ â뢠âìáï ¢ EXEC_PACKET_COMMAND
EXX
RET Z ; ¢ë室, ¥á«¨ ®è¨¡ª  ®¡à ¡ â뢠¥âáï ­¥ ¢ EXEC_PACKET_COMMAND
JP ATAPI_CHECK_ERROR
;
ATAPI_PREPARE_RW:
LD BC,IDE.Read.ByteCountLow
IN E,(C)
INC C ;LD BC,IDE.Read.ByteCountHigh
IN D,(C) ;TRANSFER BLOCK SIZE
;
LD A,D
OR E
RET Z ;BLOCK = 0
;
; 㬥­ìè ¥¬ áçñâ稪 § £à㦠¥¬ëå ¡ ©â®¢ ¢ 2 à § . —¨â ¥¬ ¯® 2 ¡ ©â 
SRL D
RR E
;
LD BC,IDE.Read.InterruptReason
IN A,(C)
AND IDE.InterruptReasonByte.IO
LD BC,IDE.Read.Data
SCF
RET
; .AddrOverflow: EX DE,HL
; AND A
; SBC HL,DE
; EX DE,HL
; RET
;
; !TODO 宫®á⮥ ç⥭¨¥
; .error_buffer: AND A
; SBC HL,DE
;.NULL:
;.RD_N_CD: IN A,(C)
; DEC B
; IN A,(C)
; DEC B
; DEC DE
; DEC DE
; LD A,D
; OR E
; JR NZ,.RD_N_CD
; ; DE = 0
; JR .AP_LOOP
;----------------------------------------------------------------------;
;----------------------------------------------------------------------;
; ¯®à⨬ ⮫쪮 ॣ¨áâà AF
ATAPI_GET_ERROR_REG:
XOR A ;LD BC,IDE.Read.Error
IN A,(IDE.Read.Error) ;IN A,(C)
RRCA
RRCA
RRCA
RRCA
AND #0F
OR BIOS.Error.ATAPI
RET
;----------------------------------------------------------------------;
;----------------------------------------------------------------------;
; D - MASK, E - PATTERN
; !!! ­¥ª®â®àë¥ ä㭪樨 ­ ¤¥îâáï, çâ® ­  ¢ë室¥ ¢á¥£¤  ZF
; ­¥ ¤®«¦­  âண âì ॣ. C
ATAPI_WAITPRT: LD DE,256*IDE.CtrlByte.Busy + 0
.Custom: LD B,100
LD HL,#0000
.LOOP: LD A,high IDE.Read.Status
IN A,(low IDE.Read.Status)
CP #FF
JR Z,.error
AND D
CP E
;
RET Z
;
.NEXT_TRY: DEC L
JR NZ,.LOOP
DEC H
JR NZ,.LOOP
DJNZ .LOOP
.error: SCF
RET
;----------------------------------------------------------------------;
;----------------------------------------------------------------------;
; DE - buffer
ATAPI_READ_CAPACITY_DATA:
LD BC,28 ;áçñâ稪
;
.loop: PUSH BC
PUSH DE
LD A,SYS_PAGE
EX AF,AF'
LD A,1
LD HL,ATAPI_CMD_PACKET.READ_CAPACITY_DATA
CALL EXEC_PACKET_COMMAND.start_custom
POP DE
POP BC
RET NC
;
CALL ATAPI_GET_ERROR_REG
CP BIOS.Error.ATAPI.NotReady
SCF
RET NZ
;
PUSH BC
CALL ATAPI_MEDIA_ERROR
CP BIOS.Error.ATAPI.NotReady
SCF
POP BC
RET NZ
;
CPI
RET PO ;áçñâ稪
;
LD HL,0
.pause: DEC HL
LD A,H
OR L
JR NZ,.pause
;
JP .loop
;RET
;----------------------------------------------------------------------;
;----------------------------------------------------------------------;
; ATAPI_TEST: LD HL,ATAPI_CMD_PACKET.TEST_UNIT_READY
; LD DE,0 ; ¬ àª¥à ⮣®, çâ® ­¥ ­ã¦­® ç¨â âì á ãáâனá⢠ ¢ އ“
; JP EXEC_PACKET_COMMAND
;----------------------------------------------------------------------;
;----------------------------------------------------------------------;
ATAPI_MEDIA_ERROR:
PUSH IX
PUSH HL
;
IN A,(SLOT3)
PUSH AF
LD A,SYS_PAGE
OUT (SLOT3),A
EX AF,AF' ; set page with buffer to SYS_PAGE
LD DE,SYS_PAGE.SHARED_BUFFER_256b
CALL ATAPI_REQUEST_SENSE.FN
;
LD A,(SYS_PAGE.SHARED_BUFFER_256b + 2) ; SenceKey
CP 2 ; NOT READY
JR Z,.Not_Ready
CP 6 ; UNIT ATTENTION
JR NZ,.unkn_error
;
LD A,(SYS_PAGE.SHARED_BUFFER_256b + 12) ; AdditionalSenceKey
CP #28 ; NOT READY TO READY TRANSITION
JR Z,.MedCh3
CP #29 ; POWER ON, RESET OR BUS DEVICE RESET OCCURRED
JR Z,.MedChanged
JR .unkn_error
;
.MedCh3: LD A,(SYS_PAGE.SHARED_BUFFER_256b + 13) ; AdditionalSenseCodeQualifier. 0
AND A
JR NZ,.unkn_error
;
.MedChanged: LD A,(IY + IDE.HDD_INIT_TABLE.MediaParameters)
OR %0000'0011
LD (IY + IDE.HDD_INIT_TABLE.MediaParameters),A
;
;LD HL,ATAPI_CMD_PACKET.READ_CAPACITY_DATA
LD DE,SYS_PAGE.TMP_BUFFER
;CALL EXEC_PACKET_COMMAND.start_sys_page
CALL ATAPI_READ_CAPACITY_DATA
;
LD HL,#FFFF
LD C,BIOS.Error.ATAPI.MediumError
JR C,.No_Media
;
LD HL,(SYS_PAGE.TMP_BUFFER) ; media size high
LD (IY+IDE.HDD_INIT_TABLE.MediaSizeHigh),H
LD (IY+IDE.HDD_INIT_TABLE.MediaSizeHigh+1),L
LD HL,(SYS_PAGE.TMP_BUFFER + 2) ; media size low
LD (IY+IDE.HDD_INIT_TABLE.MediaSizeLow),H
LD (IY+IDE.HDD_INIT_TABLE.MediaSizeLow+1),L
LD HL,(SYS_PAGE.TMP_BUFFER + 6) ; sector size
;
LD C,BIOS.Error.ATAPI.UnitAttention
.No_Media: LD (IY+IDE.HDD_INIT_TABLE.SectorSize),H ;[ ] sector size
LD (IY+IDE.HDD_INIT_TABLE.SectorSize + 1),L
;
.exit: POP AF
POP HL
POP IX
OUT (SLOT3),A
LD A,C
SCF
RET
;
.Not_Ready: LD A,(SYS_PAGE.SHARED_BUFFER_256b + 12) ; AdditionalSenceKey
LD C,BIOS.Error.ATAPI.MediumError ; ­¥â ­®á¨â¥«ï
;!TODO
; 06,00 - NO REFERENCE POSITION FOUND (media may be upside down)
; 3A - MEDIUM NOT PRESENT
;
CP 4
JR NZ,.exit
; [ ] !(test for ZIP)
LD A,(SYS_PAGE.SHARED_BUFFER_256b + 13) ; AdditionalSenseCodeQualifier
CP 1 ; LOGICAL DRIVE NOT READY - IN PROGRESS OF BECOMING READY
JR NZ,.exit
;
; ¨¤ñâ ¨­¨æ¨ «¨§ æ¨ï
LD C,BIOS.Error.ATAPI.NotReady
JR .exit
;
.unkn_error: LD C,BIOS.Error.ATAPI.MediumError
JR .exit
;----------------------------------------------------------------------;
; !!! SELECT_DRIVE ¤®«¦¥­ ®âà ¡®â âì § à ­¥¥
EXEC_TEST_CMD: LD HL,ATAPI_CMD_PACKET.TEST_UNIT_READY
LD DE,0 ; ¬ àª¥à ⮣®, çâ® ­¥ ­ã¦­® ç¨â âì á ãáâனá⢠ ¢ އ“
JP EXEC_PACKET_COMMAND.start
////////////////////////////////////////////////////////////////////////
ATAPI_CMD_PACKET:
.TEST_UNIT_READY: DUP 12
DB #00
EDUP
;
.OPEN: DB #1B
DB #00,#00,#00
DB #02
DB #00,#00,#00,#00,#00,#00,#00
;
.CLOSE: DB #1B
DB #00,#00,#00
DB #03
DB #00,#00,#00,#00,#00,#00,#00
;
.READ: DB #28,#00
DB #00,#00,#00,#00 ; sector dword
DB #00
DB #00,#01,#00,#00 ; counter dword
DB #00
;
.WRITE: DB #2E,#00
DB #00,#00,#00,#00 ; sector dword
DB #00
DB #00,#01,#00,#00 ; counter dword
DB #00
;
.READ_CAPACITY_DATA: DB #25
BLOCK 11,0
;
.REQUEST_SENSE: DB #03
DB #00,#00,#00
DB MAX_DATA_PACKET_FOR_REQUEST_SENSE
DB #00,#00,#00,#00,#00,#00,#00
;
ATAPI_PACKET:
.SECTOR EQU 2
.COUNTER EQU 7
////////////////////////////////////////////////////////////////////////
;
; E - Second * 10
; PAUSE LD HL,#0000
; PAUSE1 DEC L
; JR NZ,PAUSE1
; DEC H
; JR NZ,PAUSE1
; DEC E
; JR NZ,PAUSE1
; RET
;
/*
᫨ «®¢¨âáï ®è¨¡ª  media changed, â® ¡¨®á ¤®«¦¥­ ¢ëáâ ¢«ïâì ¢ HDD_INIT_TABLE.MediaParameters = 3
¨ § â¨à âì FF SectorSize.
®á ¯®á«¥ ¯®«ã祭¨ï â ª®© ®è¨¡ª¨ ¤®«¦¥­ ¢ë§ë¢ âì BIOS.DRV_DETECT ¨ ¥á«¨ ¢áñ ŽŠ, â® ReScanDRV
*/