;[x] 18/12/2023. добавление/допиливание API CD-ROM (ATAPI) ;======================================================================= ; Вход: A - номер устройства, C - DriveType ; Выход: A - MediaParameters, C - DriveType ; не портит L SELECT_DRIVE: CALL .drv_params EXX SCF LD A,BIOS.Error.BadNumber RET NZ ; LD A,B RRA LD A,IDE.Chanel.Secondary JR C,.device LD A,IDE.Chanel.Primary .device: OUT (IDE.Chanel.Set),A ;R02 LD A,B AND #F0 LD BC,IDE.Write.DeviceHead OUT (C),A ; LD A,high IDE.Read.Status IN A,(low IDE.Read.Status) AND IDE.CtrlByte.Busy ; тестирование задержек JR Z,.notBusy LD B,32 DJNZ $ ; .notBusy: LD A,H EXX RET ; .error: LD A,BIOS.Error.BadNumber SCF RET ; ; не портит регистры B,DE .drv_params: AND #0F LD IY,IDE.INIT_TBL_IDE0 JR Z,.channel ; DEC A LD IY,IDE.INIT_TBL_IDE1 JR Z,.channel ; DEC A LD IY,IDE.INIT_TBL_IDE2 JR Z,.channel ; DEC A LD IY,IDE.INIT_TBL_IDE3 RET NZ ; .channel: EXX IN A,(SLOT3) PUSH AF LD A,SYS_PAGE OUT (SLOT3),A ; LD H,(IY + IDE.HDD_INIT_TABLE.MediaParameters) LD C,(IY + IDE.HDD_INIT_TABLE.DriveType) LD B,(IY + IDE.HDD_INIT_TABLE.DRV_Flags) POP AF OUT (SLOT3),A ;возврат страницы ; LD A,C EXX CP C RET ;======================================================================= ;======================================================================= ;======================================================================= ;======================================================================= ; next page in mem block CHANGE_MEM_BLK: 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 RET ;======================================================================= ; NOT USED ;======================================================================= ; IN: B - бит 4..7 - тип устройства, бит 0..3 - номер устройства ; DE - буффер 64 байта для названия устройства ; OUT: NC - в буфере название ; СF - в A номер ошибки ; ATAxx_5x_GET_DRIVE_NAME: ; LD A,B ; AND #0F ; LD HL,SYS_PAGE.IDE_0.NAME ; JR Z,.ldir ; ; ; DEC A ; LD HL,SYS_PAGE.IDE_1.NAME ; JR Z,.ldir ; DEC A ; LD HL,SYS_PAGE.IDE_2.NAME ; JR Z,.ldir ; DEC A ; LD HL,SYS_PAGE.IDE_3.NAME ; JR NZ,.error ; ; ; .ldir: EXX ; LD C,SLOT3 ; IN B,(C) ; LD D,SYS_PAGE ; OUT (C),D ; EXX ; LD A,(HL) ; EXX ; OUT (C),B ; EXX ; AND A ;CONFIGURE_IDE_DRIVES.IDE_NAME_MARKER.None ; JR Z,.error ; ; ; INC A ;CONFIGURE_IDE_DRIVES.IDE_NAME_MARKER.NoInfo ; JR Z,.autodetect ; ; ; INC A ;CONFIGURE_IDE_DRIVES.IDE_NAME_MARKER.Unknown ; JR Z,.UnknownName ; ; ; LD B,SYS_PAGE.IDE_x.NAME.Size ; .loop: EXX ; OUT (C),D ; EXX ; LD A,(HL) ; EXX ; OUT (C),B ; EXX ; LD (DE),A ; INC HL ; INC DE ; DJNZ .loop ; RET ; ; ; .UnknownName: LD HL,.Unknown_str ; LD BC,.Unknown_str.Size ; LDIR ; XOR A ; EX DE,HL ; LD B,SYS_PAGE.IDE_x.NAME.Size - .Unknown_str.Size ; .loop_zero: LD (HL),A ; INC HL ; DJNZ .loop_zero ; RET ; ; ; .autodetect: ;!FIXIT сделать детект!!! ; JR .UnknownName ; ; ; ; если нет драйва ; .error: LD A,BIOS.Error.BadNumber ; SCF ; RET ; ; ; .Unknown_str: BYTE 'Unknown' ; .Unknown_str.Size EQU $ - .Unknown_str ; если не поддерживается возврат имени для устройства ;LD A,BIOS.Error.InvalidSubFunction ;SCF ;RET ;======================================================================= ;======================================================================= ; !FIXIT можно попробовать использовать в AUTOIDE.asm для сокращения кода ; A - бит 4..7 - тип устройства, бит 0..3 - номер устройства ; C - IDE.Device.HDD ; E - IDE.CMD.ATA.IdentifyDevice / IDE.CMD.ATAPI.IdentifyPacketDevice ; HL - Buffer ATAxx_IdentifyDevice: PUSH HL PUSH BC CALL .RUN_CMD POP BC JR C,.error ; DJNZ .get_full_name ; B=1 POP HL .read_hdd_data: LD BC,IDE.Read.Data INIR INIR RET ; .invalidFunction: POP HL LD A,BIOS.Error.InvalidSubFunction SCF RET ; ; B=2 .get_full_name: DJNZ .invalidFunction ; LD HL,SYS_PAGE.MS_BUF IN A,(SLOT3) PUSH AF ; страница пользователя LD A,SYS_PAGE OUT (SLOT3),A CALL .read_hdd_data LD HL,SYS_PAGE.MS_BUF + _ATA_IDENTIFY_DEVICE_DATA.FirmwareRevision LD B,+(_ATA_IDENTIFY_DEVICE_DATA.MaximumBlockTransfer - _ATA_IDENTIFY_DEVICE_DATA.FirmwareRevision)/2 CALL ATAxx_IdentifyDevice.STR_BIG_ENDIAN_TO_LITTLE LD HL,SYS_PAGE.MS_BUF + _ATA_IDENTIFY_DEVICE_DATA.SerialNumber LD B,+(_ATA_IDENTIFY_DEVICE_DATA.BufferType - _ATA_IDENTIFY_DEVICE_DATA.SerialNumber)/2 CALL ATAxx_IdentifyDevice.STR_BIG_ENDIAN_TO_LITTLE POP AF ; страница пользователя EXX LD B,A LD C,SLOT3 LD D,SYS_PAGE EXX POP DE LD HL,SYS_PAGE.MS_BUF + _ATA_IDENTIFY_DEVICE_DATA.ModelNumber LD B,_ATA_IDENTIFY_DEVICE_DATA.MaximumBlockTransfer - _ATA_IDENTIFY_DEVICE_DATA.ModelNumber CALL .ldirSwitched ; LD HL,SYS_PAGE.MS_BUF + _ATA_IDENTIFY_DEVICE_DATA.SerialNumber LD B,_ATA_IDENTIFY_DEVICE_DATA.BufferType - _ATA_IDENTIFY_DEVICE_DATA.SerialNumber CALL .ldir ; LD HL,SYS_PAGE.MS_BUF + _ATA_IDENTIFY_DEVICE_DATA.FirmwareRevision LD B,_ATA_IDENTIFY_DEVICE_DATA.ModelNumber - _ATA_IDENTIFY_DEVICE_DATA.FirmwareRevision ;CALL .ldir .ldir: EXX OUT (C),D EXX .ldirSwitched: LD A,(HL) EXX OUT (C),B EXX LD (DE),A INC HL INC DE AND A RET Z ; DJNZ .ldir XOR A LD (DE),A INC DE RET ; .error: POP HL CP BIOS.Error.BadNumber SCF RET Z LD A,BIOS.Error.NotReady RET ; ; .RUN_CMD: CALL SELECT_DRIVE RET C ; LD BC,IDE.Write.Command OUT (C),E LD A,E EXX SUB IDE.CMD.ATA.IdentifyDevice LD H,A LD L,A JR Z,.wait ; LD H,#0C .wait: LD DE,IDE.CtrlByte.Busy * 256 + 0 CALL WAITPRT.custom ; HL = 0 or #0CB7 EXX RET C ; LD BC,IDE.Read.Status IN A,(C) RRCA RET C ; AND (IDE.CtrlByte.DataRequest + IDE.CtrlByte.Ready) / 2 SCF RET Z ; EXX LD DE,256*IDE.CtrlByte.DataRequest + IDE.CtrlByte.DataRequest CALL WAITPRT.custom_DE EXX RET ; ; LD BC,IDE.Read.Data ; LD HL,SYS_PAGE.MS_BUF ; IN A,(SLOT3) ; EX AF,AF' ; LD A,SYS_PAGE ; OUT (SLOT3),A ; INIR ; INIR ; EX AF,AF' ; RET ; ; ; 1 - печать с порчей буфера без пропуска двойных пробелов - в 3 раза шустрее стока ; может потом сделать из этого API печати для BIG ENDIAN .STR_BIG_ENDIAN_TO_LITTLE: LD D,H LD E,L LD A,(HL) AND A RET Z ; INC HL .loop_ch: LD A,(DE) LDI LD (DE),A INC HL INC DE DJNZ .loop_ch RET ;======================================================================= /* ; D - MASK ; E - PATTERN ; !!! некоторые функции надеются, что на выходе всегда ZF WAITPRT: LD DE,256*(IDE.CtrlByte.Busy+IDE.CtrlByte.Ready+IDE.CtrlByte.Error) + IDE.CtrlByte.Ready .custom: LD BC,IDE.Read.Status ; ATAPI or Absent ; Exit: CF - No device ; NC - ATAPI .IdentPDevChk: LD E,IDE.CMD.ATAPI.IdentifyPacketDevice LD BC,IDE.Write.Command OUT (C),E ; LD HL,PAUSES.HALT.Time_2s LD DE,IDE.CtrlByte.Busy*256 + 0 CALL BITS_WAITS.Clear_BUSY RET C ; ; BC = IDE.Read.Status IN A,(C) RRCA RET */