;======================================================== ;R03 !25.07.2001! BUG FIX WITH RETURN ERROR CODE ;R02 !24.07.2001! ADD SECONDARY CHANEL ;R01 !16.08.2000! REMOVED "DI" /* ;Write IDE.Write.Command EQU #4153 ; #1F7 Command IDE.Write.DeviceHead EQU #4152 ; #1F6 Drive Control HDW_CLH EQU #0155 ; #1F5 Cylinder High HDW_CLL EQU #0154 ; #1F4 Cylinder Low HDW_SEC EQU #0153 ; #1F3 Sector HDW_CNT EQU #0152 ; #1F2 Counter HDW_ERR EQU #0151 ; #1F1 Error HDW_DAT EQU #0150 ; #1F0 Data ;Read IDE.Read.Status EQU #4053 ; #1F7 Status (Control) HDR_DRV EQU #4052 ; #1F6 Drive Control HDR_CLH EQU #0055 ; #1F5 Cylinder High HDR_CLL EQU #0054 ; #1F4 Cylinder Low HDR_SEC EQU #0053 ; #1F3 Sector HDR_CNT EQU #0052 ; #1F2 Counter HDR_ERR EQU #0051 ; #1F1 Error HDR_DAT EQU #0050 ; #1F0 Data ;Bits for IDE.Read.Status ;---[] BSY EQU 7 RDY EQU 6 DRQ EQU 3 ERR EQU 0 ;---[] HDD EQU 1 CDROM EQU 2 ;EQU FOR IY+ IDE.HDD_INIT_TABLE.DRV_Flags EQU 0 IDE.HDD_INIT_TABLE.SectorsPerTrack EQU 1 IDE.HDD_INIT_TABLE.HeadsNumber EQU 2 IDE.HDD_INIT_TABLE.CylinderNumberLow EQU 3 IDE.HDD_INIT_TABLE.CylinderNumberHigh EQU 4 IDE.HDD_INIT_TABLE.SectorsPerCylinderLow EQU 5 IDE.HDD_INIT_TABLE.SectorsPerCylinderHigh EQU 6 DTYPE_H EQU 7 IDE0 EQU #C1C0 IDE1 EQU #C1C8 IDE2 EQU #C1D0 IDE3 EQU #C1D8 */ ;IDE0 DB #FF ;DRIVE/HEAD REGISTER ;00 ; DB #FF ;SECTORS PER TRACK ;01 ; DB #FF ;HEADS ;02 ; DB #FF ;CYLINDERS LOW ;03 ; DB #FF ;CYLINDERS HIGH ;04 ; DB #FF ;SECTOR PER CYLINDER LOW ;05 ; DB #FF ;SECTOR PER CYLINDER HIGH ;06 ; DB #FF ;RESERVED ;07 ;IDE1 DB #FF ;DRIVE/HEAD REGISTER ;00 ; DB #FF ;SECTORS PER TRACK ;01 ; DB #FF ;HEADS ;02 ; DB #FF ;CYLINDERS LOW ;03 ; DB #FF ;CYLINDERS HIGH ;04 ; DB #FF ;SECTOR PER CYLINDER LOW ;05 ; DB #FF ;SECTOR PER CYLINDER HIGH ;06 ; DB #FF ;RESERVED ;07 WRITE_OUTI_DUPs EQU 32 ; bytes ;[]================================================================[#51] ;Function: Reset drive HDD_5x_RESET: ; !FIXIT не ресетится? ;For non-ATAPI drives, the only method a driver has of resetting a drive ; after a major error is to do a "software reset" on the bus. ; Set bit 2 (SRST, value = 4) in the proper Control Register for the ; bus. This will reset both ATA devices on the bus. Then, you have to ; clear that bit again, yourself. The master drive on the bus is ; automatically selected. XOR A RET ;[]================================================================[#51] ;[]================================================================[#58] ;Function: Get Current Media Parameters ; A - Disk ;Return: ; H - Heads ; L - Sectors per cylinder ; DE - Cylinders ; IX - Capacity sector in bytes ; B - Flags: MASTER/SLAVE, LBA/CHS HDD_5x_GETMED: LD C,IDE.Device.HDD CALL SELECT_DRIVE RET C IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A LD L,(IY+IDE.HDD_INIT_TABLE.SectorsPerTrack) LD H,(IY+IDE.HDD_INIT_TABLE.HeadsNumber) LD E,(IY+IDE.HDD_INIT_TABLE.CylinderNumberLow) LD D,(IY+IDE.HDD_INIT_TABLE.CylinderNumberHigh) LD B,(IY+IDE.HDD_INIT_TABLE.DRV_Flags) LD IX,512 ;!HARDCODE sector size EX AF,AF' OUT (SLOT3),A ;EX AF,AF' AND A RET ;[]================================================================[#58] ;[]================================================================[#59] ;Function: Set Current Media Parameters ; A - Disk ; H - Heads ; L - Sectors ; DE - Cylinders ; IX - Capacity sector in bytes ; B - Flags ;Return: None HDD_5x_SETMED: LD C,IDE.Device.HDD CALL SELECT_DRIVE RET C IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A LD (IY+IDE.HDD_INIT_TABLE.SectorsPerTrack),L LD (IY+IDE.HDD_INIT_TABLE.HeadsNumber),H LD (IY+IDE.HDD_INIT_TABLE.CylinderNumberLow),E LD (IY+IDE.HDD_INIT_TABLE.CylinderNumberHigh),D LD (IY+IDE.HDD_INIT_TABLE.DRV_Flags),B EX AF,AF' OUT (SLOT3),A ;EX AF,AF' AND A RET ;[]================================================================[#59] ;[]================================================================[#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) HDD_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) HDD_5x_LONG_READ: PUSH IY SAFE_PORTY_2 PUSH BC PUSH IX PUSH HL CALL RDS000 EX DE,HL JR C,HERRRD0 LD A,XH EX AF,AF' POP HL POP IX POP BC XOR A CP B LD C,B LD B,A JR NZ,RNOT256 INC B ADD IX,BC LD B,C ADC HL,BC ;EX AF,AF' ;!TEST 21/11/23 JR RST8RDR RNOT256 ADD IX,BC LD C,B ADC HL,BC ;EX AF,AF' ;!TEST 21/11/23 JR RST8RDR HERRRD0 LD B,A LD C,XL LD A,XH EX AF,AF' POP HL POP IX PUSH BC LD B,0 ADD IX,BC LD C,B ADC HL,BC POP BC POP AF SUB C LD C,A LD A,B LD B,C ;R03 SCF ;EX AF,AF' ;!TEST 21/11/23 ; RST8RDR: RESTORE_PORTY POP IY ;EX AF,AF' ;!TEST 21/11/23 RET ;READ SECTOR(S) RDS000: LD C,IDE.Device.HDD CALL SELECT_DRIVE RET C EXX LD DE,#C140 ;WAIT BUSY=0 & READY=1 & ERR=0 CALL WAITPRT EXX RET C EX AF,AF' PUSH AF PUSH DE CALL PRESET POP HL POP AF LD XL,0 LD XH,A LD BC,IDE.Write.Command LD A,IDE.ATA.ReadSectorsWithRetry OUT (C),A ;????? ;SAVE HL! RDS002: EXX LD DE,#8908 ;WAIT BUSY=0 & DRQ=1 & ERR=0 CALL WAITPRT EXX RET C ;NOP ;R01 REMOVED "DI" IN A,(SLOT3) EX AF,AF' LD A,XH OUT (SLOT3),A LD BC,IDE.Read.Data RDS003: DUP 16 INI EDUP JP NZ,RDS003 RDS004: DUP 16 INI EDUP JP NZ,RDS004 EX AF,AF' OUT (SLOT3),A ; LD A,H OR L JR NZ,.W44 LD HL,#C000 IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A LD D,#C2 LD E,XH LD A,(DE) LD XH,A EX AF,AF' OUT (SLOT3),A ; .W44: INC XL ;INC LOADED SECTORS EXX LD DE,#C140 ;WAIT BUSY=0 & ERR=0 & READY=1 CALL WAITPRT EXX RET C LD BC,IDE.Read.Status IN A,(C) BIT IDE.ControlBit.DataRequest,A JP NZ,RDS002 XOR A RET ;[]===========================================================[#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) HDD_5x_WRITE: EX AF,AF' IN A,(SLOT3) EX AF,AF' ;[]================================================================[#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) HDD_5x_LONG_WRITE: PUSH IY SAFE_PORTY_2 PUSH IX PUSH HL PUSH BC CALL WRS000 EX DE,HL JP C,HERRWR0 LD A,XH EX AF,AF' POP BC POP HL POP IX XOR A CP B LD C,B LD B,A JR NZ,WNOT256 INC B ADD IX,BC LD B,C ADC HL,BC ;EX AF,AF' JR RST8WRR WNOT256 ADD IX,BC LD C,B ADC HL,BC ;EX AF,AF' JR RST8WRR HERRWR0 LD B,A LD C,XL LD A,XH EX AF,AF' POP HL POP IX PUSH BC LD B,0 ADD IX,BC LD C,B ADC HL,BC POP BC POP AF SUB C LD C,A LD A,B LD B,C ;R03 SCF ;R03 ;EX AF,AF' ;R03 ;!FIXIT намудрил он чёт в этом R03 ; RST8WRR: RESTORE_PORTY POP IY ;EX AF,AF' RET ;WRITE SECTOR(S) WRS000: LD C,IDE.Device.HDD CALL SELECT_DRIVE RET C EXX LD DE,#C140 ;WAIT BUSY=0 & READY=1 & ERR=0 CALL WAITPRT EXX RET C EX AF,AF' PUSH AF PUSH DE ;[x] CMOS Write Protect Disabled IF HDDwriteProtect PUSH BC LD D,CMOS_CELL.Options CALL CMOS_RD POP BC AND 1 JR Z,NO_WriteProtect POP HL POP AF EX AF,AF' LD XL,0 LD A,BIOS.Error.WriteProtect SCF RET ENDIF NO_WriteProtect: CALL PRESET POP HL POP AF LD XL,0 LD XH,A LD BC,IDE.Write.Command LD A,IDE.ATA.WriteSectorsWithRetry OUT (C),A ;SAVE HL! WRS002: EXX LD DE,#8908 ;WAIT BUSY=0 & DRQ=1 & ERR=0 CALL WAITPRT EXX RET C ;DI IN A,(SLOT3) EX AF,AF' LD A,XH OUT (SLOT3),A LD BC,IDE.Write.Data ;LD D,#20 LD D,512/WRITE_OUTI_DUPs WRS003: DUP WRITE_OUTI_DUPs OUTI EDUP DEC D JR NZ,WRS003 EX AF,AF' OUT (SLOT3),A //EI ; LD A,H OR L JR NZ,.W33 LD HL,#C000 IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A LD D,#C2 LD E,XH LD A,(DE) LD XH,A EX AF,AF' OUT (SLOT3),A .W33: INC XL ;INC SAVED SECTORS EXX LD DE,#C140 ;WAIT BUSY=0 & ERR=0 & READY=1 CALL WAITPRT EXX RET C LD BC,IDE.Read.Status IN A,(C) BIT IDE.ControlBit.DataRequest,A JP NZ,WRS002 XOR A RET ;[]===========================================================[#53, #56] ;[]================================================================[#54] ;Function: Verify Sectors ; A - Disk ; HL:IX - Sector ; B - Sector counter ;Return: None ;VERIFY SECTOR(S) HDD_5x_VERIFY: PUSH IY SAFE_PORTY_2 PUSH IX PUSH HL CALL VRS000 POP HL POP IX RESTORE_PORTY POP IY RET ;[]================================================================[#54] ;VERIFY SECTOR(S) VRS000: LD C,IDE.Device.HDD CALL SELECT_DRIVE RET C EXX LD DE,#C140 ;WAIT BUSY=0 & READY=1 & ERR=0 CALL WAITPRT EXX RET C PUSH DE CALL PRESET POP HL LD BC,IDE.Write.Command LD A,IDE.ATA.ReadVerifySectorsWithRetry OUT (C),A VRS002: LD BC,IDE.Read.Status IN A,(C) BIT IDE.ControlBit.Error,A JR Z,VRS003 SCF RET VRS003: LD DE,#C140 ;WAIT BUSY=0 & ERR=0 & READY=1 CALL WAITPRT RET C XOR A RET ; HL:IX - LBA SECTOR ; B - SECTOR COUNTER PRESET: LD A,B LD BC,IDE.Write.Counter OUT (C),A IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A LD A,(IY+IDE.HDD_INIT_TABLE.DRV_Flags) LD BC,IDE.Write.DeviceHead OUT (C),A ;бит CHS/LBA ;!FIXIT сделать метками номера бит AND %0100'0000 LD E,XL LD D,XH CALL Z,LBA_CHS LD BC,IDE.Write.Sector OUT (C),E ;LBA 0..7 IF IDE_Optimization INC C ; LD BC,IDE.Write.CylinderLow OUT (C),D ;LBA 8..15 INC C ; LD BC,IDE.Write.CylinderHigh OUT (C),L ;LBA 16..23 LD BC,IDE.Read.Control IN A,(C) AND #F0 ;!HARDCODE DRIVE/HEAD REGISTER PHISICAL DISK bitmask OR H ;LBA 24..27 INC B ; LD BC,IDE.Write.DeviceHead ELSE LD BC,IDE.Write.CylinderLow OUT (C),D ;LBA 8..15 LD BC,IDE.Write.CylinderHigh OUT (C),L ;LBA 16..23 LD BC,IDE.Read.Control IN A,(C) AND #F0 ;!HARDCODE DRIVE/HEAD REGISTER PHISICAL DISK bitmask OR H ;LBA 24..27 LD BC,IDE.Write.DeviceHead ENDIF OUT (C),A EX AF,AF' OUT (SLOT3),A AND A RET ; HL:DE - SECTOR OFFSET LBA_CHS: LD C,(IY+IDE.HDD_INIT_TABLE.SectorsPerCylinderLow) LD B,(IY+IDE.HDD_INIT_TABLE.SectorsPerCylinderHigh) ; HL:DE / BC => DE:IX HL-OSTATOK DIV32X: LD XH,D LD XL,E EX DE,HL LD HL,0 LD A,#20 DIV011: ADD IX,IX EX DE,HL ADC HL,HL EX DE,HL ADC HL,HL SBC HL,BC JR NC,DIV012 ADD HL,BC DEC A JR NZ,DIV011 JR DIV014 DIV012: INC IX DEC A JR NZ,DIV011 DIV014: LD E,(IY+IDE.HDD_INIT_TABLE.SectorsPerTrack) LD D,0 XOR A CHS005: INC A SBC HL,DE JR NC,CHS005 ADD HL,DE DEC A LD H,A LD E,L INC E LD D,XL LD A,XH LD L,A RET ;----------------------------------------------------------------------; ; D - MASK ; E - PATTERN WAITPRT: LD BC,IDE.Read.Status LD HL,#0000 ; задержка ;!HARDCODE ; .loop: PUSH HL ; .loop2: IN A,(C) AND D CP E JR Z,.ok DEC HL LD A,L OR H JP NZ,.loop2 ; POP HL DEC L JR NZ,.loop ; .error: LD A,BIOS.Error.NotReady SCF RET .ok: POP HL RET ;----------------------------------------------------------------------; ;[]================================================================[#57] ;[x] 18/12/2023. добавление/допиливание API CD-ROM (ATAPI) ;Function: Detect Disk ; A - Disk ;Return: CF=0 - A=Drive type ; CF=1 - drive not present, A=#02 HDD_5x_DETECT: LD C,IDE.Device.HDD JP DRV_DETECT ;[]================================================================[#57]