;[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 _ZIP_WAITS_ EQU 128 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 LD C,A ; ;CALL ATAPI_CHECK_MEDIA_CHANGED.noWait ;RET C CP BIOS.Error.ATAPI.UnitAttention SCF RET Z ; CP BIOS.Error.ATAPI.MediumError SCF RET Z ; не трогать прерывания ; EI ; HALT EXX XOR A .pause_loop: LD B,A DJNZ $ DEC A JR NZ,.pause_loop EXX DJNZ .loop LD A,C AND A SCF RET NZ RET /* HL = 1e00 B = 1 ATAPI_WAITPRT.LOOP DE = 00FF */ ;[]================================================================[#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 RES 1,(IY + IDE.HDD_INIT_TABLE.MediaParameters) ; [ ] removable media 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.MediumError JR NZ,.unknown_error ;!FIXIT костыль LD A,BIOS.Error.ATAPI.UnitAttention ;!FIXIT костыль RES 1,(IY + IDE.HDD_INIT_TABLE.MediaParameters) ; [ ] removable media ; .unknown_error: LD HL,#FFFF LD D,H LD E,L PUSH HL POP IX SCF EX AF,AF' ; тут маскируем ошибку, изначально CF=1 только если устройство отсутствует OUT (SLOT3),A 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) AND %000'0100 CALL NZ,.RereadCapacity ; 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 .RereadCapacity: EX AF,AF' PUSH AF CALL GET_ATAPI_CAPACITY POP AF 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 ; !FIXIT зачем? LD C,0 ; признак short EX AF,AF' IN A,(SLOT3) EX AF,AF' JR 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 ; !FIXIT зачем? LD C,1 ; признак long .main: EX AF,AF' AND A ;read EX AF,AF' JR ATAPI_BEGIN_RW ; ; SAFE_PORTY_2 ; PUSH BC ; PUSH IX ; PUSH HL ; ; ; 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] ATAPI_BEGIN_RW: SAFE_PORTY_2 PUSH BC PUSH IX PUSH HL ; CALL RW_ATAPI_SECTORs ; JP ATA_5x_LONG_READ.shared ;[]================================================================[#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 ; !FIXIT зачем? ; проба бага LD C,0 ; признак short ;LD C,1 ; признак long ; EX AF,AF' IN A,(SLOT3) EX AF,AF' JR 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 ; !FIXIT зачем? LD C,1 ; признак long .main: EX AF,AF' SCF ;write EX AF,AF' JR ATAPI_BEGIN_RW ;[]================================================================[#53] ;[]================================================================[#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 ; .next_check: 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 ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; HL - указатель на пакетную команду (первый или второй слот) ; DE - указатель на буффер для команды ATAPI_CUSTOM_CMD: IN A,(SLOT3) EX AF,AF' LD A,1 ; признак, что ошибка смены носителя НЕ обрабатываться в 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.start ; INPUT: HL - AP packet (12bytes) ; DE - address for/with data if needed ; A' - начальная страница для R/W Long ; ; RETURN: CF - ERROR ; !FIXIT номера неправильные ; !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 RET NZ LD A,BIOS.Error.Failure RET ; .error_TimeOut: CP #FF EX DE,HL JR Z,.error_fail LD A,BIOS.Error.ATAPI.TimeOut SCF RET ; ; ; .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 ; pause ; LD B,0 ; DJNZ $ ; DJNZ $ ; EX AF,AF' LD XH,A ; страница для R/W_LONG EX AF,AF' ;A=0 LD XL,A EX DE,HL ; .AP_LOOP: ;CALL ATAPI_WAITPRT.wait_NZ LD B,_ZIP_WAITS_ DJNZ $ CALL ATAPI_CHECK_DRV JP C,.error;_APLOOP RET Z ;====== IF DATA REQUEST ===============================================; IN A,(SLOT3) EX AF,AF' ;>-----------> \ ; LD A,XH OUT (SLOT3),A 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_WAITPRT.wait_NZ LD B,_ZIP_WAITS_ DJNZ $ CALL ATAPI_CHECK_DRV JP C,.error JR NZ,ATAPI_IdlePasses.Enter RET ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ATAPI_IdlePasses: LD B,_ZIP_WAITS_ DJNZ $ CALL ATAPI_CHECK_DRV JP C,EXEC_PACKET_COMMAND.error JP Z,EXEC_PACKET_COMMAND.error_fail ; .Enter: 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 .zeroWait CALL ATAPI_WAITPRT EXX ; ZF=1 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 RET NC ; DataRequest CF=0, ZF=0 ; CALL ATAPI_GET_ERROR_REG EXX DEC C ; признак того, что ошибка смены носителя должна обрабатываться в EXEC_PACKET_COMMAND EXX SCF RET Z ; выход, если ошибка обрабатывается не в EXEC_PACKET_COMMAND ; ; 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 ; ;CP BIOS.Error.ATAPI.IllegalRequest ;RET Z ; SCF RET ; 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 ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; портим только регистр 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,9 ; 3 = общая задержка около секунды LD HL,#0000 ; 4 128 768 .LOOP: LD A,high IDE.Read.Status IN A,(low IDE.Read.Status) CP #FF SCF RET Z ; AND D CP E RET Z ; DEC HL LD A,H OR L JR NZ,.LOOP DJNZ .LOOP ; LD A,BIOS.Error.Busy 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_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 ; CALL GET_ATAPI_CAPACITY .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 ;----------------------------------------------------------------------; GET_ATAPI_CAPACITY: ; LD DE,SYS_PAGE.TMP_BUFFER 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 RET NC SET 2,(IY + IDE.HDD_INIT_TABLE.MediaParameters) RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; !!! 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 ; write and verify 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 //////////////////////////////////////////////////////////////////////// ; Если ловится ошибка media changed, то биос должен выставлять в HDD_INIT_TABLE.MediaParameters = 3 ; и затирать FF SectorSize. ; Дос после получения такой ошибки должен вызывать BIOS.DRV_DETECT и если всё ОК, то ReScanDRV