File_Start DEFL $ DISPLAY "====================================================" ;███████████████████████████████████████████████████████████████████████ ;******************************************** ; MS-DOS system ;******************************************** ; MS-DOS utilites ;******************************************** MSD_R_W_UT: PUSH AF CALL DISK_REDIR CP #40 JR C,.NOT_HDD ;************************************************ ;* Подпрограмма чтения/записи MS-DOS дисков * ;* 1. Адрес буфера - HL * ;* 2. Номер сектора - DE * ;* 3. Число секторов - B * ;* 4. Команда - C * ;* 5. Страница ОЗУ - A * ;************************************************ .HDD: POP AF ;!TEST 06/01/2024 убираем лишние телодвижения ;CALL HD_CMD SET 6,C CALL EXP_FNS ; RET NC JP HDD_ERROR ;************************************************ .NOT_HDD: POP AF EX AF,AF' LD A,C SUB 4 JR Z,MSD_cmd4 ; JR Z,MSD_cmd4M DEC A JR Z,MSD_cmd5 ; JR Z,MSD_cmd5M DEC A JR Z,MSD_cmd6 ; JR Z,MSD_cmd6M EX AF,AF' RET ;MSD_cmd4M: ; LD DE,0 ; LD IX,0 ; LD B,1 ;MSD_cmd5M: ; EX DE,HL ; PUSH IX ; EX (SP),HL ; POP IX ; LD C,12H ; LD A,(ZX_VARS.OPER_DISK) ; DI ; PUSH IY ; CALL HD_CMD ; POP IY ; EI ; PUSH IX ; EX (SP),HL ; POP IX ; EX DE,HL ; JP C,ERROR_MSDOS ; EX AF,AF' ; AND A ; RET ; ;MSD_cmd6M: ; EX DE,HL ; PUSH IX ; EX (SP),HL ; POP IX ; LD C,13H ; LD A,(ZX_VARS.OPER_DISK) ; DI ; PUSH IY ; CALL HD_CMD ; POP IY ; EI ; PUSH IX ; EX (SP),HL ; POP IX ; EX DE,HL ; JP C,ERROR_MSDOS ; EX AF,AF' ; AND A ; RET ;************************************* MSD_cmd4: PUSH HL ;PUSH AF ;!TEST 21/2/2024 CALL RESET_WG ;POP AF ;!TEST 21/2/2024 POP HL LD B,1 ;!TEST 21/2/2024 ; LD DE,0 XOR A LD D,A LD E,A MSD_cmd5: ; LD A,0 ; A=0 LD (ZX_VARS.RD_WR_COM),A EX AF,AF' JR MSD_RWU1 MSD_cmd6: LD A,255 LD (ZX_VARS.RD_WR_COM),A EX AF,AF' JR MSD_RWU1 PREPARE1: LD (ZX_VARS.MED_START),A LD (ZX_VARS.CONT_BUF_ADR),HL DI IN A,(SLOT2) LD C,A LD A,SYS_PAGE OUT (SLOT2),A LD A,(SYS_PAGE.DS_1440-4000H) AND BIT_MASK_1440 SET 0,A LD (SYS_PAGE.DS_1440-4000H),A LD A,C OUT (SLOT2),A EI CALL Z,RES_1440 CALL NZ,SET_1440 CALL CALC_SECTOR LD (ZX_VARS.CONT_SEC),DE LD A,(ZX_VARS.RD_WR_COM) RET MSD_RWU1: PUSH BC PUSH HL CALL PREPARE1 ; JR MSD_R_W_LOOP MSD_R_W_LOOP: POP HL POP BC LD A,(ZX_VARS.MED_START) INC B DEC B LD DE,(ZX_VARS.CONT_SEC) RET Z DEC B PUSH BC PUSH HL LD (ZX_VARS.CONT_BUF_ADR),HL LD A,(ZX_VARS.CONT_SEC) LD (ZX_VARS.SEC_NUM),A LD A,(ZX_VARS.CONT_TRK) CALL Global_trk LD A,(ZX_VARS.RD_WR_COM) OR A PUSH AF CALL Z,MSD_3F0E POP AF CALL NZ,MSD_3F0A DI IN A,(SLOT2) LD C,A LD A,SYS_PAGE OUT (SLOT2),A LD DE,(SYS_PAGE.MS_BPB+SEC_SIZE-#4000) LD A,C OUT (SLOT2),A EI POP HL ADD HL,DE LD A,H OR L JR NZ,MSD_NO_PAGE DI IN A,(SLOT2) LD C,A LD A,SYS_PAGE OUT (SLOT2),A LD A,(ZX_VARS.MED_START) LD HL,SYS_PAGE.RAM_TABLE-#4000 LD L,A LD L,(HL) LD A,C OUT (SLOT2),A EI LD A,L LD HL,#C000 LD (ZX_VARS.MED_START),A MSD_NO_PAGE: LD (ZX_VARS.CONT_BUF_ADR),HL PUSH HL DI IN A,(SLOT2) LD C,A LD A,SYS_PAGE OUT (SLOT2),A LD A,(SYS_PAGE.DS_1440-#4000) AND %1111'1110 LD (SYS_PAGE.DS_1440-#4000),A LD A,(SYS_PAGE.MSD_SECS-#4000) LD L,A LD A,C OUT (SLOT2),A EI LD A,L LD HL,ZX_VARS.CONT_SEC INC (HL) CP (HL) JP NZ,MSD_R_W_LOOP LD (HL),0 LD HL,ZX_VARS.CONT_TRK INC (HL) JP MSD_R_W_LOOP ;***************************************** ; ;***************************************** MSD_3F0A: LD A,160 JR MSD_3F10 MSD_3F0E: LD A,128 MSD_3F10: LD (ZX_VARS.COMAND_WG),A MSD_3F13: LD D,5 ; ЧИСЛО ПОВТОРЕНИЙ MSD_3F15: PUSH DE PUSH IX DI IN A,(SLOT3) EX AF,AF' LD A,(ZX_VARS.MED_START) OUT (SLOT3),A AND A JR Z,NO_OFF_SCR LD A,#C0 OUT (RGADR),A NO_OFF_SCR: LD IX,MSD_RET_ADR LD A,(ZX_VARS.SEC_NUM) INC A OUT (FDC_93.Sector),A LD HL,(ZX_VARS.CONT_BUF_ADR) LD C,127 LD A,(ZX_VARS.COMAND_WG) OUT (FDC_93.Command),A CP 160 JP Z,MSD_3FBA ; ЗАПИСЬ СЕКТОРА JP MSD_3FD5 ; ЧТЕНИЕ СЕКТОРА MSD_RET_ADR: LD A,0 OUT (RGADR),A EX AF,AF' OUT (SLOT3),A POP IX POP DE EI IN A,(FDC_93.Command) LD B,A AND 127 RET Z ;MSD_3F39: LD HL,READ_ONLY_MSG AND '@' JR NZ,MSD_3F4B LD A,B AND 4 JR Z,MSD_3FA0 ; -> ДРУГАЯ ОШИБКА DEC D ; ПОТЕРЯ ДАННЫХ JR Z,MSD_3F48 ; MSD_3F15 CALL SWITCH_DT JR MSD_3F15 MSD_3F48: LD HL,DISK_ERROR_MSG MSD_3F4B: LD A,208 OUT (FDC_93.Command),A LD A,B AND 1 JP NZ,AUTO_3EE7 PUSH HL CALL AUTO_1D97 POP HL RST PRINT_LN LD HL,AUTO_2A13 RST PRINT_LN IN A,(FDC_93.Track) CALL AUTO_1DA3 LD HL,AUTO_2A18 RST PRINT_LN IN A,(FDC_93.Sector) CALL AUTO_1DA3 LD HL,AUTO_29FE RST PRINT_LN MSD_3F7B: CALL AUTO_1052 CP 'I' RET Z CP 'R' JR Z,MSD_3F94 CP 'A' JR NZ,MSD_3F7B CALL exit_No_disk LD A,7 LD (ZX_VARS.DOS_ERR_2),A JP AUTO_01D3 MSD_3F94: LD A,(ZX_VARS.CONT_TRK) CALL Global_trk CALL pause_750ms JP MSD_3F13 MSD_3FA0: DEC D JP Z,MSD_3F48 CALL SWITCH_DT PUSH DE CALL AUTO_3D98 ; RESET_WG LD A,(ZX_VARS.CONT_TRK) CALL Global_trk ; ПОЗИЦИОНИРОВАНИЕ POP DE JP MSD_3F15 SWITCH_DT: DI IN A,(SLOT2) LD C,A LD A,SYS_PAGE OUT (SLOT2),A LD A,(SYS_PAGE.DS_1440-4000H) BIT 0,A JR Z,NO_SW_DT XOR BIT_MASK_1440 LD (SYS_PAGE.DS_1440-4000H),A AND BIT_MASK_1440 LD A,C OUT (SLOT2),A EI ;!TEST ;CALL Z,RES_1440 ;CALL NZ,SET_1440 ;RET JR Z,RES_1440 JR SET_1440 ; NO_SW_DT: LD A,C OUT (SLOT2),A EI RET ;****************************************** ; Sector Write !!! ;****************************************** MSD_3FBA: LD B,4 MSD_3FBC: IN A,(FDC_93.DrvCTRL) AND #C0 JR NZ,MSD_3FD1 INC DE LD A,E OR D JR NZ,MSD_3FBC DJNZ MSD_3FBC MSD_RET_IX: JP (IX) MSD_3FCA: IN A,(FDC_93.DrvCTRL) AND #C0 JR Z,MSD_3FCA JP M,MSD_RET_IX MSD_3FD1: OUTI JR MSD_3FCA ;****************************************** ; Sector Read !!! ;****************************************** MSD_3FD5: LD B,4 MSD_3FD7: IN A,(FDC_93.DrvCTRL) AND #C0 JR NZ,MSD_3FEC INC DE LD A,E OR D JR NZ,MSD_3FD7 DJNZ MSD_3FD7 MSD_RET_IX2: JP (IX) MSD_3FE5: IN A,(FDC_93.DrvCTRL) AND #C0 JR Z,MSD_3FE5 JP M,MSD_RET_IX2 MSD_3FEC: INI JR MSD_3FE5 ;****************************************** ;**************************************** RES_1440: LD A,FDD_Density.SET_720 OUT (FDD_Density),A RET SET_1440: LD A,FDD_Density.SET_1440 OUT (FDD_Density),A RET READ_BPB: CALL DISK_REDIR ; LD C,BIOS.GET_DISK_REDIR ; CALL EXP_FNS CP #40 JR NC,.HDD CP 4 JP NC,ERROR_MSG ; CALL SET_DISK ; CALL .MAIN RET NC JP ERROR_MSG ; .HDD: CALL .MAIN RET NC ; old hdd LD IX,0 LD DE,63 ;!HARDCODE LD A,SYS_PAGE LD HL,SYS_PAGE.MS_BPB ; LD BC,256*1 + TRDOS_ROM_CMD.READ CALL MSD_R_W_UT ; CALL .PARAMS RET NC JP ERROR_MSG ; .MAIN: LD A,SYS_PAGE LD HL,SYS_PAGE.MS_BPB LD C,TRDOS_ROM_CMD.READ_BPB CALL MSD_R_W_UT ;CALL BPB_PARAMS ;RET ; ; LD C,18H ; LD A,(ZX_VARS.OPER_DISK) ; CALL HD_CMD ; ; ; DI ; IN A,(SLOT3) ; EX AF,AF' ; LD A,SYS_PAGE ; OUT (SLOT3),A ; ; ; LD A,(SYS_PAGE.MS_BPB+S_P_T) ; Количество секторов на трек ; LD L,A ; ; ; EX AF,AF' ; OUT (SLOT3),A ; EI ; ; ; LD A,(ZX_VARS.OPER_DISK) ; LD C,19H ; CALL HD_CMD .PARAMS: DI IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A LD A,(SYS_PAGE.MS_BPB+FORM_CODE) CP #F0 JP C,.ERROR_BPB LD DE,SYS_PAGE.MS_BPB+FAT_ID LD HL,.FAT1_MSG LD B,4 .L1: LD A,(DE) CP ' ' JR NZ,.L11 INC DE JR .L1 .L11: CP (HL) JR NZ,.PC_DOS INC HL INC DE DJNZ .L1 LD A,(DE) CP '6' LD HL,#81FF ; FAT16 флаг JR Z,.FAT CP '2' JP NZ,.ERROR_BPB .PC_DOS: LD HL,#01FF ; FAT12 флаг .FAT: LD (SYS_PAGE.FAT_FLAG),HL LD A,(SYS_PAGE.MS_BPB+S_P_T) ; Количество секторов на трек LD (SYS_PAGE.MSD_SECS),A ; BIT 7,H ; LD IX,0 ; LD HL,0 ; вычислить начальный сектор FAT ; JR Z,.NO_LD_SPECIAL LD IX,(SYS_PAGE.MS_BPB+SPECIAL_SECS) LD HL,(SYS_PAGE.MS_BPB+SPECIAL_SECS+2) ;.NO_LD_SPECIAL: LD BC,0 LD DE,(SYS_PAGE.MS_BPB+RESERV_SECS) ADD IX,DE ADC HL,BC LD (SYS_PAGE.MSD_FAT_SEC),IX ; начальный сектор FAT LD (SYS_PAGE.MSD_FAT_SEC2),HL ; начальный сектор FAT LD DE,(SYS_PAGE.MS_BPB+S_P_F) ; число секторов в FAT ;LD BC,0 LD A,(SYS_PAGE.MS_BPB+FATS_NUM) ; количество FATs .NEXT_ADD: ADD IX,DE ADC HL,BC DEC A JR NZ,.NEXT_ADD LD (SYS_PAGE.MSD_CAT_SEC),IX ; начальный сектор DIR LD (SYS_PAGE.MSD_CAT_SEC2),HL ; начальный сектор DIR LD BC,(SYS_PAGE.MS_BPB+SEC_SIZE) ; Размер сектора LD A,B RL C RLA RL C RLA RL C RLA LD C,A LD B,0 ; BC - число файловых записей в секторе LD (SYS_PAGE.FilesPerSector),A LD DE,(SYS_PAGE.MS_BPB+FLS_NUM) ; Число файловых записей EX DE,HL DEC HL XOR A .NEXT_ADD2: INC A JR Z,.ERROR_BPB SBC HL,BC JR NC,.NEXT_ADD2 EX DE,HL LD E,A ; A - число секторов в DIR LD BC,0 LD D,B LD (SYS_PAGE.SectorsPerCluster),A ADD IX,DE ; Начало DATA area ADC HL,BC LD (SYS_PAGE.MSD_DAT_SEC),IX LD (SYS_PAGE.MSD_DAT_SEC2),HL LD BC,(SYS_PAGE.MS_BPB+SEC_SIZE) ; Размер сектора ; D = 0 LD H,D LD L,D LD E,D LD A,(SYS_PAGE.MS_BPB+CLAST_SIZE) LD D,A XOR A .NEXT_ADD3: ADD HL,BC ; Вычисление длины кластера ADC A,E DEC D JR NZ,.NEXT_ADD3 LD (SYS_PAGE.CLUSTER_LEN),HL LD B,E LD C,A LD (SYS_PAGE.CLUSTER_LEN2),BC ; ; DE=0 EX DE,HL ;LD HL,0 LD BC,(SYS_PAGE.MS_BPB+S_P_T) LD A,(SYS_PAGE.MS_BPB+H_P_S) .BPB_L1:; ВЫЧИСЛИТЬ КОЛИЧЕСТВО СЕКТОРОВ НА ЦИЛИНДР ADD HL,BC DEC A JR NZ,.BPB_L1 LD (SYS_PAGE.S_X_H),HL ; EX AF,AF' OUT (SLOT3),A CALL RESTORE_CURRENT_DIR ; [x] new tr-hdd AND A EI RET .ERROR_BPB: EX AF,AF' OUT (SLOT3),A SCF EI RET ; ; .ERROR_MSDOS: ; LD HL,MSG_3 ; JP AUTO_03E4 ; .FAT1_MSG: DB 'FAT1' ;******************************************** READ_NEXT_DIR: DI IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A LD DE,(SYS_PAGE.MSD_CONT_SEC) LD IX,(SYS_PAGE.MSD_CONT_SEC2) JR READ_NEXT2 ;******************************************** READ_1ST_DIR: DI IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A LD IX,(SYS_PAGE.MSD_CAT_SEC2) LD DE,(SYS_PAGE.MSD_CAT_SEC) ; НАЧАЛЬНЫЙ СЕКТОР КАТАЛОГА LD (SYS_PAGE.MSD_CONT_SEC),DE LD (SYS_PAGE.MSD_CONT_SEC2),IX LD A,(SYS_PAGE.SectorsPerCluster) ; СЕКТОРОВ В КАТАЛОГЕ LD (SYS_PAGE.COUNT_SEC),A READ_NEXT2: EX AF,AF' OUT (SLOT3),A ; RET_PAGE3 EI LD HL,SYS_PAGE.MS_DIR LD A,SYS_PAGE LD BC,256*1 + TRDOS_ROM_CMD.READ CALL MSD_R_W_UT DI IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A LD DE,(SYS_PAGE.MSD_CONT_SEC) INC DE LD (SYS_PAGE.MSD_CONT_SEC),DE LD A,D OR E JR NZ,READ_NEXT3 LD IX,(SYS_PAGE.MSD_CONT_SEC2) INC IX LD (SYS_PAGE.MSD_CONT_SEC2),IX READ_NEXT3: LD A,(SYS_PAGE.FilesPerSector) ; ФАЙЛОВ В СЕКТОРЕ LD (SYS_PAGE.COUNT_FL),A EX AF,AF' OUT (SLOT3),A ; RET_PAGE3 EI LD HL,SYS_PAGE.MS_DIR AND A RET ;****************************************** ;******************************************** CALC_SECTOR: ; ВЫЧИСЛИТЬ ТРЕК/СЕКТОР для дискет LD A,D ; DE - абс. номер сектора OR E JR NZ,CALC_SECT_L1 LD HL,0 RET CALC_SECT_L1: PUSH BC EX DE,HL DI IN A,(SLOT3) EX AF,AF' LD A,SYS_PAGE OUT (SLOT3),A LD BC,(SYS_PAGE.MS_BPB+S_P_T) XOR A LOOP_TRK: SBC HL,BC JR C,SEC_ENDER INC A JR NZ,LOOP_TRK POP BC JP READ_BPB.ERROR_BPB SEC_ENDER: ADD HL,BC LD H,A ; ТРЕК ; LD L,L ; СЕКТОР EX AF,AF' OUT (SLOT3),A EI EX DE,HL POP BC RET ;************************************************ REDIR_LINE_CODING: LD (ZX_VARS.MED_START),HL LD HL,(ZX_VARS.DOS_CH_ADR) LD A,(HL) CP '/' RET Z JP AUTO_3057 PRINT_HEX_A: PUSH AF RRCA RRCA RRCA RRCA CALL PRINT_HEX_SYM POP AF PRINT_HEX_SYM: PUSH HL PUSH DE PUSH BC AND #0F ADD A,'0' CP '9'+1 JR C,NO_ADD ADD A,7 NO_ADD: RST #10 POP BC POP DE POP HL RET ;******************************************* ;███████████████████████████████████████████████████████████████████████ DISPLAY "TR_MSD_S.ASZ size: ",/A,$-File_Start DISPLAY "===================================================="