; ; for INCLUDE ; 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,(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,(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 CALL RESET_WG POP AF POP HL LD B,1 LD DE,0 MSD_cmd5: LD A,0 LD (RD_WR_COM),A EX AF,AF' JR MSD_RWU1 MSD_cmd6: LD A,255 LD (RD_WR_COM),A EX AF,AF' JR MSD_RWU1 PREPARE1: LD (MED_START),A LD (CONT_BUF_ADR),HL DI IN A,(PAGE2) LD C,A LD A,SYS_PAGE OUT (PAGE2),A LD A,(DS_1440-4000H) AND BIT_MASK_1440 SET 0,A LD (DS_1440-4000H),A LD A,C OUT (PAGE2),A EI CALL Z,RES_1440 CALL NZ,SET_1440 CALL CALC_SECTOR LD (CONT_SEC),DE LD A,(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,(MED_START) INC B DEC B LD DE,(CONT_SEC) RET Z DEC B PUSH BC PUSH HL LD (CONT_BUF_ADR),HL LD A,(CONT_SEC) LD (SEC_NUM),A LD A,(CONT_TRK) CALL Global_trk LD A,(RD_WR_COM) OR A PUSH AF CALL Z,MSD_3F0E POP AF CALL NZ,MSD_3F0A DI IN A,(PAGE2) LD C,A LD A,SYS_PAGE OUT (PAGE2),A LD DE,(MS_BPB+SEC_SIZE-#4000) LD A,C OUT (PAGE2),A EI POP HL ADD HL,DE LD A,H OR L JR NZ,MSD_NO_PAGE DI IN A,(PAGE2) LD C,A LD A,SYS_PAGE OUT (PAGE2),A LD A,(MED_START) LD HL,RAMD_FAT-#4000 LD L,A LD L,(HL) LD A,C OUT (PAGE2),A EI LD A,L LD HL,#C000 LD (MED_START),A MSD_NO_PAGE: LD (CONT_BUF_ADR),HL PUSH HL DI IN A,(PAGE2) LD C,A LD A,SYS_PAGE OUT (PAGE2),A LD A,(DS_1440-#4000) AND %1111'1110 LD (DS_1440-#4000),A LD A,(MSD_SECS-#4000) LD L,A LD A,C OUT (PAGE2),A EI LD A,L LD HL,CONT_SEC INC (HL) CP (HL) JP NZ,MSD_R_W_LOOP LD (HL),0 LD HL,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 (COMAND_WG),A MSD_3F13: LD D,5 ; ЧИСЛО ПОВТОРЕНИЙ MSD_3F15: PUSH DE PUSH IX DI IN A,(PAGE3) EX AF,AF' LD A,(MED_START) OUT (PAGE3),A AND A JR Z,NO_OFF_SCR LD A,0C0H OUT (RGADR),A NO_OFF_SCR: LD IX,MSD_RET_ADR LD A,(SEC_NUM) INC A OUT (WG_SEC),A LD HL,(CONT_BUF_ADR) LD C,127 LD A,(COMAND_WG) OUT (WG_COM),A CP 160 JP Z,MSD_3FBA ; ЗАПИСЬ СЕКТОРА JP MSD_3FD5 ; ЧТЕНИЕ СЕКТОРА MSD_RET_ADR: LD A,0 OUT (RGADR),A EX AF,AF' OUT (PAGE3),A POP IX POP DE EI IN A,(WG_COM) 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 (WG_COM),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,(WG_TRK) CALL AUTO_1DA3 LD HL,AUTO_2A18 RST PRINT_LN IN A,(WG_SEC) 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 (DOS_ERR_2),A JP AUTO_01D3 MSD_3F94: LD A,(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,(CONT_TRK) CALL Global_trk ; ПОЗИЦИОНИРОВАНИЕ POP DE JP MSD_3F15 SWITCH_DT: DI IN A,(PAGE2) LD C,A LD A,SYS_PAGE OUT (PAGE2),A LD A,(DS_1440-4000H) BIT 0,A JR Z,NO_SW_DT XOR BIT_MASK_1440 LD (DS_1440-4000H),A AND BIT_MASK_1440 LD A,C OUT (PAGE2),A EI CALL Z,RES_1440 CALL NZ,SET_1440 RET NO_SW_DT: LD A,C OUT (PAGE2),A EI RET ;****************************************** ; Sector Write !!! ;****************************************** MSD_3FBA: LD B,4 MSD_3FBC: IN A,(P_DOS_FF) AND 192 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,(P_DOS_FF) AND 192 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,(P_DOS_FF) AND 192 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,(P_DOS_FF) AND 192 JR Z,MSD_3FE5 JP M,MSD_RET_IX2 MSD_3FEC: INI JR MSD_3FE5 ;****************************************** ;**************************************** RES_1440: LD A,01h OUT (0BDh),A RET SET_1440: LD A,21h OUT (0BDh),A RET READ_BPB: CALL DISK_REDIR CP #40 JR NC,.HDD_REDIR2 CP 4 JP NC,.ERROR_MSDOS CALL SET_DISK CALL .MAIN RET NC JP .ERROR_MSDOS .HDD_REDIR2: CALL .MAIN RET NC .SPACIAL: LD IX,0 LD DE,63 ;!HARDCODE LD A,SYS_PAGE LD HL,MS_BPB ; LD BC,256*1 + TRDOS_ROM_CMD.READ CALL MSD_R_W_UT ; CALL .PARAMS RET NC JP .ERROR_MSDOS .MAIN: LD A,SYS_PAGE LD HL,MS_BPB LD C,TRDOS_ROM_CMD.READ_BPB CALL MSD_R_W_UT ;CALL BPB_PARAMS ;RET ; LD C,18H ; LD A,(OPER_DISK) ; CALL HD_CMD ; ; ; DI ; IN A,(PAGE3) ; EX AF,AF' ; LD A,SYS_PAGE ; OUT (PAGE3),A ; ; ; LD A,(MS_BPB+S_P_T) ; Количество секторов на трек ; LD L,A ; ; ; EX AF,AF' ; OUT (PAGE3),A ; EI ; ; ; LD A,(OPER_DISK) ; LD C,19H ; CALL HD_CMD .PARAMS: DI IN A,(PAGE3) EX AF,AF' LD A,SYS_PAGE OUT (PAGE3),A LD A,(MS_BPB+FORM_CODE) CP #F0 JP C,.ERROR_BPB LD HL,MS_BPB+FAT_ID LD DE,.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,(HL) CP '6' LD HL,#81FF ; FAT16 флаг JR Z,.FAT CP '2' JP NZ,.ERROR_BPB .PC_DOS: LD HL,#01FF ; FAT12 флаг .FAT: LD (FAT_FLAG),HL LD A,(MS_BPB+S_P_T) ; Количество секторов на трек LD (MSD_SECS),A BIT 7,H LD IX,0 LD HL,0 ; вычислить начальный сектор FAT JR Z,.NO_LD_SPECIAL LD IX,(MS_BPB+SPECIAL_SECS) LD HL,(MS_BPB+SPECIAL_SECS+2) .NO_LD_SPECIAL: LD BC,0 LD DE,(MS_BPB+RESERV_SECS) ADD IX,DE ADC HL,BC LD (MSD_FAT_SEC),IX ; начальный сектор FAT LD (MSD_FAT_SEC2),HL ; начальный сектор FAT LD DE,(MS_BPB+S_P_F) ; число секторов в FAT LD BC,0 LD A,(MS_BPB+FATS_NUM) ; количество FATs .NEXT_ADD: ADD IX,DE ADC HL,BC DEC A JR NZ,.NEXT_ADD LD (MSD_CAT_SEC),IX ; начальный сектор DIR LD (MSD_CAT_SEC2),HL ; начальный сектор DIR LD BC,(MS_BPB+SEC_SIZE) ; Размер сектора RL C RL B RL C RL B RL C RL B LD C,B LD B,0 ; BC - число файловых записей в секторе LD A,C LD (F_P_S),A LD DE,(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 D,0 LD BC,0 LD (S_P_C),A ADD IX,DE ; Начало DATA area ADC HL,BC LD (MSD_DAT_SEC),IX LD (MSD_DAT_SEC2),HL LD BC,(MS_BPB+SEC_SIZE) ; Размер сектора LD HL,0 LD A,(MS_BPB+CLAST_SIZE) LD D,A LD A,0 .NEXT_ADD3: ADD HL,BC ; Вычисление длины кластера ADC A,0 DEC D JR NZ,.NEXT_ADD3 LD (CLASTER_LEN),HL LD B,0 LD C,A LD (CLASTER_LEN2),BC LD HL,0 LD BC,(MS_BPB+S_P_T) LD A,(MS_BPB+H_P_S) .BPB_L1:; ВЫЧИСЛИТЬ КОЛИЧЕСТВО СЕКТОРОВ НА ЦИЛИНДР ADD HL,BC DEC A JR NZ,.BPB_L1 LD (S_X_H),HL ; EX AF,AF' OUT (PAGE3),A EI AND A RET .ERROR_BPB: EX AF,AF' OUT (PAGE3),A SCF EI RET .ERROR_MSDOS: LD HL,MSG_3 JP AUTO_03E4 .FAT1_MSG: DB 'FAT1' ;******************************************** READ_NEXT_DIR: DI IN A,(PAGE3) EX AF,AF' LD A,SYS_PAGE OUT (PAGE3),A LD DE,(MSD_CONT_SEC) LD IX,(MSD_CONT_SEC2) JR READ_NEXT2 ;******************************************** READ_1ST_DIR: DI IN A,(PAGE3) EX AF,AF' LD A,SYS_PAGE OUT (PAGE3),A LD IX,(MSD_CAT_SEC2) ; LD DE,(MSD_CAT_SEC) ; НАЧАЛЬНЫЙ СЕКТОР КАТАЛОГА LD (MSD_CONT_SEC),DE LD (MSD_CONT_SEC2),IX LD A,(S_P_C) ; СЕКТОРОВ В КАТАЛОГЕ LD (COUNT_SEC),A READ_NEXT2: EX AF,AF' OUT (PAGE3),A ; RET_PAGE3 EI LD HL,MS_DIR LD A,SYS_PAGE LD BC,256*1 + TRDOS_ROM_CMD.READ CALL MSD_R_W_UT DI IN A,(PAGE3) EX AF,AF' LD A,SYS_PAGE OUT (PAGE3),A LD DE,(MSD_CONT_SEC) INC DE LD (MSD_CONT_SEC),DE LD A,D OR E JR NZ,READ_NEXT3 LD IX,(MSD_CONT_SEC2) INC IX LD (MSD_CONT_SEC2),IX READ_NEXT3: LD A,(F_P_S) ; ФАЙЛОВ В СЕКТОРЕ LD (COUNT_FL),A EX AF,AF' OUT (PAGE3),A ; RET_PAGE3 EI LD HL,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,(PAGE3) EX AF,AF' LD A,SYS_PAGE OUT (PAGE3),A LD BC,(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 (PAGE3),A EI EX DE,HL POP BC RET ;************************************************ REDIR_LINE_CODING: LD (MED_START),HL LD HL,(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 0FH ADD A,'0' CP '9'+1 JR C,NO_ADD ADD A,7 NO_ADD: RST 10H POP BC POP DE POP HL RET ;*******************************************