;[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 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 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) 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 ; !FIXIT зачем? 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 ; !FIXIT зачем? 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 ; !FIXIT зачем? 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 ; !FIXIT зачем? 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 ; .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 ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; 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 ; признак, что ошибка смены носителя НЕ обрабатываться в 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 ; ;!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_APLOOP: LD A,BIOS.Error.ATAPI.UnitAttention ; RET ;CALL ATAPI_GET_ERROR_REG .error_ex: EX DE,HL .error: CP #FF .error_fail: SCF RET NZ LD A,BIOS.Error.Failure RET ; ; .error_ex: EX DE,HL ; .error: CP #FF ; .error_fail: SCF ; LD C,A ; LD A,BIOS.Error.Failure ; RET Z ; ; ; LD A,BIOS.Error.ATAPI.UnitAttention ; CP C ; SCF ; RET Z ; ; ; LD A,BIOS.Error.ATAPI.MediumError ; CP C ; SCF ; 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;_APLOOP RET Z ;====== IF 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 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 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 ; .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 ; DEC HL LD A,H OR L JR NZ,.LOOP DJNZ .LOOP LD A,BIOS.Error.Busy .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 ; write and verify ;DB #2A,#00 ; write 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 */