;[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 PKTSIZE EQU 12 RAM_ATAPI_PK EQU SYS_PAGE.SHARED_BUFFER_32b RAM_ATAPI_RW_CMD EQU SYS_PAGE.SHARED_BUFFER_32b+16 ASSERT ((PKTSIZE % 4) = 0), "PKTSIZE must be an even number" ;[]================================================================[#51] CD_5x_RESET: LD C,IDE.Device.ATAPI CALL SELECT_DRIVE RET C LD B,50 .loop: PUSH BC CALL CD_TEST POP BC RET NC EI HALT DJNZ .loop RET ;[]================================================================[#51] ;!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) CD_5x_READ: EX AF,AF' IN A,(SLOT3) EX AF,AF' ;[]================================================================[#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) CD_5x_LONG_READ: PUSH IY SAFE_PORTY_2 PUSH BC PUSH IX PUSH HL ; EX AF,AF' AND A ;read EX AF,AF' CALL RW_ATAPI_SECTORs JP HDD_5x_LONG_READ.shared RW_ATAPI_SECTORs: LD C,IDE.Device.ATAPI CALL SELECT_DRIVE RET C ; EXX LD C,SLOT3 IN A,(C) PUSH AF LD A,SYS_PAGE OUT (C),A 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,PKTSIZE 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 ; EX AF,AF' OUT (SLOT3),A ; ; POP AF ; OUT (SLOT3),A LD HL,RAM_ATAPI_RW_CMD CALL EXEC_PACKET_COMMAND ; POP BC LD C,SLOT3 OUT (C),B RET ;[]===========================================================[#52, #55] ;[]================================================================[#57] ;Function: Detect Disk ; A - Disk ;Return: CF=0 - A=Drive type ; CF=1 - drive not present, A=#02 CD_5x_DETECT: LD C,IDE.Device.ATAPI AND %1011'1111 JP DRV_DETECT ;[]================================================================[#57] ;[]================================================================[#5E] ;Function: Extended ; A - Disk ; B - SubFunction ;Return: ; CD_5x_Extended: LD C,IDE.Device.ATAPI CALL SELECT_DRIVE RET C ; LD A,B CP 2 JR C,TRAY_FN ; ... ; ... ;LD A,#AA LD A,BIOS.Error.InvalidSubFunction SCF RET ;[]================================================================[#5E] ;----------------------------------------------------------------------; TRAY_FN: LD HL,ATAPI_CMD_PACKET.CLOSE LD DE,0 ; маркер того, что не нужно читать с устройства в ОЗУ DEC A JR Z,EXEC_PACKET_COMMAND LD HL,ATAPI_CMD_PACKET.OPEN JR EXEC_PACKET_COMMAND ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; INPUT: HL - AP packet (12bytes) ; DE - address for/with data if needed ; ; 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: EXX CALL CD_WAITPRT EXX JR NC,.READY ; LD BC,IDE.Write.Command LD A,IDE.ATAPI.Reset OUT (C),A ; LD B,#80 .pause: DJNZ .pause ; EXX CALL CD_WAITPRT EXX RET C ; .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,PKTSIZE LDIR ; POP BC POP DE OUT (C),B ; XOR A EXX ;OUT (C),A ;XOR A LD BC,IDE.Write.Features OUT (C),A LD DE,MAX_ATAPI_SEC_SIZE ;SIZE BLOCK ;!HARDCODE доставать из переменной какой-нибудь LD BC,IDE.Write.CylinderLow OUT (C),E LD BC,IDE.Write.CylinderHigh OUT (C),D LD BC,IDE.Write.Command LD A,IDE.ATAPI.Packet OUT (C),A CALL CD_WAITPRT EXX RET C EXX LD DE,256*(IDE.CtrlByte.DataRequest+IDE.CtrlByte.Error)+IDE.CtrlByte.DataRequest CALL CD_WAITPRT.Custom EXX BIT IDE.CtrlBit.Error,A JR NZ,.CDERROR JR NC,.YEP_DRQ LD A,#80 ; ERROR TIME OUT ;!HARDCODE RET ; .CDERROR: LD BC,IDE.Read.Error ;ERROR IN A,(C) RRCA RRCA RRCA RRCA AND #0F SCF RET ; .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,PKTSIZE/4 .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: EX DE,HL IN A,(SLOT3) EX AF,AF' ;>-----------> \ ; EXX CALL CD_WAITPRT EXX RET C LD BC,IDE.Read.Status IN A,(C) BIT IDE.CtrlBit.Error,A JR NZ,.CDERROR ; AND IDE.CtrlByte.DataRequest RET Z ;NO DATA REQUEST. A = 0: BIOS.Error.NoErrors ; LD A,XH OUT (SLOT3),A ; ;====== IF DATA REQUEST =======================================; ; EX DE,HL LD BC,IDE.Read.CylinderLow IN E,(C) LD BC,IDE.Read.CylinderHigh IN D,(C) ;TRANSFER BLOCK SIZE LD A,D OR E RET Z ;BLOCK = 0 ; LD BC,IDE.Read.Counter IN A,(C) AND %0000'0010 ;SENSE DATA AVAILABLE bit LD BC,IDE.Read.Data JR Z,.WRITE_DATA ; ;READ .read_loop: INI INI DEC DE DEC DE LD A,D OR E JR NZ,.read_loop ; .return_rw: INC XL ;INC LOADED SECTORS LD A,H OR L JR NZ,.AP_LOOP ; next page in mem block 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 JR .AP_LOOP ; ; ;WRITE .WRITE_DATA: INC B ; LD BC,IDE.Write.Data .write_loop: OUTI OUTI DEC DE DEC DE LD A,D OR E JR NZ,.write_loop JR .return_rw ;.NULL: LD BC,IDE.Read.Data ;.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 ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; ; D - MASK, E - PATTERN CD_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 ; ;EX AF,AF' .error: ; !FIXIT error number SCF RET ;----------------------------------------------------------------------; ;----------------------------------------------------------------------; CD_TEST: LD HL,ATAPI_CMD_PACKET.NOP LD DE,0 ; маркер того, что не нужно читать с устройства в ОЗУ JP EXEC_PACKET_COMMAND ;----------------------------------------------------------------------; //////////////////////////////////////////////////////////////////////// ATAPI_CMD_PACKET: .NOP: 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 ; 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 ;