;!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 PARTITION_BUFFER _sBOOT_SECTOR = #C000 HDDRIVE: INC C DEC C JP Z,INIT_H ; c=0 Initialization DEC C JP Z,RESE_H ; c=1 open DEC C JP Z,STAT_H ; c=2 close DEC C JP Z,CHEK_H ; c=3 media check (смена носителя) DEC C JP Z,GBPB_H ; c=4 get BPB DEC C JP Z,READH ; c=5 read (чтение секторов) DEC C JP Z,WRITEH ; c=6 write (запись секторов) DEC C JP Z,REMOV_H ; c=7 Removable DEC C JP Z,IOCTL_H ; c=8 узнать геометрию диска Generic IOCTL DEC C JP Z,.Reserved ; c=9 Reserved DEC C JP Z,LREADH ; c=10 Read Long DEC C JP Z,LWRITEH ; c=11 Write Long ; .Reserved: LD A,DSS_Error.drv.INVALID_COMMAND SCF RET //////////////////////////////////////////////////////////////////////// // Commands for restart #18 // //////////////////////////////////////////////////////////////////////// ;--------------------------------------------------------------------[v] ; c=0 Initialization INIT_H: PUSH IY ;!TEST ;[ ] для rescanDRV XOR A LD (DRVCLC.count),A ; LD HL,LOGDRV LD (OFFSECT),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 (28) ; IN A,(SLOT3) LD C,A LD A,SYS_PAGE OUT (SLOT3),A XOR A LD B,(IX+2) ;количество HDD для процедуры NX_DVCI CP B LD A,C OUT (SLOT3),A JR Z,NO_HARDS LD C,#80 ;!HARDCODE - ID винта для процедуры BIOS.DRV_DETECT NX_DVCI: PUSH BC LD A,C LD (DRV_NUM),A LD C,BIOS.DRV_DETECT RST ToBIOS ;JR C,.NO_DRIVE CALL NC,DEFINE_PARTITIONS.BEGIN POP BC INC C JR C,NX_DVCI DJNZ NX_DVCI ; NO_HARDS: POP IY ;!TEST ; LD HL,(OFFSECT) ; LD DE,LOGDRV ; XOR A ; SBC HL,DE ; RET Z ; LD DE,LOGDRV.TBL_Entry DRVCLC: ; INC A ; SBC HL,DE ; JR NZ,DRVCLC ; .count+1: LD A,0 ; AND A RET ;---------------------------------------------------------------------[^] ; ;+00 BYTE MASTER/SLAVE PHISICAL DRIVE NUMBER #80/#81/... ; ;+01 DWORD SECTOR OFFSET ; ;+05 DWORD SIZE IN SECTORS ; ;+09 FREE ; ;+15 ; LOGDRV: BLOCK .TBL_Entry * LD_DSK,0 ; .TBL_Entry EQU 16 ; .Size EQU $-LOGDRV SELHDD: PUSH DE PUSH HL ; LD L,A LOGDRV_ENTRY_FIND LOGDRV ; !HARDCODE LD E,(IY+1) LD D,(IY+2) ADD IX,DE LD E,(IY+3) LD D,(IY+4) POP HL ADC HL,DE LD A,(IY+0) ;DRIVE NUMBER POP DE RET ; 00 - GET DEVICE PARAMETERS ; 01 - READ TRACK ; 02 - TEST TRACK ; 80 - SET DEVICE PARAMETERS ; 81 - WRITE TRACK ; 82 - FORMAT TRACK IOCTL_H BIT 7,B JR NZ,O_CTL_H INC B DEC B JP Z,HGETPRM DEC B JP Z,HRDTRAC DEC B JP Z,HCHTRAC LD A,DSS_Error.drv.INVALID_COMMAND SCF RET O_CTL_H RES 7,B INC B DEC B JP Z,HSETPRM DEC B JP Z,HWRTRAC DEC B JP Z,HFRTRAC LD A,DSS_Error.drv.INVALID_COMMAND SCF RET HRDTRAC LD A,DSS_Error.drv.GENERAL_FAILURE SCF RET HCHTRAC LD B,L CALL CHECKH RET HSETPRM AND A RET HWRTRAC LD A,DSS_Error.drv.GENERAL_FAILURE SCF RET HFRTRAC LD A,DSS_Error.drv.GENERAL_FAILURE SCF RET ; 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 HGETPRM: 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 LD A,DSS_Error.drv.INVALID_DRIVE JR C,.error ; перетасовка регистров с результатом от 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 REMOV_H: LD A,1 AND A RET RESE_H: XOR A RET STAT_H: XOR A RET CHEK_H: ;LD A,#FF XOR A ;AND A RET ; DE - ADDRESS ; A - DRIVE GBPB_H: PUSH IY PUSH DE LD L,A ; LOGDRV_ENTRY_FIND LOGDRV ; 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.SECTOR_OFFSET.PHISICAL_DRV_NUMBER) POP DE POP IY LD BC,1*256 + BIOS.DRV_READ JP ToBIOS ;HL:IX - SECTOR ; DE - ADDRESS ; B - COUNTER ; A'- PAGE ; A - HDD LOG NUMBER ;READ SECTOR LREADH: PUSH IY CALL SELHDD LD C,BIOS.DRV_READ_LONG RST ToBIOS POP IY RET ;HL:IX - SECTOR ; DE - ADDRESS ; B - COUNTER ; A'- PAGE ; A - HDD LOG NUMBER ;WRITE SECTOR LWRITEH: PUSH IY CALL SELHDD LD C,BIOS.DRV_WRITE_LONG RST ToBIOS POP IY RET ;HL:IX - SECTOR ; DE - ADDRESS ; B - COUNTER ; A - HDD LOG NUMBER ;WRITE SECTOR WRITEH: PUSH IY CALL SELHDD LD C,BIOS.DRV_WRITE RST ToBIOS POP IY RET ;HL:IX - SECTOR ; DE - ADDRESS ; B - COUNTER ; A - HDD LOG NUMBER ;READ SECTOR READH: PUSH IY CALL SELHDD LD C,BIOS.DRV_READ RST ToBIOS POP IY RET ;HL:IX - SECTOR ; DE - ADDRESS ; B - COUNTER ; A - HDD LOG NUMBER ;CHECK SECTOR CHECKH: PUSH IY CALL SELHDD LD C,BIOS.DRV_VERIFY RST ToBIOS POP IY RET ;------------------------------[ PARTIT ]------------------------------; DEFINE_PARTITIONS: .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_L) ADD IX,DE LD DE,(CURRENT_SECTOR_H) ADC HL,DE LD D,XH LD E,XL ;BPB SECTOR LD IX,(OFFSECT) 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 ;[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 ; ;!TEST Подстраховка от переполнения таблицы LOGDRV LD A,(DRVCLC.count) INC A CP DSS_MAX_DRIVES_AMOUNT+1 RET NC LD (DRVCLC.count),A ; LD A,(DRV_NUM) LD (IX + LOGDRV.PHISICAL_DRV_NUMBER),A LD DE,LOGDRV.TBL_Entry ;DSKITEM ADD IX,DE LD (OFFSECT),IX JP .NextPartition ; .NotExtended: CP PartitionSysTypes.FAT16 JR Z,.HIGHDOS CP PartitionSysTypes.FAT16_LBA JR Z,.HIGHDOS CP PartitionSysTypes.FAT16_32Mb JR Z,.MEDIDOS CP PartitionSysTypes.FAT12 JR Z,.EASYDOS ;[ ] fat32 CP PartitionSysTypes.FAT32 JP Z,.FAT32_DOS CP PartitionSysTypes.FAT32_LBA JP Z,.FAT32_DOS ; CP PartitionSysTypes.Win_Ext_LBA JR Z,.SubLevel ;[x] 17/12/23 пропуск разделов с неизвестными ФС, оптимизация детекта ;OR A ;PartitionSysTypes.Empty ;JR NZ,NXTPART JR .NextPartition ; раздел не поддерживается ;POP BC ; баланс стека ;RET ;POP BC ;OR A ;RET Z ;NODEFIN: ;SCF ;RET ; .BEGIN: IN A,(SLOT3) PUSH AF LD A,SHARED_PAGE OUT (SLOT3),A CALL .Start POP AF OUT (SLOT3),A RET .Start: LD IX,0 LD DE,0 LD (EXTDOSL),DE ;R01 LD (EXTDOSH),IX ;R01 ; .LOOP: LD (CURRENT_SECTOR_L),DE LD (CURRENT_SECTOR_H),IX CALL .LOAD_SECTOR ; LD HL,(PARTITION_BUFFER.MBR_SIGNATURE) LD DE,#AA55 AND A SBC HL,DE ;[x] 17/12/23 пропуск разделов с неизвестными ФС, оптимизация перебора разделов ;JR NZ,NODEFIN SCF RET NZ ; 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 JR NZ,.NotExtended ; .SubLevel: PUSH IY LD DE,(CURRENT_SECTOR_L) LD IX,(CURRENT_SECTOR_H) 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_L),DE LD (CURRENT_SECTOR_H),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 AND A RET ; .ParseExtended: LD HL,(EXTDOSL) LD DE,(EXTDOSH) 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 (EXTDOSL),DE LD (EXTDOSH),HL PUSH DE JR .set_regs ; .ext_in_ext: LD IX,(EXTDOSL) ADD IX,DE LD DE,(EXTDOSH) ADC HL,DE PUSH IX .set_regs: PUSH HL POP IX POP DE JP .LOOP ; .LOAD_SECTOR: PUSH IY LD IX,(CURRENT_SECTOR_L) LD HL,(CURRENT_SECTOR_H) LD DE,PARTITION_BUFFER LD A,(DRV_NUM) LD BC,1*256 + BIOS.DRV_READ RST ToBIOS POP IY RET ;----------------------------------------------------------------------; ; ;======================================================================= ; PHISICAL DRIVE NUMBER ; #80/#81 - primary мастер/слейв, #82/#83 - secondary мастер/слейв DRV_NUM: DB #00 CURRENT_SECTOR_L: DW #0000 CURRENT_SECTOR_H: DW #0000 EXTDOSL: DW #0000 ;CURRENT PARTITION TABLE EXTDOSH: DW #0000 OFFSECT: DW LOGDRV ;POINTER ON CURRENT DISK RECORD ;=======================================================================