;[BEGIN] ;//MODULE: DOS_X ;//CREATE: 19-05-1998 AUTHOR: Denis Parinov ;//UPDATE: 24-10-1999 DNS Restore module ;--------------------------------------------------------------- ;Rev Date Name Description ;--------------------------------------------------------------- ;R13 06-04-2023 BAO Функцию SETBOOT можно вызвать только раз (если завершится корректно) ;R12 03-04-2023 BAO Добавлена функция рескана драйвов LD C,8 : RST #10 ;R11 15-04-2003 DNS ROUTINE FOR STORE CURDISK AND CURDIR ;!FIXIT работает криво ;R10 03-04-2003 DNS IMPROVED FN. VERSION ;R09 27-03-2003 DNS PASTED SET/GET BOOT FN. ;R08 14-11-2002 DNS IMPROVE BPB-FUNCTION ;R07 17-12-1999 DNS BUG FIX SIGNATURE #55AA AT 510 OFFSET ;R06 21-11-1999 DNS FN. DISKINF SUPPORT ALL DISKS ;R05 21-11-1999 DNS BUG FIX SIGNATURE #55AA IN BOOT SECTOR ;R04 08-11-1999 DNS KILL OLD FUNCTIONS ;R03 23-11-1998 DNS BUG FIX (IX+28) -> (IY+28) ;R02 21-11-1998 DNS CHANGE FUNCTION "MAKE FAT" ;R01 20-11-1998 DNS REPAIR FUNCTION "SAVE" ;--------------------------------------------------------------- ; RGADR EQU #89 ;VIDEO CONTROL REGISTER ; SLOT0 EQU #82 ;WIN #0000-#3FFF ; SLOT1 EQU #A2 ;WIN #4000-#7FFF ; SLOT2 EQU #C2 ;WIN #8000-#BFFF ; SLOT3 EQU #E2 ;WIN #C000-#FFFF ; SYSPAGE EQU #FE ;Commands for restart #10 //NOPS: LD A,DSS_Error.sys.INVALID_FUNCTION // SCF // RET ;///////////////////////////////////////////////////////////////////// ; Функция #00. Версия ДОС. ; Возвращает номер версии дисковой системы. ; вход: нет ; выход: DE = номер версии/модификации ; BC = номер билда (0..999) ;///////////////////////////////////////////////////////////////////// VERSION: ;XOR A ;LD H,A ;!TODO пихать сюда OSINFO ;LD L,A LD HL,0 LD DE,VERS*256+MODF LD BC,BUILD RET //;R10 //OSINFO: //OSINFO_SIG: DB "OSINFOSTRUCTURE",0 //BOOTDRV: DB 0 ;///////////////////////////////////////////////////////////////////// ; Функция #09. Номер системного диска. ; Возвращает номер диска, c которого загружена система. ; ; вход: B = 0 (01h - исп. boot-загрузчик системы) ; выход: A - номер системного диска (0=A,1=B,..) ;///////////////////////////////////////////////////////////////////// BOOTDSK: INC B DEC B JR Z,GETBOOT DEC B .chg: JR Z,SETBOOT ;R13 меняется на JR С,SETBOOT после первого удачного исполнения SETBOOT LD A,DSS_Error.sys.INVALID_FUNCTION SCF RET ;GET BOOT DISK GETBOOT: BOOTDRV+1: LD A,0 ;R09 AND A RET ;SET BOOT DISK ; Сообщить DSS с какого диска загружается система. ; Исп. загрузчик системы для иниц. ячейки "boot_disk". SETBOOT: LD B,A LD C,0 .loop: PUSH BC LD A,C LD DE,#55AA LD BC,256*0 + Dss.DRV.GenIOCTL RST ToDSS.DRV POP BC JR C,.NoSupport EX AF,AF' ;PHISICAL DRIVE NUMBER CP B JR NZ,.NoSupport ;R13 LD A,#38 ; opcode for JR C,addr LD (BOOTDSK.chg),A ;R13 LD A,C LD (BOOTDRV),A AND A RET .NoSupport: INC C LD A,(LDRIVE) CP C JR NZ,.loop SCF RET ;R09 ;!!!!! Дубль - CHNDISK = OPENDSK /* CHNDISK: PUSH AF LD C,Dss.DRV.Open RST ToDSS.DRV POP BC JP C,NDISK11 LD A,B LD (FatBuffer.DRIVE),A CALL RD_BPB RET C LD A,(LDRIVE) AND A RET NDISK11: CP DSS_Error.sys.INVALID_DRIVE SCF RET Z LD A,DSS_Error.sys.NOT_READY RET */ ;///////////////////////////////////////////////////////////////////// ; Функция #02. Номер текущего диска. ; ; вход: нет ; выход: A - номер диска (0=A,1=B,..) ;///////////////////////////////////////////////////////////////////// CURRDSK: LD A,(FatBuffer.DRIVE) AND A RET ;///////////////////////////////////////////////////////////////////// ; Функция #03. Информация о диске. ; Возвращает информацию об общем и свободном пространстве дискового ; устройства. ; ; вход: A - номер диска (0=A,1=B,..#FF-текущий) ; выход: A - размер кластера в секторах, если CF=0 ; HL - общее кол-во кластеров ; DE - свободных кластеров ; BC - размер сектора в байтах ; A - код ошибки, если CF=1 ;///////////////////////////////////////////////////////////////////// DISKINF: CP #FF JR Z,CURRDS ;R06 CALL CHNDISK ;R06 RET C ;R06 CURRDS: LD HL,2 LD BC,0 FRESP: PUSH BC CALL R_F_FAT POP BC CP DSS_Error.sys.DISK_FULL JR Z,FRESP2 LD A,E OR D JR NZ,SKIC INC BC SKIC: INC HL JP FRESP FRESP2: LD D,B LD E,C LD HL,(MAX_CLU) DEC HL LD BC,(BootSector.B_P_S) LD A,(BootSector.S_P_C) AND A RET ; Номер последнего диска в системе LDRIVE: DB DSS_MAX_DRIVES_AMOUNT IF COMPILE_UNUSED_CODE TDRIVE: DB #00 TCLUST: DW #0000 TCOUNT: DW #0000 ENDIF ;R04SIZE2CL LD DE,(B_P_C) ;R04 XOR A ;R04 SCF ;R04S2C01 RR D ;R04 RR E ;R04 JR C,S2C02 ;R04 RR H ;R04 RR L ;R04 RR B ;R04 RR C ;R04 JP NC,S2C01 ;R04 LD A,1 ;R04 JP S2C01 ;R04S2C02 OR A ;R04 RET Z ;R04 INC BC ;R04 RET ;R04L_SEC_X DW 0 ;R04H_SEC_X DW 0 ; !FIXIT чёт не используется IF COMPILE_UNUSED_CODE TESTDSK: LD A,(FatBuffer.DRIVE) LD C,Dss.DRV.MediaCheck RST ToDSS.DRV OR A RET Z ENDIF RD_BPB: LD C,SLOT3 IN B,(C) PUSH BC IN A,(SLOT0) OUT (SLOT3),A ;R08 ;LD DE,BOOT+#C000 LD DE,SECBUF+#C000 ;R08 LD A,(FatBuffer.DRIVE) ;вызов RD_BPB может в дальнейшем понадобиться, пускай она сама достаёт переменную DRIVE LD C,Dss.DRV.GetBPB RST ToDSS.DRV POP BC OUT (C),B JP C,DOS_X_Error.Not_ready //PUSH IY ; пока без индексного, но может пригодиться LD DE,#AA55 ; сигнатура ;R05 LD HL,(SECBUF+510) ;R08 ;R07 ;R05 AND A SBC HL,DE JP NZ,DOS_X_Error.UnknownBPB ;R08 LD HL,SECBUF LD DE,BootSector LD BC,_sBOOT_SEC ; size LDIR ; //LD IY,BootSector ; пока без индексного, но может пригодиться //LD A,(IY+_sBOOT_SEC.ID_FORM) LD A,(BootSector.ID_FORM) CP #F0 JP C,DOS_X_Error.UnknownBPB ;!TEST ;LD HL,0 ; calc. first sector FAT ;LD E,(IY+_sBOOT_SEC.RESERVE) ;Reserve sec ;LD D,(IY+_sBOOT_SEC.RESERVE+1) ;ADD HL,DE //LD L,(IY+_sBOOT_SEC.RESERVE) ;Reserve sec //LD H,(IY+_sBOOT_SEC.RESERVE+1) LD HL,(BootSector.RESERVE) ; ; LD E,(IY+_sBOOT_SEC.HIDDEN) ;Hidden sec ; LD D,(IY+_sBOOT_SEC.HIDDEN+1) ; ADD HL,DE ;LD (FatBuffer.FAT_FRM),HL ; first sector FAT LD (FatBuffer.FAT1_XX),HL ; first sector FAT #1 LD (FatBuffer.FAT2_XX),HL //LD E,(IY+_sBOOT_SEC.S_P_F) ; sectors in FAT //LD D,(IY+_sBOOT_SEC.S_P_F+1) LD DE,(BootSector.S_P_F) LD A,(BootSector.FAT_NUM) ; amount FATs CP 1 JR Z,.loop1 DEC A ADD HL,DE LD (FatBuffer.FAT2_XX),HL ;C_DATA1 .loop1: ADD HL,DE DEC A JR NZ,.loop1 LD (FatBuffer.DIR_FRM),HL ; first sector DIR ; CF = ? мало ли AND A ; CF = 0 //LD C,(IY+_sBOOT_SEC.B_P_S) ; Size sectors //LD B,(IY+_sBOOT_SEC.B_P_S+1) LD BC,(BootSector.B_P_S) ; RL C ; RL B ; RL C ; RL B ; RL C ; RL B ; LD C,B ; LD B,0 ; BC - File handels in sectors ; LD A,C ;;;; LD A,B RL C RLA RL C RLA RL C RLA LD C,A LD B,0 ; BC - File handels in sectors ;;;; LD (FatBuffer.F_P_S),A //LD E,(IY+_sBOOT_SEC.F_P_DIR) ; Number file handel //LD D,(IY+_sBOOT_SEC.F_P_DIR+1) LD DE,(BootSector.F_P_DIR) EX DE,HL DEC HL XOR A ;NEXTAD2 .loop2: INC A JP Z,DOS_X_Error.UnknownBPB SBC HL,BC JR NC,.loop2 EX DE,HL LD C,A ; A - sectors in DIR LD B,0 LD (FatBuffer.DIR_S_S),A ADD HL,BC ; Start DATA area LD (FatBuffer.DAT_FRM),HL ;!TODO не используются значения вычисляемые и сохраняемые в FatBuffer //////////////////////////////////////////////////////////////////////// IF COMPILE_UNUSED_CODE ;LD HL,0 ;LD H,B ; тут в B ноль должен быть ;LD L,B ;LD C,(IY+_sBOOT_SEC.B_P_S) ; Size sector ;LD B,(IY+_sBOOT_SEC.B_P_S+1) //LD L,(IY+_sBOOT_SEC.B_P_S) ; Size sector //LD H,(IY+_sBOOT_SEC.B_P_S+1) LD HL,(BootSector.B_P_S) ; Size sector LD A,(BootSector.S_P_C) ;!TODO FATcacheSize ;NEXTAD3 ; .loop3: ADD HL,BC ; calc. cluster size ; DEC A ; JR NZ,.loop3 ;!TODO проверить правильно ли считает XOR 1 ; calc. cluster size JR Z,.loop3.end RRA .loop3: ADD HL,HL RRA JP NC,.loop3 .loop3.end: ; LD (FatBuffer.CLU_LEN),HL EX DE,HL LD HL,#3FFF ;!TODO FATcacheSize XOR A ;NEXTAD4 ;!FIXIT оптимизировать когда понадобится .loop4: INC A JP Z,DOS_X_Error.UnknownBPB SBC HL,DE JR NC,.loop4 LD (FatBuffer.C_P_B),A ; A - Clusters per bank (16k) ENDIF //////////////////////////////////////////////////////////////////////// LD HL,BootSector.ID_FAT ;!!!!! а если IY используется для переменного BootSector, то будет бага LD DE,FatBuffer.MSG LD B,3 ;R_BPBL1 .loop5: LD A,(DE) CP (HL) JP NZ,.IBM_DOS INC HL INC DE DJNZ .loop5 ;FID .loop6: LD A,(HL) INC HL CP ' ' JR Z,.loop6 CP '1' JP NZ,DOS_X_Error.UnknownBPB LD A,(HL) CP '6' ; FAT16 LD HL,#FFFF JR Z,.BPB_FAT CP '2' ; FAT12 JP NZ,DOS_X_Error.UnknownBPB LD HL,#0FFF .BPB_FAT: LD (FatBuffer.FAT_TYP),A LD (FatBuffer.ENDCLUS),HL ;!TODO не используются значения вычисляемые и сохраняемые в FatBuffer //////////////////////////////////////////////////////////////////////// IF COMPILE_UNUSED_CODE LD HL,0 //LD C,(IY+_sBOOT_SEC.S_P_T) ; Sector per track //LD B,(IY+_sBOOT_SEC.S_P_T+1) LD BC,(BootSector.S_P_T) ; Sector per track LD A,(BootSector.HEADS) ;!!!!! а если IY используется для переменного BootSector, то будет бага .BPB_L1: ; calc. sector per cylinder ADD HL,BC DEC A JR NZ,.BPB_L1 LD (FatBuffer.S_X_H),HL ENDIF //////////////////////////////////////////////////////////////////////// LD DE,(FatBuffer.DAT_FRM) ; LD E,(IY+_sBOOT_SEC.HIDDEN) ;Hidden sec ; LD D,(IY+_sBOOT_SEC.HIDDEN+1) ; AND A ; SBC HL,DE ; EX DE,HL //LD L,(IY+_sBOOT_SEC.S_P_D) //LD H,(IY+_sBOOT_SEC.S_P_D+1) LD HL,(BootSector.S_P_D) LD A,H OR L JP NZ,.HDDSMAL ; //LD L,(IY+_sBOOT_SEC.BPB_BIG_TOTAL_SECTORS) //LD H,(IY+_sBOOT_SEC.BPB_BIG_TOTAL_SECTORS+1) LD HL,(BootSector.BPB_BIG_TOTAL_SECTORS) //LD C,(IY+_sBOOT_SEC.BPB_BIG_TOTAL_SECTORS+2) //LD B,(IY+_sBOOT_SEC.BPB_BIG_TOTAL_SECTORS+3) LD BC,(BootSector.BPB_BIG_TOTAL_SECTORS+2) AND A SBC HL,DE JP NC,.HDDBIG DEC BC JP .HDDBIG .HDDSMAL: ;AND A ;тут CF полюбас сброшен должен быть SBC HL,DE LD BC,0 .HDDBIG: LD A,(BootSector.S_P_C) ;!!!!! а если IY используется для переменного BootSector, то будет бага SCF .S4C01: RRA JR C,.S4C02 RR B RR C RR H RR L JP .S4C01 .S4C02: INC HL LD (MAX_CLU),HL //POP IY ; LD DE,FAT ; LD HL,0 ; LD IX,(FAT_FRM) ; LD B,3 ; LD A,(DRIVE) ; LD C,Dss.DRV.Read ; RST ToDSS.DRV ; JP C,RDERR1 LD HL,0 LD (FATCASH),HL SET_PAGE_X FATPAGE PUSH AF XOR A CALL RE_FAT POP AF OUT (SLOT3),A CALL R_CLUST XOR A RET .IBM_DOS: LD A,(BootSector.ID_FORM) CP #F0 JR C,DOS_X_Error.UnknownBPB ;????? надо ли изменить? // OR 2 // CP #FA ; ID ram-диска CP #F8 ; а если не F8? ;????? LD A,'6' LD HL,#FFFF JP Z,.BPB_FAT LD A,'2' LD HL,#0FFF JP .BPB_FAT DOS_X_Error: .UnknownBPB: //POP IY LD A,DSS_Error.sys.UNKNOWN_FORMAT SCF RET .Not_ready: LD A,DSS_Error.sys.NOT_READY ; CF = 1 RET ;!TODO к буферам! FatBuffer: .MSG: DB 'FAT' .READ_PG: DB #00 .BLOCK: DB #00 .DIR_CLU: DW #0000 .DRIVE: DB #FF .FAT_FRM: .FAT1_XX: DW #0000 ; MSD_FAT_SEC first sector FAT .FAT2_XX: DW #0000 .DIR_FRH: DW #0000 ; MSD_CAT_SEC first sector DIR .DIR_FRL: .DIR_FRM: DW #0000 ; MSD_CAT_SEC first sector DIR .F_P_S: DB #00 ; число файловых записей в секторе .DIR_S_S: DB #00 ; DIR_SEC_SIZE .DAT_FRM: DW #0000 ; MSD_DAT_SEC .CLU_LEN: .B_P_C: DW #0000 ; CLUSTER_LEN .C_P_B: DB #00 ; A - Clusters per bank (16k) (число кластеров на блок ОЗУ) ; ????? это используется? .FAT_TYP: DB #00 ; TYPE FAT (#32 - 12bit, #36 - 16bit) .S_X_H: DW #0000 ; количество секторов на цилиндре ; ????? это используется? .ENDCLUS: DW #FFFF ; ;!TODO к буферам! DIRSPEC: DB '\' BLOCK DIRSPEC.DEPTH ; ;R11 ; !TODO починить IF SAVE_PATH_MACRO SAVE_CUR_PATH PUSH IX PUSH IY PUSH HL PUSH DE PUSH BC PUSH AF SET_PAGE_X ENVPAGE PUSH AF CALL CURRDSK ADD A,"A" LD HL,TMP_CURDIR LD (HL),A INC HL LD A,":" LD (HL),A INC HL CALL CURRDIR ; почему не POP AF : OUT (SLOT3),A //POP BC //LD A,B //OUT (SLOT3),A POP AF OUT (SLOT3),A ; ; POP AF POP BC POP DE POP HL POP IY POP IX RET ; !TODO починить BACK_CUR_PATH: PUSH IY PUSH IX PUSH HL PUSH DE PUSH BC PUSH AF SET_PAGE_X ENVPAGE PUSH AF LD HL,TMP_CURDIR CALL CHDIR ; почему не POP AF : OUT (SLOT3),A //POP BC //LD A,B //OUT (SLOT3),A POP AF OUT (SLOT3),A ; POP AF POP BC POP DE POP HL POP IX POP IY RET ENDIF ;R11 ;R12 ;/////////////////////////////////////////////////////////////////////// ; Функция #08 (DSS_RESCAN). Пересканировать девайсы системы. ; ; вход: нет ; выход: A - номер последнего лог. диска в системе ;/////////////////////////////////////////////////////////////////////// ; INCLUDE 'ScanDRV.asm' INCLUDE 'NScanDRV.asm' ;/////////////////////////////////////////////////////////////////////// ; ;R12 ;GOD EQU 1999-1980*512 ;FHAND DB " " ; DB " " ; DB #20 ; DW 0,0,0,0,0 ; DW #0000 ; DW 5*32+19+GOD ;SAVEC DW #0000 ;SIZEC DW #0000,#0000 ;============================================= ;//MODULE: DOS_X ;[END]