INIT_RMD: LD C,9FH CALL EXP_FNS EI RET ; DI ; LD C,PAGE3 ; IN B,(C) ; LD A,SYS_PAGE ; OUT (C),A ; LD A,(0C000H) ; CPL ; LD (0C000H),A ; OUT (C),B ; EI ; CALL INIT_SYS_PAGE ; JP AUTO_03E1 ;INIT_SYS_PAGE: ; LD C,97H ; CALL EXP_FNS ; EI ; RET RAMD_FAT_PROG: CALL AUTO_1D97 ; CLS CALL OPEN_CH2 LD HL,RAMD_FAT RAMD_F_L1: DI IN A,(PAGE3) LD C,A LD A,SYS_PAGE OUT (PAGE3),A LD A,C LD C,(HL) OUT (PAGE3),A ; RET_PAGE3 EI PUSH HL LD A,C CALL PRINT_HEX_A POP HL INC L JR NZ,RAMD_F_L1 CALL OPEN_CH0 JP AUTO_03E1 ;*************************************************************************** TB_ONOFF: DEC DE DEC DE LD A,(DE) CP 'F' JR Z,TB_OFF_EXE CP 'f' JR Z,TB_OFF_EXE TB_ON_EXE: LD C,8Fh LD A,4 JP EXP_FNS TB_OFF_EXE: LD C,8Fh LD A,3 JP EXP_FNS ; ;*************************************************************************** ; ; Алгоритм чтения файла ; ;*************************************************************************** ; Вход - данные файла в переменных TR-DOS - длина,стартовый кластер ; адрес загрузки, начальный блок загрузки ; предварительное значение max2 - длина блока, флаг блоковой ; загрузки ;*************************************************************************** MSDOS_WRITE_FILE: LD (CONT_BUF_ADR),HL ; адрес загрузки LD (MED_START),A ; страница загрузки LD A,6 JR MSDOS_R_W_FILE ; MSDOS_READ_FILE: LD (CONT_BUF_ADR),HL ; адрес загрузки LD (MED_START),A ; страница загрузки LD A,5 MSDOS_R_W_FILE: LD (MED_LEN),A ; beg=start_claster ; Получить начальный кластер LD IX,(START_CLASTER) ; стартовый кластер ; next=beg ; max=file_len ; длина в кластерах CALL GET_FILE_CLASTERS_BC ; LD A,B ; CALL PRINT_HEX_A ; LD A,C ; CALL PRINT_HEX_A msd_rf_cont2: ; max2=blk_len ; длина блока в кластерах ; DI ; GET_BLK_CLASTERS_L ; IN A,(PAGE3) ; EX AF,AF' ; LD A,SYS_PAGE ; OUT (PAGE3),A ; LD A,(C_P_B) ; LD L,A ; EX AF,AF' ; OUT (PAGE3),A ; EI LD L,128 msd_rf_cont1: ; num=0 PUSH IX POP DE LD A,0 ;--------------------------------- msd_rf_cont: ; num=num+1 INC A ; if num=max then goto msd_rf_last_blk ; Проверить число кластеров, CP C JR NZ,msd_rf_l1 DEC B INC B JR Z,msd_rf_last_blk msd_rf_l1: ; if num=max2 then goto msd_rf_blk ; Проверить число кластеров, CP L PUSH HL PUSH BC PUSH AF JR Z,msd_rf_blk ; sec=next ; читаемых за один раз ; next=FAT(sec) ; Вычислить следующий кластер CALL FAT_DE_to_HL ; if next = end then goto msd_rf_last_blk ; проверить конец JR C,msd_rf_last_blk2 EX DE,HL AND A INC HL ; if next-sec = 1 then goto msd_rf_cont ; Проверить next SBC HL,DE JR NZ,msd_rf_blk2 POP AF POP BC POP HL JR msd_rf_cont ;--------------------------------- msd_rf_blk: CALL FAT_DE_to_HL JR C,msd_rf_last_blk2 EX DE,HL msd_rf_blk2: ; beg=next ; EX DE,IX PUSH IX PUSH DE POP IX POP DE POP AF PUSH AF call READ_num_clasters_from_beg ; читать с кластера DE POP AF POP BC POP HL LD H,A ; max=max-num LD A,C SUB H LD C,A JR NC,msd_rf_l2 DEC B msd_rf_l2: ; max2=max2-num ; блок окончен ? LD A,L SUB H LD L,A ; if not max2=0 then goto msd_rf_cont1 ; если да,следующий блок JR NZ,msd_rf_cont1 ; max2=blk_len ; длина блока в кластерах для чтения JR msd_rf_cont2 ;------------------------------- msd_rf_last_blk2: POP AF POP BC POP HL msd_rf_last_blk: ; EX DE,IX push de push ix pop de pop ix call READ_num_clasters_from_beg RET ;========================================= READ_num_clasters_from_beg: PUSH IX PUSH DE CALL CLAST_TO_SEC PUSH AF LD A,(MED_LEN) LD C,A SUB 5 JR Z,CONT_XX1 DEC A JR NZ,SKEEP_XX1 CONT_XX1: POP AF ADD A,A INC A LOOP_128: PUSH AF PUSH DE PUSH IX PUSH BC LD HL,(CONT_BUF_ADR) LD A,(MED_START) CALL MSD_R_W_UT LD (CONT_BUF_ADR),HL LD (MED_START),A POP BC POP IX POP DE POP AF LD H,0 LD L,B AND A ADC HL,DE JR NC,NO_INC_IX INC IX NO_INC_IX: EX DE,HL LD B,128 DEC A JR NZ,LOOP_128 POP DE POP IX RET SKEEP_XX1: POP AF POP DE POP IX RET ;***************************************** MADE_next_blk: PUSH BC LD C,95h CALL EXP_FNS POP BC INC L ; SET ZF, if END BLK !!! LD HL,0C000H RET ;***************************************** CLAST_TO_SEC: PUSH AF EX DE,HL CALL CALC_CLAST DI IN A,(PAGE3) LD B,A LD A,SYS_PAGE OUT (PAGE3),A LD A,(MS_BPB+CLAST_SIZE) LD C,A LD A,B OUT (PAGE3),A EI POP AF PUSH HL LD L,A LD H,0 LD A,C CLAST_TO_SEC_L: RRA JR C,CLAST_TO_SEC_L2 ADD HL,HL JR CLAST_TO_SEC_L CLAST_TO_SEC_L2: LD B,L LD A,H POP HL RET FAT_DE_to_HL: ; LD H,D ; LD L,E ; INC HL ; AND A ; RET PUSH AF PUSH DE PUSH BC PUSH IX DI IN A,(PAGE3) LD C,A LD A,SYS_PAGE OUT (PAGE3),A LD A,C LD HL,(FAT_FLAG) LD BC,(MS_BPB+SEC_SIZE) ; размер сектора OUT (PAGE3),A EI PUSH HL LD A,H AND 80H LD C,A LD H,D LD L,E ADD HL,DE ADC A,C JR NC,FAT_12_L1 ADD HL,DE ADC A,C FAT_12_L1: ADD HL,DE ADC A,C RRA ; A,HL = FATx4..3/2 RR H RR L POP DE ; восстановить флаги FAT в DE PUSH AF ; запомнить флаг смещения ; HL - смещение от начала FAT ; A,HL - смещение в FAT PUSH HL LD C,0 PUSH BC FAT_DE_L1: RR B JR C,FAT_DE_L2 RRA RR H JR FAT_DE_L1 FAT_DE_L2: LD A,H ; A - сектор FAT BIT 0,D JR NZ,CALL_ALL CP E ; номер ранее считанного сектора FAT CALL_ALL: CALL NZ,READ_FAT_SEC ; читать FAT сектор номер A POP BC ; вспомнить размер сектора POP HL ; вспомнить адрес в FAT DEC BC LD A,H AND B LD H,A LD BC,MS_FAT ADD HL,BC DI IN A,(PAGE3) LD C,A LD A,SYS_PAGE OUT (PAGE3),A LD A,C LD (FAT_FLAG),DE LD C,(HL) ; считать кластер INC HL LD B,(HL) INC HL OUT (PAGE3),A ; RET_PAGE3 EI POP AF JR NC,FAT_HALF LD A,4 FAT_HALF_L: RR B RR C DEC A JR NZ,FAT_HALF_L FAT_HALF: BIT 7,D LD A,0FFH JR NZ,FAT_16_L2 LD A,0FH AND B LD B,A LD A,0FH FAT_16_L2: CP B JR NZ,NO_END_CLAST FAT_ALL: LD A,C CP 0F0H JR C,NO_END_CLAST LD L,C LD H,B POP IX POP BC POP DE POP AF SCF RET BLOCK #09FF-$, #FF BLOCK #0A01-$, #FF NO_END_CLAST: ; PUSH AF ; LD A,B ; CALL PRINT_HEX_A ; LD A,C ; CALL PRINT_HEX_A ; POP AF LD H,B LD L,C POP IX POP BC POP DE POP AF AND A RET ERROR_FAT: LD HL,MSG_3 ; ERROR JP AUTO_03E4 ;********************************************** READ_FAT_SEC: PUSH IX PUSH HL PUSH BC LD E,A RES 0,D PUSH DE LD D,0 DI IN A,(PAGE3) LD L,A LD A,SYS_PAGE OUT (PAGE3),A LD A,L LD IX,(MSD_FAT_SEC) LD HL,(MSD_FAT_SEC2) OUT (PAGE3),A EI LD BC,0 ADD IX,DE ADC HL,BC PUSH IX POP DE PUSH HL POP IX LD HL,(CONT_BUF_ADR) LD A,(MED_START) PUSH AF PUSH HL LD HL,MS_FAT LD A,SYS_PAGE LD B,2 LD C,5 CALL MSD_R_W_UT POP HL POP AF LD (CONT_BUF_ADR),HL LD (MED_START),A POP DE POP BC POP HL POP IX RET ;********************************************** ; ; Считывание FAT по три сектора ??? ; ;********************************************** GET_FILE_CLASTERS_BC: DI IN A,(PAGE3) LD L,A LD A,SYS_PAGE OUT (PAGE3),A LD A,L LD HL,(CLASTER_LEN) OUT (PAGE3),A ; RET_PAGE3 EI LD BC,(FL_SIZE) LD A,(FL_SIZE+2) LD DE,0 SCF GET_FL_CL_2: ; вычисление количества кластеров в файле RR H ; HL/2 RR L JR C,GET_FL_L2 ; если первый бит = 1 - выйти из цикла RRA ; file_len/2 RR B RR C JR NC,GET_FL_CL_2 LD E,1 JR GET_FL_CL_2 GET_FL_L2: BIT 0,E RET Z INC BC RET ;*************************************************************************** HDD_PROG: LD C,0 CALL HD_CMD JP C,HDD_PROG_E LD HL,HD_IDF_ADR+54 LD B,32 HDD_PROG_L: DI IN A,(PAGE3) LD D,A LD A,SYS_PAGE OUT (PAGE3),A LD A,L XOR 1 LD L,A LD C,(HL) LD A,L XOR 1 LD L,A INC HL LD A,D OUT (PAGE3),A ; RET_PAGE3 EI LD A,C PUSH BC RST 10H POP BC DJNZ HDD_PROG_L LD C,1 CALL HD_CMD JP NC,AUTO_03E1 HDD_ERROR: CALL PRINT_HEX_A LD HL,HD_TX JP AUTO_03E4 ; JP AUTO_03E1 HDD_PROG_E: LD HL,HD_TX2 JP AUTO_03E4 ; ;***************************************************************************