INIT_RMD: LD C,BIOS.FullInit ;!TEST 06/01/2024 сохраняем состояние прерываний зачем-то JP EXP_FNS ;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,SYS_PAGE.RAMD_FAT RAMD_F_L1: DI IN A,(SLOT3) LD C,A LD A,SYS_PAGE OUT (SLOT3),A LD A,C LD C,(HL) OUT (SLOT3),A 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 ;*************************************************************************** ;[x] исправлен баг с неработающими командами TBON/TBOFF TB_ONOFF: DEC DE DEC DE LD A,(DE) OR %0010'0000 CP 'f' LD C,BIOS.FN_TURBO LD A,BIOS.FN_TURBO.OFF JR Z,.set ; LD A,BIOS.FN_TURBO.ON .set: JP EXP_FNS ; TB_ON_EXE: ; LD C,BIOS.FN_TURBO ; LD A,4 ; JP EXP_FNS ; TB_OFF_EXE: ; LD C,BIOS.FN_TURBO ; LD A,3 ; JP EXP_FNS ; ;*************************************************************************** ; ; Алгоритм чтения файла ; ;*************************************************************************** ; Вход - данные файла в переменных TR-DOS - длина,стартовый кластер ; адрес загрузки, начальный блок загрузки ; предварительное значение max2 - длина блока, флаг блоковой ; загрузки ;*************************************************************************** MSDOS_WRITE_FILE: LD (ZX_VARS.CONT_BUF_ADR),HL ; адрес загрузки LD (ZX_VARS.MED_START),A ; страница загрузки LD A,TRDOS_ROM_CMD.WRITE JR MSDOS_R_W_FILE ; MSDOS_READ_FILE: LD (ZX_VARS.CONT_BUF_ADR),HL ; адрес загрузки LD (ZX_VARS.MED_START),A ; страница загрузки LD A,TRDOS_ROM_CMD.READ MSDOS_R_W_FILE: LD (ZX_VARS.MED_LEN),A ; beg=start_claster. Получить начальный кластер LD IX,(ZX_VARS.START_CLUSTER) ; стартовый кластер ; 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,(SLOT3) ; EX AF,AF' ; LD A,SYS_PAGE ; OUT (SLOT3),A ; LD A,(C_P_B) ; LD L,A ; EX AF,AF' ; OUT (SLOT3),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,(ZX_VARS.MED_LEN) LD C,A SUB TRDOS_ROM_CMD.READ JR Z,CONT_XX1 DEC A JR NZ,SKEEP_XX1 ;TRDOS_ROM_CMD.WRITE CONT_XX1: POP AF ADD A,A INC A LOOP_128: PUSH AF PUSH DE PUSH IX PUSH BC LD HL,(ZX_VARS.CONT_BUF_ADR) LD A,(ZX_VARS.MED_START) CALL MSD_R_W_UT LD (ZX_VARS.CONT_BUF_ADR),HL LD (ZX_VARS.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,#95 ;!HARDCODE BIOS.GetMemPageNext (#C7) CALL EXP_FNS POP BC INC L ; SET ZF, if END BLK !!! LD HL,#C000 RET ;***************************************** CLAST_TO_SEC: PUSH AF EX DE,HL CALL CALC_CLAST DI IN A,(SLOT3) LD B,A LD A,SYS_PAGE OUT (SLOT3),A LD A,(SYS_PAGE.MS_BPB+CLAST_SIZE) LD C,A LD A,B OUT (SLOT3),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,(SLOT3) LD C,A LD A,SYS_PAGE OUT (SLOT3),A LD A,C LD HL,(SYS_PAGE.FAT_FLAG) LD BC,(SYS_PAGE.MS_BPB+SEC_SIZE) ; размер сектора OUT (SLOT3),A EI PUSH HL LD A,H AND #80 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,SYS_PAGE.MS_FAT ADD HL,BC DI IN A,(SLOT3) LD C,A LD A,SYS_PAGE OUT (SLOT3),A LD A,C LD (SYS_PAGE.FAT_FLAG),DE LD C,(HL) ; считать кластер INC HL LD B,(HL) INC HL OUT (SLOT3),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,#FF JR NZ,FAT_16_L2 LD A,#0F AND B LD B,A LD A,#0F FAT_16_L2: CP B JR NZ,NO_END_CLAST FAT_ALL: LD A,C CP #F0 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,(SLOT3) LD L,A LD A,SYS_PAGE OUT (SLOT3),A LD A,L LD IX,(SYS_PAGE.MSD_FAT_SEC) LD HL,(SYS_PAGE.MSD_FAT_SEC2) OUT (SLOT3),A EI LD BC,0 ADD IX,DE ADC HL,BC PUSH IX POP DE PUSH HL POP IX LD HL,(ZX_VARS.CONT_BUF_ADR) LD A,(ZX_VARS.MED_START) PUSH AF PUSH HL LD HL,SYS_PAGE.MS_FAT LD A,SYS_PAGE LD BC,256*2 + TRDOS_ROM_CMD.READ CALL MSD_R_W_UT POP HL POP AF LD (ZX_VARS.CONT_BUF_ADR),HL LD (ZX_VARS.MED_START),A POP DE POP BC POP HL POP IX RET ;********************************************** ; ; Считывание FAT по три сектора ??? ; ;********************************************** GET_FILE_CLASTERS_BC: DI IN A,(SLOT3) LD L,A LD A,SYS_PAGE OUT (SLOT3),A LD A,L LD HL,(SYS_PAGE.CLASTER_LEN) OUT (SLOT3),A ; RET_PAGE3 EI LD BC,(ZX_VARS.FL_SIZE) LD A,(ZX_VARS.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: ;!TEST 06/01/2024 убираем лишние телодвижения ;LD C,BIOS.HDD_INIT and #BF ;CALL HD_CMD LD C,BIOS.HDD_INIT CALL EXP_FNS ; JP C,HDD_PROG_E LD HL,SYS_PAGE.HD_IDF_ADR+54 LD B,32 HDD_PROG_L: DI IN A,(SLOT3) LD D,A LD A,SYS_PAGE OUT (SLOT3),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 (SLOT3),A ; RET_PAGE3 EI LD A,C PUSH BC RST 10H POP BC DJNZ HDD_PROG_L ;!TEST 06/01/2024 убираем лишние телодвижения ;LD C,BIOS.HDD_RECAL and #BF ;CALL HD_CMD LD C,BIOS.HDD_RECAL CALL EXP_FNS ; 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 ; ;***************************************************************************