;!TODO привести к общему виду в одну инструкцию, проверить корректность ;--------------------------------------------------------------- ;Rev Date Name Description ;--------------------------------------------------------------- ;R02 06-08-2001 DNS Secondary IDE ;R01 06-08-2001 DNS Fixed BUG with partitions on Second hard disk ;--------------------------------------------------------------- ; ; Disk Driver Specification ver. 2.20 ;[]===========================================================[0] ;Procedure: Initialization ; ;Function: Initialization device(s) ; ;Input: C = #00 ; IX = Environment ; ;Output: A = Amount drive support ;[]===========================================================[0] ;[]===========================================================[1] ;Procedure: Open ; ;Function: Open disk ; ;Input: C = #01 ; A = Drive ; ;Output: None ;[]===========================================================[1] ;[]===========================================================[2] ;Procedure: Close ; ;Function: Close disk ; ;Input: C = #02 ; A = Drive ; ;Output: None ;[]===========================================================[2] ;[]===========================================================[3] ;Procedure: Media check ; ;Function: Checking change line ; ;Input: C = #03 ; A = Drive ; ;Output: A = #00 disk no changed ; #FF disk changed ;[]===========================================================[3] ;[]===========================================================[4] ;Procedure: Get BPB ; ;Function: Get Block Parameters BIOS ; ;Input: C = #04 ; A = Drive ; DE = Address ; ;Output: None ;[]===========================================================[4] ;[]===========================================================[5] ;Procedure: Read ; ;Function: Read from disk ; ;Input: C = #05 ; HL:IX = Logical Block (sector) ; DE = Address ; B = Sector count ; A = Drive ; ;Output: None ;[]===========================================================[5] ;[]===========================================================[6] ;Procedure: Write ; ;Function: Write to disk ; ;Input: C = #06 ; HL:IX = Logical Block (sector) ; DE = Address ; B = Sector count ; ;Output: None ;[]===========================================================[6] ;[]===========================================================[7] ;Procedure: Removable ; ;Function: Checking change line ; ;Input: C = #07 ; A = Drive ; ;Output: A = #00 Removable ; A = #FF Non-removable ;[]===========================================================[7] ;[]===========================================================[8] ;Procedure: Generic IOCTL ; ;Function: Generic Input Output Control ; ;Input: C = #08 ; B = Subcommand ; DE = #55AA Magic Number ; A = Drive ; ;Subcommands: #00 - Get Device Parameters ; #01 - Read track ; #02 - Test track ; #80 - Set Device Parameters ; #81 - Write track ; #82 - Format track ;Output: ;[]===========================================================[8] ;[]===========================================================[9] ;Procedure: Read Long ; ;Function: Reading sectors from disk ; ;Input: C = #0A ; HL:IX = Logical Block (sector) ; DE = Address ; B = Sector count ; A' = Page ; ;Output: A' = Next Page ; HL:IX = Next Logical Block (sector) ; DE = Next Address ;[]===========================================================[9] ;[]===========================================================[10] ;Procedure: Write Long ; ;Function: Writing sectors to disk ; ;Input: C = #0B ; HL:IX = Logical Block (sector) ; DE = Address ; B = Sector count ; A' = Page ; ;Output: A' = Next Page ; HL:IX = Next Logical Block (sector) ; DE = Next Address ;[]===========================================================[10] ; ; Errors: ; 0 (#00) - NO ERRORS ; 1 (#01) - BAD COMMAND ; 2 (#02) - BAD DRIVE NUMBER ; 3 (#03) - UNKNOW FORMAT ; 4 (#04) - NOT READY ; 5 (#05) - SEEK ERROR ; 6 (#06) - SECTOR NOT FOUND ; 7 (#07) - CRC ERROR ; 8 (#08) - WRITE PROTECT ; 9 (#09) - READ ERROR ; 10 (#0A) - WRITE ERROR ; 11 (#0B) - FAILURE ; 12 (#0C) - BUSY (DEVICE OPENED) ; 13 (#0D) - RESERVED ; IDE0 EQU #0C1C0 ; IDE1 EQU #0C1C8 MODULE IDE_DRV PARTITION_BUFFER _sBOOT_SECTOR = #C000 ATAPI_BUFFER _sCDFS_PRIMARY_VOLUME_DESCRIPTOR = #C000 API_TABLE: INC C DEC C JP Z,Init ; [ ] ; c=0 Initialization DEC C JP Z,Open ; [ ] ; c=1 open DEC C JP Z,Close ; [ ] ; c=2 close DEC C JP Z,MediaCheck ; [ ] ; c=3 media check (смена носителя) DEC C JP Z,GetBPB ; [ ] ; c=4 get BPB DEC C JP Z,Read ; [ ] ; c=5 read (чтение секторов) DEC C JP Z,Write ; [ ] ; c=6 write (запись секторов) DEC C JP Z,Removable ; [ ] ; c=7 Removable DEC C JP Z,GenIOCTL ; [ ] ; c=8 узнать геометрию диска Generic IOCTL DEC C JP Z,.Reserved ; [ ] ; c=9 Reserved DEC C JP Z,ReadLong ; [ ] ; c=10 Read Long DEC C JP Z,WriteLong ; [ ] ; c=11 Write Long ; .Reserved: LD A,DSS_Error.drv.INVALID_COMMAND SCF RET //////////////////////////////////////////////////////////////////////// // Commands for restart #18 // //////////////////////////////////////////////////////////////////////// ;--------------------------------------------------------------------[v] ; c=0 Initialization Init: PUSH IY ;!TEST ;[ ] для rescanDRV XOR A LD (.count),A ; LD HL,LOGDRV LD (LOGDRV_OFFSET),HL LD IX,SYS_PAGE.TMP_BUFFER LD C,BIOS.DRV_LIST RST ToBIOS ; DRV_LIST: ; +0 LEN ; +1 FDD COUNT ; +2 ATA COUNT ; +3 ATAPI COUNT ; +4 RESERVED (14) ; IN A,(SLOT3) LD C,A LD A,SYS_PAGE OUT (SLOT3),A LD A,(IX+3) ;количество ATAPI для процедуры NX_DVCI AND A PUSH AF XOR A LD B,(IX+2) ;количество ATA для процедуры NX_DVCI CP B LD A,C OUT (SLOT3),A JR Z,.NO_HARDS LD C,DRIVE_CODES.SPRINTER.ATA CALL .NX_DVCI ; .NO_HARDS: POP AF JR Z,.skip_atapi ; LD B,A LD C,DRIVE_CODES.SPRINTER.ATAPI CALL .NX_DVCI ; .skip_atapi: POP IY .count+1: LD A,0 ; AND A RET ; .NX_DVCI: PUSH BC LD A,C LD (CURRENT_DRIVE.Number),A LD C,BIOS.DRV_DETECT ;[ ] media change переделать логику тут и в биос? ; !FIXIT RST ToBIOS CALL C,.check_error CALL NC,DEFINE_PARTITIONS .skip: POP BC INC C JR C,.NX_DVCI DJNZ .NX_DVCI RET ; .check_error: XOR BIOS.Error.BadNumber RET NZ SCF RET ;---------------------------------------------------------------------[^] ;+00 BYTE MASTER/SLAVE PHISICAL DRIVE NUMBER #80/#81/... ;+01 LONG SECTOR OFFSET ;+05 LONG SIZE IN SECTORS ;+09 BYTE PARTITION RECORD NUMBER (in drive MBR) ;+10 WORD Sector Size ;+12 BYTE Removable Media Byte flags ;+13_15 FREE ; SelectDrive: PUSH DE ; PUSH HL ; ; ; LD L,A ; ; ; LOGDRV_ENTRY_FIND LOGDRV ; ; ; ; [ ] custorm sector size ; CALL CHECK_IDE_SECTOR_SIZE ; RLA ; ; ; ; ; LD E,(IY+LOGDRV.SECTOR_OFFSET) ; LD D,(IY+LOGDRV.SECTOR_OFFSET+1) ; ADD IX,DE ; LD E,(IY+LOGDRV.SECTOR_OFFSET+2) ; LD D,(IY+LOGDRV.SECTOR_OFFSET+3) ; POP HL ; ADC HL,DE ; ; [ ] custom sector size ; ;JR C,.exit ; RRA ; ; ; .exit: LD A,(IY+LOGDRV.PHISICAL_DRV_NUMBER) ; POP DE ; RET NC ; LD A,DSS_Error.drv.UNKNOWN_FORMAT ; RET ; ; A - HDD LOG NUMBER SelectDrive.NoSector: LD HL,0 LD IX,0 ;HL:IX - SECTOR ; DE - ADDRESS ; B - COUNTER ; A - HDD LOG NUMBER SelectDrive: PUSH DE PUSH HL ; LD L,A ADD 0 - DSS_MAX_DRIVES_AMOUNT - 1 LD A,DSS_Error.sys.INVALID_DRIVE JR C,.error_pop ; LOGDRV_ENTRY_FIND LOGDRV ; ; ; [ ] custom sector size ; CALL CHECK_IDE_SECTOR_SIZE ; LD A,DSS_Error.sys.UNKNOWN_FORMAT ; JR C,.error_pop ; ; ; ; ; LD E,(IY+LOGDRV.SECTOR_OFFSET) ; LD D,(IY+LOGDRV.SECTOR_OFFSET+1) ; ADD IX,DE ; LD E,(IY+LOGDRV.SECTOR_OFFSET+2) ; LD D,(IY+LOGDRV.SECTOR_OFFSET+3) POP HL CALL .get_data JR C,.error_pop2 ; POP DE ; LD A,DSS_Error.sys.SECTOR_NOT_FOUND ; RET C ; LD A,(IY+LOGDRV.PHISICAL_DRV_NUMBER) RET ; .error_pop: POP HL .error_pop2: POP DE RET ; .get_data: ; [ ] custom sector size CALL CHECK_IDE_SECTOR_SIZE LD A,DSS_Error.sys.UNKNOWN_FORMAT RET C ; LD E,(IY+LOGDRV.SECTOR_OFFSET) LD D,(IY+LOGDRV.SECTOR_OFFSET+1) ADD IX,DE LD E,(IY+LOGDRV.SECTOR_OFFSET+2) LD D,(IY+LOGDRV.SECTOR_OFFSET+3) ADC HL,DE LD A,DSS_Error.sys.SECTOR_NOT_FOUND RET ; 00 - GET DEVICE PARAMETERS ; 01 - READ TRACK ; 02 - TEST TRACK ; 80 - SET DEVICE PARAMETERS ; 81 - WRITE TRACK ; 82 - FORMAT TRACK GenIOCTL: BIT 7,B JR NZ,.Set INC B DEC B JR Z,GetParams DEC B JR Z,.error ;ReadTrack DEC B JR Z,TestTRK LD A,DSS_Error.drv.INVALID_COMMAND SCF RET ; .Set: RES 7,B INC B DEC B RET Z ;SetParams DEC B JR Z,.error ;WriteTrack DEC B JR Z,.error LD A,DSS_Error.drv.INVALID_COMMAND SCF RET ; .error: LD A,DSS_Error.drv.GENERAL_FAILURE SCF RET ;HL:IX - SECTOR ; DE - ADDRESS ; B - COUNTER ; A - HDD LOG NUMBER ;CHECK SECTOR TestTRK: LD C,BIOS.DRV_VERIFY JP Exec_BIOS ; HL:DE - SECTORS ON LOGICAL DISK ; C - PARTITION RECORD NUMBER IN DRIVE MBR. if #FF - then not supported ;[x] 17.12.2023 загрузка с активного раздела, а не с первого ; HL' - CYLINDERS ON PHISICAL DISK ; DE' - HEADS ON PHISICAL DISK ; BC' - SECTORS PER TRACK ON PHISICAL DISK ; A' - PHISICAL DRIVE NUMBER ; A - DRIVE/HEAD REGISTER PHISICAL DISK: ; bit7 - reserved "1" ; bit6 - ADDRESSING MODE LBA/CHS ; bit5 - reserved "1" ; bit4 - DEVICE MASTER/SLAVE ; bit3 - reserved "0" (MAY BE OTHER) ; bit2 - reserved "0" (MAY BE OTHER) ; bit1 - reserved "0" (MAY BE OTHER) ; bit0 - Primary/Secondary Chanel ; B - ;[ ] sector size ;!TODO ; 00 - undefined ; 01 - 128 bytes ; 02 - 256 bytes ; 04 - 512 bytes ; 08 - 1024 bytes ; 16 - 2048 bytes ; 32 - 4096 bytes ; 64 - 8192 bytes ; 128 - 16384 bytes GetParams: EX DE,HL LD BC,#55AA AND A SBC HL,BC LD L,A LD A,DSS_Error.drv.GENERAL_FAILURE SCF RET NZ ; PUSH IX PUSH IY ; LOGDRV_ENTRY_FIND LOGDRV ; LD A,(IY+LOGDRV.PHISICAL_DRV_NUMBER) ;MASTER/SLAVE PHISICAL DRIVE NUMBER #80/#81/... PUSH IY LD C,BIOS.DRV_GET_PAR RST ToBIOS POP IY JR NC,.next ; ;CP BIOS.Error.ATAPI.NotReady ;SCF ;LD A,DSS_Error.drv.NOT_READY ;JR Z,.error ;LD A,DSS_Error.drv.INVALID_DRIVE ;JR .error ; CP BIOS.Error.BadNumber SCF LD A,DSS_Error.drv.INVALID_DRIVE JR Z,.error LD A,DSS_Error.drv.NOT_READY JR .error ; [ ] media change - убрать ;!FIXIT .next: EX AF,AF JR NC,.NoMediaChange CP BIOS.Error.ATAPI.UnitAttention JR NZ,.NoMediaChange ; PUSH IX PUSH IY PUSH HL PUSH DE PUSH BC CALL ReDEFINE_PARTITIONS POP BC POP DE POP HL POP IY POP IX ; .NoMediaChange: ;EX AF,AF ; перетасовка регистров с результатом от BIOS EX DE,HL LD C,E LD E,D LD D,0 LD A,B LD B,D EXX ;[ ] 04/01/2025 возвращение размера сектора EX AF,AF' LD A,XH LD E,XL RL E RLA ; ; SECTORS ON LOGICAL DISK LD E,(IY+LOGDRV.SIZE_IN_SECTORS+0) LD D,(IY+LOGDRV.SIZE_IN_SECTORS+1) LD L,(IY+LOGDRV.SIZE_IN_SECTORS+2) LD H,(IY+LOGDRV.SIZE_IN_SECTORS+3) ; ;[x] 17.12.2023 загрузка с активного раздела, а не с первого LD C,(IY+LOGDRV.PARTITION_RECORD_NUM) ; номер партиции в MBR диска ; ;[ ] 04/01/2025 возвращение размера сектора ; 00 - undefined ; 01 - 128 bytes ; 02 - 256 bytes ; 04 - 512 bytes ; 08 - 1024 bytes ; 16 - 2048 bytes ; 32 - 4096 bytes ; 64 - 8192 bytes ; 128 - 16384 bytes ;EX AF,AF' LD B,A ; LD A,(IY+LOGDRV.PHISICAL_DRV_NUMBER) ;MASTER/SLAVE PHISICAL DRIVE NUMBER #80/#81/... EX AF,AF' ; AND A .error: POP IY POP IX RET Removable: XOR A INC A RET Close: XOR A RET ;!TODO пока Open ничего не делает кроме проверки MediaCheck Open: CALL MediaCheck RET Z RET C ;!TODO ??? ;CALL READ_PARTITION_PARAMETERS ; INC A RET NZ LD A,DSS_Error.sys.MEDIA_CHANGED SCF RET ; ;[ ] media changed - bios 5x DETECT ; выход A=#FF - changed, A=0 - not changed, ZF=1 - not changed ; MediaCheck: PUSH IY ; CALL SelectDrive ; JR C,.exit ; ; ; ; [ ] media changed ; LD A,(IY + LOGDRV.PHISICAL_DRV_NUMBER) ; LD C,BIOS.DRV_DETECT ;[ ] media change переделать логику тут и в биос? ; !FIXIT ; PUSH IY ; RST ToBIOS ; POP IY ; JR NC,.next_check ; ; ; CP BIOS.Error.ATAPI.UnitAttention ; JR Z,.Reinit ; JR .exit ; ; ; .next_check: BIT 1,(IY + LOGDRV.MediaParameters) ; JR NZ,.Reinit ; ; ; XOR A ; .exit: POP IY ; RET ; ; ; .Reinit: LD A,(IY + LOGDRV.PHISICAL_DRV_NUMBER) ; LD (CURRENT_DRIVE.Number),A ; LD (LOGDRV_OFFSET),IY ; ;RES 1,(IY + LOGDRV.MediaParameters) ; CALL DEFINE_PARTITIONS ; LD A,#FF ;!HARDCODE drive changed ; OR A ; POP IY ; RET MediaCheck: PUSH IY CALL SelectDrive.NoSector JR NC,.next_step ; CP DSS_Error.sys.UNKNOWN_FORMAT JR NZ,.exit AND A ; сброс ZF SCF ; [ ] media changed .next_step: PUSH AF ; Сохраняем CF и код ошибки UNKNOWN_FORMAT, если CF=1 LD A,(IY + LOGDRV.PHISICAL_DRV_NUMBER) LD C,BIOS.DRV_GET_PAR ;[ ] media change переделать логику тут и в биос? ; !FIXIT PUSH IY RST ToBIOS POP IY EX AF,AF' JR NC,.next_check ; CP BIOS.Error.ATAPI.UnitAttention JR Z,.Reinit POP BC ; Баланс стека .exit: SCF POP IY RET ; .next_check: BIT 1,(IY + LOGDRV.MediaParameters) JR NZ,.Reinit ; POP AF ; Восстанавливаем CF и код ошибки UNKNOWN_FORMAT, если CF=1 POP IY RET C XOR A RET ; .Reinit: PUSH IY CALL ReDEFINE_PARTITIONS POP IY POP AF ; Восстанавливаем CF и код ошибки UNKNOWN_FORMAT, если CF=1 CALL C,SelectDrive.get_data POP IY JR NC,.no_errors ; CP DSS_Error.sys.UNKNOWN_FORMAT SCF RET Z ; .no_errors: LD A,#FF ;!HARDCODE drive changed OR A RET ; [ ] custorm sector size CHECK_IDE_SECTOR_SIZE: ;RET LD E,(IY+LOGDRV.SECTOR_SIZE) LD D,(IY+LOGDRV.SECTOR_SIZE+1) ; LD HL,DSS_MAX_SECTOR_SIZE ; AND A ; SBC HL,DE PUSH HL LD HL,-DSS_MAX_SECTOR_SIZE - 1 ADD HL,DE POP HL RET ; ReDEFINE_PARTITIONS: LD A,DSS_MAX_DRIVES_AMOUNT - 1 ; ограничитель, чтоб не детектить больше 1 раздела LD (Init.count),A LD A,(IY + LOGDRV.PHISICAL_DRV_NUMBER) LD (CURRENT_DRIVE.Number),A LD (LOGDRV_OFFSET),IY ;RES 1,(IY + LOGDRV.MediaParameters) - сбрасывается в DEFINE_PARTITIONS JP DEFINE_PARTITIONS ;HL:IX - SECTOR ; DE - ADDRESS ; B - COUNTER ; A - HDD LOG NUMBER ;READ SECTOR ; DE - ADDRESS ; A - DRIVE GetBPB: ; !FIXIT выбирать значения исходя из типа драйва или ещё чего-нибудь LD HL,0 LD IX,0 LD B,1 JR Read ; PUSH IY ; PUSH DE ; LD L,A ; ; ; LOGDRV_ENTRY_FIND LOGDRV ; ; ; ; [ ] custorm sector size ; CALL CHECK_IDE_SECTOR_SIZE ; JR C,.error ; ; ; LD E,(IY+LOGDRV.SECTOR_OFFSET) ; LD D,(IY+LOGDRV.SECTOR_OFFSET+1) ; LD L,(IY+LOGDRV.SECTOR_OFFSET+2) ; LD H,(IY+LOGDRV.SECTOR_OFFSET+3) ; LD XL,E ; LD XH,D ; LD A,(IY+LOGDRV.PHISICAL_DRV_NUMBER) ; POP DE ; POP IY ; LD BC,1*256 + BIOS.DRV_READ ; JP ToBIOS ; ; ; .error: POP DE ; POP IY ; LD A,DSS_Error.drv.UNKNOWN_FORMAT ; RET ;HL:IX - SECTOR ; DE - ADDRESS ; B - COUNTER ; A'- PAGE ; A - HDD LOG NUMBER ;READ SECTOR ReadLong: LD C,BIOS.DRV_READ_LONG JP Exec_BIOS ;HL:IX - SECTOR ; DE - ADDRESS ; B - COUNTER ; A'- PAGE ; A - HDD LOG NUMBER ;WRITE SECTOR WriteLong: LD C,BIOS.DRV_WRITE_LONG JP Exec_BIOS ;HL:IX - SECTOR ; DE - ADDRESS ; B - COUNTER ; A - HDD LOG NUMBER ;WRITE SECTOR Write: LD C,BIOS.DRV_WRITE JP Exec_BIOS ;HL:IX - SECTOR ; DE - ADDRESS ; B - COUNTER ; A - HDD LOG NUMBER ;READ SECTOR Read: LD C,BIOS.DRV_READ ; Exec_BIOS: PUSH IY CALL .exec POP IY RET ; .exec: CALL SelectDrive RET C ;!FIXIT переделать номер ошибки с драйвера на дос RST ToBIOS RET NC CP BIOS.Error.ATAPI.UnitAttention SCF RET NZ SET 1,(IY + LOGDRV.MediaParameters) RET ;------------------------------[ PARTIT ]------------------------------; ; вход: B - bit0=1 removable, bit1=1 drive changed, bit7..2 reserved DEFINE_PARTITIONS: IN A,(SLOT3) PUSH AF LD A,SHARED_PAGE OUT (SLOT3),A LD A,(Init.count) ; [ ] for ZIP disk A: PUSH AF ; [ ] for ZIP disk A: CALL .Start ; [ ] for ZIP disk A: LD A,(Init.count) LD B,A POP AF CP B CALL Z,.Check_0_BPB ; POP AF OUT (SLOT3),A RET ; .FAT32_DOS: .EASYDOS: .MEDIDOS: .HIGHDOS: LD E,(IY + BOOT_SECTOR.Partition.Start_LBA + 0) LD D,(IY + BOOT_SECTOR.Partition.Start_LBA + 1) LD L,(IY + BOOT_SECTOR.Partition.Start_LBA + 2) LD H,(IY + BOOT_SECTOR.Partition.Start_LBA + 3) LD IX,(CURRENT_SECTOR.Low) ADD IX,DE LD DE,(CURRENT_SECTOR.High) ADC HL,DE LD D,XH LD E,XL ;BPB SECTOR LD IX,(LOGDRV_OFFSET) LD (IX + LOGDRV.SECTOR_OFFSET + 0),E LD (IX + LOGDRV.SECTOR_OFFSET + 1),D LD (IX + LOGDRV.SECTOR_OFFSET + 2),L LD (IX + LOGDRV.SECTOR_OFFSET + 3),H LD E,(IY + BOOT_SECTOR.Partition.Size_LBA + 0) LD D,(IY + BOOT_SECTOR.Partition.Size_LBA + 1) LD L,(IY + BOOT_SECTOR.Partition.Size_LBA + 2) LD H,(IY + BOOT_SECTOR.Partition.Size_LBA + 3) ;SIZE DISK LD (IX + LOGDRV.SIZE_IN_SECTORS + 0),E LD (IX + LOGDRV.SIZE_IN_SECTORS + 1),D LD (IX + LOGDRV.SIZE_IN_SECTORS + 2),L LD (IX + LOGDRV.SIZE_IN_SECTORS + 3),H ; [ ] sector size CALL GetSectorSize LD IX,(LOGDRV_OFFSET) LD (IX + LOGDRV.SECTOR_SIZE),C LD (IX + LOGDRV.SECTOR_SIZE + 1),B LD A,(CURRENT_DRIVE.Removable) LD (IX + LOGDRV.MediaParameters),A ;[x] 17.12.2023 загрузка с активного раздела, а не с первого .ExtendedPartitionFlag+1: LD A,0 OR A ; !TODO загрузка с расширенного раздела не поддерживается LD A,#FF JR NZ,.not_supported ; если расширенный раздел, то облом ; POP BC PUSH BC LD A,+(_sMBR_PARTITION_TABLE / _sMBR_PARTITION_RECORD) ; Number of entries in the partition table SUB B .not_supported: LD (IX + LOGDRV.PARTITION_RECORD_NUM),A ; CALL INC_DRV_COUNT RET NC ; CALL .set_drv_tbl JP .NextPartition ; .NotExtended: CP PartitionSysTypes.FAT16 JR Z,.HIGHDOS CP PartitionSysTypes.FAT16_LBA JP Z,.HIGHDOS CP PartitionSysTypes.FAT16_32Mb JP Z,.MEDIDOS CP PartitionSysTypes.FAT12 JP Z,.EASYDOS ;[ ] fat32 CP PartitionSysTypes.FAT32 JP Z,.FAT32_DOS CP PartitionSysTypes.FAT32_LBA JP Z,.FAT32_DOS ; CP PartitionSysTypes.Win_Ext_LBA JP Z,.SubLevel JP .NextPartition ; раздел не поддерживается ; .set_drv_tbl: LD A,(CURRENT_DRIVE.Number) LD (IX + LOGDRV.PHISICAL_DRV_NUMBER),A LD DE,LOGDRV.TBL_Entry ;DSKITEM ADD IX,DE LD (LOGDRV_OFFSET),IX RET ; .CDFS_TST: ;JR .check_atapi ;!FIXIT CDFS ;SCF ;RET .check_atapi: LD A,(CURRENT_DRIVE.Number) ;LD B,A AND #F0 CP DRIVE_CODES.SPRINTER.ATAPI SCF ;RET NZ PUSH AF ; CALL GetSectorSize CALL .set_LOGDRV POP AF RET NZ ; результат CP DRIVE_CODES.SPRINTER.ATAPI ; для правильного выхода из парсера разделов LD B,1 PUSH BC ;загрузка с активного раздела, а не с первого LD A,#FF ; для пропуска .tst_zipNoMBR и записи в LOGDRV.PARTITION_RECORD_NUM LD (CURRENT_SECTOR.Low),A JP .not_supported ; .set_LOGDRV: ;BPB SECTOR ;!TODO если CD-ROM, то другой номер сектора LD IX,(LOGDRV_OFFSET) LD A,(CURRENT_DRIVE.Removable) LD (IX + LOGDRV.MediaParameters),A XOR A LD (IX + LOGDRV.SECTOR_OFFSET + 0),A LD (IX + LOGDRV.SECTOR_OFFSET + 1),A LD (IX + LOGDRV.SECTOR_OFFSET + 2),A LD (IX + LOGDRV.SECTOR_OFFSET + 3),A ; [ ] SIZE DISK LD (IX + LOGDRV.SIZE_IN_SECTORS + 0),E LD (IX + LOGDRV.SIZE_IN_SECTORS + 1),D LD (IX + LOGDRV.SIZE_IN_SECTORS + 2),L LD (IX + LOGDRV.SIZE_IN_SECTORS + 3),H ; [ ] sector size LD (IX + LOGDRV.SECTOR_SIZE),C LD (IX + LOGDRV.SECTOR_SIZE + 1),B RET ; ; вход: B - bit0=1 removable, bit1=1 drive changed, bit7..2 reserved .Start: LD IX,0 LD DE,0 LD A,B AND %1111'1101 LD (CURRENT_DRIVE.Removable),A LD (EXT_Partition.Low),DE ;R01 LD (EXT_Partition.High),IX ;R01 ; .LOOP: LD (CURRENT_SECTOR.Low),DE LD (CURRENT_SECTOR.High),IX CALL .LOAD_SECTOR JR C,.check_atapi ; .check_sign: LD HL,(PARTITION_BUFFER.MBR_SIGNATURE) LD DE,#AA55 AND A SBC HL,DE ;[x] 17/12/23 пропуск разделов с неизвестными ФС, оптимизация перебора разделов ;JR NZ,NODEFIN ; [ ] CDFS JR NZ,.CDFS_TST ;SCF ;RET NZ ; ; [ ] если ATAPI, то пробуем прочесть 0 сектор как-будто нет MBR ;LD A,(CURRENT_DRIVE.Number) ;CP DRIVE_CODES.SPRINTER.CDROM ; LD IY,PARTITION_BUFFER.PARTITION_TABLE ; Offset of partition table in the MBR LD B,+(_sMBR_PARTITION_TABLE / _sMBR_PARTITION_RECORD) ; Number of entries in the partition table .DOSAGA: PUSH BC LD A,(IY+_sMBR_PARTITION_RECORD.FS_ID) CP PartitionSysTypes.Extended JR Z,.SubLevel CP PartitionSysTypes.Win_Ext_LBA JP NZ,.NotExtended ; .SubLevel: PUSH IY LD DE,(CURRENT_SECTOR.Low) LD IX,(CURRENT_SECTOR.High) PUSH DE PUSH IX ;[x] 17/12/23 пропуск разделов с неизвестными ФС, оптимизация перебора разделов LD A,(.ExtendedPartitionFlag) INC A LD (.ExtendedPartitionFlag),A ; !TODO загрузка с расширенного раздела не поддерживается ; CALL .ParseExtended ;[x] 17/12/23 пропуск разделов с неизвестными ФС, оптимизация перебора разделов LD A,(.ExtendedPartitionFlag) DEC A LD (.ExtendedPartitionFlag),A ; !TODO загрузка с расширенного раздела не поддерживается ; POP IX POP DE LD (CURRENT_SECTOR.Low),DE LD (CURRENT_SECTOR.High),IX CALL .LOAD_SECTOR POP IY .NextPartition: LD DE,_sMBR_PARTITION_RECORD ;Size of a partition table entry ADD IY,DE POP BC DJNZ .DOSAGA .exit: AND A RET ; .ParseExtended: LD HL,(EXT_Partition.Low) LD DE,(EXT_Partition.High) LD A,L OR H OR E OR D LD E,(IY + _sMBR_PARTITION_RECORD.Start_LBA + 0) LD D,(IY + _sMBR_PARTITION_RECORD.Start_LBA + 1) LD L,(IY + _sMBR_PARTITION_RECORD.Start_LBA + 2) LD H,(IY + _sMBR_PARTITION_RECORD.Start_LBA + 3) JP NZ,.ext_in_ext LD (EXT_Partition.Low),DE LD (EXT_Partition.High),HL PUSH DE JR .set_regs ; .ext_in_ext: LD IX,(EXT_Partition.Low) ADD IX,DE LD DE,(EXT_Partition.High) ADC HL,DE PUSH IX .set_regs: PUSH HL POP IX POP DE JP .LOOP ; .LOAD_SECTOR: PUSH IY LD IX,(CURRENT_SECTOR.Low) LD HL,(CURRENT_SECTOR.High) LD DE,PARTITION_BUFFER LD A,(CURRENT_DRIVE.Number) LD BC,1*256 + BIOS.DRV_READ RST ToBIOS POP IY RET ; .Check_0_BPB: LD A,(CURRENT_DRIVE.Number) CP DRIVE_CODES.SPRINTER.ATAPI RET C LD C,BIOS.DRV_GET_PAR RST ToBIOS RET C ; LD B,XH LD C,XL CALL .set_LOGDRV LD A,(CURRENT_DRIVE.Removable) LD (IX + LOGDRV.MediaParameters),A LD (IX + LOGDRV.PARTITION_RECORD_NUM),#FF CALL .set_drv_tbl JP INC_DRV_COUNT ; ; ; ; GetSectorSize: PUSH IY LD A,(CURRENT_DRIVE.Number) ; sector size LD C,BIOS.DRV_GET_PAR ; [ ] media change заменить на drv_detect ? RST ToBIOS JR NC,.no_err ; LD IX,#FFFF .no_err: LD B,XH LD C,XL POP IY RET ;----------------------------------------------------------------------; ; ;!TEST Подстраховка от переполнения таблицы LOGDRV INC_DRV_COUNT: LD A,(Init.count) INC A CP DSS_MAX_DRIVES_AMOUNT+1 RET NC LD (Init.count),A RET ;======================================================================= ; PHISICAL DRIVE NUMBER ; #80/#81 - primary мастер/слейв, #82/#83 - secondary мастер/слейв CURRENT_DRIVE: .Number: DB #00 .Removable: DB #00 ; CURRENT_SECTOR: .Low: DW #0000 .High: DW #0000 ; EXT_Partition: ;CURRENT PARTITION TABLE .Low: DW #0000 .High: DW #0000 ; LOGDRV_OFFSET: DW LOGDRV ;POINTER ON CURRENT DISK RECORD ;======================================================================= ENDMODULE