From 0e38bd4a91fcac1c165ec8f92d21d1addfe30f82 Mon Sep 17 00:00:00 2001 From: Anatoliy Belyanskiy Date: Fri, 1 Dec 2023 02:05:37 +1000 Subject: [PATCH] =?UTF-8?q?-bug=20in=20NSECTOR=20=D1=81=D0=B0=D0=BC=20?= =?UTF-8?q?=D0=B7=D0=B0=D1=82=D1=83=D0=BF=D0=B8=D0=BB,=20=D1=81=D0=B0?= =?UTF-8?q?=D0=BC=20=D0=BF=D0=BE=D1=87=D0=B8=D0=BD=D0=B8=D0=BB.=20=20?= =?UTF-8?q?=D0=A0=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE=D1=80=D0=B8=D0=BD?= =?UTF-8?q?=D0=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BOOT/DSSBOOT.ASM | 76 +- DSS/API.asm | 180 ++ DSS/API/Attribute.asm | 81 + DSS/API/ChDir.asm | 35 + DSS/API/ChnDisk.asm | 25 + DSS/API/Close.asm | 74 + DSS/API/Create.asm | 82 + DSS/API/CurrDir.asm | 24 + DSS/API/Delete.asm | 51 + DSS/API/DosName.asm | 22 + DSS/API/Find.asm | 126 ++ DSS/API/GetDateTime.asm | 24 + DSS/API/MkDir.asm | 167 ++ DSS/API/Open.asm | 69 + DSS/API/Rename.asm | 72 + DSS/API/RmDir.asm | 110 ++ DSS/API/ScanDRV.asm | 38 + DSS/API/SetDateTime.asm | 30 + DSS/API/Time.asm | 180 ++ DSS/API/Version.asm | 19 + DSS/API/bootDsk.asm | 57 + DSS/API/curDisk.asm | 16 + DSS/API/diskINF.asm | 139 ++ DSS/DOS5.ASM | 2397 ------------------------ DSS/DOS_FM.ASM | 9 +- DSS/DOS_Proc.asm | 512 +++++ DSS/DOS_X.ASM | 799 -------- DSS/DSS-MAIN.ASM | 41 +- DSS/ENVIRON.ASM | 2 +- DSS/EXECUTE.ASM | 12 +- DSS/FS/FAT/FAT.asm | 829 ++++++++ DSS/{FAT_X.ASM => FS/FAT/FAT12_16.asm} | 1069 +++++------ DSS/Media_drivers/ide-drv.asm | 11 +- DSS/Procedures.asm | 191 ++ DSS/build.txt | 2 +- DSS/defines.inc | 34 +- 36 files changed, 3821 insertions(+), 3784 deletions(-) create mode 100644 DSS/API.asm create mode 100644 DSS/API/Attribute.asm create mode 100644 DSS/API/ChDir.asm create mode 100644 DSS/API/ChnDisk.asm create mode 100644 DSS/API/Close.asm create mode 100644 DSS/API/Create.asm create mode 100644 DSS/API/CurrDir.asm create mode 100644 DSS/API/Delete.asm create mode 100644 DSS/API/DosName.asm create mode 100644 DSS/API/Find.asm create mode 100644 DSS/API/GetDateTime.asm create mode 100644 DSS/API/MkDir.asm create mode 100644 DSS/API/Open.asm create mode 100644 DSS/API/Rename.asm create mode 100644 DSS/API/RmDir.asm create mode 100644 DSS/API/ScanDRV.asm create mode 100644 DSS/API/SetDateTime.asm create mode 100644 DSS/API/Time.asm create mode 100644 DSS/API/Version.asm create mode 100644 DSS/API/bootDsk.asm create mode 100644 DSS/API/curDisk.asm create mode 100644 DSS/API/diskINF.asm delete mode 100644 DSS/DOS5.ASM create mode 100644 DSS/DOS_Proc.asm delete mode 100644 DSS/DOS_X.ASM create mode 100644 DSS/FS/FAT/FAT.asm rename DSS/{FAT_X.ASM => FS/FAT/FAT12_16.asm} (86%) create mode 100644 DSS/Procedures.asm diff --git a/BOOT/DSSBOOT.ASM b/BOOT/DSSBOOT.ASM index dcd444f..88062d5 100644 --- a/BOOT/DSSBOOT.ASM +++ b/BOOT/DSSBOOT.ASM @@ -523,27 +523,61 @@ SMALL_CLUSTER: ; HL - CLUSTER ; HL:IX - SECTOR -NSECTOR DEC HL +; NSECTOR: +; DEC HL +; DEC HL +; EX DE,HL +; LD A,(BOOT.S_P_C) +; LD B,A +; LD HL,0 +; LD IX,0 +; ADD_DE1 ADD IX,DE +; JP NC,ADD_DE2 +; INC HL +; ADD_DE2 DJNZ ADD_DE1 +; LD DE,(DAT_FRM) +; ADD IX,DE +; LD DE,#0000 +; ADC HL,DE + +; LD DE,(DISKL) +; ADD IX,DE +; LD DE,(DISKH) +; ADC HL,DE +; RET + + +NSECTOR: + LD DE,0 + DEC HL DEC HL - EX DE,HL LD A,(BOOT.S_P_C) - LD B,A - LD HL,0 - LD IX,0 -ADD_DE1 ADD IX,DE - JP NC,ADD_DE2 - INC HL -ADD_DE2 DJNZ ADD_DE1 - LD DE,(DAT_FRM) + XOR 1 + JR Z,.skip + ; + RRA +.loop: ADD HL,HL + RL E + RL D + ; + RRA + JP NC,.loop + ; +.skip: EX DE,HL + LD XL,E + LD XH,D + LD DE,(DAT_FRM) ;first data sector + XOR A ADD IX,DE - LD DE,#0000 + LD D,A + LD E,A ADC HL,DE + ; LD DE,(DISKL) ADD IX,DE LD DE,(DISKH) ADC HL,DE - RET - + RET ;----------------- ;!TODO сделать это макросами или инклюдами универсальными. повторяются в досе и ещё где-то ; HL - CLUSTER @@ -611,15 +645,15 @@ R_F_00 INC A ; HL - FAT OFFSET R_F_F01 LD A,E AND #F0 + RR D ; вправо на 4 битa + RRA + RR D + RRA + RR D + RRA + RR D + RRA LD E,A - RR D - RR E - RR D - RR E - RR D - RR E - RR D - RR E R_F_F02 LD HL,#0FEF XOR A SBC HL,DE diff --git a/DSS/API.asm b/DSS/API.asm new file mode 100644 index 0000000..b0c0c0d --- /dev/null +++ b/DSS/API.asm @@ -0,0 +1,180 @@ + +;[BEGIN] +;//MODULE: DOS_X +;//CREATE: 19-05-1998 AUTHOR: Denis Parinov +;//UPDATE: 24-10-1999 DNS Restore module +;--------------------------------------------------------------- +;Rev Date Name Description +;--------------------------------------------------------------- +;R011 17-04-2023 BAO Временный костыль для недопускания переполнения буфера пути каталога +;R010 15-04-2023 BAO FIXED BUG WITH CHANGE DISK WITHOUT CHANGE PATH +;R009 13-04-2023 BAO FIX BUG WITH PARSING DIRECTORY BUFFER +;R13 06-04-2023 BAO Функцию SETBOOT можно вызвать только раз (если завершится корректно) +;R12 03-04-2023 BAO Добавлена функция рескана драйвов LD C,8 : RST #10 +;R008 - 15-04-2003 DNS SAVE AND RESTORE CUR-PATH MACROS +;R11 - 15-04-2003 DNS ROUTINE FOR STORE CURDISK AND CURDIR +;R10 - 03-04-2003 DNS IMPROVED FN. VERSION +;R09 27-03-2003 DNS PASTED SET/GET BOOT FN. +;R007 06-02-2003 DNS FIX BUG IN MASK ROUTINE, IT ALLOW NAMES WHICH BEGAN FROM "." ".NAM" +;R006 29-01-2003 DNS FIX BUG WITH SET FILE DATE AND TIME +;R005 26-11-2002 DNS FIX ERROR IN CHDIR, DON'T ALLOWED "." FOR ROOT +;R004 19-11-2002 DNS DON'T ALLOW DIR & LABEL ATTR FOR FILES +;R003 19-11-2002 DNS ADD RESET OF VOLUME LABEL ATTRIBUT +;R002 19-11-2002 DNS FIX GET/SET ATTRIBUTES +;R08 14-11-2002 DNS IMPROVE BPB-FUNCTION +;R07 17-12-1999 DNS BUG FIX SIGNATURE #55AA AT 510 OFFSET +;R001 16-12-1999 DNS Y2K fix +;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" + +; +;--------------------------------------------------------------- + + include 'API/Version.asm' + include 'API/bootDsk.asm' + include 'API/curDisk.asm' + include 'API/diskINF.asm' + include 'API/ScanDRV.asm' + include 'API/Attribute.asm' + include 'API/Create.asm' + include 'API/Delete.asm' + include 'API/Rename.asm' + include 'API/Open.asm' + include 'API/Close.asm' + include 'API/Find.asm' + include 'API/ChnDisk.asm' + include 'API/CurrDir.asm' + include 'API/Time.asm' + include 'API/GetDateTime.asm' + include 'API/SetDateTime.asm' + include 'API/ChDir.asm' + include 'API/MkDir.asm' + include 'API/RmDir.asm' + include 'API/DosName.asm' + +;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 +; + + +;R04 + ;SIZE2CL: LD DE,(B_P_C) + ; XOR A + ; SCF + ;S2C01: RR D + ; RR E + ; JR C,S2C02 + ; RR H + ; RR L + ; RR B + ; RR C + ; JP NC,S2C01 + ; LD A,1 + ; JP S2C01 + ;S2C02: OR A + ; RET Z + ; INC BC + ; RET + ;L_SEC_X: DW 0 + ;H_SEC_X: DW 0 +; + + +;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] + +;R11 + ; 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_AUTO + ; LD (HL),A + ; INC HL + ; LD A,":" + ; LD (HL),A + ; INC HL + ; CALL CURRDIR_FN + ; + ; POP AF + ; OUT (SLOT3),A + ; + ; POP AF + ; POP BC + ; POP DE + ; POP HL + ; POP IY + ; POP IX + ; RET + ; + ; BACK_CUR_PATH: + ; RET NC + ; .force: PUSH IY + ; PUSH IX + ; PUSH HL + ; PUSH DE + ; PUSH BC + ; PUSH AF + ; + ; SET_PAGE_X ENVPAGE + ; PUSH AF + ; + ; LD HL,TMP_CURDIR_AUTO + ; CALL CHDIR + ; + ; POP AF + ; OUT (SLOT3),A + ; + ; POP AF + ; POP BC + ; POP DE + ; POP HL + ; POP IX + ; POP IY + ; RET + ; ENDIF +; \ No newline at end of file diff --git a/DSS/API/Attribute.asm b/DSS/API/Attribute.asm new file mode 100644 index 0000000..18b2568 --- /dev/null +++ b/DSS/API/Attribute.asm @@ -0,0 +1,81 @@ +//////////////////////////////////////////////////////////////////////// +; INPUT: HL - "C:\DIR1\DIR2\filename.ext",#00 +; A - ATTRIB +; B - MODE +; B = 0 GET ATTRIB +; B = 1 SET ATTRIB +; OUTPUT: A - ATTRIB +//////////////////////////////////////////////////////////////////////// +ATTRIB: ;!TEST Current Dir ;[x] 15/10/23 + LD C,A + PUSH HL + PUSH BC + CALL DIR_PATH_CHECK + POP BC + POP HL + RET C + LD A,C + ; + ; + INC B + DEC B + JP Z,.READ + DEC B + JP Z,.WRITE + LD A,DSS_Error.sys.INVALID_FUNCTION + SCF + RET +.READ: ;!TEST ;[x] 16/11/23 optimize get attribute + ;XOR A + ; + CALL .OPENATR ;R002 + RET C + ;!TEST ;[x] 16/11/23 optimize get attribute + LD A,(HANDBUF+_sFM.ATTRIBUT) + ;LD B,(IY+_sFM.ATTRIBUT) + ;PUSH BC + ;CALL CLOSE + ;POP BC + ;RET C + ;LD A,B + ; + RET + ; +.WRITE: PUSH AF + XOR A + ;!TEST ;[x] 16/11/23 optimize get attribute + LD (OPEN_FN.TMP),A + ; + CALL .OPENATR ;R002 + ;!TEST ;[x] 16/11/23 optimize get attribute + CALL NC,OPEN_FN.FM + ; + POP BC + RET C + SET 7,(IY+_sFM.ACCESS_MODE) + RES 3,B ;CLEAR LABEL ATTR ;R003 ;!HARDCODE attribute bit + LD (IY+_sFM.ATTRIBUT),B + PUSH BC + CALL CLOSE_FN +.error: POP BC + RET C + LD A,B + RET +;R002 +.OPENATR: + ;!TEST ;[x] 16/11/23 optimize get attribute + ;LD (OPEN.TMP),A ; раб. ячейка (здесь атрибут записи) + ; + CALL GETWORD ; тест на допуст. имя и настр. на диск + RET C + CALL MASK + RET C + LD A,FAT_ATTR.NoVolID + ;!TEST ;[x] 16/11/23 optimize get attribute + JP SEARCH.Custom + ;CALL SEARCH.Custom + ;RET C ; запись не найдена + ;JP OPEN.FM ; на поиск своб. дескриптора + ; + ; +;R002 \ No newline at end of file diff --git a/DSS/API/ChDir.asm b/DSS/API/ChDir.asm new file mode 100644 index 0000000..2f82fa0 --- /dev/null +++ b/DSS/API/ChDir.asm @@ -0,0 +1,35 @@ +//////////////////////////////////////////////////////////////////////// +; Функция #1D. Смена текущего каталога. +; Меняет текущий каталог и текущий диск, если он указан в файловой +; спецификации. Если путь начинается с "\" - это означает путь от +; корневого каталога, иначе от текущего. +; +; вход: HL - указатель на имя каталога +; выход: нет +; +; INPUT: HL - "C:\DIR\DIR\DIR_NAME[\]",0 +//////////////////////////////////////////////////////////////////////// +CHDIR_FN: + ;!TEST Current Dir ;[x] 15/10/23 + PUSH HL + CALL DIR_PATH_CHECK + POP HL + RET C + CALL CHDIR + ; если удачно, то копируем WorkDirectory в CurrentDirectory + JP NC,DIR_PATH_CHANGE.FullCurrent + ; если неудачно, то возвращаемся туда откуда пришли + PUSH AF + LD HL,CurrentDirectory + CALL CHDIR + POP AF + RET + ; +CHDIR: CALL GETWORD ; тест на допуст. имя и настр. на диск + RET C + LD HL,TMPNAME + LD A,(HL) + OR A + CALL NZ,OPENDIR + RET +; \ No newline at end of file diff --git a/DSS/API/ChnDisk.asm b/DSS/API/ChnDisk.asm new file mode 100644 index 0000000..272db10 --- /dev/null +++ b/DSS/API/ChnDisk.asm @@ -0,0 +1,25 @@ +//////////////////////////////////////////////////////////////////////// +; +; +//////////////////////////////////////////////////////////////////////// +CHNDISK_FN: + CALL CHNDISK + RET C + PUSH AF + CALL DIR_PATH_CHANGE.FullCurrent + POP AF + RET +CHNDISK:;[x] более корректная смена диска + CALL OPENDSK + ; + ;R010 + RET C + LD HL,WorkDirectory + LD (HL),0 + PUSH AF + CALL OPENDIR + POP BC + RET C + LD A,B + RET +; \ No newline at end of file diff --git a/DSS/API/Close.asm b/DSS/API/Close.asm new file mode 100644 index 0000000..256e18e --- /dev/null +++ b/DSS/API/Close.asm @@ -0,0 +1,74 @@ +//////////////////////////////////////////////////////////////////////// +;Входные значения: +; C - #12 +; A - файловый манипулятор +;Выходные значения: +; A - код ошибки, если CF=1 +//////////////////////////////////////////////////////////////////////// +CLOSE_FN: +;R008 ; +;CLOSE: ; + LD (.TMP),A + CALL SET_FM + RET C + LD A,(TASK) + CP (IY+_sFM.TASK_NUM) + LD A,DSS_Error.sys.ACCESS_DENIED + SCF + RET NZ + BIT 7,(IY+_sFM.ACCESS_MODE) + JR Z,.NOTMODF + LD E,(IY+_sFM.DIR_CLUSTER) + LD D,(IY+_sFM.DIR_CLUSTER+1) + PUSH DE + ; [x] 15/11/2023 -bug with bad clusters ;!TEST + LD A,(IY+_sFM.DRIVE) + CALL OPENDSK + ; + XOR A + CALL SET_FM + POP DE + LD (IY+_sFM.DIR_CLUSTER),E + LD (IY+_sFM.DIR_CLUSTER+1),D + ; [x] 15/11/2023 -bug with bad clusters ;!TEST + LD (IY+_sFM.ST_CLUSTER),E + LD (IY+_sFM.ST_CLUSTER+1),D + ; + CALL LOADDIR +.TMP+1: LD A,0 + CALL SET_FM + ; + SET_PAGE_X DIRPAGE + ; + ;TEST 9/11/23 + ; LD HL,DIR + ; LD DE,#0020 + ; LD C,(IY+_sFM.HANDLE) + ; LD B,(IY+_sFM.HANDLE+1) + ; JR .CLOSE2 + ; .CLOSE1: + ; ADD HL,DE + ; DEC BC + ; .CLOSE2: + ; LD A,B + ; OR C + ; JR NZ,.CLOSE1 + LD L,(IY+_sFM.HANDLE) + LD H,(IY+_sFM.HANDLE+1) + ; + LD D,YH + LD E,YL + EX DE,HL + ;PUSH HL + ;SET_PAGE_X DIRPAGE + ;POP HL + LD BC,#0020 ;!HARDCODE + LDIR + OUT (SLOT3),A + CALL SAVEDIR +.NOTMODF: + LD A,(.TMP) + ;CALL RES_FM + JP RES_FM + ;RET +; \ No newline at end of file diff --git a/DSS/API/Create.asm b/DSS/API/Create.asm new file mode 100644 index 0000000..d69d921 --- /dev/null +++ b/DSS/API/Create.asm @@ -0,0 +1,82 @@ +//////////////////////////////////////////////////////////////////////// +; INPUT: HL - "C:\DIR1\DIR2\filename.ext",#00 +; OUTPUT: A - FM +//////////////////////////////////////////////////////////////////////// +CREATE: ;!TEST Current Dir ;[x] 15/10/23 + PUSH HL + CALL DIR_PATH_CHECK + POP HL + RET C + ; + CALL .Prepare + RET C + CALL SEARCH.File + CALL NC,DEL_FN.DELETE ;FILE EXIST RECREAT + JR .DO + ; +.NEW: ;!TEST Current Dir ;[x] 15/10/23 + PUSH HL + CALL DIR_PATH_CHECK + POP HL + RET C + ; + CALL .Prepare + RET C + CALL SEARCH.File + LD A,DSS_Error.sys.FILE_EXISTS + CCF + RET C + ; +.DO: LD HL,MASKARE + LD DE,HANDBUF + LD BC,11 + LDIR + EX DE,HL +.TMP+1: LD A,0 + LD (HL),A + INC HL + LD BC,#0A00 ;!HARDCODE + ; +.loop1: LD (HL),C + INC HL + DJNZ .loop1 + ; + PUSH HL + CALL SYSTIME + CALL MK_TIME + POP HL + LD (HL),E + INC HL + LD (HL),D + INC HL + LD (HL),C + INC HL + LD (HL),B + INC HL + LD BC,#0600 + ; +.loop2: LD (HL),C + INC HL + DJNZ .loop2 + ; + CALL WRT_HND + RET C + ;CALL SAVEDIR +.PATH0+1: + LD HL,0 + XOR A + LD (OPEN_FN.TMP),A + JP OPEN_FN.FILE ;R008 +.Prepare: + AND #E7 ;R004 %76A00SHR = !FAT_ATTR ;!HARDCODE + LD (.TMP),A + LD (.PATH0),HL + CALL GETWORD + RET C + ; LD HL,TMPNAME + ; LD DE,MASKARE + JP MASK +; INPUT: HL - "C:\DIR1\DIR2\filename.ext",#00 +; OUTPUT: A - FM +CREAT_N EQU CREATE.NEW +; \ No newline at end of file diff --git a/DSS/API/CurrDir.asm b/DSS/API/CurrDir.asm new file mode 100644 index 0000000..93e2d5a --- /dev/null +++ b/DSS/API/CurrDir.asm @@ -0,0 +1,24 @@ +//////////////////////////////////////////////////////////////////////// +; Функция #1E. Информация о текущем каталоге. +; +; вход: HL - буфер в памяти 256 байт +; выход: A - код ошибки, если CF=1 +//////////////////////////////////////////////////////////////////////// +CURRDIR: LD DE,WorkDirectory + JR CURRDIR_FN.skip +CURRDIR_FN: + LD DE,CurrentDirectory +.skip: EX DE,HL + LD BC,DIRECTORY_PATH_LENGTH ;[x] 15/11/2023 могло выйти за пределы буфера + XOR A +.loop: CP (HL) + LDI + JP PO,.error ;[x] 15/11/2023 могло выйти за пределы буфера + JR NZ,.loop + RET + ;[x] 15/11/2023 могло выйти за пределы буфера +.error: LD A,DSS_Error.sys.TOO_DEEP_DIR_DEPTH + SCF + RET + ; +; \ No newline at end of file diff --git a/DSS/API/Delete.asm b/DSS/API/Delete.asm new file mode 100644 index 0000000..63cea09 --- /dev/null +++ b/DSS/API/Delete.asm @@ -0,0 +1,51 @@ +//////////////////////////////////////////////////////////////////////// +; INPUT: HL - "c:\dir\filename.ext",#00 without simbols * ? +//////////////////////////////////////////////////////////////////////// +DEL_FN: ;!TEST + ;!TEST Current Dir ;[x] 15/10/23 + PUSH HL + CALL DIR_PATH_CHECK + POP HL + RET C + ; + CALL GETWORD ; тест на допуст. имя и настр. на диск + RET C + CALL MASK + RET C + ; + ;!TEST optimization + ;LD HL,MASKARE + ;LD BC,11 + ;LD A,"?" + ;CPIR + ;LD A,DSS_Error.sys.INVALID_NAME + ;SCF + CALL CHECK_NAME + ; + RET Z + CALL LOADDIR + CALL SEARCH.File + RET C + ;JP .DELETE +; пометить запись как "удаленная" +.DELETE: SET_PAGE_X DIRPAGE + LD (IX+_sFM.NAME),#E5 ; признак удаления файла + LD E,(IX+_sFM.ST_CLUSTER) ; № первого кластера + LD D,(IX+_sFM.ST_CLUSTER+1) + ; + OUT (SLOT3),A + LD A,E + OR D + JP Z,SAVEDIR ; сбросить кеш каталога на диск +.loop: EX DE,HL ; hl=номер кластера + CALL R_F_FAT ; прочитать из кеша FAT-а номер след. кластера + PUSH DE ; номер след. кластера + PUSH AF + LD DE,#0000 ; номер кластера + CALL W_T_FAT ; записать в кеш FAT-а номер кластера + POP AF + POP DE + JP NC,.loop + CALL WR_FAT + JP SAVEDIR ; сбросить кеш каталога на диск +; \ No newline at end of file diff --git a/DSS/API/DosName.asm b/DSS/API/DosName.asm new file mode 100644 index 0000000..512de5c --- /dev/null +++ b/DSS/API/DosName.asm @@ -0,0 +1,22 @@ +//////////////////////////////////////////////////////////////////////// +;Входные значения: +; C - #44 +; B = 0, преобразовать из 11 символьного формата в формат ДОС +; HL - 11 символов имени файла +; DE - буфер для имени в формате ДОС +; B = 1, преобразовать из формата ДОС в 11 символьный формат +; HL - имя файла в формате ДОС +; DE - 11 символов имени файла +;Выходные значения: +; A - код ошибки, если CF=1 +//////////////////////////////////////////////////////////////////////// +DOSNAME: + INC B + DEC B + JP Z,GetName + DEC B + JP Z,MASK.custom + LD A,DSS_Error.sys.INVALID_FUNCTION + SCF + RET +; \ No newline at end of file diff --git a/DSS/API/Find.asm b/DSS/API/Find.asm new file mode 100644 index 0000000..c3c3972 --- /dev/null +++ b/DSS/API/Find.asm @@ -0,0 +1,126 @@ +//////////////////////////////////////////////////////////////////////// +;Входные значения: +; C - #19 +; HL - указатель на файловую спецификацию +; DE - рабочий буфер 44 байта, если B=0, иначе 256 байт +; ;!!!!! на самом деле сейчас если B=1, рабочий буфер 46 байт +; A - атрибуты, используемые при поиске +; B = 0 - имя найденного файла в формате 11 байт "FilenameExt" +; B = 1 - имя найденного файла в формате DOS "filename.ext",0 +;Выходные значения: +; A - код ошибки, если CF=1 +//////////////////////////////////////////////////////////////////////// +F_FIRST: + ; Current Dir [x] 15/10/23 + ; LD C,A + ; PUSH HL + ; PUSH DE + ; PUSH BC + ; CALL DIR_PATH_CHECK + ; POP BC + ; POP DE + ; POP HL + ; RET C + ; LD A,C + ; ; + LD (.TMP),A + LD (.DTABUF),DE + LD A,B + LD (.FNDMODE),A + PUSH HL + ;!TEST Current Dir ;[x] 15/10/23 + CALL DIR_PATH_CHECK + RET C + ; + CALL LOADDIR + POP HL + CALL GETWORD + RET C + CALL MASK + RET C + LD A,(.TMP) + CALL SEARCH.Custom + RET C + LD HL,MASKARE +.DTABUF+1: + LD DE,0 + LD BC,11 ;!HARDCODE + LDIR +.TMP+1: LD A,0 + LD (DE),A +.FIND_S: + INC DE + LD BC,#0020 + ADD IX,BC + LD (F_NEXT.CURHND),IX + LD HL,HANDBUF+12 ;!HARDCODE + LD BC,HANDBUF.SIZE-12 ;????? метку вместо числа? + LDIR + LD A,(HANDBUF+11) + LD (DE),A + INC DE + LD HL,HANDBUF +.FNDMODE+1: + LD A,0 + OR A + JR NZ,.FIND_M2 + LD BC,11 ;!HARDCODE + LDIR + LD A,F_NEXT.NO_NEXT.NO + LD (F_NEXT.NO_NEXT),A + XOR A + RET +.FIND_M2: + CALL GetName + LD A,F_NEXT.NO_NEXT.NO + LD (F_NEXT.NO_NEXT),A + XOR A + RET + +//////////////////////////////////////////////////////////////////////// +; +; +//////////////////////////////////////////////////////////////////////// +F_NEXT: +.NO_NEXT.YES EQU 0 +.NO_NEXT.NO EQU #FF +.NO_NEXT+1: + LD A,0 + OR A + LD A,DSS_Error.sys.INVALID_ACCESS + SCF + RET Z + LD (F_FIRST.DTABUF),DE + EX DE,HL + LD DE,MASKARE + LD BC,11 ;!HARDCODE + LDIR + + XOR A ; F_NEXT.NO_NEXT.YES + LD (F_NEXT.NO_NEXT),A + + LD A,(HL) + PUSH HL + CALL .NSEARCH + POP DE + RET C + JP F_FIRST.FIND_S +.NSEARCH: + EX AF,AF' + SET_PAGE_X DIRPAGE + ;PUSH AF + EX AF,AF' + CPL + LD C,A + ;TEST 9/11/23 + ; EXX + ; LD DE,0 + ; EXX + ; +.CURHND+2: + LD IX,0 + LD A,XH + OR XL + JP Z,SEARCH.error_too_many_files + JP SEARCH.loop +; \ No newline at end of file diff --git a/DSS/API/GetDateTime.asm b/DSS/API/GetDateTime.asm new file mode 100644 index 0000000..ed8ba32 --- /dev/null +++ b/DSS/API/GetDateTime.asm @@ -0,0 +1,24 @@ +//////////////////////////////////////////////////////////////////////// +; Функция #17. Информация о дате и времени файла. +; +; вход: A - дескриптор файла +; выход: D - день +; E - месяц +; IX - год +; H - час +; L - минуты +; B - секунды +; A - код ошибки, если CF=1 +//////////////////////////////////////////////////////////////////////// +GET_D_T: + CALL SET_FM + RET C + ; время/дату из структуры дескр. + LD E,(IY+_sFM.TIME) ; время + LD D,(IY+_sFM.TIME+1) ; + LD C,(IY+_sFM.DATE) ; дата + LD B,(IY+_sFM.DATE+1) ; + CALL RMKTIME ; раскодировать время/дату + AND A + RET +; \ No newline at end of file diff --git a/DSS/API/MkDir.asm b/DSS/API/MkDir.asm new file mode 100644 index 0000000..7173502 --- /dev/null +++ b/DSS/API/MkDir.asm @@ -0,0 +1,167 @@ +//////////////////////////////////////////////////////////////////////// +; Функция #1B. Создание каталога. +; +; вход: HL - указатель на имя каталога +; выход: A - код ошибки, если CF=1 +; +; INPUT: HL - "C:\DIR\DIR\DIR_NAME",0 +//////////////////////////////////////////////////////////////////////// +MKDIR: ;!TEST Current Dir ;[x] 15/10/23 + PUSH HL + CALL DIR_PATH_CHECK + POP HL + RET C + CALL .START + PUSH AF + LD HL,CurrentDirectory + CALL CHDIR + POP AF + RET + ; +.START: CALL GETWORD ; тест на допуст. имя и настр. на диск + RET C + ;LD HL,TMPNAME ; 8.3 имя + ;LD DE,MASKARE ; буфер имени 11 симв. формата + CALL MASK ; преобр. имя 8.3 -> 11 формат + RET C + ;!TEST optimization ранее GETWORD уже загрузил директорию + ;CALL LOADDIR ; прочитать список каталога + ; + CALL SEARCH.Dir ; поиск записи каталога в списке диска + LD A,DSS_Error.sys.DIR_EXISTS + CCF + RET C ; каталог найден + ; + CALL G_CLUST + RET C + PUSH HL + LD DE,(FatBuffer.ENDCLUS) ; номер кластера + CALL W_T_FAT ; записать в кеш FAT-а номер кластера + CALL WR_FAT ; подкл. банку кеша FAT и записать его на диск + LD HL,MASKARE + LD DE,HANDBUF + LD BC,11 + LDIR + EX DE,HL + LD A,#10 ; атрибут записи каталога + LD (HL),A + INC HL + LD BC,#0A00 ; b=счетчик + ; +.loop1: LD (HL),C + INC HL + DJNZ .loop1 + ; + PUSH HL + CALL SYSTIME ; узнать тек. дату и время + CALL MK_TIME ; закодировать время/дату + POP HL + LD (HL),E ; de=время + INC HL + LD (HL),D + INC HL + LD (HL),C ; день + INC HL + LD (HL),B ; месяц + INC HL + POP DE + PUSH DE + LD (HL),E + INC HL + LD (HL),D + INC HL + LD BC,#0400 ; b=счетчик + ; +.loop2: LD (HL),C + INC HL + DJNZ .loop2 + ; + CALL WRT_HND ; скопир. новую запись в список диска (каталога) + ;CALL SAVEDIR ; и сбросить кеш каталога на диск + LD HL,CORE_BUFFERS.SECBUF ; буфер + LD (HL),"." ; запись тек. каталога + LD BC,10*256 + ' ' ; b=счетчик, c=пробел + ; +.loop3: INC HL + LD (HL),C + DJNZ .loop3 + ; + INC HL + LD DE,HANDBUF+11 ; ячейка атрибутов файла + EX DE,HL + LD BC,21 + LDIR + EX DE,HL + LD (HL),"." ; запись родит. каталога + INC HL + LD (HL),"." + LD BC,9*256 + ' ' ; b=счетчик, c=пробел +.MKD03: INC HL + LD (HL),C + DJNZ .MKD03 + ; + INC HL + SET_PAGE_X DIRPAGE + PUSH AF + ; + LD A,(DIRPAGE.buffer) + CP "." + LD DE,DIRPAGE.buffer+11 ; атрибуты записи ;!HARDCODE + JP Z,.MKD04 + LD IX,HANDBUF + XOR A + LD (IX+_sFM.ST_CLUSTER),A + LD (IX+_sFM.ST_CLUSTER+1),A + LD DE,HANDBUF+11 ; ячейка атрибутов файла +.MKD04: EX DE,HL + LD BC,HANDBUF.SIZE-11 + LDIR + POP AF + OUT (SLOT3),A + ; + EX DE,HL + LD D,H + LD E,L + INC DE + LD (HL),0 + LD BC,512-65 ;!HARDCODE + LDIR + ; + POP HL + CALL NSECTOR + LD A,(CORE_BUFFERS.BootSector.S_P_C) ; секторов на кластер +.MKD12: PUSH AF + PUSH HL ; ст. разряд + PUSH IX ; номер лог. сектора + IN A,(SLOT3) + PUSH AF + IN A,(SLOT0) + OUT (SLOT3),A + ; + LD A,(FatBuffer.DRIVE) + LD DE,CORE_BUFFERS.SECBUF+#C000 + LD BC,1*256 + Dss.DRV.Write + RST ToDSS.DRV + ; + POP AF + OUT (SLOT3),A + ; + LD HL,CORE_BUFFERS.SECBUF + LD DE,CORE_BUFFERS.SECBUF+1 + LD BC,511 + LD (HL),0 + LDIR + ; + POP IX + POP HL + INC IX + LD A,XH + OR XL + JR NZ,.MKD11 + INC HL +.MKD11 POP AF + DEC A + JR NZ,.MKD12 + AND A + RET +; \ No newline at end of file diff --git a/DSS/API/Open.asm b/DSS/API/Open.asm new file mode 100644 index 0000000..3bcf788 --- /dev/null +++ b/DSS/API/Open.asm @@ -0,0 +1,69 @@ +//////////////////////////////////////////////////////////////////////// +; Функция #11. Открытие файла. +; +; вход: HL - указатель на имя файла +; A - режим доступа: +; A=0 чтение/запись +; A=1 чтение +; A=2 запись +; выход: CF=0, A - дескриптор файла. +; CF=1, A - код ошибки. +//////////////////////////////////////////////////////////////////////// +OPEN_FN:;!TEST Current Dir ;[x] 15/10/23 + LD (.TMP),A + PUSH HL + CALL DIR_PATH_CHECK.forceCheck + POP HL + RET C + JR .start + ;!FIXIT сделать как в mkdir или rmdir? +;R008 ; +;OPEN: ; + LD (.TMP),A ; enter point from CREATE +.start: CALL GETWORD + RET C + CALL MASK ; enter point from OPEN_FN + RET C +.FILE: CALL SEARCH.File ; enter point from EXEC + RET C +;R002 ; +.FM: CALL GET_FM ; enter point from ATTRIB + RET C + LD A,C + EX AF,AF' + EXX + LD (IY+_sFM.HANDLE),E + LD (IY+_sFM.HANDLE+1),D + EXX + LD D,YH + LD E,YL + LD HL,HANDBUF + LD BC,HANDBUF.SIZE + LDIR +.TMP+1: LD A,0 + LD (IY+_sFM.ACCESS_MODE),A + LD A,(TASK) + LD (IY+_sFM.TASK_NUM),A + XOR A + ; + LD (IY+_sFM.KnownCluster_L),A + LD (IY+_sFM.KnownCluster_H),A + LD (IY+_sFM.KnownOffset_L),A + LD (IY+_sFM.KnownOffset_H),A + ; + LD (IY+_sFM.F_POSITION),A + LD (IY+_sFM.F_POSITION+1),A + LD (IY+_sFM.F_POSITION+2),A + LD (IY+_sFM.F_POSITION+3),A + LD A,(FatBuffer.DRIVE) + LD (IY+_sFM.DRIVE),A + LD HL,CORE_BUFFERS.FM_BUF+_sFM.ST_CLUSTER + LD E,(HL) + INC HL + LD D,(HL) + LD (IY+_sFM.DIR_CLUSTER),E + LD (IY+_sFM.DIR_CLUSTER+1),D + EX AF,AF' + AND A + RET +; \ No newline at end of file diff --git a/DSS/API/Rename.asm b/DSS/API/Rename.asm new file mode 100644 index 0000000..e324224 --- /dev/null +++ b/DSS/API/Rename.asm @@ -0,0 +1,72 @@ +//////////////////////////////////////////////////////////////////////// +; Функция #10. Переименование файла. +; Глобальные символы * и ? в именах файлов не допускаются. +; +; вход: HL - указатель на старое имя файла +; DE - указатель на новое имя файла +; выход: A - код ошибки, если CF=1 +; +; INPUT: HL - "old_name.ext",#00 without simbols * ? +; DE - "new_name.ext",#00 without simbols * ? +//////////////////////////////////////////////////////////////////////// +RENAME: ;!TEST Current Dir ;[x] 15/10/23 + PUSH HL + PUSH DE + CALL DIR_PATH_CHECK.forceCheck + POP DE + POP HL + RET C + ; + PUSH DE + ;LD DE,MASKARE + CALL MASK.name + POP DE + RET C + ;!TEST optimization + ;LD HL,MASKARE + ;LD BC,11 + ;LD A,"?" + ;CPIR + ;LD A,DSS_Error.sys.INVALID_NAME + ;SCF + CALL CHECK_NAME + ; + RET Z + PUSH DE + CALL LOADDIR ; прочитать список каталога + ;LD A,#33 + LD A,FAT_ATTR.NoSYSnoVolID + CALL SEARCH.Custom ; поиск записи в списке диска + POP HL + RET C + ;LD DE,MASKARE + CALL MASK.name + RET C + ;!TEST optimization + ;LD HL,MASKARE + ;LD BC,11 + ;LD A,"?" + ;CPIR + ;LD A,DSS_Error.sys.INVALID_NAME + ;SCF + CALL CHECK_NAME + ; + RET Z + PUSH IX + LD A,FAT_ATTR.NoSYSnoVolID + CALL SEARCH.Custom ; поиск записи в списке диска + POP IX + LD A,DSS_Error.sys.FILE_EXISTS + CCF + RET C + + SET_PAGE_X DIRPAGE + + LD HL,MASKARE + LD D,XH + LD E,XL + LD BC,11 + LDIR + OUT (SLOT3),A + JP SAVEDIR +; \ No newline at end of file diff --git a/DSS/API/RmDir.asm b/DSS/API/RmDir.asm new file mode 100644 index 0000000..d3ee43a --- /dev/null +++ b/DSS/API/RmDir.asm @@ -0,0 +1,110 @@ +//////////////////////////////////////////////////////////////////////// +; Функция #1C. Удаление каталога. +; Можно удалить только пустой каталог. +; +; вход: HL - указатель на имя каталога +; выход: A - код ошибки, если CF=1 +; +; INPUT: HL - "C:\DIR\DIR\DIR_NAME",0 +//////////////////////////////////////////////////////////////////////// +RMDIR: ;!TEST Current Dir ;[x] 15/10/23 + PUSH HL + CALL DIR_PATH_CHECK + POP HL + RET C + CALL .START + PUSH AF + LD HL,CurrentDirectory + CALL CHDIR + CALL DIR_PATH_CHANGE.Current + POP AF + RET + ; +.START: CALL GETWORD + RET C + CALL MASK + RET C + ;!TEST optimization + ;LD HL,MASKARE + ;LD BC,11 + ;LD A,"?" + ;CPIR + ;LD A,DSS_Error.sys.INVALID_NAME + ;SCF + CALL CHECK_NAME + ; + RET Z + CALL LOADDIR + CALL SEARCH.Dir + RET C + LD HL,(HANDBUF+_sFM.ST_CLUSTER) + PUSH IX +.RMD17: PUSH HL + CALL NSECTOR + LD A,(CORE_BUFFERS.BootSector.S_P_C) +.RMD12: PUSH AF + PUSH HL + PUSH IX + IN A,(SLOT3) + PUSH AF + IN A,(SLOT0) + OUT (SLOT3),A + + LD DE,CORE_BUFFERS.SECBUF+#C000 + LD BC,1*256 + Dss.DRV.Read + LD A,(FatBuffer.DRIVE) + RST ToDSS.DRV + + POP AF + OUT (SLOT3),A + + LD B,16 ;!HARDCODE 16 * 32 = 512; 32 - размер записи, 512 - размер считанного сектора + LD HL,CORE_BUFFERS.SECBUF +.RMD10: LD A,(HL) + OR A + JP Z,.RMD15 ;DIR EMPTY + CP "." + JR Z,.RMD14 + CP #E5 ;!HARDCODE байт удаления файла + JR Z,.RMD14 + LD DE,11 ;!HARDCODE смещ. до байта атрибутов + ADD HL,DE + LD A,(HL) + SBC HL,DE + ;BIT 3,A + AND %0000'1000 + JP Z,.error ;DIR NOT EMPTY +.RMD14: LD DE,#0020 + ADD HL,DE + DJNZ .RMD10 + + POP IX + POP HL + INC IX + LD A,XH + OR XL + JR NZ,.RMD11 + INC HL +.RMD11: POP AF + DEC A + JR NZ,.RMD12 + POP HL ; номер кластера + CALL R_F_FAT ; прочитать из кеша FAT-а номер след. кластера + EX DE,HL ; hl=номер след. кластера + JR NC,.RMD17 ; не конец цепочки +.RMD18: POP IX + JP DEL_FN.DELETE ; пометить запись как "удаленная" +.RMD15: POP IX + POP HL + POP AF + POP HL + JR .RMD18 +.error: POP IX + POP HL + POP AF + POP HL + POP IX + LD A,DSS_Error.sys.DIR_NOT_EMPTY + SCF + RET +; \ No newline at end of file diff --git a/DSS/API/ScanDRV.asm b/DSS/API/ScanDRV.asm new file mode 100644 index 0000000..38da595 --- /dev/null +++ b/DSS/API/ScanDRV.asm @@ -0,0 +1,38 @@ +;R12 +;/////////////////////////////////////////////////////////////////////// +; Функция #08 (DSS_RESCAN). Пересканировать девайсы системы. +; +; вход: нет +; выход: A - номер последнего лог. диска в системе +;/////////////////////////////////////////////////////////////////////// +; INCLUDE 'ScanDRV.asm' +;!TODO код дико костыльный и будет переделан вместе с процедурой INITDVC +SCANDRV: +; 1. запоминаем состояние прерываний +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; + LD A,R + DI + PUSH AF +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; +; 2. узнаём букву бут-диска +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; + CALL BOOTDSK.GET +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; +; 3. вызываем рескан +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; + ; A = Boot disk + LD B,A + LD A,Dss.DRV.RescanDRV + LD C,Dss.DRV.RescanDRV + RST ToDSS.DRV + LD (LDRIVE),A +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; +; 4. выход +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; + POP AF + RET PO + EI + RET +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; +;/////////////////////////////////////////////////////////////////////// +; diff --git a/DSS/API/SetDateTime.asm b/DSS/API/SetDateTime.asm new file mode 100644 index 0000000..c95ae82 --- /dev/null +++ b/DSS/API/SetDateTime.asm @@ -0,0 +1,30 @@ +//////////////////////////////////////////////////////////////////////// +; Функция #18. Изменение даты и времени файла. +; +; вход: A - дескриптор файла +; D - день +; E - месяц +; IX - год +; H - час +; L - минуты +; B - секунды +; выход: A - код ошибки, если CF=1 +//////////////////////////////////////////////////////////////////////// +PUT_D_T: + PUSH AF + CALL MK_TIME ; закодировать время/дату + POP AF ; дескриптор + PUSH DE + PUSH BC + CALL SET_FM + POP BC + POP DE + RET C + LD (IY+_sFM.TIME),E + LD (IY+_sFM.TIME+1),D + LD (IY+_sFM.DATE),C + LD (IY+_sFM.DATE+1),B + SET 7,(IY+_sFM.ACCESS_MODE) ;R006 ; уст. признак изменения файла + AND A + RET +; \ No newline at end of file diff --git a/DSS/API/Time.asm b/DSS/API/Time.asm new file mode 100644 index 0000000..0d0813a --- /dev/null +++ b/DSS/API/Time.asm @@ -0,0 +1,180 @@ +//////////////////////////////////////////////////////////////////////// +; Функция #21. Текущая дата и время. +; +; вход: нет +; выход: D - день +; E - месяц +; IX - год +; H - час +; L - минуты +; B - секунды +; C - день недели +//////////////////////////////////////////////////////////////////////// +SYSTIME: + LD C,BIOS.CMOS_TEST + RST ToBIOS + JP C,.NOCMOS + LD D,7 ;DAY + CALL RCMOS + PUSH AF + LD D,8 ;MONTH + CALL RCMOS + POP DE + LD E,A + PUSH DE + LD D,4 ;HOUR + CALL RCMOS + PUSH AF + LD D,2 ;MINUTE + CALL RCMOS + POP DE + LD E,A + PUSH DE + LD D,0 ;SECOND + CALL RCMOS + PUSH AF + LD D,6 ;WEEK DAY + LD C,BIOS.CMOS_RD + RST ToBIOS + POP DE + LD E,A + PUSH DE + LD D,9 ;YEAR + CALL RCMOS ;READ AND CONVERT TO DECIMAL + PUSH AF + LD D,#32 ;CENTURY + LD C,BIOS.CMOS_RD + RST ToBIOS + LD XH,A + + POP AF + CP 80 ;R001, TEST DECIMAL FIX + PUSH AF + JR C,.XXIAGE + LD A,#19 + CP XH + JR Z,.GOODAGE + JR .BADAGE +.XXIAGE: + LD A,#20 + CP XH + JR Z,.GOODAGE +.BADAGE: + PUSH AF + LD D,#32 ;CENTURY + LD C,BIOS.CMOS_WR + RST ToBIOS + POP AF + LD XH,A +.GOODAGE: + POP AF + LD XL,A + LD A,XH + CALL BCD2HEX + LD L,A + LD H,0 + LD C,L + LD B,H + LD XH,B + ADD HL,HL + ADD HL,HL + ADD HL,BC + ADD HL,HL ;*10 + LD B,H + LD C,L + ADD HL,HL + ADD HL,HL + ADD HL,BC + ADD HL,HL ;*10(100) + EX DE,HL + ADD IX,DE + POP BC + POP HL + POP DE + AND A + RET +.NOCMOS: +.NC_DAY+1: + LD DE,DAY*256+MONTH ;DAY/MONTH +.NC_HOUR+1: + LD HL,0 ;HOUR/MINUTE +.NC_SEC+1: + LD BC,1 ;SECOND/WEEKDAY +.NC_YEAR+2: + LD IX,YEAR ;YEAR + AND A + RET +; + +//////////////////////////////////////////////////////////////////////// +; Функция #22. Установить текущую дату и время. +; +; вход: D - день +; E - месяц +; IX - год +; H - час +; L - минуты +; B - секунды +; выход: A - код ошибки, если CF=1 +//////////////////////////////////////////////////////////////////////// +SETTIME: + PUSH IX + PUSH BC + PUSH HL + PUSH DE + LD C,BIOS.CMOS_TEST + RST ToBIOS + JP C,.NOCMOS2 + POP AF + PUSH AF + LD D,7 ;DAY + CALL WCMOS + POP BC + LD A,C + LD D,8 ;MONTH + CALL WCMOS + POP AF + PUSH AF + LD D,4 ;HOUR + CALL WCMOS + POP BC + LD A,C + LD D,2 ;MINUTE + CALL WCMOS + POP AF + PUSH AF + LD D,0 ;SECOND + CALL WCMOS + POP BC + LD A,C + LD D,6 ;WEEK DAY + LD C,BIOS.CMOS_WR + RST ToBIOS + ; + POP HL + XOR A + LD DE,100 +.YR: INC A + SBC HL,DE + JR NC,.YR + ADD HL,DE + DEC A + PUSH HL + LD D,#32 ;CENTURY + CALL WCMOS + POP BC + LD A,C + LD D,9 ;YEAR + CALL WCMOS + AND A + RET +; !FIXIT новый биос выставляет время, если с ним что-то не так. +.NOCMOS2: + LD C,0 + LD (SYSTIME.NC_DAY),DE ;DAY/MONTH + LD (SYSTIME.NC_HOUR),HL ;HOUR/MINUTE + LD (SYSTIME.NC_SEC),BC ;SECOND/WEEKDAY + LD (SYSTIME.NC_YEAR),IX ;YEAR + AND A + RET +; \ No newline at end of file diff --git a/DSS/API/Version.asm b/DSS/API/Version.asm new file mode 100644 index 0000000..561de06 --- /dev/null +++ b/DSS/API/Version.asm @@ -0,0 +1,19 @@ +;///////////////////////////////////////////////////////////////////// +; Функция #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 \ No newline at end of file diff --git a/DSS/API/bootDsk.asm b/DSS/API/bootDsk.asm new file mode 100644 index 0000000..b2c5934 --- /dev/null +++ b/DSS/API/bootDsk.asm @@ -0,0 +1,57 @@ +;///////////////////////////////////////////////////////////////////// +; Функция #09. Номер системного диска. +; Возвращает номер диска, c которого загружена система. +; +; вход: B = 0 (01h - исп. boot-загрузчик системы) +; выход: A - номер системного диска (0=A,1=B,..) +;///////////////////////////////////////////////////////////////////// +BOOTDSK: + INC B + DEC B + JR Z,.GET + DEC B +.chg: JR Z,.SET ;R13 меняется на JR С,SETBOOT после первого удачного исполнения SETBOOT + LD A,DSS_Error.sys.INVALID_FUNCTION + SCF + RET +.GET: ;GET BOOT DISK +.NUM+1: LD A,0 ;R09 + AND A + RET + ; Сообщить DSS с какого диска загружается система. + ; Исп. загрузчик системы для иниц. ячейки "boot_disk". +.SET: LD B,A ;SET BOOT DISK + 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 (BOOTDSK.NUM),A + AND A + RET +.NoSupport: + INC C + LD A,(LDRIVE) + CP C + JR NZ,.loop + SCF + RET +; Номер последнего диска в системе +LDRIVE: DB DSS_MAX_DRIVES_AMOUNT + IF COMPILE_UNUSED_CODE +TDRIVE: DB #00 +TCLUST: DW #0000 +TCOUNT: DW #0000 + ENDIF +; \ No newline at end of file diff --git a/DSS/API/curDisk.asm b/DSS/API/curDisk.asm new file mode 100644 index 0000000..7bc73e1 --- /dev/null +++ b/DSS/API/curDisk.asm @@ -0,0 +1,16 @@ +;///////////////////////////////////////////////////////////////////// +; Функция #02. Номер текущего диска. +; +; вход: нет +; выход: A - номер диска (0=A,1=B,..) +;///////////////////////////////////////////////////////////////////// +CURDISK_FN: + LD A,(CurrentPath) + SUB 'A' + RET NC + LD A,DSS_Error.sys.INVALID_DRIVE + RET +CURDISK: LD A,(FatBuffer.DRIVE) + AND A + RET +; \ No newline at end of file diff --git a/DSS/API/diskINF.asm b/DSS/API/diskINF.asm new file mode 100644 index 0000000..0f33db5 --- /dev/null +++ b/DSS/API/diskINF.asm @@ -0,0 +1,139 @@ +;///////////////////////////////////////////////////////////////////// +; [ ] новая подфункция с битом 7 в рег. А +; Возвращает информацию об общем и свободном пространстве дискового +; устройства. +; +; вход: A - номер диска (0=A,1=B .. 25=Z. #FF-текущий) +; При A bit7 = 1: +; HL - буфер (256 байтов) для расширенных данных: +; B != 0 - считать свободное место +; ; +; размер поля - 1 байт +; Файловая система +; ; +; размер поля - 1 байт +; Серийный номер диска +; ; +; размер поля - 1 байт +; Метка диска +; ; +; размер поля - 1 байт +; Зарезервировано... +; ; +; A xor #80 - номер диска +; +; выход: A - размер кластера в секторах, если CF=0 +; HL - общее кол-во кластеров +; DE - свободных кластеров +; BC - размер сектора в байтах +; A - код ошибки, если CF=1 +;///////////////////////////////////////////////////////////////////// + ; [ ] 22/11/23 подфункция с доп.инфой + MACRO _mCOPY_LOOP + LD C,A + LD B,0 + LD (DE),A + INC DE + LDIR +; .loop: +; LD (HL),A +; INC DE +; INC HL +; LD A,(DE) +; DJNZ .loop + ENDM + ; +DISKINF:; [ ] 22/11/23 подфункция с доп.инфой + LD C,B + LD B,1 + ; + CP #80 + JR C,.CustomDisk + CP #FF + JR Z,.CurrentDisk + ; more info + LD B,C + PUSH HL + AND %0111'1111 + CALL .CustomDisk + JR C,.error + ; + EX (SP),HL + PUSH AF + PUSH DE + PUSH BC + ;;;; + ; + EX DE,HL + LD HL,CORE_BUFFERS.BootSector.ID_FAT + LD A,8 ;!HARDCODE _sBOOT_SEC.ID_FAT.length + _mCOPY_LOOP + ; + LD HL,CORE_BUFFERS.BootSector.BPB_SERIAL_NUMBER + LD A,4 ;!HARDCODE _sBOOT_SEC.BPB_SERIAL_NUMBER + _mCOPY_LOOP + ; + LD HL,CORE_BUFFERS.BootSector.BPB_LABEL + LD A,11 ;!HARDCODE _sBOOT_SEC.BPB_LABEL + _mCOPY_LOOP + ; + + XOR A + LD (DE),A + ;;;; + POP BC + POP DE + POP AF +.error: POP HL + RET + ; + + ;CP #FF ; !FIXIT WorkDirectory + ;!TEST Current Dir + ;JR Z,CURRDS ;R06 +.CurrentDisk: + LD A,(CurrentPath) + SUB 'A' + LD HL,FatBuffer.DRIVE + CP (HL) + JR Z,.CheckFreeSpace + ; +.CustomDisk: + PUSH BC + CALL CHNDISK ;R06 + POP BC + RET C ;R06 + ; +.CheckFreeSpace: + ; + XOR A + OR B + CALL NZ,.CURRDS + ; + ; +.FRESP2: + LD D,B + LD E,C + LD HL,(FAT_Max_Cluster) + DEC HL + LD BC,(CORE_BUFFERS.BootSector.B_P_S) + LD A,(CORE_BUFFERS.BootSector.S_P_C) + AND A + RET + ; +.CURRDS: + LD HL,2 + LD BC,0 +.FRESP: PUSH BC + CALL R_F_FAT + POP BC + CP DSS_Error.sys.DISK_FULL + RET Z + + LD A,E + OR D + JR NZ,.SKIC + INC BC +.SKIC: INC HL + JP .FRESP +; \ No newline at end of file diff --git a/DSS/DOS5.ASM b/DSS/DOS5.ASM deleted file mode 100644 index d28b2e5..0000000 --- a/DSS/DOS5.ASM +++ /dev/null @@ -1,2397 +0,0 @@ - -;[BEGIN] -;//MODULE: DOS5 -;//CREATE: 19-05-1998 AUTHOR: Denis Parinov -;//UPDATE: 24-10-1999 DNS Restore module -;------------------------------------------------------------- -;Rev Date Name Description -;------------------------------------------------------------- -;R11 17-04-2023 BAO Временный костыль для недопускания переполнения буфера пути каталога -;R10 15-04-2023 BAO FIXED BUG WITH CHANGE DISK WITHOUT CHANGE PATH -;R09 13-04-2023 BAO FIX BUG WITH PARSING DIRECTORY BUFFER -;R08 15-04-2003 DNS SAVE AND RESTORE CUR-PATH MACROS -;R07 06-02-2003 DNS FIX BUG IN MASK ROUTINE, IT ALLOW NAMES WHICH BEGAN -; FROM "." ".NAM" -;R06 29-01-2003 DNS FIX BUG WITH SET FILE DATE AND TIME -;R05 26-11-2002 DNS FIX ERROR IN CHDIR, DON'T ALLOWED "." FOR ROOT -;R04 19-11-2002 DNS DON'T ALLOW DIR & LABEL ATTR FOR FILES -;R03 19-11-2002 DNS ADD RESET OF VOLUME LABEL ATTRIBUT -;R02 19-11-2002 DNS FIX GET/SET ATTRIBUTES -;R01 16-12-1999 DNS Y2K fix -;------------------------------------------------------------- - - -//////////////////////////////////////////////////////////////////////// -; INPUT: HL - "C:\DIR1\DIR2\filename.ext",#00 -; A - ATTRIB -; B - MODE -; B = 0 GET ATTRIB -; B = 1 SET ATTRIB -; OUTPUT: A - ATTRIB -//////////////////////////////////////////////////////////////////////// -ATTRIB: ;!TEST Current Dir ;[x] 15/10/23 - LD C,A - PUSH HL - PUSH BC - CALL DIR_PATH_CHECK - POP BC - POP HL - RET C - LD A,C - ; - ; - INC B - DEC B - JP Z,.RATTRIB - DEC B - JP Z,.WATTRIB - LD A,DSS_Error.sys.INVALID_FUNCTION - SCF - RET -.RATTRIB: - ;!TEST ;[x] 16/11/23 optimize get attribute - ;XOR A - ; - CALL .OPENATR ;R02 - RET C - ;!TEST ;[x] 16/11/23 optimize get attribute - LD A,(HANDBUF+_sFM.ATTRIBUT) - ;LD B,(IY+_sFM.ATTRIBUT) - ;PUSH BC - ;CALL CLOSE - ;POP BC - ;RET C - ;LD A,B - ; - RET -.WATTRIB: - PUSH AF - XOR A - ;!TEST ;[x] 16/11/23 optimize get attribute - LD (OPEN.TMP),A - ; - CALL .OPENATR ;R02 - ;!TEST ;[x] 16/11/23 optimize get attribute - CALL NC,OPEN.FM - ; - POP BC - RET C - SET 7,(IY+_sFM.ACCESS_MODE) - RES 3,B ;CLEAR LABEL ATTR ;R03 ;!HARDCODE attribute bit - LD (IY+_sFM.ATTRIBUT),B - PUSH BC - CALL CLOSE -.error: POP BC - RET C - LD A,B - RET -;R02 -.OPENATR: - ;!TEST ;[x] 16/11/23 optimize get attribute - ;LD (OPEN.TMP),A ; раб. ячейка (здесь атрибут записи) - ; - CALL GETWORD ; тест на допуст. имя и настр. на диск - RET C - CALL MASK - RET C - LD A,FAT_ATTR.NoVolID - ;!TEST ;[x] 16/11/23 optimize get attribute - JP SEARCH.Custom - ;CALL SEARCH.Custom - ;RET C ; запись не найдена - ;JP OPEN.FM ; на поиск своб. дескриптора - ; - ; -;R02 - -//////////////////////////////////////////////////////////////////////// -; INPUT: HL - "C:\DIR1\DIR2\filename.ext",#00 -; OUTPUT: A - FM -//////////////////////////////////////////////////////////////////////// -CREATE: ;!TEST Current Dir ;[x] 15/10/23 - PUSH HL - CALL DIR_PATH_CHECK - POP HL - RET C - ; - CALL .Prepare - RET C - CALL SEARCH.File - CALL NC,DELETE ;FILE EXIST RECREAT - JR .DO - ; -; INPUT: HL - "C:\DIR1\DIR2\filename.ext",#00 -; OUTPUT: A - FM -.NEW: ;!TEST Current Dir ;[x] 15/10/23 - PUSH HL - CALL DIR_PATH_CHECK - POP HL - RET C - ; - CALL .Prepare - RET C - CALL SEARCH.File - LD A,DSS_Error.sys.FILE_EXISTS - CCF - RET C - ; -.DO: LD HL,MASKARE - LD DE,HANDBUF - LD BC,11 - LDIR - EX DE,HL -.TMP+1: LD A,0 - LD (HL),A - INC HL - LD BC,#0A00 ;!HARDCODE - ; -.loop1: LD (HL),C - INC HL - DJNZ .loop1 - ; - PUSH HL - CALL SYSTIME - CALL MK_TIME - POP HL - LD (HL),E - INC HL - LD (HL),D - INC HL - LD (HL),C - INC HL - LD (HL),B - INC HL - LD BC,#0600 - ; -.loop2: LD (HL),C - INC HL - DJNZ .loop2 - ; - CALL WRT_HND - RET C - ;CALL SAVEDIR -.PATH0+1: - LD HL,0 - XOR A - LD (OPEN.TMP),A - JP OPEN.FILE ;R08 -.Prepare: - AND #E7 ;R04 %76A00SHR = !FAT_ATTR ;!HARDCODE - LD (.TMP),A - LD (.PATH0),HL - CALL GETWORD - RET C - ; LD HL,TMPNAME - ; LD DE,MASKARE - JP MASK -CREAT_N EQU CREATE.NEW - - -//////////////////////////////////////////////////////////////////////// -; INPUT: HL - "c:\dir\filename.ext",#00 without simbols * ? -//////////////////////////////////////////////////////////////////////// -DEL_FN: ;!TEST - ;!TEST Current Dir ;[x] 15/10/23 - PUSH HL - CALL DIR_PATH_CHECK - POP HL - RET C - ; - CALL GETWORD ; тест на допуст. имя и настр. на диск - RET C - CALL MASK - RET C - ; - ;!TEST optimization - ;LD HL,MASKARE - ;LD BC,11 - ;LD A,"?" - ;CPIR - ;LD A,DSS_Error.sys.INVALID_NAME - ;SCF - CALL CHECK_NAME - ; - RET Z - CALL LOADDIR - CALL SEARCH.File - RET C - ;JP DELETE -; пометить запись как "удаленная" -DELETE: SET_PAGE_X DIRPAGE - LD (IX+_sFM.NAME),#E5 ; признак удаления файла - LD E,(IX+_sFM.ST_CLUSTER) ; № первого кластера - LD D,(IX+_sFM.ST_CLUSTER+1) - ; - OUT (SLOT3),A - LD A,E - OR D - JP Z,SAVEDIR ; сбросить кеш каталога на диск -.loop: EX DE,HL ; hl=номер кластера - CALL R_F_FAT ; прочитать из кеша FAT-а номер след. кластера - PUSH DE ; номер след. кластера - PUSH AF - LD DE,#0000 ; номер кластера - CALL W_T_FAT ; записать в кеш FAT-а номер кластера - POP AF - POP DE - JP NC,.loop - CALL WR_FAT - JP SAVEDIR ; сбросить кеш каталога на диск - -//////////////////////////////////////////////////////////////////////// -; Функция #10. Переименование файла. -; Глобальные символы * и ? в именах файлов не допускаются. -; -; вход: HL - указатель на старое имя файла -; DE - указатель на новое имя файла -; выход: A - код ошибки, если CF=1 -; -; INPUT: HL - "old_name.ext",#00 without simbols * ? -; DE - "new_name.ext",#00 without simbols * ? -//////////////////////////////////////////////////////////////////////// -RENAME: ;!TEST Current Dir ;[x] 15/10/23 - PUSH HL - PUSH DE - CALL DIR_PATH_CHECK.forceCheck - POP DE - POP HL - RET C - ; - PUSH DE - ;LD DE,MASKARE - CALL MASK.name - POP DE - RET C - ;!TEST optimization - ;LD HL,MASKARE - ;LD BC,11 - ;LD A,"?" - ;CPIR - ;LD A,DSS_Error.sys.INVALID_NAME - ;SCF - CALL CHECK_NAME - ; - RET Z - PUSH DE - CALL LOADDIR ; прочитать список каталога - ;LD A,#33 - LD A,FAT_ATTR.NoSYSnoVolID - CALL SEARCH.Custom ; поиск записи в списке диска - POP HL - RET C - ;LD DE,MASKARE - CALL MASK.name - RET C - ;!TEST optimization - ;LD HL,MASKARE - ;LD BC,11 - ;LD A,"?" - ;CPIR - ;LD A,DSS_Error.sys.INVALID_NAME - ;SCF - CALL CHECK_NAME - ; - RET Z - PUSH IX - LD A,FAT_ATTR.NoSYSnoVolID - CALL SEARCH.Custom ; поиск записи в списке диска - POP IX - LD A,DSS_Error.sys.FILE_EXISTS - CCF - RET C - - SET_PAGE_X DIRPAGE - - LD HL,MASKARE - LD D,XH - LD E,XL - LD BC,11 - LDIR - OUT (SLOT3),A - JP SAVEDIR - -//////////////////////////////////////////////////////////////////////// -; Функция #11. Открытие файла. -; -; вход: HL - указатель на имя файла -; A - режим доступа: -; A=0 чтение/запись -; A=1 чтение -; A=2 запись -; выход: CF=0, A - дескриптор файла. -; CF=1, A - код ошибки. -//////////////////////////////////////////////////////////////////////// -OPEN_FN:;!TEST Current Dir ;[x] 15/10/23 - LD (OPEN.TMP),A - PUSH HL - CALL DIR_PATH_CHECK.forceCheck - POP HL - RET C - JR OPEN.start - ;!FIXIT сделать как в mkdir или rmdir? - ; -;R08 -OPEN: LD (.TMP),A ; enter point from CREATE -.start: CALL GETWORD - RET C - CALL MASK ; enter point from OPEN_FN - RET C -.FILE: CALL SEARCH.File ; enter point from EXEC - RET C -;R02 -.FM: CALL GET_FM ; enter point from ATTRIB - RET C - LD A,C - EX AF,AF' - EXX - LD (IY+_sFM.HANDLE),E - LD (IY+_sFM.HANDLE+1),D - EXX - LD D,YH - LD E,YL - LD HL,HANDBUF - LD BC,HANDBUF.SIZE - LDIR -.TMP+1: LD A,0 - LD (IY+_sFM.ACCESS_MODE),A - LD A,(TASK) - LD (IY+_sFM.TASK_NUM),A - XOR A - ; - LD (IY+_sFM.KnownCluster_L),A - LD (IY+_sFM.KnownCluster_H),A - LD (IY+_sFM.KnownOffset_L),A - LD (IY+_sFM.KnownOffset_H),A - ; - LD (IY+_sFM.F_POSITION),A - LD (IY+_sFM.F_POSITION+1),A - LD (IY+_sFM.F_POSITION+2),A - LD (IY+_sFM.F_POSITION+3),A - LD A,(FatBuffer.DRIVE) - LD (IY+_sFM.DRIVE),A - LD HL,CORE_BUFFERS.FM_BUF+_sFM.ST_CLUSTER - LD E,(HL) - INC HL - LD D,(HL) - LD (IY+_sFM.DIR_CLUSTER),E - LD (IY+_sFM.DIR_CLUSTER+1),D - EX AF,AF' - AND A - RET - -//////////////////////////////////////////////////////////////////////// -;Входные значения: -; C - #12 -; A - файловый манипулятор -;Выходные значения: -; A - код ошибки, если CF=1 -//////////////////////////////////////////////////////////////////////// -CLOSE_FN: -;R08 -CLOSE: LD (.TMP),A - CALL SET_FM - RET C - LD A,(TASK) - CP (IY+_sFM.TASK_NUM) - LD A,DSS_Error.sys.ACCESS_DENIED - SCF - RET NZ - BIT 7,(IY+_sFM.ACCESS_MODE) - JR Z,.NOTMODF - LD E,(IY+_sFM.DIR_CLUSTER) - LD D,(IY+_sFM.DIR_CLUSTER+1) - PUSH DE - ; [x] 15/11/2023 -bug with bad clusters ;!TEST - LD A,(IY+_sFM.DRIVE) - CALL OPENDSK - ; - XOR A - CALL SET_FM - POP DE - LD (IY+_sFM.DIR_CLUSTER),E - LD (IY+_sFM.DIR_CLUSTER+1),D - ; [x] 15/11/2023 -bug with bad clusters ;!TEST - LD (IY+_sFM.ST_CLUSTER),E - LD (IY+_sFM.ST_CLUSTER+1),D - ; - CALL LOADDIR -.TMP+1: LD A,0 - CALL SET_FM - ; - SET_PAGE_X DIRPAGE - ; - ;TEST 9/11/23 - ; LD HL,DIR - ; LD DE,#0020 - ; LD C,(IY+_sFM.HANDLE) - ; LD B,(IY+_sFM.HANDLE+1) - ; JR .CLOSE2 - ; .CLOSE1: - ; ADD HL,DE - ; DEC BC - ; .CLOSE2: - ; LD A,B - ; OR C - ; JR NZ,.CLOSE1 - LD L,(IY+_sFM.HANDLE) - LD H,(IY+_sFM.HANDLE+1) - ; - LD D,YH - LD E,YL - EX DE,HL - ;PUSH HL - ;SET_PAGE_X DIRPAGE - ;POP HL - LD BC,#0020 ;!HARDCODE - LDIR - OUT (SLOT3),A - CALL SAVEDIR -.NOTMODF: - LD A,(.TMP) - CALL RES_FM - RET - -//////////////////////////////////////////////////////////////////////// -;Входные значения: -; C - #19 -; HL - указатель на файловую спецификацию -; DE - рабочий буфер 44 байта, если B=0, иначе 256 байт -; ;!!!!! на самом деле сейчас если B=1, рабочий буфер 46 байт -; A - атрибуты, используемые при поиске -; B = 0 - имя найденного файла в формате 11 байт "FilenameExt" -; B = 1 - имя найденного файла в формате DOS "filename.ext",0 -;Выходные значения: -; A - код ошибки, если CF=1 -//////////////////////////////////////////////////////////////////////// -F_FIRST: - ; Current Dir [x] 15/10/23 - ; LD C,A - ; PUSH HL - ; PUSH DE - ; PUSH BC - ; CALL DIR_PATH_CHECK - ; POP BC - ; POP DE - ; POP HL - ; RET C - ; LD A,C - ; ; - LD (.TMP),A - LD (.DTABUF),DE - LD A,B - LD (.FNDMODE),A - PUSH HL - ;!TEST Current Dir ;[x] 15/10/23 - CALL DIR_PATH_CHECK - RET C - ; - CALL LOADDIR - POP HL - CALL GETWORD - RET C - CALL MASK - RET C - LD A,(.TMP) - CALL SEARCH.Custom - RET C - LD HL,MASKARE -.DTABUF+1: - LD DE,0 - LD BC,11 ;!HARDCODE - LDIR -.TMP+1: LD A,0 - LD (DE),A -.FIND_S: - INC DE - LD BC,#0020 - ADD IX,BC - LD (F_NEXT.CURHND),IX - LD HL,HANDBUF+12 ;!HARDCODE - LD BC,HANDBUF.SIZE-12 ;????? метку вместо числа? - LDIR - LD A,(HANDBUF+11) - LD (DE),A - INC DE - LD HL,HANDBUF -.FNDMODE+1: - LD A,0 - OR A - JR NZ,.FIND_M2 - LD BC,11 ;!HARDCODE - LDIR - LD A,F_NEXT.NO_NEXT.NO - LD (F_NEXT.NO_NEXT),A - XOR A - RET -.FIND_M2: - CALL GETNAME - LD A,F_NEXT.NO_NEXT.NO - LD (F_NEXT.NO_NEXT),A - XOR A - RET - -//////////////////////////////////////////////////////////////////////// -; -; -//////////////////////////////////////////////////////////////////////// -F_NEXT: -.NO_NEXT.YES EQU 0 -.NO_NEXT.NO EQU #FF -.NO_NEXT+1: - LD A,0 - OR A - LD A,DSS_Error.sys.INVALID_ACCESS - SCF - RET Z - LD (F_FIRST.DTABUF),DE - EX DE,HL - LD DE,MASKARE - LD BC,11 ;!HARDCODE - LDIR - - XOR A ; F_NEXT.NO_NEXT.YES - LD (F_NEXT.NO_NEXT),A - - LD A,(HL) - PUSH HL - CALL .NSEARCH - POP DE - RET C - JP F_FIRST.FIND_S -.NSEARCH: - EX AF,AF' - SET_PAGE_X DIRPAGE - ;PUSH AF - EX AF,AF' - CPL - LD C,A - ;TEST 9/11/23 - ; EXX - ; LD DE,0 - ; EXX - ; -.CURHND+2: - LD IX,0 - LD A,XH - OR XL - JP Z,SEARCH.error_too_many_files - JP SEARCH.loop - -//////////////////////////////////////////////////////////////////////// -; -; -//////////////////////////////////////////////////////////////////////// -CHNDISK_FN: - CALL CHNDISK - RET C - PUSH AF - CALL DIR_PATH_CHANGE.FullCurrent - POP AF - RET -CHNDISK:;[x] более корректная смена диска - CALL OPENDSK - ; - ;R10 - RET C - LD HL,WorkDirectory - LD (HL),0 - PUSH AF - CALL OPENDIR - POP BC - RET C - LD A,B - RET - -//////////////////////////////////////////////////////////////////////// -; Функция #1E. Информация о текущем каталоге. -; -; вход: HL - буфер в памяти 256 байт -; выход: A - код ошибки, если CF=1 -//////////////////////////////////////////////////////////////////////// -CURRDIR: LD DE,WorkDirectory - JR CURRDIR_FN.skip -CURRDIR_FN: - LD DE,CurrentDirectory -.skip: EX DE,HL - LD BC,DIRECTORY_PATH_LENGTH ;[x] 15/11/2023 могло выйти за пределы буфера - XOR A -.loop: CP (HL) - LDI - JP PO,.error ;[x] 15/11/2023 могло выйти за пределы буфера - JR NZ,.loop - RET - ;[x] 15/11/2023 могло выйти за пределы буфера -.error: LD A,DSS_Error.sys.TOO_DEEP_DIR_DEPTH - SCF - RET - ; -//////////////////////////////////////////////////////////////////////// -; Функция #21. Текущая дата и время. -; -; вход: нет -; выход: D - день -; E - месяц -; IX - год -; H - час -; L - минуты -; B - секунды -; C - день недели -//////////////////////////////////////////////////////////////////////// -SYSTIME: - LD C,BIOS.CMOS_TEST - RST ToBIOS - JP C,.NOCMOS - LD D,7 ;DAY - CALL RCMOS - PUSH AF - LD D,8 ;MONTH - CALL RCMOS - POP DE - LD E,A - PUSH DE - LD D,4 ;HOUR - CALL RCMOS - PUSH AF - LD D,2 ;MINUTE - CALL RCMOS - POP DE - LD E,A - PUSH DE - LD D,0 ;SECOND - CALL RCMOS - PUSH AF - LD D,6 ;WEEK DAY - LD C,BIOS.CMOS_RD - RST ToBIOS - POP DE - LD E,A - PUSH DE - LD D,9 ;YEAR - CALL RCMOS ;READ AND CONVERT TO DECIMAL - PUSH AF - LD D,#32 ;CENTURY - LD C,BIOS.CMOS_RD - RST ToBIOS - LD XH,A - - POP AF - CP 80 ;R01, TEST DECIMAL FIX - PUSH AF - JR C,.XXIAGE - LD A,#19 - CP XH - JR Z,.GOODAGE - JR .BADAGE -.XXIAGE: - LD A,#20 - CP XH - JR Z,.GOODAGE -.BADAGE: - PUSH AF - LD D,#32 ;CENTURY - LD C,BIOS.CMOS_WR - RST ToBIOS - POP AF - LD XH,A -.GOODAGE: - POP AF - LD XL,A - LD A,XH - CALL BCD2HEX - LD L,A - LD H,0 - LD C,L - LD B,H - LD XH,B - ADD HL,HL - ADD HL,HL - ADD HL,BC - ADD HL,HL ;*10 - LD B,H - LD C,L - ADD HL,HL - ADD HL,HL - ADD HL,BC - ADD HL,HL ;*10(100) - EX DE,HL - ADD IX,DE - POP BC - POP HL - POP DE - AND A - RET -.NOCMOS: -.NC_DAY+1: - LD DE,DAY*256+MONTH ;DAY/MONTH -.NC_HOUR+1: - LD HL,0 ;HOUR/MINUTE -.NC_SEC+1: - LD BC,1 ;SECOND/WEEKDAY -.NC_YEAR+2: - LD IX,YEAR ;YEAR - AND A - RET - -//////////////////////////////////////////////////////////////////////// -; Функция #22. Установить текущую дату и время. -; -; вход: D - день -; E - месяц -; IX - год -; H - час -; L - минуты -; B - секунды -; выход: A - код ошибки, если CF=1 -//////////////////////////////////////////////////////////////////////// -SETTIME: - PUSH IX - PUSH BC - PUSH HL - PUSH DE - LD C,BIOS.CMOS_TEST - RST ToBIOS - JP C,.NOCMOS2 - POP AF - PUSH AF - LD D,7 ;DAY - CALL WCMOS - POP BC - LD A,C - LD D,8 ;MONTH - CALL WCMOS - POP AF - PUSH AF - LD D,4 ;HOUR - CALL WCMOS - POP BC - LD A,C - LD D,2 ;MINUTE - CALL WCMOS - POP AF - PUSH AF - LD D,0 ;SECOND - CALL WCMOS - POP BC - LD A,C - LD D,6 ;WEEK DAY - LD C,BIOS.CMOS_WR - RST ToBIOS - ; - POP HL - XOR A - LD DE,100 -.YR: INC A - SBC HL,DE - JR NC,.YR - ADD HL,DE - DEC A - PUSH HL - LD D,#32 ;CENTURY - CALL WCMOS - POP BC - LD A,C - LD D,9 ;YEAR - CALL WCMOS - AND A - RET -; !FIXIT новый биос выставляет время, если с ним что-то не так. -.NOCMOS2: - LD C,0 - LD (SYSTIME.NC_DAY),DE ;DAY/MONTH - LD (SYSTIME.NC_HOUR),HL ;HOUR/MINUTE - LD (SYSTIME.NC_SEC),BC ;SECOND/WEEKDAY - LD (SYSTIME.NC_YEAR),IX ;YEAR - AND A - RET - -; Дата по-умолчанию -; NC_DAY DW DAY*256+MONTH ;DAY/MONTH -; NC_HOUR DW #0000 ;HOUR/MINUTE -; NC_SEC DW #0001 ;SECOND/WEEKDAY -; NC_YEAR DW YEAR ;YEAR - -//////////////////////////////////////////////////////////////////////// -; Функция #17. Информация о дате и времени файла. -; -; вход: A - дескриптор файла -; выход: D - день -; E - месяц -; IX - год -; H - час -; L - минуты -; B - секунды -; A - код ошибки, если CF=1 -//////////////////////////////////////////////////////////////////////// -GET_D_T: - CALL SET_FM - RET C - ; время/дату из структуры дескр. - LD E,(IY+_sFM.TIME) ; время - LD D,(IY+_sFM.TIME+1) ; - LD C,(IY+_sFM.DATE) ; дата - LD B,(IY+_sFM.DATE+1) ; - CALL RMKTIME ; раскодировать время/дату - AND A - RET - -//////////////////////////////////////////////////////////////////////// -; Функция #18. Изменение даты и времени файла. -; -; вход: A - дескриптор файла -; D - день -; E - месяц -; IX - год -; H - час -; L - минуты -; B - секунды -; выход: A - код ошибки, если CF=1 -//////////////////////////////////////////////////////////////////////// -PUT_D_T: - PUSH AF - CALL MK_TIME ; закодировать время/дату - POP AF ; дескриптор - PUSH DE - PUSH BC - CALL SET_FM - POP BC - POP DE - RET C - LD (IY+_sFM.TIME),E - LD (IY+_sFM.TIME+1),D - LD (IY+_sFM.DATE),C - LD (IY+_sFM.DATE+1),B - SET 7,(IY+_sFM.ACCESS_MODE) ;R06 ; уст. признак изменения файла - AND A - RET - -//////////////////////////////////////////////////////////////////////// -; Функция #1D. Смена текущего каталога. -; Меняет текущий каталог и текущий диск, если он указан в файловой -; спецификации. Если путь начинается с "\" - это означает путь от -; корневого каталога, иначе от текущего. -; -; вход: HL - указатель на имя каталога -; выход: нет -; -; INPUT: HL - "C:\DIR\DIR\DIR_NAME[\]",0 -//////////////////////////////////////////////////////////////////////// -CHDIR_FN: - ;!TEST Current Dir ;[x] 15/10/23 - PUSH HL - CALL DIR_PATH_CHECK - POP HL - RET C - CALL CHDIR - ; если удачно, то копируем WorkDirectory в CurrentDirectory - JP NC,DIR_PATH_CHANGE.FullCurrent - ; если неудачно, то возвращаемся туда откуда пришли - PUSH AF - LD HL,CurrentDirectory - CALL CHDIR - POP AF - RET - ; -CHDIR: CALL GETWORD ; тест на допуст. имя и настр. на диск - RET C - LD HL,TMPNAME - LD A,(HL) - OR A - CALL NZ,OPENDIR - RET - - -//////////////////////////////////////////////////////////////////////// -; Функция #1B. Создание каталога. -; -; вход: HL - указатель на имя каталога -; выход: A - код ошибки, если CF=1 -; -; INPUT: HL - "C:\DIR\DIR\DIR_NAME",0 -//////////////////////////////////////////////////////////////////////// -MKDIR: ;!TEST Current Dir ;[x] 15/10/23 - PUSH HL - CALL DIR_PATH_CHECK - POP HL - RET C - CALL .START - PUSH AF - LD HL,CurrentDirectory - CALL CHDIR - POP AF - RET - ; -.START: CALL GETWORD ; тест на допуст. имя и настр. на диск - RET C - ;LD HL,TMPNAME ; 8.3 имя - ;LD DE,MASKARE ; буфер имени 11 симв. формата - CALL MASK ; преобр. имя 8.3 -> 11 формат - RET C - ;!TEST optimization ранее GETWORD уже загрузил директорию - ;CALL LOADDIR ; прочитать список каталога - ; - CALL SEARCH.Dir ; поиск записи каталога в списке диска - LD A,DSS_Error.sys.DIR_EXISTS - CCF - RET C ; каталог найден - ; - CALL G_CLUST - RET C - PUSH HL - LD DE,(FatBuffer.ENDCLUS) ; номер кластера - CALL W_T_FAT ; записать в кеш FAT-а номер кластера - CALL WR_FAT ; подкл. банку кеша FAT и записать его на диск - LD HL,MASKARE - LD DE,HANDBUF - LD BC,11 - LDIR - EX DE,HL - LD A,#10 ; атрибут записи каталога - LD (HL),A - INC HL - LD BC,#0A00 ; b=счетчик - ; -.loop1: LD (HL),C - INC HL - DJNZ .loop1 - ; - PUSH HL - CALL SYSTIME ; узнать тек. дату и время - CALL MK_TIME ; закодировать время/дату - POP HL - LD (HL),E ; de=время - INC HL - LD (HL),D - INC HL - LD (HL),C ; день - INC HL - LD (HL),B ; месяц - INC HL - POP DE - PUSH DE - LD (HL),E - INC HL - LD (HL),D - INC HL - LD BC,#0400 ; b=счетчик - ; -.loop2: LD (HL),C - INC HL - DJNZ .loop2 - ; - CALL WRT_HND ; скопир. новую запись в список диска (каталога) - ;CALL SAVEDIR ; и сбросить кеш каталога на диск - LD HL,CORE_BUFFERS.SECBUF ; буфер - LD (HL),"." ; запись тек. каталога - LD BC,10*256 + ' ' ; b=счетчик, c=пробел - ; -.loop3: INC HL - LD (HL),C - DJNZ .loop3 - ; - INC HL - LD DE,HANDBUF+11 ; ячейка атрибутов файла - EX DE,HL - LD BC,21 - LDIR - EX DE,HL - LD (HL),"." ; запись родит. каталога - INC HL - LD (HL),"." - LD BC,9*256 + ' ' ; b=счетчик, c=пробел -.MKD03: INC HL - LD (HL),C - DJNZ .MKD03 - ; - INC HL - SET_PAGE_X DIRPAGE - PUSH AF - ; - LD A,(DIRPAGE.buffer) - CP "." - LD DE,DIRPAGE.buffer+11 ; атрибуты записи ;!HARDCODE - JP Z,.MKD04 - LD IX,HANDBUF - XOR A - LD (IX+_sFM.ST_CLUSTER),A - LD (IX+_sFM.ST_CLUSTER+1),A - LD DE,HANDBUF+11 ; ячейка атрибутов файла -.MKD04: EX DE,HL - LD BC,HANDBUF.SIZE-11 - LDIR - POP AF - OUT (SLOT3),A - ; - EX DE,HL - LD D,H - LD E,L - INC DE - LD (HL),0 - LD BC,512-65 ;!HARDCODE - LDIR - ; - POP HL - CALL NSECTOR - LD A,(CORE_BUFFERS.BootSector.S_P_C) ; секторов на кластер -.MKD12: PUSH AF - PUSH HL ; ст. разряд - PUSH IX ; номер лог. сектора - IN A,(SLOT3) - PUSH AF - IN A,(SLOT0) - OUT (SLOT3),A - ; - LD A,(FatBuffer.DRIVE) - LD DE,CORE_BUFFERS.SECBUF+#C000 - LD BC,1*256 + Dss.DRV.Write - RST ToDSS.DRV - ; - POP AF - OUT (SLOT3),A - ; - LD HL,CORE_BUFFERS.SECBUF - LD DE,CORE_BUFFERS.SECBUF+1 - LD BC,511 - LD (HL),0 - LDIR - ; - POP IX - POP HL - INC IX - LD A,XH - OR XL - JR NZ,.MKD11 - INC HL -.MKD11 POP AF - DEC A - JR NZ,.MKD12 - AND A - RET - - -//////////////////////////////////////////////////////////////////////// -; Функция #1C. Удаление каталога. -; Можно удалить только пустой каталог. -; -; вход: HL - указатель на имя каталога -; выход: A - код ошибки, если CF=1 -; -; INPUT: HL - "C:\DIR\DIR\DIR_NAME",0 -//////////////////////////////////////////////////////////////////////// -RMDIR: ;!TEST Current Dir ;[x] 15/10/23 - PUSH HL - CALL DIR_PATH_CHECK - POP HL - RET C - CALL .START - PUSH AF - LD HL,CurrentDirectory - CALL CHDIR - CALL DIR_PATH_CHANGE.Current - POP AF - RET - ; -.START: CALL GETWORD - RET C - CALL MASK - RET C - ;!TEST optimization - ;LD HL,MASKARE - ;LD BC,11 - ;LD A,"?" - ;CPIR - ;LD A,DSS_Error.sys.INVALID_NAME - ;SCF - CALL CHECK_NAME - ; - RET Z - CALL LOADDIR - CALL SEARCH.Dir - RET C - LD HL,(HANDBUF+_sFM.ST_CLUSTER) - PUSH IX -.RMD17: PUSH HL - CALL NSECTOR - LD A,(CORE_BUFFERS.BootSector.S_P_C) -.RMD12: PUSH AF - PUSH HL - PUSH IX - IN A,(SLOT3) - PUSH AF - IN A,(SLOT0) - OUT (SLOT3),A - - LD DE,CORE_BUFFERS.SECBUF+#C000 - LD BC,1*256 + Dss.DRV.Read - LD A,(FatBuffer.DRIVE) - RST ToDSS.DRV - - POP AF - OUT (SLOT3),A - - LD B,16 ;!HARDCODE 16 * 32 = 512; 32 - размер записи, 512 - размер считанного сектора - LD HL,CORE_BUFFERS.SECBUF -.RMD10: LD A,(HL) - OR A - JP Z,.RMD15 ;DIR EMPTY - CP "." - JR Z,.RMD14 - CP #E5 ;!HARDCODE байт удаления файла - JR Z,.RMD14 - LD DE,11 ;!HARDCODE смещ. до байта атрибутов - ADD HL,DE - LD A,(HL) - SBC HL,DE - ;BIT 3,A - AND %0000'1000 - JP Z,.error ;DIR NOT EMPTY -.RMD14: LD DE,#0020 - ADD HL,DE - DJNZ .RMD10 - - POP IX - POP HL - INC IX - LD A,XH - OR XL - JR NZ,.RMD11 - INC HL -.RMD11: POP AF - DEC A - JR NZ,.RMD12 - POP HL ; номер кластера - CALL R_F_FAT ; прочитать из кеша FAT-а номер след. кластера - EX DE,HL ; hl=номер след. кластера - JR NC,.RMD17 ; не конец цепочки -.RMD18: POP IX - JP DELETE ; пометить запись как "удаленная" -.RMD15: POP IX - POP HL - POP AF - POP HL - JR .RMD18 -.error: POP IX - POP HL - POP AF - POP HL - POP IX - LD A,DSS_Error.sys.DIR_NOT_EMPTY - SCF - RET - -//////////////////////////////////////////////////////////////////////// -;Входные значения: -; C - #44 -; B = 0, преобразовать из 11 символьного формата в формат ДОС -; HL - 11 символов имени файла -; DE - буфер для имени в формате ДОС -; B = 1, преобразовать из формата ДОС в 11 символьный формат -; HL - имя файла в формате ДОС -; DE - 11 символов имени файла -;Выходные значения: -; A - код ошибки, если CF=1 -//////////////////////////////////////////////////////////////////////// -DOSNAME: - INC B - DEC B - JP Z,GETNAME - DEC B - JP Z,MASK.custom - LD A,DSS_Error.sys.INVALID_FUNCTION - SCF - RET -//////////////////////////////////////////////////////////////////////// - - - - - -;----------------------------------------------------------------------; -; Чтение регистров CMOS -; вход: d=номер регистра -RCMOS: LD C,BIOS.CMOS_RD - RST ToBIOS - ;JP BCD2HEX -; INPUT : A - BCD -; OUTPUT: A - HEX -BCD2HEX: - LD E,A - RRCA - RRCA - RRCA - RRCA - AND #0F - LD D,A - ADD A,A - ADD A,A - ADD A,D - ADD A,A - LD D,A - LD A,E - AND #0F - ADD A,D - RET -;----------------------------------------------------------------------; - - -;----------------------------------------------------------------------; -;!FIXIT переделать по доке на Даллас и заись в ячейки часов -; Запись регистров CMOS -; вход: d=номер регистра -WCMOS: CALL HEX2BCD - LD C,BIOS.CMOS_WR - JP ToBIOS - -; INPUT : A - HEX -; OUTPUT: A - BCD -HEX2BCD: - LD BC,#0AFF -.loop: INC C - SUB B - JR NC,.loop - ADD A,B - LD B,A - LD A,C - RLCA - RLCA - RLCA - RLCA - AND #F0 - OR B - RET -;----------------------------------------------------------------------; - - -;----------------------------------------------------------------------; -; Закодировать время/дату -; вход: de - день/месяц -; hl - часы/минуты -; b - секунды -; ix - год -; выход: de - время -; bc - месяц/день -; ix - год -; -;INPUT: D - DAY; E - MONTH -; H - HOUR; L - MINUTE -; B - SECOND (0...59) -; IX- YEAR (0...65535) -;OUTPUT: DE - hhhhhmmmmmmsssss h - hour, m - min, s - sec/2 -; BC - yyyyyyymmmmddddd y - year, m - month, d - day -; (1980-2108) - -MK_TIME: - LD A,L - RLCA - RLCA - SLA A - RL H - SLA A - RL H - SLA A - RL H - SRL B - OR B - LD L,A - - LD BC,#F844 ;(-1980) - ADD IX,BC - LD A,E - RLCA - RLCA - RLCA - RLCA - AND #F0 - LD B,XL - SLA A - RL B - OR D - LD C,A - EX DE,HL - AND A - RET -;----------------------------------------------------------------------; - - -;----------------------------------------------------------------------; -; Раскодировать время/дату -; вход: de - время -; bc - месяц/день -; ix - год -; выход: de - день/месяц -; hl - часы/минуты -; b - секунды -; ix - год -; -;INPUT: DE - hhhhhmmmmmmsssss h - hour, m - min, s - sec/2 -; BC - yyyyyyymmmmddddd y - year, m - month, d - day -; (1980-2108) -;OUTPUT: D - DAY; E - MONTH -; H - HOUR; L - MINUTE -; B - SECOND (0...59) -; IX- YEAR (0...65535) -RMKTIME: - EX DE,HL - LD A,C - AND #1F - LD D,A - SRL B - RR C - LD A,C - RRCA - RRCA - RRCA - RRCA - AND #0F - LD E,A - LD C,B - LD B,0 - LD IX,1980 - ADD IX,BC - LD A,L - AND #1F - ADD A,A - LD B,A - SRL H - RR L - SRL H - RR L - SRL H - RR L - SRL L - SRL L - AND A - RET -;----------------------------------------------------------------------; - - -;----------------------------------------------------------------------; -; HL - 11 bytes filename "FILENAMEEXT" -; DE - DOS filename "FILENAME.EXT",0 -; GETNAME: -; LD BC,#08FF -; .GETN1: LD A,(HL) -; CP " " -; JR NZ,.GETN3 -; .GETN2: INC HL -; DJNZ .GETN2 -; JR .GETN4 -; .GETN3: LDI -; DJNZ .GETN1 -; ; -; .GETN4: LD A,(HL) -; CP " " -; LD A,"." -; JR NZ,.GETN5 -; LD A,#00 -; .GETN5: LD (DE),A -; INC DE -; RET Z -; LD B,#03 -; .GETN6: LD A,(HL) -; CP " " -; RET Z -; LDI -; XOR A -; LD (DE),A -; DJNZ .GETN6 -; RET -;---------------;---------------;--------------- -GETNAME: - LD BC,#08FF - LD A,' ' -.loop: CP (HL) - JR Z,.skip - LDI - DJNZ .loop - ;;;; - JP .extension - ;;;; -.skip: LD C,B - LD B,0 - ; CF=0 - ADC HL,BC - ;;;; -.extension: - CP (HL) - LD A,"." - JR NZ,.copy_extension - XOR A -.copy_extension: - LD (DE),A - INC DE - RET Z ;no copy extension - ; copy extension - LD BC,#03FF ;!HARDCODE длина расширения + счётчик - LD A,' ' -.loop2: CP (HL) - JR Z,.exit - LDI - DJNZ .loop2 -.exit: XOR A - LD (DE),A - RET -;----------------------------------------------------------------------; - - -;----------------------------------------------------------------------; -; Поиск записи каталога в списке каталога -; -; вход: a=атрибут записи -; выход: de'=индекс записи в списке каталога -; (HANDBUF) = file's direcory record -; CF - каталог не найден -SEARCH: -.Dir: LD A,FAT_ATTR.DIRECTORY - CALL SEARCH.Custom - RET NC - CP DSS_Error.sys.PATH_NOT_FOUND + 1 - RET C - ; - SCF - LD A,DSS_Error.sys.TOO_MANY_FILES_IN_DIR - RET - ; -.File: LD A,FAT_ATTR.NoDIRnoVolID -.Custom: EX AF,AF' ; A = 76ADLSHR - SET_PAGE_X DIRPAGE - ;PUSH AF - EX AF,AF' - ; - CPL - LD C,A - LD IX,DIRPAGE.buffer - ;!TEST 9/11/23 - ; EXX - ; LD DE,0 - ; EXX - ; -.loop: LD A,(IX+00) - OR A - JR Z,.error_file_not_found - CP #E5 ;!HARDCODE #E5 - запись в директории свободна, так как файл/директория были удалены - JR Z,.next_record - LD A,(IX+11) - AND C - JR NZ,.next_record - LD HL,MASKARE - LD D,XH - LD E,XL - LD B,11 - EX DE,HL -.loop_compare: - LD A,(DE) - CP '?' - JR Z,.next_char - CP (HL) - JR NZ,.next_record -.next_char: - INC HL - INC DE - DJNZ .loop_compare - ;!TEST 9/11/23 ;[x] some optimize - ; LD D,XH - ; LD E,XL - LD D,XH - LD E,XL - EXX - LD D,XH - LD E,XL - EXX - ; - LD HL,HANDBUF - EX DE,HL - LD BC,HANDBUF.SIZE - LDIR - ;POP AF - EX AF,AF' - OUT (SLOT3),A - EX AF,AF' - AND A - RET -.next_record: - ;!TEST 9/11/23 ;[x] some optimize - ; EXX - ; INC DE - ; EXX - ; - LD DE,#0020 ;!HARDCODE - ADD IX,DE - JR NC,.loop -.error_too_many_files: - ;POP AF - EX AF,AF' - OUT (SLOT3),A - LD A,DSS_Error.sys.TOO_MANY_FILES_IN_DIR - SCF - RET - ; -.error_file_not_found: - ;POP AF - EX AF,AF' - OUT (SLOT3),A - LD A,DSS_Error.sys.FILE_NOT_FOUND - SCF - RET -;----------------------------------------------------------------------; - - -;----------------------------------------------------------------------; -; Тест на допустимое имя и настроиться на диск. -; вход: hl=строка имени -; выход: (TMPNAME) -GETWORD: - ; !TEST - INC HL - LD A,(HL) - DEC HL - CP ':' - JR NZ,.dir_loop - - LD A,(HL) - CP 'a' - JR C,.next - CP '{' - JR NC,.next - SUB #20 -.next: SUB 'A' - INC HL - INC HL - PUSH HL - CALL CHNDISK - ;CALL OPENDSK - POP HL - RET C - LD A,(HL) - OR A - RET Z - CP ' ' ; - RET Z - CP '\' ; - SCF - LD A,DSS_Error.sys.PATH_NOT_FOUND - RET NZ - INC HL - ; -.dir_loop: - LD DE,TMPNAME - LD BC,#0DFF - ; -.loop: LD A,(HL) - INC HL - CP '\' ; - JR Z,.DIR_NAME - ; AND A - ; JR Z,.DIR_NAME - ;CP ':' - ;JR Z,.DRV_NAME - LD (DE),A - INC DE - CP ' '+1 - CCF - RET NC - DJNZ .loop - LD A,DSS_Error.sys.INVALID_NAME - SCF - RET - ; -.DIR_NAME: - XOR A - LD (DE),A - PUSH HL - LD HL,TMPNAME - CALL OPENDIR - POP HL - RET C - JR .dir_loop -; .DRV_NAME: -; LD A,(TMPNAME) -; CP 'a' -; JR C,.next -; CP '{' -; JR NC,.next -; SUB #20 -; .next: SUB 'A' -; PUSH HL -; ;!TEST CHNDISK OPENDSK -; ;CALL OPENDSK -; CALL CHNDISK -; ; -; POP HL -; RET C -; JR .loop -; - -; Буфер имени 8.3 формата -TMPNAME: DZ ' ' ; 12 пробелов и 0 ;!FIXIT к буферам -;----------------------------------------------------------------------; - - -;----------------------------------------------------------------------; -; IN: A - drive number -; - -OPENDSK: - ;!TEST DRV.Open обход R10 - LD C,A - LD A,(FatBuffer.DRIVE) - CP C - JR Z,.exit - LD A,C - ; -.force: PUSH AF - LD C,Dss.DRV.Open - RST ToDSS.DRV - POP BC - JP C,.error - LD A,B - LD (FatBuffer.DRIVE),A - CALL RD_BPB - RET C -.exit: LD A,(LDRIVE) - AND A - RET -.error: CP DSS_Error.sys.INVALID_DRIVE - SCF - RET Z - LD A,DSS_Error.sys.NOT_READY - RET -;----------------------------------------------------------------------; - - -;----------------------------------------------------------------------; -OPENDIR:;!TEST ;[x] some optimize - ;XOR A - ;CALL SET_FM - LD IY,CORE_BUFFERS.FM_BUF - ; - LD A,(HL) - OR A - JR NZ,.SUBDIR -.REROOT1: - LD DE,0 - ;!TEST ;[x] some optimize - ;LD (IY+_sFM.ST_CLUSTER),E - ;LD (IY+_sFM.ST_CLUSTER+1),D - EX DE,HL - LD (CORE_BUFFERS.FM_BUF + _sFM.ST_CLUSTER),HL - EX DE,HL - ; - CALL LOADDIR - LD HL,WorkDirectory - LD (HL),'\' - INC HL - LD (HL),#00 - ; CF=0 - ;AND A - RET -.SUBDIR: - CP "." - JR NZ,.SUBDIR2 - ;!TEST ;[x] some optimize - ;LD A,(IY+_sFM.ST_CLUSTER) ;R05 - LD A,(CORE_BUFFERS.FM_BUF + _sFM.ST_CLUSTER) ;R05 - ; - OR (IY+_sFM.ST_CLUSTER+1) ;R05 - JR NZ,.SUDI1 ;R05 - INC HL ;R05 - LD A,(HL) ;R05 - OR A ;R05 - DEC HL ;R05 - JR Z,.REROOT1 ;R05 -.SUDI1: EXX - LD HL,MASKARE - LD DE,MASKARE+1 - LD BC,10 ;!HARDCODE - LD (HL),' ' - LDIR - EXX - LD DE,MASKARE -.loop: LDI - LD A,(HL) - OR A - JR NZ,.loop - JR .SUBDIR3 -.SUBDIR2: - CALL MASK.name - RET C -.SUBDIR3: - CALL FINDDIR - RET C - ;!TEST ;[x] some optimize - ;LD (IY+_sFM.ST_CLUSTER),E - ;LD (IY+_sFM.ST_CLUSTER+1),D - ;LD DE,#4000 ;!HARDCODE - ;LD (IY+_sFM.F_SIZE),E - ;LD (IY+_sFM.F_SIZE+1),D - EX DE,HL - LD (CORE_BUFFERS.FM_BUF + _sFM.ST_CLUSTER),HL - LD HL,#4000 ;!HARDCODE - LD (CORE_BUFFERS.FM_BUF + _sFM.F_SIZE),HL - EX DE,HL - ; - CALL LOADDIR - ; CF=0 - ;AND A - RET -;----------------------------------------------------------------------; - - -;----------------------------------------------------------------------; -; FIND "MASKAREA" IN DIRECTORY -FINDDIR: - SET_PAGE_X DIRPAGE - ; - PUSH AF - LD IX,DIRPAGE.buffer -.big_loop: - LD A,(IX+00) - OR A - JR Z,.error - CP #E5 - JR Z,.next_step - LD A,(IX+11) ;!HARDCODE - AND #10 ;!HARDCODE - JR Z,.next_step - LD HL,MASKARE - LD D,XH - LD E,XL - EX DE,HL - LD B,11 ;!HARDCODE -.loop: LD A,(DE) - CP "?" - JR Z,.compared - CP (HL) - JR NZ,.next_step -.compared: - INC HL - INC DE - DJNZ .loop - ; - LD A,(IX+0) - CP "." - JP NZ,.ADDSPEC - LD A,(IX+1) ;!HARDCODE - CP "." - JP NZ,.IT_DIR - LD HL,WorkDirectory - LD D,H - LD E,L - INC HL - LD BC,WorkDirectory.DEPTH - XOR A - CPIR - JP PO,.error ;[x] 20/11/23 проверка на выход за границы - DEC HL ;R09 - DEC HL - LD BC,WorkDirectory.DEPTH - LD A,'\' - CPDR - INC HL - EX DE,HL - ; CF = 0 - SBC HL,DE - EX DE,HL - JR NZ,.MM3 - INC HL -.MM3: LD (HL),0 - JP .IT_DIR - ; -.next_step: - LD BC,#0020 ;!HARDCODE - ADD IX,BC - JR NC,.big_loop - ; -.error: POP AF - OUT (SLOT3),A - LD A,DSS_Error.sys.PATH_NOT_FOUND - SCF - RET -.ADDSPEC: - LD HL,WorkDirectory+1 - LD BC,WorkDirectory.DEPTH-1 - CALL .CHECK_SLASH - JR C,.error - ;R11 - LD A,B - AND A - JR NZ,.nxt - LD A,C - CP 8+1+3 ;!HARDCODE имя каталога + точка + расширение - JR C,.error -.nxt: ; - LD E,XL - LD D,XH - ; [x] оптимизация по размеру - EX DE,HL - CALL GETNAME - EX DE,HL - ; - -; LD BC,256*8 + ' ' ;!HARDCODE -; .MM1: LD A,(DE) -; INC DE -; CP C -; JR Z,.MM2 -; LD (HL),A -; INC HL -; .MM2 DJNZ .MM1 ;x42-40 50-55 -; LD A,(DE) -; INC DE -; CP C -; JR Z,.MM3 -; LD (HL),"." -; INC HL -; LD (HL),A -; INC HL -; LD A,(DE) -; INC DE -; CP C -; JR Z,.MM3 -; LD (HL),A -; INC HL -; LD A,(DE) -; CP C -; JR Z,.MM3 -; LD (HL),A -; .MM2_5: INC HL -; .MM3: LD (HL),0 -; ; JP IT_DIR - -.IT_DIR: - LD E,(IX+_sFM.ST_CLUSTER) - LD D,(IX+_sFM.ST_CLUSTER+1) - POP AF - OUT (SLOT3),A - AND A - RET -.CHECK_SLASH: - XOR A - CPIR - ;[x] 20/11/23 проверка на выход за границы - SCF - RET PO - ; - DEC HL - DEC HL - LD A,'\' ; #5C - CP (HL) - INC HL - RET Z - LD (HL),A - INC HL - RET -;----------------------------------------------------------------------; - - -;----------------------------------------------------------------------; -; .custom: -; Преобразовать имя 8.3 -> 11 формат -; вход: hl = 8.3 имя -; de = буфер имени 11 симв. формата -; при ошибке CF - недоп. имя -; -; HL - MASK "file*.t??" -; DE - 11 bytes filename -; RET: C=2 FILE WITHOUT EXTENTION -; C=1 FILE WITH EXTENTION -MASK: LD HL,TMPNAME -.name: LD DE,MASKARE -.custom: PUSH HL - PUSH DE - LD H,D - LD L,E - INC DE - LD (HL),' ' - LD BC,10 ;!HARDCODE = size (FileName + Extension - 1) - LDIR - POP DE - POP HL - LD A,(HL) - CP '.' ;R07 - SCF ;R07 - JR Z,.MASKB ;R07 - CP ' '+1 -.MASKB: LD A,DSS_Error.sys.INVALID_NAME - RET C - LD BC,#0902 ; B - счетчик -.MASK1: LD A,(HL) - CP ' '+1 - CCF - RET NC - CP '"' - JR Z,.MASK_ERR - CP '*' - JR Z,.MASK3 - CP '+' - JR Z,.MASK_ERR - CP ',' - JR Z,.MASK_ERR - CP '.' - JR Z,.MASK5 - CP '/' - JR Z,.MASK_ERR - CP ':' - JR Z,.MASK_ERR - CP ';' - JR Z,.MASK_ERR - CP '<' - JR Z,.MASK_ERR - CP '=' - JR Z,.MASK_ERR - CP '>' - JR Z,.MASK_ERR - CP '[' - JR Z,.MASK_ERR - CP '\' - JR Z,.MASK_ERR - CP ']' - JR Z,.MASK_ERR - CP '|' - JR Z,.MASK_ERR -; CP 'a' ;????? -; JR C,.MASK2 -; CP 'z' + 1 -; JR NC,.MASK2 -; SUB #20 - CALL UPPER ; a..z -> A..Z -.MASK2: LD (DE),A - INC HL - INC DE - DJNZ .MASK1 -.MASK_ERR: - LD A,DSS_Error.sys.INVALID_NAME - SCF - RET -.MASK3: LD A,'?' - INC HL - DJNZ .MASK6 - LD A,DSS_Error.sys.INVALID_NAME - SCF - RET -.MASK6: LD (DE),A - INC DE - DJNZ .MASK6 - LD B,1 - JR .MASK1 -.MASK5: LD A,' ' - INC HL - DJNZ .MASK4 - LD B,4 - DEC C - JP NZ,.MASK1 - LD A,DSS_Error.sys.INVALID_NAME - SCF - RET -.MASK4: LD (DE),A - INC DE - DJNZ .MASK4 - LD B,4 - DEC C - JP NZ,.MASK1 - LD A,DSS_Error.sys.INVALID_NAME - SCF - RET -;----------------------------------------------------------------------; - - -;----------------------------------------------------------------------; -; a..z -> A..Z -UPPER: CP 'a' - RET C - CP 'z' + 1 - JR NC,.MDUPPER - SUB #20 -.NOUPPER: - RET -.MDUPPER: - CP 'а' ; русская буква а, код #A0 - JR C,.NOUPPER - CP 'п' ; русская буква п, код #B0 - JR NC,.BGUPPER - SUB #20 - RET -.BGUPPER: - CP 'р' ; русская буква р, код #E0 - JR C,.NOUPPER - CP 'Ё' ; русская буква Ё, код #F0 - JR NC,.HGUPPER - SUB #50 - RET -.HGUPPER: CP 'ё' ; русская буква ё, код #F1 - RET NZ - DEC A - RET -;----------------------------------------------------------------------; - - -;----------------------------------------------------------------------; -; Прочитать список каталога -LOADDIR: - XOR A - LD H,A - LD L,A - LD IX,0 - LD B,A ; от начала файла - CALL MOVE_FP - - SET_PAGE_X DIRPAGE - - PUSH AF - ;!TEST no ldir - ; очистить кеш каталога - ; LD HL,#C000 - ; LD DE,#C001 - ; LD BC,#3FFF - ; LD (HL),L - ; LDIR - ; - ; - LD A,(FatBuffer.DRIVE) ; номер диска - LD (IY+_sFM.DRIVE),A ; сохр. в дескриптор - LD D,(IY+_sFM.ST_CLUSTER) ; de=номер первого кластера - LD E,(IY+_sFM.ST_CLUSTER+1) - LD A,D - OR E - JP Z,.LROTDIR ; root ?? - LD HL,DIRPAGE.buffer ; куда - LD DE,#4000 ; сколько - XOR A ; дескриптор - CALL READ ; чтение из файла - ;!FIXIT проверка на ошибку - LD (SAVEDIR.DIRSIZE),DE ; число прочит. байтов - POP AF - OUT (SLOT3),A - AND A - RET -.LROTDIR: - LD HL,(FatBuffer.DIR_FRH) ; ст. разряд - LD IX,(FatBuffer.DIR_FRL) ; номер лог. сектора - LD A,(FatBuffer.DIR_S_S) - ;!TEST - LD B,32 ; !HARDCODE 16384/(sector 512). размер root-каталога - CP B - JR NC,.RTD1 - LD B,A ; число секторов - ;LD B,32 ; !HARDCODE 16384/(sector 512). размер root-каталога - ;SUB B - ;JR NC,.RTD1 - ;ADD A,B - ;LD B,A ; число секторов - ; -.RTD1: LD A,(FatBuffer.DRIVE) ; номер диска - LD DE,DIRPAGE.buffer ; буфер - LD C,Dss.DRV.Read ; чтение секторов - RST ToDSS.DRV - POP AF - OUT (SLOT3),A - AND A - RET -;----------------------------------------------------------------------; - - -;----------------------------------------------------------------------; -; скопировать запись в список диска (каталога) -; и сбросить кеш каталога на диск -WRT_HND: SET_PAGE_X DIRPAGE - EX AF,AF' - ; - LD IX,DIRPAGE.buffer - ;TEST 9/11/23 - ; EXX - ; LD DE,0 - ; EXX - ; -.loop: LD A,(IX+00) - OR A - JR Z,.WRT_HN2 - CP #E5 - JR Z,.WRT_HN2 - LD BC,#0020 - ADD IX,BC - JR NC,.loop - ; - EX AF,AF' - OUT (SLOT3),A - LD A,DSS_Error.sys.ROOT_OVERFLOW - SCF - RET -.WRT_HN2: - LD D,XH - LD E,XL - LD HL,HANDBUF - LD BC,HANDBUF.SIZE - LDIR - EX AF,AF' - OUT (SLOT3),A - LD HL,DIRPAGE.buffer - LD BC,(SAVEDIR.DIRSIZE) - DEC BC - ADD HL,BC - AND A - SBC HL,DE - JR NC,SAVEDIR - LD HL,(SAVEDIR.DIRSIZE) - LD BC,(FatBuffer.B_P_C) - ADD HL,BC - LD (SAVEDIR.DIRSIZE),HL - AND A - JP SAVEDIR -;----------------------------------------------------------------------; - - -;----------------------------------------------------------------------; -; Сбросить кеш каталога на диск. -; вход: iy=структура дескриптора -SAVEDIR: - XOR A - LD HL,0 - LD IX,0 - LD B,0 - CALL MOVE_FP - ; - SET_PAGE_X DIRPAGE - PUSH AF - ; - LD A,(FatBuffer.DRIVE) - LD (IY+_sFM.DRIVE),A - LD D,(IY+_sFM.ST_CLUSTER) - LD E,(IY+_sFM.ST_CLUSTER+1) - LD A,D - OR E - JP Z,.SROTDIR - LD HL,DIRPAGE.buffer -; размер списка каталога size_cash_directory -.DIRSIZE+1: - LD DE,0 - XOR A - CALL WRITE - POP AF - OUT (SLOT3),A - AND A - RET -.SROTDIR: - LD HL,(FatBuffer.DIR_FRH) - LD IX,(FatBuffer.DIR_FRL) - LD A,(FatBuffer.DIR_S_S) - LD B,32 ;!HARDCODE - SUB B - JR NC,.RTD1S - ADD A,B - LD B,A -.RTD1S: LD A,(FatBuffer.DRIVE) - LD DE,DIRPAGE.buffer - LD C,Dss.DRV.Write - RST ToDSS.DRV - POP AF - OUT (SLOT3),A - AND A - RET -;----------------------------------------------------------------------; - - -;----------------------------------------------------------------------; -;!TEST Current Dir ;[x] 15/10/23 -DIR_PATH_CHANGE: -.FullCurrent: LD A,(FatBuffer.DRIVE) - ADD 'A' - LD (CurrentPath),A - ; -.Current: LD HL,CurrentDirectory - JP CURRDIR - ; -.FullWork: LD A,(CurrentPath) - SUB 'A' - LD (FatBuffer.DRIVE),A - ; -.Work: LD HL,WorkDirectory - JP CURRDIR_FN -; - -; -DIR_PATH_CHECK: LD A,(HL) - CP '\' - JR NZ,.notRootDir - ; - CALL .checkDrive - RET Z - LD A,(CurrentPath) - SUB 'A' - JP OPENDSK - ; -.notRootDir: INC HL - LD A,(HL) - CP ':' - RET Z - ; -.forceCheck: LD HL,CurrentDirectory+1 - LD BC,CurrentDirectory.DEPTH-1 - CALL .checkDrive - JR Z,.checkDir - ; - LD HL,CurrentPath - LD A,(FatBuffer.DRIVE) - ADD 'A' - CP (HL) - JR NZ,.gotoPath - ; -.checkDir: LD HL,CurrentDirectory+1 - LD DE,WorkDirectory+1 - ; -.loop: LD A,(DE) - AND A - JR Z,.end - CP (HL) - INC HL - INC DE - JR Z,.loop - JP .gotoPath - ; -.end: CP (HL) - RET Z - JR .gotoPath - ; -.checkDrive: LD HL,CurrentPath - LD A,(FatBuffer.DRIVE) - ADD 'A' - CP (HL) - RET -.gotoPath: CALL FINDDIR.CHECK_SLASH - LD A,DSS_Error.sys.PATH_NOT_FOUND - RET C - LD HL,CurrentPath - JP GETWORD -;----------------------------------------------------------------------; - - -;----------------------------------------------------------------------; -CHECK_NAME: - LD HL,MASKARE -.custom: LD BC,11 ;!HARDCODE - LD A,"?" - CPIR - LD A,DSS_Error.sys.INVALID_NAME - SCF - RET -;----------------------------------------------------------------------; - - -;!FIXIT к буферам -; Массив лог. номеров банок расширения DSS -BANKTBL: BLOCK USING_MEMPAGES+1,#FF ; +1 для COREPAGE -; - -HANDBUF: BLOCK HANDBUF.SIZE,0 -; - -MASKARE: BLOCK 8,0 ; имя файла - BLOCK 3,0 ; расш. - BLOCK 21,0 ; 11+21=32 -;TMP_BYTE: DB 0 ; ACCESS: -; - -;PATH0: DW #0000 -;ACCESS: DB #00 -;DTABUF: DW #0000 -;CURHND: DW #0000 -;NO_NEXT: DB #00 -;.YES EQU 0 -;.NO EQU #FF -;FNDMODE: DB #00 -;//MODULE: DOS5 -;[END] - -;DIRSIZE: WORD 0 ; размер списка каталога size_cash_directory - - -;!TODO ? -GHANDLE: -; PUSH DE -; PUSH HL -; PUSH IX -; CALL TESTDSK -; JP C,G_HAND1 -; CALL LOADDIR -; POP DE -; LD HL,DIR -; LD BC,#0020 -;G_HAND2: -; LD A,D -; OR E -; JP Z,G_HAND3 -; ADD HL,BC -; DEC DE -; JP G_HAND2 -;G_HAND3: -; EXX -; POP DE -; EXX -;G_HAND4: -; EX DE,HL -; LD A,DIRPAGE -; CALL BANK -; EX DE,HL -; LD DE,HANDTA -; -; DUP 32 -; LDI -; EDUP -; -; EXX -; OUT (SLOT3),A -; LD HL,HANDTA -; -; DUP 32 -; LDI -; EDUP -; -; EXX -; POP BC -; DEC BC -; LD A,B -; OR C -; RET Z -; PUSH BC -; JP G_HAND4 -;G_HAND1 POP IX -; POP HL -; POP DE -; RET -;HANDTA BLOCK 32,0 -;----------------------------------------------------------------------; -; ;!TEST -; SAVE_CURRENT_PATH: -; 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 -; RET -; BACK_CURRENT_PATH: -; SET_PAGE_X ENVPAGE -; PUSH AF -; LD HL,TMP_CURDIR -; CALL CHDIR -; POP AF -; OUT (SLOT3),A -; RET -; ; -;----------------------------------------------------------------------; -;!TEST - ;BANK: - ; LD C,A - ; LD B,0 - ; LD HL,BANKTBL - ; ADD HL,BC - ; IN A,(SLOT3) - ; LD C,SLOT3 - ; OUTI - ; RET -; diff --git a/DSS/DOS_FM.ASM b/DSS/DOS_FM.ASM index 44ced0c..72e1d29 100644 --- a/DSS/DOS_FM.ASM +++ b/DSS/DOS_FM.ASM @@ -961,9 +961,10 @@ WRITE: LD (.R_POINT),HL ////////////// NEW ////////////////// ; in: HL - CLUSTER ; out: HL:IX - SECTOR -NSECTOR: DEC HL - DEC HL +NSECTOR: LD DE,0 + DEC HL + DEC HL LD A,(CORE_BUFFERS.BootSector.S_P_C) XOR 1 JR Z,.skip @@ -971,7 +972,8 @@ NSECTOR: DEC HL RRA .loop: ADD HL,HL RL E - ; RL D + RL D + ; RRA JP NC,.loop ; @@ -984,6 +986,7 @@ NSECTOR: DEC HL LD D,A LD E,A ADC HL,DE + ;!TODO а надо ли проверять переполнение HL:IX? RET ///////////////////////////////////// diff --git a/DSS/DOS_Proc.asm b/DSS/DOS_Proc.asm new file mode 100644 index 0000000..73b42b3 --- /dev/null +++ b/DSS/DOS_Proc.asm @@ -0,0 +1,512 @@ +;[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 +;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" +;--------------------------------------------------------------- + +;[BEGIN] +;//MODULE: FAT_X +;//CREATE: 19-05-1998 AUTHOR: Denis Parinov +;//UPDATE: 24-10-1999 DNS Restore module +;--------------------------------------------------------------- +;Rev Date Name Description +;--------------------------------------------------------------- +;RX01 10-02-1999 DNS UPGRADE FAT CASH +;--------------------------------------------------------------- + + +;----------------------------------------------------------------------; +; HL - 11 bytes filename "FILENAMEEXT" +; DE - DOS filename "FILENAME.EXT",0 +; GetName: +; LD BC,#08FF +; .GETN1: LD A,(HL) +; CP " " +; JR NZ,.GETN3 +; .GETN2: INC HL +; DJNZ .GETN2 +; JR .GETN4 +; .GETN3: LDI +; DJNZ .GETN1 +; ; +; .GETN4: LD A,(HL) +; CP " " +; LD A,"." +; JR NZ,.GETN5 +; LD A,#00 +; .GETN5: LD (DE),A +; INC DE +; RET Z +; LD B,#03 +; .GETN6: LD A,(HL) +; CP " " +; RET Z +; LDI +; XOR A +; LD (DE),A +; DJNZ .GETN6 +; RET +;---------------;---------------;--------------- +GetName: + LD BC,#08FF ;!HARDCODE длина имени + счётчик + LD A,' ' +.loop: CP (HL) + JR Z,.skip + LDI + DJNZ .loop + ;;;; + JP .extension + ;;;; +.skip: LD C,B + LD B,0 + ; CF=0 + ADC HL,BC + ;;;; +.extension: + CP (HL) + LD A,"." + JR NZ,.copy_extension + XOR A +.copy_extension: + LD (DE),A + INC DE + RET Z ;no copy extension + ; copy extension + LD BC,#03FF ;!HARDCODE длина расширения + счётчик + LD A,' ' +.loop2: CP (HL) + JR Z,.exit + LDI + DJNZ .loop2 +.exit: XOR A + LD (DE),A + RET +;----------------------------------------------------------------------; + + + +;----------------------------------------------------------------------; +; Тест на допустимое имя и настроиться на диск. +; вход: hl=строка имени +; выход: (TMPNAME) +GETWORD: + ; !TEST + INC HL + LD A,(HL) + DEC HL + CP ':' + JR NZ,.dir_loop + + LD A,(HL) + CP 'a' + JR C,.next + CP '{' + JR NC,.next + SUB #20 +.next: SUB 'A' + INC HL + INC HL + PUSH HL + CALL CHNDISK + ;CALL OPENDSK + POP HL + RET C + LD A,(HL) + OR A + RET Z + CP ' ' ; + RET Z + CP '\' ; + SCF + LD A,DSS_Error.sys.PATH_NOT_FOUND + RET NZ + INC HL + ; +.dir_loop: + LD DE,TMPNAME + LD BC,#0DFF + ; +.loop: LD A,(HL) + INC HL + CP '\' ; + JR Z,.DIR_NAME + ; AND A + ; JR Z,.DIR_NAME + ;CP ':' + ;JR Z,.DRV_NAME + LD (DE),A + INC DE + CP ' '+1 + CCF + RET NC + DJNZ .loop + LD A,DSS_Error.sys.INVALID_NAME + SCF + RET + ; +.DIR_NAME: + XOR A + LD (DE),A + PUSH HL + LD HL,TMPNAME + CALL OPENDIR + POP HL + RET C + JR .dir_loop +; .DRV_NAME: +; LD A,(TMPNAME) +; CP 'a' +; JR C,.next +; CP '{' +; JR NC,.next +; SUB #20 +; .next: SUB 'A' +; PUSH HL +; ;!TEST CHNDISK OPENDSK +; ;CALL OPENDSK +; CALL CHNDISK +; ; +; POP HL +; RET C +; JR .loop +; + +; Буфер имени 8.3 формата +TMPNAME: DZ ' ' ; 12 пробелов и 0 ;!FIXIT к буферам +;----------------------------------------------------------------------; + + + +;----------------------------------------------------------------------; +; IN: A - drive number +; +OPENDSK: + ;!TEST DRV.Open обход R10 + LD C,A + LD A,(FatBuffer.DRIVE) + CP C + IF CHECK_DRIVE_CHANGE + JR NZ,.open + PUSH BC + LD C,Dss.DRV.MediaCheck + RST ToDSS.DRV + POP BC + ENDIF + JR Z,.exit + +.open: LD A,C + ; +.force: PUSH AF + LD C,Dss.DRV.Open + RST ToDSS.DRV + POP BC + JP C,.error + LD A,B + LD (FatBuffer.DRIVE),A + CALL RD_BPB + RET C +.exit: LD A,(LDRIVE) + AND A + RET +.error: CP DSS_Error.sys.INVALID_DRIVE + SCF + RET Z + LD A,DSS_Error.sys.NOT_READY + RET +;----------------------------------------------------------------------; + + + +;----------------------------------------------------------------------; +OPENDIR:;!TEST ;[x] some optimize + ;XOR A + ;CALL SET_FM + LD IY,CORE_BUFFERS.FM_BUF + ; + LD A,(HL) + OR A + JR NZ,.SUBDIR +.REROOT1: + LD DE,0 + ;!TEST ;[x] some optimize + ;LD (IY+_sFM.ST_CLUSTER),E + ;LD (IY+_sFM.ST_CLUSTER+1),D + EX DE,HL + LD (CORE_BUFFERS.FM_BUF + _sFM.ST_CLUSTER),HL + EX DE,HL + ; + CALL LOADDIR + LD HL,WorkDirectory + LD (HL),'\' + INC HL + LD (HL),#00 + ; CF=0 + ;AND A + RET +.SUBDIR: + CP "." + JR NZ,.SUBDIR2 + ;!TEST ;[x] some optimize + ;LD A,(IY+_sFM.ST_CLUSTER) ;R005 + LD A,(CORE_BUFFERS.FM_BUF + _sFM.ST_CLUSTER) ;R005 + ; + OR (IY+_sFM.ST_CLUSTER+1) ;R005 + JR NZ,.SUDI1 ;R005 + INC HL ;R005 + LD A,(HL) ;R005 + OR A ;R005 + DEC HL ;R005 + JR Z,.REROOT1 ;R005 +.SUDI1: EXX + LD HL,MASKARE + LD DE,MASKARE+1 + LD BC,10 ;!HARDCODE + LD (HL),' ' + LDIR + EXX + LD DE,MASKARE +.loop: LDI + LD A,(HL) + OR A + JR NZ,.loop + JR .SUBDIR3 +.SUBDIR2: + CALL MASK.name + RET C +.SUBDIR3: + CALL FINDDIR + RET C + ;!TEST ;[x] some optimize + ;LD (IY+_sFM.ST_CLUSTER),E + ;LD (IY+_sFM.ST_CLUSTER+1),D + ;LD DE,#4000 ;!HARDCODE + ;LD (IY+_sFM.F_SIZE),E + ;LD (IY+_sFM.F_SIZE+1),D + EX DE,HL + LD (CORE_BUFFERS.FM_BUF + _sFM.ST_CLUSTER),HL + LD HL,#4000 ;!HARDCODE + LD (CORE_BUFFERS.FM_BUF + _sFM.F_SIZE),HL + EX DE,HL + ; + CALL LOADDIR + ; CF=0 + ;AND A + RET +;----------------------------------------------------------------------; + + + +;----------------------------------------------------------------------; +; .custom: +; Преобразовать имя 8.3 -> 11 формат +; вход: hl = 8.3 имя +; de = буфер имени 11 симв. формата +; при ошибке CF - недоп. имя +; +; HL - MASK "file*.t??" +; DE - 11 bytes filename +; RET: C=2 FILE WITHOUT EXTENTION +; C=1 FILE WITH EXTENTION +MASK: LD HL,TMPNAME +.name: LD DE,MASKARE +.custom: PUSH HL + PUSH DE + LD H,D + LD L,E + INC DE + LD (HL),' ' + LD BC,10 ;!HARDCODE = size (FileName + Extension - 1) + LDIR + POP DE + POP HL + LD A,(HL) + CP '.' ;R007 + SCF ;R007 + JR Z,.MASKB ;R007 + CP ' '+1 +.MASKB: LD A,DSS_Error.sys.INVALID_NAME + RET C + LD BC,#0902 ; B - счетчик +.MASK1: LD A,(HL) + CP ' '+1 + CCF + RET NC + CP '"' + JR Z,.MASK_ERR + CP '*' + JR Z,.MASK3 + CP '+' + JR Z,.MASK_ERR + CP ',' + JR Z,.MASK_ERR + CP '.' + JR Z,.MASK5 + CP '/' + JR Z,.MASK_ERR + CP ':' + JR Z,.MASK_ERR + CP ';' + JR Z,.MASK_ERR + CP '<' + JR Z,.MASK_ERR + CP '=' + JR Z,.MASK_ERR + CP '>' + JR Z,.MASK_ERR + CP '[' + JR Z,.MASK_ERR + CP '\' + JR Z,.MASK_ERR + CP ']' + JR Z,.MASK_ERR + CP '|' + JR Z,.MASK_ERR +; CP 'a' ;????? +; JR C,.MASK2 +; CP 'z' + 1 +; JR NC,.MASK2 +; SUB #20 + CALL UPPER ; a..z -> A..Z +.MASK2: LD (DE),A + INC HL + INC DE + DJNZ .MASK1 +.MASK_ERR: + LD A,DSS_Error.sys.INVALID_NAME + SCF + RET +.MASK3: LD A,'?' + INC HL + DJNZ .MASK6 + LD A,DSS_Error.sys.INVALID_NAME + SCF + RET +.MASK6: LD (DE),A + INC DE + DJNZ .MASK6 + LD B,1 + JR .MASK1 +.MASK5: LD A,' ' + INC HL + DJNZ .MASK4 + LD B,4 + DEC C + JP NZ,.MASK1 + LD A,DSS_Error.sys.INVALID_NAME + SCF + RET +.MASK4: LD (DE),A + INC DE + DJNZ .MASK4 + LD B,4 + DEC C + JP NZ,.MASK1 + LD A,DSS_Error.sys.INVALID_NAME + SCF + RET +;----------------------------------------------------------------------; + + + +;----------------------------------------------------------------------; +;!TEST Current Dir ;[x] 15/10/23 +DIR_PATH_CHANGE: +.FullCurrent: LD A,(FatBuffer.DRIVE) + ADD 'A' + LD (CurrentPath),A + ; +.Current: LD HL,CurrentDirectory + JP CURRDIR + ; +.FullWork: LD A,(CurrentPath) + SUB 'A' + LD (FatBuffer.DRIVE),A + ; +.Work: LD HL,WorkDirectory + JP CURRDIR_FN +; +DIR_PATH_CHECK: LD A,(HL) + CP '\' + JR NZ,.notRootDir + ; + CALL .checkDrive + RET Z + LD A,(CurrentPath) + SUB 'A' + JP OPENDSK + ; +.notRootDir: INC HL + LD A,(HL) + CP ':' + RET Z + ; +.forceCheck: LD HL,CurrentDirectory+1 + LD BC,CurrentDirectory.DEPTH-1 + CALL .checkDrive + JR Z,.checkDir + ; + LD HL,CurrentPath + LD A,(FatBuffer.DRIVE) + ADD 'A' + CP (HL) + JR NZ,.gotoPath + ; +.checkDir: LD HL,CurrentDirectory+1 + LD DE,WorkDirectory+1 + ; +.loop: LD A,(DE) + AND A + JR Z,.end + CP (HL) + INC HL + INC DE + JR Z,.loop + JP .gotoPath + ; +.end: CP (HL) + RET Z + JR .gotoPath + ; +.checkDrive: LD HL,CurrentPath + LD A,(FatBuffer.DRIVE) + ADD 'A' + CP (HL) + RET +.gotoPath: CALL FINDDIR.CHECK_SLASH + LD A,DSS_Error.sys.PATH_NOT_FOUND + RET C + LD HL,CurrentPath + JP GETWORD +;----------------------------------------------------------------------; + + + +;----------------------------------------------------------------------; +CHECK_NAME: + LD HL,MASKARE +.custom: LD BC,11 ;!HARDCODE + LD A,"?" + CPIR + LD A,DSS_Error.sys.INVALID_NAME + SCF + RET +;----------------------------------------------------------------------; + + + diff --git a/DSS/DOS_X.ASM b/DSS/DOS_X.ASM deleted file mode 100644 index 8de28c4..0000000 --- a/DSS/DOS_X.ASM +++ /dev/null @@ -1,799 +0,0 @@ - -;[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 -;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_FN: - LD A,(CurrentPath) - SUB 'A' - RET NC - LD A,DSS_Error.sys.INVALID_DRIVE - RET -CURRDSK: LD A,(FatBuffer.DRIVE) - AND A - RET - - -;///////////////////////////////////////////////////////////////////// -; [ ] новая подфункция с битом 7 в рег. А -; Возвращает информацию об общем и свободном пространстве дискового -; устройства. -; -; вход: A - номер диска (0=A,1=B .. 25=Z. #FF-текущий) -; При A bit7 = 1: -; HL - буфер (256 байтов) для расширенных данных: -; B != 0 - считать свободное место -; ; -; размер поля - 1 байт -; Файловая система -; ; -; размер поля - 1 байт -; Серийный номер диска -; ; -; размер поля - 1 байт -; Метка диска -; ; -; размер поля - 1 байт -; Зарезервировано... -; ; -; A xor #80 - номер диска -; -; выход: A - размер кластера в секторах, если CF=0 -; HL - общее кол-во кластеров -; DE - свободных кластеров -; BC - размер сектора в байтах -; A - код ошибки, если CF=1 -;///////////////////////////////////////////////////////////////////// - ; [ ] 22/11/23 подфункция с доп.инфой - MACRO _mCOPY_LOOP - LD C,A - LD B,0 - LD (DE),A - INC DE - LDIR -; .loop: -; LD (HL),A -; INC DE -; INC HL -; LD A,(DE) -; DJNZ .loop - ENDM - ; -DISKINF:; [ ] 22/11/23 подфункция с доп.инфой - LD C,B - LD B,1 - ; - CP #80 - JR C,.CustomDisk - CP #FF - JR Z,.CurrentDisk - ; more info - LD B,C - PUSH HL - AND %0111'1111 - CALL .CustomDisk - JR C,.error - ; - EX (SP),HL - PUSH AF - PUSH DE - PUSH BC - ;;;; - ; - EX DE,HL - LD HL,CORE_BUFFERS.BootSector.ID_FAT - LD A,8 ;!HARDCODE _sBOOT_SEC.ID_FAT.length - _mCOPY_LOOP - ; - LD HL,CORE_BUFFERS.BootSector.BPB_SERIAL_NUMBER - LD A,4 ;!HARDCODE _sBOOT_SEC.BPB_SERIAL_NUMBER - _mCOPY_LOOP - ; - LD HL,CORE_BUFFERS.BootSector.BPB_LABEL - LD A,11 ;!HARDCODE _sBOOT_SEC.BPB_LABEL - _mCOPY_LOOP - ; - - XOR A - LD (DE),A - ;;;; - POP BC - POP DE - POP AF -.error: POP HL - RET - ; - - ;CP #FF ; !FIXIT WorkDirectory - ;!TEST Current Dir - ;JR Z,CURRDS ;R06 -.CurrentDisk: - LD A,(CurrentPath) - SUB 'A' - LD HL,FatBuffer.DRIVE - CP (HL) - JR Z,.CheckFreeSpace - ; -.CustomDisk: - PUSH BC - CALL CHNDISK ;R06 - POP BC - RET C ;R06 - -.CheckFreeSpace: - ; - XOR A - OR B - CALL NZ,.CURRDS - ; - ; -.FRESP2: - LD D,B - LD E,C - LD HL,(FAT_Max_Cluster) - DEC HL - LD BC,(CORE_BUFFERS.BootSector.B_P_S) - LD A,(CORE_BUFFERS.BootSector.S_P_C) - AND A - RET - ; -.CURRDS: - LD HL,2 - LD BC,0 -.FRESP: PUSH BC - CALL R_F_FAT - POP BC - CP DSS_Error.sys.DISK_FULL - RET Z - - LD A,E - OR D - JR NZ,.SKIC - INC BC -.SKIC: INC HL - JP .FRESP -; - - -; Номер последнего диска в системе -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,CORE_BUFFERS.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,(CORE_BUFFERS.SECBUF+510) ;R08 ;R07 - ;R05 - AND A - SBC HL,DE - JP NZ,DOS_X_Error.UnknownBPB - ;R08 - LD HL,CORE_BUFFERS.SECBUF - LD DE,CORE_BUFFERS.BootSector - LD BC,_sBOOT_SEC ; size - LDIR - ; - - //LD IY,BootSector ; пока без индексного, но может пригодиться - //LD A,(IY+_sBOOT_SEC.ID_FORM) - LD A,(CORE_BUFFERS.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,(CORE_BUFFERS.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,(CORE_BUFFERS.BootSector.S_P_F) - - - LD A,(CORE_BUFFERS.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,(CORE_BUFFERS.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,(CORE_BUFFERS.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,(CORE_BUFFERS.BootSector.B_P_S) ; Size sector - - LD A,(CORE_BUFFERS.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,CORE_BUFFERS.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,(CORE_BUFFERS.BootSector.S_P_T) ; Sector per track - - LD A,(CORE_BUFFERS.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,(CORE_BUFFERS.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,(CORE_BUFFERS.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,(CORE_BUFFERS.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,(CORE_BUFFERS.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 (FAT_Max_Cluster),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 (FatCache),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,(CORE_BUFFERS.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 ;!TODO не используются некоторые значения, но задумка неплохая))) -.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 к буферам! -CurrentPath: DB 'X' - DB ':' -CurrentDirectory: DB '\' -.DEPTH: EQU DIRECTORY_PATH_LENGTH - BLOCK CurrentDirectory.DEPTH,0 ; не .DEPTH-1 чтоб был 0 в конце - - IF SAVE_PATH_CODE -WorkDirectory: DB '\' -.DEPTH: EQU DIRECTORY_PATH_LENGTH - BLOCK WorkDirectory.DEPTH,0 ; не .DEPTH-1 чтоб был 0 в конце - ELSE -WorkDirectory EQU CurrentDirectory -.DEPTH EQU CurrentDirectory.DEPTH - ENDIF - -;R12 -;/////////////////////////////////////////////////////////////////////// -; Функция #08 (DSS_RESCAN). Пересканировать девайсы системы. -; -; вход: нет -; выход: A - номер последнего лог. диска в системе -;/////////////////////////////////////////////////////////////////////// -; INCLUDE 'ScanDRV.asm' -;!TODO код дико костыльный и будет переделан вместе с процедурой INITDVC -SCANDRV: -; 1. запоминаем состояние прерываний -; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; - LD A,R - DI - PUSH AF -; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; -; 2. узнаём букву бут-диска -; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; - CALL GETBOOT -; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; -; 3. вызываем рескан -; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; - ; A = Boot disk - LD B,A - LD A,Dss.DRV.RescanDRV - LD C,Dss.DRV.RescanDRV - RST ToDSS.DRV - LD (LDRIVE),A -; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; -; 4. выход -; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; - POP AF - RET PO - EI - RET -; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; -;/////////////////////////////////////////////////////////////////////// -; - -;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] - -;R11 - ; 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_AUTO - ; LD (HL),A - ; INC HL - ; LD A,":" - ; LD (HL),A - ; INC HL - ; CALL CURRDIR_FN - ; - ; POP AF - ; OUT (SLOT3),A - ; - ; POP AF - ; POP BC - ; POP DE - ; POP HL - ; POP IY - ; POP IX - ; RET - ; - ; BACK_CUR_PATH: - ; RET NC - ; .force: PUSH IY - ; PUSH IX - ; PUSH HL - ; PUSH DE - ; PUSH BC - ; PUSH AF - ; - ; SET_PAGE_X ENVPAGE - ; PUSH AF - ; - ; LD HL,TMP_CURDIR_AUTO - ; CALL CHDIR - ; - ; POP AF - ; OUT (SLOT3),A - ; - ; POP AF - ; POP BC - ; POP DE - ; POP HL - ; POP IX - ; POP IY - ; RET - ; ENDIF -; diff --git a/DSS/DSS-MAIN.ASM b/DSS/DSS-MAIN.ASM index 7d5b25e..4db215d 100644 --- a/DSS/DSS-MAIN.ASM +++ b/DSS/DSS-MAIN.ASM @@ -377,7 +377,7 @@ GO_ZERO EQU #0000 ADRST10: ;DS 512 ;,0 ;...............................................[LOW ADDRESS ]: ; 0 1 2 3 4 5 6 7 8 9 DEC HEX - DB low F_START, low CHNDISK_FN, low CURRDSK_FN,low DISKINF, low NOPS, low NOPS, low NOPS, low NOPS, low SCANDRV, low BOOTDSK ; 0 00..09 + DB low F_START, low CHNDISK_FN, low CURDISK_FN,low DISKINF, low NOPS, low NOPS, low NOPS, low NOPS, low SCANDRV, low BOOTDSK ; 0 00..09 DB low CREATE, low CREAT_N, low NOPS, low NOPS, low DEL_FN, low NOPS, low RENAME, low OPEN_FN, low CLOSE_FN, low READ ; 1 0A..13 DB low WRITE, low MOVE_FP, low ATTRIB, low GET_D_T, low PUT_D_T, low F_FIRST, low F_NEXT, low MKDIR, low RMDIR, low CHDIR_FN ; 2 14..1D DB low CURRDIR_FN,low NOPS, low NOPS, low SYSTIME, low SETTIME, low NOPS, low NOPS, low NOPS, low NOPS, low NOPS ; 3 1E..27 @@ -404,7 +404,7 @@ ADRST10: ;DS 512 ;,0 ;[ ] R09 ENDIF ;...............................................[HIGH ADDRESS]: - DB high F_START, high CHNDISK_FN,high CURRDSK_FN,high DISKINF,high NOPS, high NOPS, high NOPS, high NOPS, high SCANDRV, high BOOTDSK + DB high F_START, high CHNDISK_FN,high CURDISK_FN,high DISKINF,high NOPS, high NOPS, high NOPS, high NOPS, high SCANDRV, high BOOTDSK DB high CREATE, high CREAT_N, high NOPS, high NOPS, high DEL_FN, high NOPS, high RENAME, high OPEN_FN,high CLOSE_FN,high READ DB high WRITE, high MOVE_FP, high ATTRIB, high GET_D_T,high PUT_D_T,high F_FIRST,high F_NEXT, high MKDIR, high RMDIR, high CHDIR_FN DB high CURRDIR_FN,high NOPS, high NOPS, high SYSTIME,high SETTIME,high NOPS, high NOPS, high NOPS, high NOPS, high NOPS @@ -437,18 +437,47 @@ ADRST10: ;DS 512 ;,0 ;!TODO заменить по-максимому всё в KEYINTER.ASM на вызовы биоса INCLUDE "KEYINTER.ASM" ;!FIXIT из-за буфера с выравниванием align 256 в начале приходится ADRST10 добивать нулями в конце INCLUDE "VIDEO.ASM" - INCLUDE "FAT_X.ASM" - INCLUDE "DOS_X.ASM" + INCLUDE "API.ASM" + INCLUDE "DOS_Proc.asm" + INCLUDE "FS/FAT/FAT.ASM" INCLUDE "DOS_FM.ASM" - INCLUDE "DOS5.ASM" + INCLUDE "EXECUTE.ASM" INCLUDE "ENVIRON.ASM" INCLUDE "INTMOUSE.ASM" -; + INCLUDE "Procedures.asm" + + +;!FIXIT к буферам +; Массив лог. номеров банок расширения DSS +BANKTBL: BLOCK USING_MEMPAGES+1,#FF ; +1 для COREPAGE +HANDBUF: BLOCK HANDBUF.SIZE,0 +; + +MASKARE: BLOCK 8,0 ; имя файла + BLOCK 3,0 ; расш. + BLOCK 21,0 ; 11+21=32 +; DISPLAY "DOS-MAIN end address: ",/H,$-1 ; +;!TODO к буферам! +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +CurrentPath: DB 'X' + DB ':' +CurrentDirectory: DB '\' +.DEPTH: EQU DIRECTORY_PATH_LENGTH + BLOCK CurrentDirectory.DEPTH,0 ; не .DEPTH-1 чтоб был 0 в конце + IF SAVE_PATH_CODE +WorkDirectory: DB '\' +.DEPTH: EQU DIRECTORY_PATH_LENGTH + BLOCK WorkDirectory.DEPTH,0 ; не .DEPTH-1 чтоб был 0 в конце + ELSE +WorkDirectory EQU CurrentDirectory +.DEPTH EQU CurrentDirectory.DEPTH + ENDIF +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ; ;> > > > > > > > > > > > > > > > BUFFERS < < < < < < < < < < < < < < < < diff --git a/DSS/ENVIRON.ASM b/DSS/ENVIRON.ASM index 410ed0f..4a3c1d3 100644 --- a/DSS/ENVIRON.ASM +++ b/DSS/ENVIRON.ASM @@ -50,7 +50,7 @@ INITENV: PUSH AF ; ;R02 - LD A,(BOOTDRV) + LD A,(BOOTDSK.NUM) ADD A,'A' LD (DEFAULT_ENV.boot_disk),A ; diff --git a/DSS/EXECUTE.ASM b/DSS/EXECUTE.ASM index 4312538..be7d562 100644 --- a/DSS/EXECUTE.ASM +++ b/DSS/EXECUTE.ASM @@ -180,7 +180,7 @@ EX_PATH: EXX DEC B JP Z,GSWITCH ;7 ; выделить параметр ком-строки DEC B - JP Z,GETNAME ;8 ; преобр. имя 11 -> 8.3 формат + JP Z,GetName ;8 ; преобр. имя 11 -> 8.3 формат DEC B JP Z,MASK.custom ;9 ; преобр. имя 8.3 -> 11 формат EX_RESR: LD A,DSS_Error.sys.INVALID_FUNCTION @@ -839,7 +839,7 @@ EXEC: LD (CMDLINE),HL EXEC_1: ;LD (CMDLINE),HL LD HL,(CMDLINE) LD A,FAT_ATTR.READ_ONLY - LD (OPEN.TMP),A + LD (OPEN_FN.TMP),A CALL GETWORD RET C ; LD HL,TMPNAME @@ -850,7 +850,7 @@ EXEC_1: ;LD (CMDLINE),HL LD A,DSS_Error.sys.FILE_NOT_FOUND RET C _mINCTASK ;R08 - CALL OPEN.FILE + CALL OPEN_FN.FILE JR C,.Error POP HL ; убираем лишний адрес_возврата_в_вызвавшую_процедуру JP EXEC02 ;R07 CONTINUE EXECUTING PROGRAM @@ -999,7 +999,7 @@ TST_EXT: LD HL,EXE_EXT ; "EXE" ERREXE0: LD A,DSS_Error.sys.NOT_ENOUGH_MEMORY ERREXE: PUSH AF LD A,(EXE_FM) - CALL CLOSE + CALL CLOSE_FN _mDECTASK POP AF RET @@ -1166,7 +1166,7 @@ LEAVE: LD A,B ;[x] 25/10/23 close EXE FM POP AF ;CALL RES_FM - CALL CLOSE + CALL CLOSE_FN _mDECTASK ; POP AF @@ -1235,7 +1235,7 @@ M_PSP: LD HL,(CORE_BUFFERS.EXEBUFF.LD_ADDR) LD (HL),B INC HL ;!FIXIT тут восстанавливать правильный каталог - CALL CURRDSK + CALL CURDISK ADD A,'A' LD (HL),A INC HL diff --git a/DSS/FS/FAT/FAT.asm b/DSS/FS/FAT/FAT.asm new file mode 100644 index 0000000..5863482 --- /dev/null +++ b/DSS/FS/FAT/FAT.asm @@ -0,0 +1,829 @@ +;[BEGIN] +;//MODULE: FAT +;//CREATE: 19-05-1998 AUTHOR: Denis Parinov +;//UPDATE: 24-10-1999 DNS Restore module +;--------------------------------------------------------------- +;Rev Date Name Description +;--------------------------------------------------------------- +;RX01 10-02-1999 DNS UPGRADE FAT CASH +;--------------------------------------------------------------- + +;----------------------------------------------------------------------; +; Поиск записи каталога в списке каталога +; +; вход: a=атрибут записи +; выход: de'=индекс записи в списке каталога +; (HANDBUF) = file's direcory record +; CF - каталог не найден +SEARCH: +.Dir: LD A,FAT_ATTR.DIRECTORY + CALL SEARCH.Custom + RET NC + CP DSS_Error.sys.PATH_NOT_FOUND + 1 + RET C + ; + SCF + LD A,DSS_Error.sys.TOO_MANY_FILES_IN_DIR + RET + ; +.File: LD A,FAT_ATTR.NoDIRnoVolID +.Custom: EX AF,AF' ; A = 76ADLSHR + SET_PAGE_X DIRPAGE + ;PUSH AF + EX AF,AF' + ; + CPL + LD C,A + LD IX,DIRPAGE.buffer + ;!TEST 9/11/23 + ; EXX + ; LD DE,0 + ; EXX + ; +.loop: LD A,(IX+00) + OR A + JR Z,.error_file_not_found + CP #E5 ;!HARDCODE #E5 - запись в директории свободна, так как файл/директория были удалены + JR Z,.next_record + LD A,(IX+11) + AND C + JR NZ,.next_record + LD HL,MASKARE + LD D,XH + LD E,XL + LD B,11 + EX DE,HL +.loop_compare: + LD A,(DE) + CP '?' + JR Z,.next_char + CP (HL) + JR NZ,.next_record +.next_char: + INC HL + INC DE + DJNZ .loop_compare + ;!TEST 9/11/23 ;[x] some optimize + ; LD D,XH + ; LD E,XL + LD D,XH + LD E,XL + EXX + LD D,XH + LD E,XL + EXX + ; + LD HL,HANDBUF + EX DE,HL + LD BC,HANDBUF.SIZE + LDIR + ;POP AF + EX AF,AF' + OUT (SLOT3),A + EX AF,AF' + AND A + RET +.next_record: + ;!TEST 9/11/23 ;[x] some optimize + ; EXX + ; INC DE + ; EXX + ; + LD DE,#0020 ;!HARDCODE + ADD IX,DE + JR NC,.loop +.error_too_many_files: + ;POP AF + EX AF,AF' + OUT (SLOT3),A + LD A,DSS_Error.sys.TOO_MANY_FILES_IN_DIR + SCF + RET + ; +.error_file_not_found: + ;POP AF + EX AF,AF' + OUT (SLOT3),A + LD A,DSS_Error.sys.FILE_NOT_FOUND + SCF + RET +;----------------------------------------------------------------------; + +; +;!TODO ? +;GHANDLE: +; PUSH DE +; PUSH HL +; PUSH IX +; CALL TESTDSK +; JP C,G_HAND1 +; CALL LOADDIR +; POP DE +; LD HL,DIR +; LD BC,#0020 +;G_HAND2: +; LD A,D +; OR E +; JP Z,G_HAND3 +; ADD HL,BC +; DEC DE +; JP G_HAND2 +;G_HAND3: +; EXX +; POP DE +; EXX +;G_HAND4: +; EX DE,HL +; LD A,DIRPAGE +; CALL BANK +; EX DE,HL +; LD DE,HANDTA +; +; DUP 32 +; LDI +; EDUP +; +; EXX +; OUT (SLOT3),A +; LD HL,HANDTA +; +; DUP 32 +; LDI +; EDUP +; +; EXX +; POP BC +; DEC BC +; LD A,B +; OR C +; RET Z +; PUSH BC +; JP G_HAND4 +;G_HAND1 POP IX +; POP HL +; POP DE +; RET +;HANDTA BLOCK 32,0 +; + +;----------------------------------------------------------------------; +; FIND "MASKAREA" IN DIRECTORY +FINDDIR: + SET_PAGE_X DIRPAGE + ; + PUSH AF + LD IX,DIRPAGE.buffer +.big_loop: + LD A,(IX+00) + OR A + JR Z,.error + CP #E5 + JR Z,.next_step + LD A,(IX+11) ;!HARDCODE + AND #10 ;!HARDCODE + JR Z,.next_step + LD HL,MASKARE + LD D,XH + LD E,XL + EX DE,HL + LD B,11 ;!HARDCODE +.loop: LD A,(DE) + CP "?" + JR Z,.compared + CP (HL) + JR NZ,.next_step +.compared: + INC HL + INC DE + DJNZ .loop + ; + LD A,(IX+0) + CP "." + JP NZ,.ADDSPEC + LD A,(IX+1) ;!HARDCODE + CP "." + JP NZ,.IT_DIR + LD HL,WorkDirectory + LD D,H + LD E,L + INC HL + LD BC,WorkDirectory.DEPTH + XOR A + CPIR + JP PO,.error ;[x] 20/11/23 проверка на выход за границы + DEC HL ;R009 + DEC HL + LD BC,WorkDirectory.DEPTH + LD A,'\' + CPDR + INC HL + EX DE,HL + ; CF = 0 + SBC HL,DE + EX DE,HL + JR NZ,.MM3 + INC HL +.MM3: LD (HL),0 + JP .IT_DIR + ; +.next_step: + LD BC,#0020 ;!HARDCODE + ADD IX,BC + JR NC,.big_loop + ; +.error: POP AF + OUT (SLOT3),A + LD A,DSS_Error.sys.PATH_NOT_FOUND + SCF + RET +.ADDSPEC: + LD HL,WorkDirectory+1 + LD BC,WorkDirectory.DEPTH-1 + CALL .CHECK_SLASH + JR C,.error + ;R011 + LD A,B + AND A + JR NZ,.nxt + LD A,C + CP 8+1+3 ;!HARDCODE имя каталога + точка + расширение + JR C,.error +.nxt: ; + LD E,XL + LD D,XH + ; [x] оптимизация по размеру + EX DE,HL + CALL GetName + EX DE,HL + ; + +; LD BC,256*8 + ' ' ;!HARDCODE +; .MM1: LD A,(DE) +; INC DE +; CP C +; JR Z,.MM2 +; LD (HL),A +; INC HL +; .MM2 DJNZ .MM1 ;x42-40 50-55 +; LD A,(DE) +; INC DE +; CP C +; JR Z,.MM3 +; LD (HL),"." +; INC HL +; LD (HL),A +; INC HL +; LD A,(DE) +; INC DE +; CP C +; JR Z,.MM3 +; LD (HL),A +; INC HL +; LD A,(DE) +; CP C +; JR Z,.MM3 +; LD (HL),A +; .MM2_5: INC HL +; .MM3: LD (HL),0 +; ; JP IT_DIR + ; +.IT_DIR: + LD E,(IX+_sFM.ST_CLUSTER) + LD D,(IX+_sFM.ST_CLUSTER+1) + POP AF + OUT (SLOT3),A + AND A + RET +.CHECK_SLASH: + XOR A + CPIR + ;[x] 20/11/23 проверка на выход за границы + SCF + RET PO + ; + DEC HL + DEC HL + LD A,'\' ; #5C + CP (HL) + INC HL + RET Z + LD (HL),A + INC HL + RET +;----------------------------------------------------------------------; + + + +;----------------------------------------------------------------------; +; Прочитать список каталога +LOADDIR: + XOR A + LD H,A + LD L,A + LD IX,0 + LD B,A ; от начала файла + CALL MOVE_FP + + SET_PAGE_X DIRPAGE + + PUSH AF + ;!TEST no ldir + ; очистить кеш каталога + ; LD HL,#C000 + ; LD DE,#C001 + ; LD BC,#3FFF + ; LD (HL),L + ; LDIR + ; + ; + LD A,(FatBuffer.DRIVE) ; номер диска + LD (IY+_sFM.DRIVE),A ; сохр. в дескриптор + LD D,(IY+_sFM.ST_CLUSTER) ; de=номер первого кластера + LD E,(IY+_sFM.ST_CLUSTER+1) + LD A,D + OR E + JP Z,.LROTDIR ; root ?? + LD HL,DIRPAGE.buffer ; куда + LD DE,#4000 ; сколько + XOR A ; дескриптор + CALL READ ; чтение из файла + ;!FIXIT проверка на ошибку + LD (SAVEDIR.DIRSIZE),DE ; число прочит. байтов + POP AF + OUT (SLOT3),A + AND A + RET +.LROTDIR: + LD HL,(FatBuffer.DIR_FRH) ; ст. разряд + LD IX,(FatBuffer.DIR_FRL) ; номер лог. сектора + LD A,(FatBuffer.DIR_S_S) + ;!TEST + LD B,32 ; !HARDCODE 16384/(sector 512). размер root-каталога + CP B + JR NC,.RTD1 + LD B,A ; число секторов + ;LD B,32 ; !HARDCODE 16384/(sector 512). размер root-каталога + ;SUB B + ;JR NC,.RTD1 + ;ADD A,B + ;LD B,A ; число секторов + ; +.RTD1: LD A,(FatBuffer.DRIVE) ; номер диска + LD DE,DIRPAGE.buffer ; буфер + LD C,Dss.DRV.Read ; чтение секторов + RST ToDSS.DRV + POP AF + OUT (SLOT3),A + AND A + RET +;----------------------------------------------------------------------; + + + +;----------------------------------------------------------------------; +; скопировать запись в список диска (каталога) +; и сбросить кеш каталога на диск +WRT_HND: SET_PAGE_X DIRPAGE + EX AF,AF' + ; + LD IX,DIRPAGE.buffer + ;TEST 9/11/23 + ; EXX + ; LD DE,0 + ; EXX + ; +.loop: LD A,(IX+00) + OR A + JR Z,.WRT_HN2 + CP #E5 + JR Z,.WRT_HN2 + LD BC,#0020 + ADD IX,BC + JR NC,.loop + ; + EX AF,AF' + OUT (SLOT3),A + LD A,DSS_Error.sys.ROOT_OVERFLOW + SCF + RET +.WRT_HN2: + LD D,XH + LD E,XL + LD HL,HANDBUF + LD BC,HANDBUF.SIZE + LDIR + EX AF,AF' + OUT (SLOT3),A + LD HL,DIRPAGE.buffer + LD BC,(SAVEDIR.DIRSIZE) + DEC BC + ADD HL,BC + AND A + SBC HL,DE + JR NC,SAVEDIR + LD HL,(SAVEDIR.DIRSIZE) + LD BC,(FatBuffer.B_P_C) + ADD HL,BC + LD (SAVEDIR.DIRSIZE),HL + AND A + JP SAVEDIR +;----------------------------------------------------------------------; + +;!TODO FAT procedures +;----------------------------------------------------------------------; +; Сбросить кеш каталога на диск. +; вход: iy=структура дескриптора +SAVEDIR: + XOR A + LD HL,0 + LD IX,0 + LD B,0 + CALL MOVE_FP + ; + SET_PAGE_X DIRPAGE + PUSH AF + ; + LD A,(FatBuffer.DRIVE) + LD (IY+_sFM.DRIVE),A + LD D,(IY+_sFM.ST_CLUSTER) + LD E,(IY+_sFM.ST_CLUSTER+1) + LD A,D + OR E + JP Z,.SROTDIR + LD HL,DIRPAGE.buffer +; размер списка каталога size_cash_directory +.DIRSIZE+1: + LD DE,0 + XOR A + CALL WRITE + POP AF + OUT (SLOT3),A + AND A + RET +.SROTDIR: + LD HL,(FatBuffer.DIR_FRH) + LD IX,(FatBuffer.DIR_FRL) + LD A,(FatBuffer.DIR_S_S) + LD B,32 ;!HARDCODE + SUB B + JR NC,.RTD1S + ADD A,B + LD B,A +.RTD1S: LD A,(FatBuffer.DRIVE) + LD DE,DIRPAGE.buffer + LD C,Dss.DRV.Write + RST ToDSS.DRV + POP AF + OUT (SLOT3),A + AND A + RET +;----------------------------------------------------------------------; + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ; !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,CORE_BUFFERS.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,(CORE_BUFFERS.SECBUF+510) ;R08 ;R07 + ;R05 + AND A + SBC HL,DE + JP NZ,DOS_X_Error.UnknownBPB + ;R08 + LD HL,CORE_BUFFERS.SECBUF + LD DE,CORE_BUFFERS.BootSector + LD BC,_sBOOT_SEC ; size + LDIR + ; + + //LD IY,BootSector ; пока без индексного, но может пригодиться + //LD A,(IY+_sBOOT_SEC.ID_FORM) + LD A,(CORE_BUFFERS.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,(CORE_BUFFERS.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,(CORE_BUFFERS.BootSector.S_P_F) + + + LD A,(CORE_BUFFERS.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,(CORE_BUFFERS.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,(CORE_BUFFERS.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,(CORE_BUFFERS.BootSector.B_P_S) ; Size sector + + LD A,(CORE_BUFFERS.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,CORE_BUFFERS.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,(CORE_BUFFERS.BootSector.S_P_T) ; Sector per track + + LD A,(CORE_BUFFERS.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,(CORE_BUFFERS.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,(CORE_BUFFERS.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,(CORE_BUFFERS.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,(CORE_BUFFERS.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 (FAT_Max_Cluster),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 (FatCache),HL + + SET_PAGE_X FATPAGE + + PUSH AF + XOR A + CALL READ_FAT + POP AF + OUT (SLOT3),A + CALL R_CLUST + XOR A + RET + +.IBM_DOS: + LD A,(CORE_BUFFERS.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 ;!TODO не используются некоторые значения, но задумка неплохая))) +.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 +; +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +; + INCLUDE "FAT12_16.ASM" +; \ No newline at end of file diff --git a/DSS/FAT_X.ASM b/DSS/FS/FAT/FAT12_16.asm similarity index 86% rename from DSS/FAT_X.ASM rename to DSS/FS/FAT/FAT12_16.asm index 5c7e355..31cc955 100644 --- a/DSS/FAT_X.ASM +++ b/DSS/FS/FAT/FAT12_16.asm @@ -1,531 +1,538 @@ - -;[BEGIN] -;//MODULE: FAT_X -;//CREATE: 19-05-1998 AUTHOR: Denis Parinov -;//UPDATE: 24-10-1999 DNS Restore module -;--------------------------------------------------------------- -;Rev Date Name Description -;--------------------------------------------------------------- -;R01 10-02-1999 DNS UPGRADE FAT CASH -;--------------------------------------------------------------- - -; Установить начальный кластер для чтения -R_CLUST LD HL,#0001 - LD (G_CLUST.num),HL - RET - -; найти первый свободный кластер -G_CLUST: -.num+1: LD HL,#0001 -.loop: INC HL ; номер кластера - CALL R_F_FAT ; прочитать из кеша FAT-а номер след. кластера - CP DSS_Error.sys.DISK_FULL - SCF - RET Z ; ошибка ? - LD A,D - OR E - JR NZ,.loop - LD (G_CLUST.num),HL - XOR A - RET - -; HL - CLUSTER -INC_FAT PUSH HL - CALL G_CLUST - POP DE - RET C - PUSH HL - PUSH HL - EX DE,HL ; hl=номер кластера -.loop: CALL R_F_FAT ; прочитать из кеша FAT-а номер след. кластера - EX DE,HL - JR NC,.loop ; не конец цепочки - EX DE,HL - POP DE ; номер кластера - CALL W_T_FAT ; записать в кеш FAT-а номер кластера - POP HL - LD DE,(FatBuffer.ENDCLUS) ; номер кластера - CALL W_T_FAT ; записать в кеш FAT-а номер кластера - CALL WR_FAT ; подкл. банку кеша FAT и записать его на диск - AND A - RET - -;R01 - -;----------------------------------------------------------- -; Прочитать из кеша FAT-а номер след. кластера -; вход: hl = номер кластера -; выход: hl = номер кластера -; de = номер след. кластера -; CF - конец цепочки -;!FIXIT далее заточка на то, что в DE всегда 0 - раздел не больше 2Gb -;----------------------------------------------------------- -;!FIXIT отдаёт разный CF при удачном завершении в зависимости от FAT16/FAT12 -R_F_FAT: - EX DE,HL - LD HL,(FAT_Max_Cluster) - AND A - SBC HL,DE - EX DE,HL - LD A,DSS_Error.sys.DISK_FULL - RET C - - SET_PAGE_X FATPAGE - - PUSH HL - PUSH AF - LD A,(FatBuffer.FAT_TYP) - CP "2" ; fat12 - JR Z,R_F_F12 - ; fat16, просто читать след. номер -R_F_F16: - LD A,H - LD B,H - ;AND #0F - AND FAT_CACHE.Mask - LD H,A - LD A,B - ; A=A/16 ; A - BLOCK FAT (1 BLOCK = 8192 BYTES) - DUP FAT_CACHE.Degree - RRCA - EDUP - ;AND #0F - AND FAT_CACHE.Mask2 - ; - ADD HL,HL ; HL - FAT OFFSET (FROM CASH) - LD BC,(FatCache) ; C - BLOCK FAT IN CASH - CP C - CALL NZ,RE_FAT ; A != C - READ NEW BLOCK FAT - LD DE,FATPAGE.cache ; начало кеша FAT-а - ADD HL,DE ; на ячейку FAT - LD E,(HL) ; прочитать номер кластера - INC HL - LD D,(HL) - POP AF - OUT (SLOT3),A - LD HL,#FFEF ;!HARDCODE - XOR A ; DssErr.sys.NO_ERROR - SBC HL,DE ; проверка на служ. кластеры - POP HL - RET - -R_F_F12: - LD D,H - LD E,L - RR H - RR L ; сдвиг вправо через CF - PUSH AF ; сохр. флаг - ADD HL,DE ; CLUSTER * 1.5 - ; - ;!FIXIT херня какая-то - ;IF COMPILE_UNUSED_CODE - LD A,H - LD B,H - AND #1F - LD H,A - LD A,B - RLCA - RLCA - RLCA - AND #07 - LD BC,(FatCache) ; C - BLOCK FAT IN CASH - CP C - CALL NZ,RE_FAT ; прочитать в кеш 16 секторов FAT-а - ;ENDIF - ; - LD DE,FATPAGE.cache ; начало кеша FAT-а - ADD HL,DE ; на ячейку FAT - POP AF ; восст. флаг - LD E,(HL) - INC HL - LD D,(HL) - JR C,R_F_F01 - LD A,D - AND #0F - LD D,A - JP R_F_F02 - -R_F_F01: - LD A,E - AND #F0 - RR D ; вправо на 4 битa - RRA - RR D - RRA - RR D - RRA - RR D - RRA - LD E,A -R_F_F02: - POP AF - OUT (SLOT3),A - LD HL,#0FEF - XOR A ; обнуляем CF и устанавливаем код ошибки = нулю - SBC HL,DE ; проверка на служ. кластеры - POP HL - RET - -;----------------------------------------------------------- -; Записать в кеш FAT-а номер кластера -; вход: de = номер кластера -; hl = ? номер первого кластера -; выход: hl = ? номер след. кластера -; de = номер кластера -; in: HL - CLUSTER -; out: DE - (CLUSTER) -;----------------------------------------------------------- -W_T_FAT PUSH DE - EX DE,HL - LD HL,(FAT_Max_Cluster) - AND A - SBC HL,DE - EX DE,HL - POP DE - LD A,DSS_Error.sys.DISK_FULL - RET C - EXX - SET_PAGE_X FATPAGE - EXX - PUSH HL - PUSH AF - LD A,1 - LD (FatCache.Update),A - LD A,(FatBuffer.FAT_TYP) - CP "2" ; fat12 - JR Z,W_T_F12 -W_T_F16: - PUSH DE - LD A,H - LD B,H - ;AND #0F - AND FAT_CACHE.Mask - LD H,A - LD A,B - ; A=A/16 ; A - BLOCK FAT (1 BLOCK = 8192 BYTES) - DUP FAT_CACHE.Degree - RRCA - EDUP - ;AND #0F - AND FAT_CACHE.Mask2 - ; - ADD HL,HL ; HL - FAT OFFSET (FROM CASH) ;!HARDCODE fat16 - размер записи FAT - LD BC,(FatCache) ; C - BLOCK FAT IN CASH - CP C - CALL NZ,RE_FAT ; A != C - READ NEW BLOCK FAT - LD DE,FATPAGE.cache - ADD HL,DE ; на ячейку FAT - POP DE - LD (HL),E ; сохр. в кеше FAT-а - INC HL ; номер кластера - LD (HL),D - POP AF ; восст. порт - POP HL - OUT (SLOT3),A - XOR A - RET - ; - ; fat12 -W_T_F12: - PUSH DE - LD D,H - LD E,L - ; ADD HL,HL - ; ADD HL,DE - ; RR H - ; RR L ;CLUSTER * 1.5 - ; PUSH AF - RR H - RR L ; сдвиг вправо через CF - PUSH AF ; сохр. флаг - ADD HL,DE ; CLUSTER * 1.5 - ; - ;!FIXIT херня какая-то - ;IF COMPILE_UNUSED_CODE - LD A,H - LD B,H - AND #1F - LD H,A - LD A,B - RLCA - RLCA - RLCA - AND #07 - LD BC,(FatCache) ; C - BLOCK FAT IN CASH - CP C - CALL NZ,RE_FAT ; прочитать в кеш 16 секторов FAT-а - ;ENDIF - ; - LD DE,FATPAGE.cache - ADD HL,DE - POP AF - POP DE - JP C,W_T_F01 ; номер нечётный - LD (HL),E - INC HL - LD A,(HL) - AND #F0 - OR D - LD (HL),A - POP AF - POP HL - OUT (SLOT3),A - AND A - RET - - -W_T_F01:; влево на 4 битa - SLA E - LD A,E - RL D - RLA - RL D - RLA - RL D - RLA - RL D - LD E,A - ; - LD A,(HL) - AND #0F - OR E - LD (HL),A ; сохр. в кеше FAT-а - INC HL ; номер кластера - LD (HL),D - POP AF - POP HL - OUT (SLOT3),A - AND A - RET - -;R01 -; Прочитать в кеш 16 секторов FAT-а -; A - NEW FAT BLOCK -RE_FAT: PUSH HL - PUSH AF - LD A,(FatCache.Update) - OR A - CALL NZ,WR_FAT.Start - POP AF - LD L,A - LD H,0 - LD (FatCache),HL - ;FAT BLOCK * 16 = SECTOR OF FAT - DUP FAT_CACHE.Degree - ADD HL,HL ;x2 - EDUP - LD DE,(FatBuffer.FAT_FRM) - ADD HL,DE - EX DE,HL - ; - PUSH DE - POP IX - ;LD IX,0 - ;ADD IX,DE ; номер лог. сектора - ; - LD HL,0 ; ст. разряд ; HL:IX - SECTOR FAT FOR READING - LD DE,FATPAGE.cache ; куда ; DE - FAT ADDRESS - LD A,(FatBuffer.DRIVE) ; номер диска - LD BC,FAT_CACHE.Sectors*256 + Dss.DRV.Read ;рег B: 16 * 512 = 8192 (CASH SIZE) - RST ToDSS.DRV - POP HL - RET - -; Подключить банку кеша FAT и записать его на диск -WR_FAT: SET_PAGE_X FATPAGE - PUSH AF - CALL .Start ;!TODO нет контроля ошибок - POP AF - OUT (SLOT3),A - RET - ; Запись кеша (всего?) FAT-а на диск -.Start: LD HL,(FatCache) - LD H,0 - ;FAT BLOCK * 16 = SECTOR OF FAT - DUP FAT_CACHE.Degree - ADD HL,HL ;x2 - EDUP - PUSH HL - LD B,H - LD C,L ;BC - BLOCK OF FAT - LD DE,FAT_CACHE.Sectors - ADD HL,DE ;+ SIZE CASH (16 SECTORS) - LD A,E ;!HARDCODE ; MAX число секторов для чтения в кэш - LD DE,(CORE_BUFFERS.BootSector.S_P_F) ; секторов на FAT - AND A - SBC HL,DE - JR C,.WALLFAT - EX DE,HL - LD HL,FAT_CACHE.Sectors - ; CF = 0 - SBC HL,DE - JP C,.ERR - LD A,L -.WALLFAT: - LD H,B - LD L,C - LD DE,(FatBuffer.FAT_FRM) - ADD HL,DE - EX DE,HL - ; - PUSH DE - POP IX - ;LD IX,0 - ;ADD IX,DE ; номер лог. сектора - ; - LD HL,0 ; ст. разряд - ;HL:IX - SECTOR OF FAT FOR SAVE - LD DE,FATPAGE.cache ; откуда - LD B,A ; число секторов - LD C,Dss.DRV.Write ; запись секторов - LD A,(FatBuffer.DRIVE) ; номер диска - PUSH BC - RST ToDSS.DRV - POP BC ; b=число секторов - POP HL - LD DE,(FatBuffer.FAT2_XX) - ADD HL,DE - EX DE,HL - ; - PUSH DE - POP IX - ;LD IX,0 - ;ADD IX,DE ; номер лог. сектора - ; - LD DE,FATPAGE.cache - LD HL,0 - LD A,(FatBuffer.DRIVE) - LD C,Dss.DRV.Write - RST ToDSS.DRV - AND A ;!TODO нет контроля ошибок - ; -.ERR: LD A,0 - LD (FatCache.Update),A - RET NC - POP HL - ; CF = 1 - RET - - -FatCache: WORD #0000 -.Block EQU FatCache -.Update EQU FatCache+1 -FAT_Max_Cluster: WORD #0FF0 ; макс. число кластеров FAT12 (без служ.) - -;//MODULE: FAT_X -;[END] - - -;R01 - ;; HL - CLUSTER - ;; DE - (CLUSTER) - ; - ;R_F_FAT EX DE,HL - ; LD HL,(FAT_Max_Cluster) - ; AND A - ; SBC HL,DE - ; EX DE,HL - ; LD A,10 - ; RET C - ; PUSH HL - ; LD A,(FAT_TYP) - ; CP "2" - ; JP Z,R_F_F12 - ;R_F_F16 LD DE,768 ; DE - CLUSTERS IN CASH - ; XOR A - ;R_F_00H INC A ; HL - CLUSTER - ; SBC HL,DE - ; JP NC,R_F_00H - ; ADD HL,DE - ; ADD HL,HL ; HL - FAT OFFSET (FROM CASH) - ; DEC A - ; LD BC,(FatCache) ; A - ELEMENT OF CASH - ; CP C - ; CALL NZ,RE_FAT - ; LD DE,FAT - ; ADD HL,DE - ; LD E,(HL) - ; INC HL - ; LD D,(HL) - ; LD HL,#FFEF - ; AND A - ; SBC HL,DE - ; POP HL - ; LD A,0 - ; RET - ; - ;R_F_F12 LD D,H - ; LD E,L - ; ADD HL,HL - ; ADD HL,DE - ; RR H - ; RR L - ; PUSH AF - ; EX DE,HL - ; LD HL,(B_P_S) - ; LD B,H - ; LD C,L - ; ADD HL,HL - ; ADD HL,BC - ; EX DE,HL - ; XOR A ; DE - SIZE SECTOR * 3 - ;R_F_00 INC A ; HL - FAT OFFSET - ; SBC HL,DE - ; JP NC,R_F_00 - ; ADD HL,DE - ; DEC A - ; - ; - - ;WR_FAT LD HL,(FatCache) - ; LD H,0 - ; LD (FatCache),HL - ; LD E,L - ; LD D,H - ; ADD HL,HL - ; ADD HL,DE - ; PUSH HL - ; LD B,H - ; LD C,L - ; INC HL - ; INC HL - ; INC HL - ; LD DE,(S_P_F) - ; LD A,3 - ; AND A - ; SBC HL,DE - ; JP C,WR_FAT1 - ; EX DE,HL - ; LD HL,3 - ; AND A - ; SBC HL,DE - ; JP C,FATERR - ; LD A,L - ;WR_FAT1 LD H,B - ; LD L,C - ; LD DE,(FAT_FRM) - ; ADD HL,DE - ; EX DE,HL - ; LD IX,0 - ; ADD IX,DE - ; LD DE,FAT - ; LD HL,0 - ; LD B,A - ; LD C,6 - ; LD A,(DRIVE) - ; PUSH BC - ; RST #18 - ; POP BC - ; POP HL - ; LD DE,(FAT2_XX) - ; ADD HL,DE - ; EX DE,HL - ; LD IX,0 - ; ADD IX,DE - ; LD DE,FAT - ; LD HL,0 - ; LD A,(DRIVE) - ; LD C,6 - ; RST #18 - ; RET -; \ No newline at end of file +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +; FAT 12-16 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +;[BEGIN] +;//MODULE: FAT_X +;//CREATE: 19-05-1998 AUTHOR: Denis Parinov +;//UPDATE: 24-10-1999 DNS Restore module +;--------------------------------------------------------------- +;Rev Date Name Description +;--------------------------------------------------------------- +;RX01 10-02-1999 DNS UPGRADE FAT CASH +;--------------------------------------------------------------- + +; Установить начальный кластер для чтения +R_CLUST LD HL,#0001 + LD (G_CLUST.num),HL + RET + +; найти первый свободный кластер +G_CLUST: +.num+1: LD HL,#0001 +.loop: INC HL ; номер кластера + CALL R_F_FAT ; прочитать из кеша FAT-а номер след. кластера + CP DSS_Error.sys.DISK_FULL + SCF + RET Z ; ошибка ? + LD A,D + OR E + JR NZ,.loop + LD (G_CLUST.num),HL + XOR A + RET + +; HL - CLUSTER +INC_FAT PUSH HL + CALL G_CLUST + POP DE + RET C + PUSH HL + PUSH HL + EX DE,HL ; hl=номер кластера +.loop: CALL R_F_FAT ; прочитать из кеша FAT-а номер след. кластера + EX DE,HL + JR NC,.loop ; не конец цепочки + EX DE,HL + POP DE ; номер кластера + CALL W_T_FAT ; записать в кеш FAT-а номер кластера + POP HL + LD DE,(FatBuffer.ENDCLUS) ; номер кластера + CALL W_T_FAT ; записать в кеш FAT-а номер кластера + CALL WR_FAT ; подкл. банку кеша FAT и записать его на диск + AND A + RET + +;RX01 + +;----------------------------------------------------------- +; Прочитать из кеша FAT-а номер след. кластера +; вход: hl = номер кластера +; выход: hl = номер кластера +; de = номер след. кластера +; CF - конец цепочки +;!FIXIT далее заточка на то, что в DE всегда 0 - раздел не больше 2Gb +;----------------------------------------------------------- +;!FIXIT отдаёт разный CF при удачном завершении в зависимости от FAT16/FAT12 +R_F_FAT: + EX DE,HL + LD HL,(FAT_Max_Cluster) + AND A + SBC HL,DE + EX DE,HL + LD A,DSS_Error.sys.DISK_FULL + RET C + + SET_PAGE_X FATPAGE + + PUSH HL + PUSH AF + LD A,(FatBuffer.FAT_TYP) + CP "2" ; fat12 + JR Z,R_F_F12 + ; fat16, просто читать след. номер +R_F_F16: + LD A,H + LD B,H + ;AND #0F + AND FAT_CACHE.Size_Mask_16 + LD H,A + LD A,B + ; A=A/16 ; A - BLOCK FAT (1 BLOCK = 8192 BYTES) + DUP FAT_CACHE.Degree_16 + RRCA + EDUP + ;AND #0F + AND FAT_CACHE.Part_Mask_16 + ; + ADD HL,HL ; HL - FAT OFFSET (FROM CASH) + LD BC,(FatCache) ; C - BLOCK FAT IN CASH + CP C + CALL NZ,READ_FAT ; A != C - READ NEW BLOCK FAT + LD DE,FATPAGE.cache ; начало кеша FAT-а + ADD HL,DE ; на ячейку FAT + LD E,(HL) ; прочитать номер кластера + INC HL + LD D,(HL) + POP AF + OUT (SLOT3),A + LD HL,#FFEF ;!HARDCODE + XOR A ; DssErr.sys.NO_ERROR + SBC HL,DE ; проверка на служ. кластеры + POP HL + RET + ; +R_F_F12: + LD D,H + LD E,L + RR H + RR L ; сдвиг вправо через CF + PUSH AF ; сохр. флаг + ADD HL,DE ; CLUSTER * 1.5 + ; + ;!FIXIT херня какая-то + ;IF COMPILE_UNUSED_CODE + LD A,H + LD B,H + AND #1F + LD H,A + LD A,B + RLCA + RLCA + RLCA + AND #07 + LD BC,(FatCache) ; C - BLOCK FAT IN CASH + CP C + CALL NZ,READ_FAT ; прочитать в кеш 16 секторов FAT-а + ;ENDIF + ; + LD DE,FATPAGE.cache ; начало кеша FAT-а + ADD HL,DE ; на ячейку FAT + POP AF ; восст. флаг + LD E,(HL) + INC HL + LD D,(HL) + JR C,R_F_F01 + LD A,D + AND #0F + LD D,A + JP R_F_F02 + ; +R_F_F01: + LD A,E + AND #F0 + RR D ; вправо на 4 битa + RRA + RR D + RRA + RR D + RRA + RR D + RRA + LD E,A +R_F_F02: + POP AF + OUT (SLOT3),A + LD HL,#0FEF + XOR A ; обнуляем CF и устанавливаем код ошибки = нулю + SBC HL,DE ; проверка на служ. кластеры + POP HL + RET + +;----------------------------------------------------------- +; Записать в кеш FAT-а номер кластера +; вход: de = номер кластера +; hl = ? номер первого кластера +; выход: hl = ? номер след. кластера +; de = номер кластера +; in: HL - CLUSTER +; out: DE - (CLUSTER) +;----------------------------------------------------------- +W_T_FAT: + PUSH DE + EX DE,HL + LD HL,(FAT_Max_Cluster) + AND A + SBC HL,DE + EX DE,HL + POP DE + LD A,DSS_Error.sys.DISK_FULL + RET C + EXX + SET_PAGE_X FATPAGE + EXX + PUSH HL + PUSH AF + LD A,1 + LD (FatCache.Update),A + LD A,(FatBuffer.FAT_TYP) + CP "2" ; fat12 + JR Z,W_T_F12 +W_T_F16: + PUSH DE + LD A,H + LD B,H + ;AND #0F + AND FAT_CACHE.Size_Mask_16 + LD H,A + LD A,B + ; A=A/16 ; A - BLOCK FAT (1 BLOCK = 8192 BYTES) + DUP FAT_CACHE.Degree_16 + RRCA + EDUP + ;AND #0F + AND FAT_CACHE.Part_Mask_16 + ; + ADD HL,HL ; HL - FAT OFFSET (FROM CASH) ;!HARDCODE fat16 - размер записи FAT + LD BC,(FatCache) ; C - BLOCK FAT IN CASH + CP C + CALL NZ,READ_FAT ; A != C - READ NEW BLOCK FAT + LD DE,FATPAGE.cache + ADD HL,DE ; на ячейку FAT + POP DE + LD (HL),E ; сохр. в кеше FAT-а + INC HL ; номер кластера + LD (HL),D + POP AF ; восст. порт + POP HL + OUT (SLOT3),A + XOR A + RET + ; + ; fat12 +W_T_F12: ;!FIXIT переделать на переменные FAT_CACHE + PUSH DE + LD D,H + LD E,L + ; ADD HL,HL + ; ADD HL,DE + ; RR H + ; RR L ;CLUSTER * 1.5 + ; PUSH AF + RR H + RR L ; сдвиг вправо через CF + PUSH AF ; сохр. флаг + ADD HL,DE ; CLUSTER * 1.5 + ; + ;!FIXIT херня какая-то + ;IF COMPILE_UNUSED_CODE + LD A,H + LD B,H + AND #1F + LD H,A + LD A,B + RLCA + RLCA + RLCA + AND #07 + LD BC,(FatCache) ; C - BLOCK FAT IN CASH + CP C + CALL NZ,READ_FAT ; прочитать в кеш 16 секторов FAT-а + ;ENDIF + ; + LD DE,FATPAGE.cache + ADD HL,DE + POP AF + POP DE + JP C,W_T_F01 ; номер нечётный + LD (HL),E + INC HL + LD A,(HL) + AND #F0 + OR D + LD (HL),A + POP AF + POP HL + OUT (SLOT3),A + AND A + RET + ; +W_T_F01:; влево на 4 битa + SLA E + LD A,E + RL D + RLA + RL D + RLA + RL D + RLA + RL D + LD E,A + ; + LD A,(HL) + AND #0F + OR E + LD (HL),A ; сохр. в кеше FAT-а + INC HL ; номер кластера + LD (HL),D + POP AF + POP HL + OUT (SLOT3),A + AND A + RET + +;RX01 +;RE_FAT: +; Прочитать в кеш 16 секторов FAT-а +; A - NEW FAT BLOCK +READ_FAT: + PUSH HL + PUSH AF + LD A,(FatCache.Update) + OR A + CALL NZ,WR_FAT.Start + POP AF + LD L,A + LD H,0 + LD (FatCache),HL + ;FAT BLOCK ^ FAT_CACHE.Degree = SECTOR OF FAT + DUP FAT_CACHE.Degree_16 + ADD HL,HL ;x2 + EDUP + LD DE,(FatBuffer.FAT_FRM) + ADD HL,DE + EX DE,HL + ; + LD XH,D + LD XL,E + ;LD IX,0 + ;ADD IX,DE ; номер лог. сектора + ; + LD HL,0 ; ст. разряд ; HL:IX - SECTOR FAT FOR READING + LD DE,FATPAGE.cache ; куда ; DE - FAT ADDRESS + LD A,(FatBuffer.DRIVE) ; номер диска + LD BC,FAT_CACHE.Sectors*256 + Dss.DRV.Read ;рег B * FAT_CACHE.Sector_Size = CASH SIZE + RST ToDSS.DRV + POP HL + RET + +; Подключить банку кеша FAT и записать его на диск +WR_FAT: SET_PAGE_X FATPAGE + PUSH AF + CALL .Start ;!TODO нет контроля ошибок + POP AF + OUT (SLOT3),A + RET + ; Запись кеша (всего?) FAT-а на диск +.Start: LD HL,(FatCache) + LD H,0 + ;FAT BLOCK * 16 = SECTOR OF FAT + DUP FAT_CACHE.Degree_16 + ADD HL,HL ;x2 + EDUP + ; HL - номер лог. сектора + PUSH HL + LD B,H + LD C,L ;BC - BLOCK OF FAT + LD DE,FAT_CACHE.Sectors + ADD HL,DE ;+ SIZE CASH (16 SECTORS) + LD A,E ;!HARDCODE ; MAX число секторов для чтения в кэш + LD DE,(CORE_BUFFERS.BootSector.S_P_F) ; секторов на FAT + AND A + SBC HL,DE + JR C,.WALLFAT + EX DE,HL + LD HL,FAT_CACHE.Sectors + ; CF = 0 + SBC HL,DE + JP C,.ERR + LD A,L +.WALLFAT:; !TODO чёб сразу в IX не грузить FAT_FRM? + LD H,B + LD L,C + LD DE,(FatBuffer.FAT_FRM) + ADD HL,DE + EX DE,HL + ; + LD XH,D + LD XL,E + ;LD IX,0 + ;ADD IX,DE ; номер лог. сектора + ; + LD HL,0 ; ст. разряд + ;HL:IX - SECTOR OF FAT FOR SAVE + LD DE,FATPAGE.cache ; откуда + LD B,A ; число секторов + LD C,Dss.DRV.Write ; запись секторов + LD A,(FatBuffer.DRIVE) ; номер диска + PUSH BC + RST ToDSS.DRV + POP BC ; b=число секторов + POP HL + LD DE,(FatBuffer.FAT2_XX) + ADD HL,DE + EX DE,HL + ; + LD XH,D + LD XL,E + ;LD IX,0 + ;ADD IX,DE ; номер лог. сектора + ; + LD DE,FATPAGE.cache + LD HL,0 + LD A,(FatBuffer.DRIVE) + LD C,Dss.DRV.Write + RST ToDSS.DRV + AND A ;!TODO нет контроля ошибок + ; +.ERR: LD A,0 + LD (FatCache.Update),A + RET NC + POP HL + ; CF = 1 + RET + + + +FatCache: WORD #0000 +.Block EQU FatCache +.Update EQU FatCache+1 +FAT_Max_Cluster: WORD #0FF0 ; макс. число кластеров FAT12 (без служ.) + +;//MODULE: FAT_X +;[END] + + +;RX01 + ;; HL - CLUSTER + ;; DE - (CLUSTER) + ; + ;R_F_FAT EX DE,HL + ; LD HL,(FAT_Max_Cluster) + ; AND A + ; SBC HL,DE + ; EX DE,HL + ; LD A,10 + ; RET C + ; PUSH HL + ; LD A,(FAT_TYP) + ; CP "2" + ; JP Z,R_F_F12 + ;R_F_F16 LD DE,768 ; DE - CLUSTERS IN CASH + ; XOR A + ;R_F_00H INC A ; HL - CLUSTER + ; SBC HL,DE + ; JP NC,R_F_00H + ; ADD HL,DE + ; ADD HL,HL ; HL - FAT OFFSET (FROM CASH) + ; DEC A + ; LD BC,(FatCache) ; A - ELEMENT OF CASH + ; CP C + ; CALL NZ,READ_FAT + ; LD DE,FAT + ; ADD HL,DE + ; LD E,(HL) + ; INC HL + ; LD D,(HL) + ; LD HL,#FFEF + ; AND A + ; SBC HL,DE + ; POP HL + ; LD A,0 + ; RET + ; + ;R_F_F12 LD D,H + ; LD E,L + ; ADD HL,HL + ; ADD HL,DE + ; RR H + ; RR L + ; PUSH AF + ; EX DE,HL + ; LD HL,(B_P_S) + ; LD B,H + ; LD C,L + ; ADD HL,HL + ; ADD HL,BC + ; EX DE,HL + ; XOR A ; DE - SIZE SECTOR * 3 + ;R_F_00 INC A ; HL - FAT OFFSET + ; SBC HL,DE + ; JP NC,R_F_00 + ; ADD HL,DE + ; DEC A + ; + ; + + ;WR_FAT LD HL,(FatCache) + ; LD H,0 + ; LD (FatCache),HL + ; LD E,L + ; LD D,H + ; ADD HL,HL + ; ADD HL,DE + ; PUSH HL + ; LD B,H + ; LD C,L + ; INC HL + ; INC HL + ; INC HL + ; LD DE,(S_P_F) + ; LD A,3 + ; AND A + ; SBC HL,DE + ; JP C,WR_FAT1 + ; EX DE,HL + ; LD HL,3 + ; AND A + ; SBC HL,DE + ; JP C,FATERR + ; LD A,L + ;WR_FAT1 LD H,B + ; LD L,C + ; LD DE,(FAT_FRM) + ; ADD HL,DE + ; EX DE,HL + ; LD IX,0 + ; ADD IX,DE + ; LD DE,FAT + ; LD HL,0 + ; LD B,A + ; LD C,6 + ; LD A,(DRIVE) + ; PUSH BC + ; RST #18 + ; POP BC + ; POP HL + ; LD DE,(FAT2_XX) + ; ADD HL,DE + ; EX DE,HL + ; LD IX,0 + ; ADD IX,DE + ; LD DE,FAT + ; LD HL,0 + ; LD A,(DRIVE) + ; LD C,6 + ; RST #18 + ; RET +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/DSS/Media_drivers/ide-drv.asm b/DSS/Media_drivers/ide-drv.asm index ec9e206..b42a3cc 100644 --- a/DSS/Media_drivers/ide-drv.asm +++ b/DSS/Media_drivers/ide-drv.asm @@ -270,15 +270,15 @@ DRVCLC: ; INC A ;---------------------------------------------------------------------[^] ; ;+00 BYTE MASTER/SLAVE PHISICAL DRIVE NUMBER #80/#81/... -; ;+01 LONG SECTOR OFFSET -; ;+05 LONG SIZE IN SECTORS +; ;+01 DWORD SECTOR OFFSET +; ;+05 DWORD SIZE IN SECTORS ; ;+09 FREE ; ;+15 ; LOGDRV: BLOCK .TBL_Entry * LD_DSK,0 ;!FIXIT перенести к буферам в конец страницы ; .TBL_Entry EQU 16 ; .Size EQU $-LOGDRV - + ;!TODO заменить PUSH на EXX? SELHDD: PUSH DE PUSH BC PUSH HL @@ -420,9 +420,8 @@ RESE_H: XOR A STAT_H: XOR A RET -CHEK_H: - LD A,#FF - ;XOR A +CHEK_H: ;LD A,#FF + XOR A ;AND A RET diff --git a/DSS/Procedures.asm b/DSS/Procedures.asm new file mode 100644 index 0000000..dc14eb1 --- /dev/null +++ b/DSS/Procedures.asm @@ -0,0 +1,191 @@ +;!TODO Procedures +;----------------------------------------------------------------------; +; Закодировать время/дату +; вход: de - день/месяц +; hl - часы/минуты +; b - секунды +; ix - год +; выход: de - время +; bc - месяц/день +; ix - год +; +;INPUT: D - DAY; E - MONTH +; H - HOUR; L - MINUTE +; B - SECOND (0...59) +; IX- YEAR (0...65535) +;OUTPUT: DE - hhhhhmmmmmmsssss h - hour, m - min, s - sec/2 +; BC - yyyyyyymmmmddddd y - year, m - month, d - day +; (1980-2108) +MK_TIME: + LD A,L + RLCA + RLCA + SLA A + RL H + SLA A + RL H + SLA A + RL H + SRL B + OR B + LD L,A + + LD BC,#F844 ;(-1980) + ADD IX,BC + LD A,E + RLCA + RLCA + RLCA + RLCA + AND #F0 + LD B,XL + SLA A + RL B + OR D + LD C,A + EX DE,HL + AND A + RET +;----------------------------------------------------------------------; + +;!TODO Procedures +;----------------------------------------------------------------------; +; Раскодировать время/дату +; вход: de - время +; bc - месяц/день +; ix - год +; выход: de - день/месяц +; hl - часы/минуты +; b - секунды +; ix - год +; +;INPUT: DE - hhhhhmmmmmmsssss h - hour, m - min, s - sec/2 +; BC - yyyyyyymmmmddddd y - year, m - month, d - day +; (1980-2108) +;OUTPUT: D - DAY; E - MONTH +; H - HOUR; L - MINUTE +; B - SECOND (0...59) +; IX- YEAR (0...65535) +RMKTIME: + EX DE,HL + LD A,C + AND #1F + LD D,A + SRL B + RR C + LD A,C + RRCA + RRCA + RRCA + RRCA + AND #0F + LD E,A + LD C,B + LD B,0 + LD IX,1980 + ADD IX,BC + LD A,L + AND #1F + ADD A,A + LD B,A + SRL H + RR L + SRL H + RR L + SRL H + RR L + SRL L + SRL L + AND A + RET +;----------------------------------------------------------------------; + + + +;----------------------------------------------------------------------; +; a..z -> A..Z +UPPER: CP 'a' + RET C + CP 'z' + 1 + JR NC,.MDUPPER + SUB #20 +.NOUPPER: + RET +.MDUPPER: + CP 'а' ; русская буква а, код #A0 + JR C,.NOUPPER + CP 'п' ; русская буква п, код #B0 + JR NC,.BGUPPER + SUB #20 + RET +.BGUPPER: + CP 'р' ; русская буква р, код #E0 + JR C,.NOUPPER + CP 'Ё' ; русская буква Ё, код #F0 + JR NC,.HGUPPER + SUB #50 + RET +.HGUPPER: CP 'ё' ; русская буква ё, код #F1 + RET NZ + DEC A + RET +;----------------------------------------------------------------------; + + + +;!TODO hardware +;----------------------------------------------------------------------; +; Чтение регистров CMOS +; вход: d=номер регистра +RCMOS: LD C,BIOS.CMOS_RD + RST ToBIOS + ;JP BCD2HEX +; INPUT : A - BCD +; OUTPUT: A - HEX +BCD2HEX: + LD E,A + RRCA + RRCA + RRCA + RRCA + AND #0F + LD D,A + ADD A,A + ADD A,A + ADD A,D + ADD A,A + LD D,A + LD A,E + AND #0F + ADD A,D + RET +;----------------------------------------------------------------------; + +;!TODO hardware +;----------------------------------------------------------------------; +;!FIXIT переделать по доке на Даллас и заись в ячейки часов +; Запись регистров CMOS +; вход: d=номер регистра +WCMOS: CALL HEX2BCD + LD C,BIOS.CMOS_WR + JP ToBIOS + +; INPUT : A - HEX +; OUTPUT: A - BCD +HEX2BCD: + LD BC,#0AFF +.loop: INC C + SUB B + JR NC,.loop + ADD A,B + LD B,A + LD A,C + RLCA + RLCA + RLCA + RLCA + AND #F0 + OR B + RET +;----------------------------------------------------------------------; +; \ No newline at end of file diff --git a/DSS/build.txt b/DSS/build.txt index e8cbd7d..e9769c1 100644 --- a/DSS/build.txt +++ b/DSS/build.txt @@ -1 +1 @@ -734 \ No newline at end of file +759 \ No newline at end of file diff --git a/DSS/defines.inc b/DSS/defines.inc index 33862cb..c074761 100644 --- a/DSS/defines.inc +++ b/DSS/defines.inc @@ -15,23 +15,30 @@ define _shift _bit&1)) + _bit&2)) + _bit&4)) + _bit&8)) + _bit&16)) + _bit&32)) + _bit&64)) + _bit&128)) ; FAT_CACHE: -.Size EQU #2000 ; bytes -.Sector_Size EQU 512 +.Size EQU #2000 +.Sector_Size EQU #200 .Sectors EQU .Size / .Sector_Size -.bytes_record EQU 2 -.Degree EQU _shift ;.Sectors >>> (.Sectors/8) -.Mask EQU high (.Size/.bytes_record - 1) ;#07 ;.Sectors - 1 -.Mask2 EQU ((1<<(.bytes_record*8)) / (.Size/2))-1 +; for FAT16 +.bytes_record_16 EQU 2 +.Degree_16 EQU _shift +.Size_Mask_16 EQU high (.Size/.bytes_record_16 - 1) +.Part_Mask_16 EQU ((1<<(.bytes_record_16*8)) / (.Size/2))-1 +; for FAT12 +.bytes_record_12 EQU 2 +.Degree_12 EQU _shift +.Size_Mask_12 EQU high (.Size/.bytes_record_12 - 1) +.Part_Mask_12 EQU ((1<<(.bytes_record_12*8)) / (.Size/2))-1 + DISPLAY "bytes_record_16 = ",/H,.bytes_record_16 + DISPLAY "Degree_16 = ",/H,.Degree_16 + DISPLAY "Size_Mask_16 = ",/H,.Size_Mask_16 + DISPLAY "Part_Mask_16 = ",/H,.Part_Mask_16 + DISPLAY "bytes_record_12 = ",/H,.bytes_record_12 + DISPLAY "Degree_12 = ",/H,.Degree_12 + DISPLAY "Size_Mask_12 = ",/H,.Size_Mask_12 + DISPLAY "Part_Mask_12 = ",/H,.Part_Mask_12 ; undefine _bit undefine _shift - - DISPLAY ".Size = ",/A,.Size - DISPLAY ".Sectors = ",/A,.Sectors - DISPLAY ".Degree = ",/A,.Degree - DISPLAY ".Mask = ",/A,.Mask - DISPLAY ".Mask2 = ",/A,.Mask2 -; DISPLAY " test = ",/A, (1