; !FIXIT ALL ; ;[]===========================================================[] ;!TODO ; объеденить процедуры FDD_5x_LONG_READ и FDD_5x_LONG_WRITE ; объеденить процедуры READ_SECTOR и WR_SEC ; FDD.CHANGE: ; LD A,#01 ; AND A ; RET ;[]===========================================================[] ;Function: Get Current Media Parameters ; A - Disk ;Return: ; H - Heads ; L - Sectors ; DE - Cylinders ; IX - Capacity sector in bytes ; B - Flags ; D7 - "1" - High Density, "0" - Double Density ; D0 - FDD drv number ; A - D0 - "1" - Removable media ;[]===========================================================[] ;!FIXIT всегда идет работа с данными для диска А FDD_5x_GET_PAR: IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A ; LD HL,(SYS_PAGE.FDD_TABLE.SECTORS) LD DE,(SYS_PAGE.FDD_TABLE.CYLINDL) LD IX,(SYS_PAGE.FDD_TABLE.BytesPerSector) LD A,(SYS_PAGE.FDD_TABLE.DISK) LD B,A EX AF,AF' OUT (SLOT3),A XOR A INC A ; removable media. CF=0, LD A,1 RET ;[]===========================================================[] ;Function: Set Current Media Parameters ; A - Disk ; H - Heads ; L - Sectors ; DE - Cylinders ; IX - Capacity sector in bytes ; B - Flags ; D7 - "1" - High Density, "0" - Double Density ;Return: None ;[]===========================================================[] FDD_5x_SET_PAR: ;!TEST FDD 720/1440 IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A ; LD A,B LD (SYS_PAGE.FDD_TABLE.SECTORS),HL LD (SYS_PAGE.FDD_TABLE.CYLINDL),DE LD (SYS_PAGE.FDD_TABLE.BytesPerSector),IX LD (SYS_PAGE.FDD_TABLE.DISK),A ; EX AF,AF' OUT (SLOT3),A EX AF,AF' AND A RET ;[]===========================================================[] ;Function: Detect Disk Density ; A - Disk ;Return: ; A - Flag D7 - "1" - High Density, "0" - Double Density ; B - bit0=1 removable ;[]===========================================================[] FDD_5x_DETECT: CALL SAVE_INTERRUPTS.switch_off CALL SET_DOS_ON CALL DISK_ID PUSH AF CALL SET_DOS_OFF POP AF LD B,%0000'0001 ;bit0=1 removable, bit1=1 drive changed, bit7..2 reserved ; [ ] JP SAVE_INTERRUPTS.restore ;RET ;[]===========================================================[] ;Function: Reset Disk ; A - Disk ;Return: None ;[]===========================================================[] FDD_5x_RESET: CALL SAVE_INTERRUPTS.switch_off CALL SET_DOS_ON CALL S_FDD CALL DISK_ID JR C,.int ; [ ] размера сектора IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A LD H,B LD L,0 LD (SYS_PAGE.FDD_TABLE.BytesPerSector),HL EX AF,AF' OUT (SLOT3),A ; .int: CALL SAVE_INTERRUPTS.restore JR C,.MOTOR_OFF ; CALL RESWG XOR A ;!HARDCODE CMD КР1818ВГ93 OUT (FDC_93.Track),A IN A,(FDC_93.Command) ;LD C,A CALL SET_DOS_OFF ;LD A,C AND A JP SAVE_INTERRUPTS.restore ;RET .MOTOR_OFF: ;PUSH AF LD A,#D0 ;!HARDCODE CMD КР1818ВГ93 OUT (FDC_93.Command),A ;STOP OPERATION LD A,#00 OUT (FDC_93.DrvCTRL),A LD A,#3C OUT (FDC_93.DrvCTRL),A CALL SET_DOS_OFF ; CF=1 LD A,BIOS.Error.NotReady ;POP AF ;JP SAVE_INTERRUPTS.restore RET ;[]===========================================================[] ;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) ;[]===========================================================[] FDD_5x_READ: EX AF,AF' IN A,(SLOT3) EX AF,AF' ;[]===========================================================[] ;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) ;[]===========================================================[] FDD_5x_LONG_READ: EXX LD B,#80 ; COMMAND READ ;!HARDCODE CMD КР1818ВГ93 EXX ; .RW_Shared: CALL SAVE_INTERRUPTS.switch_off CALL .Start JP SAVE_INTERRUPTS.restore ; .Start: PUSH IY PUSH BC PUSH HL PUSH IX ; EX AF,AF' LD C,A ; Memory Page Number EX AF,AF' PUSH BC CALL SET_DOS_ON CALL S_FDD CALL SET_SPEED CALL NTRACK POP BC EX DE,HL IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A LD IY,(SYS_PAGE.FDD_TABLE.BytesPerSector) LD XH,C ; Memory Page Number LD A,(SYS_PAGE.FDD_TABLE.SECTORS) LD C,A EX AF,AF' OUT (SLOT3),A .DSK_LP: LD A,D EXX PUSH BC CALL SEEK POP BC EXX PUSH DE PUSH BC PUSH HL CALL FDD_RW_SECTOR JR C,.ERRDOS ; размер сектора LD D,YH LD E,YL ; POP HL POP BC ADD HL,DE ; CALL C,CHANGE_MEM_BLK ; .THISRD: POP DE LD A,C INC E CP E JR NZ,.NINC_T LD E,0 INC D .NINC_T: DJNZ .DSK_LP .RETDOS: CALL SET_DOS_OFF LD A,XH ; Memory Page Number EX AF,AF' EX DE,HL POP IX POP HL POP BC POP IY LD A,B LD C,B INC B DEC B LD B,0 JR NZ,.ADD8BIT INC B .ADD8BIT: ADD IX,BC ;!TEST ;LD BC,0 ;ADC HL,BC ;LD B,A ;XOR A ;RET ; LD B,A RET NC INC HL XOR A RET ; .ERRDOS: POP HL POP BC POP DE CALL SET_DOS_OFF EX DE,HL EX AF,AF' EXX LD C,XH ; Memory Page Number EXX LD A,B POP IX POP HL POP BC POP IY PUSH AF LD C,A LD A,B SUB C LD C,A LD B,0 ADD IX,BC LD C,B ADC HL,BC POP BC EXX LD A,C EXX EX AF,AF' SCF RET ;[]===========================================================[] ;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) ;[]===========================================================[] FDD_5x_WRITE: EX AF,AF' IN A,(SLOT3) EX AF,AF' ;[]===========================================================[] ;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) ;?? B - Sector counter ;[]===========================================================[] FDD_5x_LONG_WRITE: EXX LD B,#A0 ;COMMAND WRITE ;!HARDCODE CMD КР1818ВГ93 EXX JP FDD_5x_LONG_READ.RW_Shared ; ;------------------------------- ;WRITE SECTOR ;------------------------------- FDD_RW_SECTOR: LD D,5 ;RETRY COUNT .RETRY: ;DI PUSH HL PUSH DE LD A,E INC A OUT (FDC_93.Sector),A IN A,(SLOT3) EX AF,AF' LD A,XH OUT (SLOT3),A ; LD B,4 LD C,FDC_93.Data EXX LD A,B ; COMMAND read or write EXX OUT (FDC_93.Command),A ; .wait_loop: IN A,(FDC_93.DrvCTRL) ;WAIT INTRQ or DRQ AND %1100'0000 ;b6: DRQ (запрос данных = 1). b7: INTRQ (выполняется команда = 0). JR NZ,.RW_PROC INC DE LD A,E OR D JR NZ,.wait_loop DJNZ .wait_loop SCF JR .after_rw ; error ; .RW_PROC: EXX BIT 5,B EXX ; [ ] 15/04/25 размер сектора больше, чем установлено в SYS_PAGE.FDD_TABLE.BytesPerSector вызовет ошибку LD D,YH LD E,YL INC DE ; JR NZ,.write_loop ;READ BYTE .read_loop: DEC DE LD A,D OR E JR Z,.SectorSizeError ; INI .wait_data_r: IN A,(FDC_93.DrvCTRL) AND %1100'0000 ;b6: DRQ (запрос данных = 1). b7: INTRQ (выполняется команда = 0). JR Z,.wait_data_r JP P,.read_loop ; JUMP if "выполняется команда = 0" .rw_return: ; .after_rw: EX AF,AF' OUT (SLOT3),A EX AF,AF' ; POP DE POP HL ;EI LD A,BIOS.Error.NotReady JR C,.CMD_ERROR ; IN A,(FDC_93.Command) LD C,A AND #7F ; NORMAL EXIT RET Z ; BIT 6,C LD A,BIOS.Error.WriteProtect JR NZ,.error_exit ; BIT 2,C JR NZ,.data_lost ; LD A,BIOS.Error.Seek .CMD_ERROR: DEC D JR Z,.error_exit ; PUSH DE PUSH HL CALL RESWG ; RESET_WG LD A,XL CALL SEEK ; !!!!! посмотреть POP HL POP DE JR .RETRY ; .data_lost: DEC D ; потеря данных JR NZ,.RETRY ; EXX BIT 5,B EXX LD A,BIOS.Error.Read ; Error Read JR Z,.error_exit ; LD A,BIOS.Error.Write ; Error Write ; .error_exit: EX AF,AF' LD A,#D0 ;!HARDCODE CMD КР1818ВГ93 OUT (FDC_93.Command),A ;STOP OPERATION EX AF,AF' BIT 0,C SCF RET Z LD A,BIOS.Error.SectorNotFound RET ; ;WRITE BYTE .write_loop: DEC DE LD A,D OR E JR Z,.SectorSizeError ; OUTI .wwait_data: IN A,(FDC_93.DrvCTRL) AND %1100'0000 ;b6: DRQ (запрос данных = 1). b7: INTRQ (выполняется команда = 0). JR Z,.wwait_data JP P,.write_loop JP .rw_return ; .SectorSizeError: EX AF,AF' OUT (SLOT3),A EX AF,AF' POP DE POP HL ;EI ; A = 0 LD C,A LD A,BIOS.Error.UnknownDevice JR .error_exit ; ; Врубает третью карту портов SET_DOS_ON: EX AF,AF' LD A,CNF_PORT.CNF_3 + ROM.BIOS OUT (SYS_PORT.ROM),A ; - OPEN EX AF,AF' RET ; Врубает нулевую карту портов SET_DOS_OFF: EX AF,AF' LD A,CNF_PORT.CNF_0 + ROM.BIOS OUT (SYS_PORT.ROM),A ; - CLOSE EX AF,AF' RET ; S_FDD: PUSH BC AND 1 LD B,A OR #3C OUT (FDC_93.DrvCTRL),A IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A LD A,(SYS_PAGE.FDD_TABLE.DISK) AND #FE OR B LD (SYS_PAGE.FDD_TABLE.DISK),A EX AF,AF' OUT (SLOT3),A POP BC RET ; ;----------------------------------------------------------------------; ; CHANGE_SPEED: IN A,(SLOT3) ; EX AF,AF' ; LD A,SYS_PAGE ; OUT (SLOT3),A ; LD A,(SYS_PAGE.FDD_TABLE.DISK) ; XOR #80 ; LD (SYS_PAGE.FDD_TABLE.DISK),A ; RLA ; EX AF,AF' ; OUT (SLOT3),A ; EX AF,AF' ; JR NC,FDD.SET720 ; FDD.SET1440: LD A,FDD_Density.SET_1440 ; OUT (FDD_Density),A ; RET ; ; ; ; ; SET_SPEED: IN A,(SLOT3) ; EX AF,AF' ; LD A,SYS_PAGE ; OUT (SLOT3),A ; LD A,(SYS_PAGE.FDD_TABLE.DISK) ; ;AND #80 ; RLA ; EX AF,AF' ; OUT (SLOT3),A ; EX AF,AF' ; JR C,FDD.SET1440 ; FDD.SET720: LD A,FDD_Density.SET_720 ; OUT (FDD_Density),A ; RET CHANGE_SPEED: IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A LD A,(SYS_PAGE.FDD_TABLE.DISK) XOR #80 LD (SYS_PAGE.FDD_TABLE.DISK),A JR SET_SPEED.set ; ; SET_SPEED: IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A LD A,(SYS_PAGE.FDD_TABLE.DISK) .set: AND #80 RRA RRA OR 1 OUT (FDD_Density),A EX AF,AF' OUT (SLOT3),A RET ;----------------------------------------------------------------------; //////////////////////////////////////////////////////////////////////// ; Вход: BC - внутренний и внешний счётчики WAIT_FDD_FOR_SEARCH_TRACK: LD A,#C0 ;!HARDCODE CMD КР1818ВГ93 OUT (FDC_93.Command),A PUSH BC CALL .LOOP POP BC RET NC CALL CHANGE_SPEED DEC C JR NZ,WAIT_FDD_FOR_SEARCH_TRACK SCF RET ; .LOOP: LD HL,#F000 .loop_reg_HL: IN A,(FDC_93.DrvCTRL) AND #C0 RET NZ ; .ID_LP4: DEC HL LD A,H OR L JR NZ,.loop_reg_HL ; DJNZ .LOOP SCF RET //////////////////////////////////////////////////////////////////////// ; прерывания должны быть отключены ; выход: A - FDD_INIT_TABLE.DISK, B - sector size high byte DISK_ID: EXX CALL SET_SPEED IN A,(FDC_93.Track) OUT (FDC_93.Data),A LD A,#18 ;!TODO выписать комманды ВГ ;SEARCH ;!HARDCODE CMD КР1818ВГ93 CALL EXECOM ; кусок для быстрых флоппарей LD BC,#0104 ; 1 - счётчик CALL WAIT_FDD_FOR_SEARCH_TRACK JR NC,.Read_Index ; кусок для тормозных флоппарей LD BC,#0504 ; 1 - счётчик CALL WAIT_FDD_FOR_SEARCH_TRACK JR NC,.Read_Index EXX ;SCF RET ; .Read_Index: ; ; Данные FDC_93.Data: ; номер цилиндра BYTE ; номер головки BYTE ; номер сектора BYTE ; длина сектора BYTE ; контрольная сумма WORD LD H,4 ; !HARDCODE счётчик до байта размера сектора .ID_LP2: IN A,(FDC_93.Data) DEC H JR NZ,.ID_LP3 LD L,A ; [ ] размера сектора (старший байт) .ID_LP3: IN A,(FDC_93.DrvCTRL) AND %1100'0000 JR Z,.ID_LP3 JP P,.ID_LP2 LD A,L EXX LD B,A ; [ ] размера сектора (старший байт) IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A LD A,(SYS_PAGE.FDD_TABLE.DISK) EX AF,AF' OUT (SLOT3),A EX AF,AF' AND #80 RET //////////////////////////////////////////////////////////////////////// ; SEEK: LD XL,A LD C,A IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A LD A,(SYS_PAGE.FDD_TABLE.DISK) AND 1 EX AF,AF' OUT (SLOT3),A EX AF,AF' SRL C JR C,.GT001 ; OR #3C .GT001: OR #2C OUT (FDC_93.DrvCTRL),A IN A,(FDC_93.Track) CP C CALL NZ,P50ms LD A,C OUT (FDC_93.Data),A IN A,(FDC_93.Track) CP C EX AF,AF' ;R.TRACK==PHISICAL TRACK LD A,#18 ;!HARDCODE CMD КР1818ВГ93 CALL EXECOM RET C EX AF,AF' LD A,C OUT (FDC_93.Track),A RET Z .STOL: CALL P50ms RET ; ;P750ms LD B,3 ;PMS2 LD A,255 ; CALL P1ms ; DJNZ PMS2 ; RET P50ms: PUSH BC LD A,12 .P1ms: LD C,255 .PMS: DEC C JR NZ,.PMS DEC A JR NZ,.P1ms POP BC RET ; ; RESWG: LD A,8 ;!HARDCODE CMD КР1818ВГ93 ; EXECOM: OUT (FDC_93.Command),A LD HL,#0000 ; счётчик .WREST: DEC HL LD A,H OR L SCF RET Z ; IN A,(FDC_93.DrvCTRL) AND #80 JR Z,.WREST RET ; ; ;------------------------------- ; HL:IX - SECTOR ; H - TRACK, L - SECTOR ;HL:IX/SECTOR_PER_TRACK NTRACK: PUSH HL EX (SP),IX POP HL IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A LD A,(SYS_PAGE.FDD_TABLE.SECTORS) LD C,A LD B,0 EX AF,AF' OUT (SLOT3),A XOR A .NTRK: INC A SBC HL,BC JR NC,.NTRK EX AF,AF' LD A,XL OR XH JR Z,.NTRK3 EX AF,AF' DEC IX JR .NTRK .NTRK3: EX AF,AF' ADD HL,BC DEC A LD H,A RET ; SAVE_INTERRUPTS: .switch_off: PUSH AF LD A,R DI LD A,#80 JP PE,.set_R XOR A .set_R: LD R,A POP AF RET ; ; .restore: PUSH AF LD A,R DI RLA JR NC,.set_di EI .set_di: POP AF ; PE RET ;[]===========================================================[]