From 9d0d096208526052128949febe861932ff47412e Mon Sep 17 00:00:00 2001 From: Tolik <85737314+Tolik-Trek@users.noreply.github.com> Date: Mon, 16 Dec 2024 22:14:32 +1000 Subject: [PATCH] .. --- DSS/API.asm | 26 +- DSS/API/Attribute.asm | 2 +- DSS/API/ChDir.asm | 2 +- DSS/API/Clear.asm | 14 + DSS/API/Create.asm | 2 +- DSS/API/Cursor.asm | 10 + DSS/API/Delete.asm | 2 +- DSS/API/Execute.ASM | 4 +- DSS/API/Find.asm | 2 +- DSS/API/GetVMod.asm | 14 + DSS/API/Locate.asm | 10 + DSS/API/MkDir.asm | 4 +- DSS/API/Move_FP.asm | 41 + DSS/API/Open.asm | 2 +- DSS/API/PChars.asm | 14 + DSS/API/PutChar.asm | 98 +++ DSS/API/RdChar.asm | 15 + DSS/API/Rename.asm | 2 +- DSS/API/RmDir.asm | 2 +- DSS/API/Scroll.asm | 105 +++ DSS/API/SelPage.asm | 20 + DSS/API/SetVMod.asm | 246 ++++++ DSS/API/Time.asm | 1 + DSS/API/WinCopy.asm | 23 + DSS/API/WinRest.asm | 23 + DSS/API/WrChar.asm | 23 + DSS/DOS_FM.ASM | 207 ----- DSS/DOS_Proc.asm | 158 +++- DSS/DSS-MAIN.ASM | 6 +- DSS/FS/CDFS.ASM | 3 + DSS/FS/{FAT/FAT_X.asm => FAT.asm} | 1208 +++++++++++++++++++++++++++- DSS/FS/FAT/FAT.asm | 1199 --------------------------- DSS/FS_Module.asm | 8 + DSS/Kernel_Panic.asm | 81 -- DSS/Procedures.asm | 86 +- DSS/VIDEO.ASM | 696 ---------------- DSS/drivers/media/ReScanDRV.ASM | 495 ++++++++++++ DSS/drivers/media/fdd-drv.asm | 417 ++++++++++ DSS/drivers/media/ide-drv.asm | 715 ++++++++++++++++ DSS/drivers/media/ram_disk-drv.asm | 533 ++++++++++++ DSS/drivers/media/shared-drv.asm | 290 +++++++ 41 files changed, 4572 insertions(+), 2237 deletions(-) create mode 100644 DSS/API/Clear.asm create mode 100644 DSS/API/Cursor.asm create mode 100644 DSS/API/GetVMod.asm create mode 100644 DSS/API/Locate.asm create mode 100644 DSS/API/Move_FP.asm create mode 100644 DSS/API/PChars.asm create mode 100644 DSS/API/PutChar.asm create mode 100644 DSS/API/RdChar.asm create mode 100644 DSS/API/Scroll.asm create mode 100644 DSS/API/SelPage.asm create mode 100644 DSS/API/SetVMod.asm create mode 100644 DSS/API/WinCopy.asm create mode 100644 DSS/API/WinRest.asm create mode 100644 DSS/API/WrChar.asm delete mode 100644 DSS/DOS_FM.ASM create mode 100644 DSS/FS/CDFS.ASM rename DSS/FS/{FAT/FAT_X.asm => FAT.asm} (56%) delete mode 100644 DSS/FS/FAT/FAT.asm create mode 100644 DSS/FS_Module.asm delete mode 100644 DSS/Kernel_Panic.asm delete mode 100644 DSS/VIDEO.ASM create mode 100644 DSS/drivers/media/ReScanDRV.ASM create mode 100644 DSS/drivers/media/fdd-drv.asm create mode 100644 DSS/drivers/media/ide-drv.asm create mode 100644 DSS/drivers/media/ram_disk-drv.asm create mode 100644 DSS/drivers/media/shared-drv.asm diff --git a/DSS/API.asm b/DSS/API.asm index bded5af..5cb89d0 100644 --- a/DSS/API.asm +++ b/DSS/API.asm @@ -11,9 +11,9 @@ ;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 +;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 @@ -21,6 +21,8 @@ ;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 +;R101 07-11-2002 DNS FIX BUG WITH SCROLLUP FN. (A=0) +;R102 07-11-2002 DNS CORRECT FN. WINCOPY & WINREST, ADD "DI+EI" ;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 @@ -28,10 +30,23 @@ ;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" - ; ;--------------------------------------------------------------- - + ; VIDEO + include 'API/Clear.asm' + include 'API/PChars.asm' + include 'API/PutChar.asm' + include 'API/Locate.asm' + include 'API/Cursor.asm' + include 'API/RdChar.asm' + include 'API/WrChar.asm' + include 'API/WinCopy.asm' + include 'API/WinRest.asm' + include 'API/Scroll.asm' + include 'API/SelPage.asm' + include 'API/GetVMod.asm' + include 'API/SetVMod.asm' + ; include 'API/Version.asm' include 'API/bootDsk.asm' include 'API/curDisk.asm' @@ -67,6 +82,7 @@ include 'API/Lib_Sub.asm' include "API/EXECUTE.ASM" include "API/Print.asm" + include "API/Move_FP.asm" diff --git a/DSS/API/Attribute.asm b/DSS/API/Attribute.asm index 8f07db9..27b8259 100644 --- a/DSS/API/Attribute.asm +++ b/DSS/API/Attribute.asm @@ -74,7 +74,7 @@ ATTRIB: ;!TEST Current Dir ;[x] 15/10/23 .OPENATR: ;!TEST ;[x] 16/11/23 optimize get attribute ;LD (OPEN.TMP),A ; раб. ячейка (здесь атрибут записи) ; - CALL GETWORD ; тест на допуст. имя и настр. на диск + CALL SetPath_GetName ; тест на допуст. имя и настр. на диск RET C ; [ ] 26/06/2024 CALL CHECK_64kb_CLUSTER diff --git a/DSS/API/ChDir.asm b/DSS/API/ChDir.asm index 5a50614..ff2a5a4 100644 --- a/DSS/API/ChDir.asm +++ b/DSS/API/ChDir.asm @@ -34,7 +34,7 @@ CHDIR_FN: POP AF RET ; -CHDIR: CALL GETWORD ; тест на допуст. имя и настр. на диск +CHDIR: CALL SetPath_GetName ; тест на допуст. имя и настр. на диск RET C LD HL,TMPNAME LD A,(HL) diff --git a/DSS/API/Clear.asm b/DSS/API/Clear.asm new file mode 100644 index 0000000..85b994d --- /dev/null +++ b/DSS/API/Clear.asm @@ -0,0 +1,14 @@ +;/////////////////////////////////////////////////////////////////////// +; Функция #56. Очистить окно. +; +; вход: D - строка левого верхнего угла окна +; E - столбец левого верхнего угла окна +; H - высота окна +; L - ширина окна +; A - символ заполнитель +; B - атрибут заполнитель +; выход: нет +;/////////////////////////////////////////////////////////////////////// +CLEAR: LD C,BIOS.LP_CLS_WIN2 + JP ToBIOS +;/////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/DSS/API/Create.asm b/DSS/API/Create.asm index d41492b..05de412 100644 --- a/DSS/API/Create.asm +++ b/DSS/API/Create.asm @@ -106,7 +106,7 @@ CREATE: ;!TEST Current Dir ;[x] 15/10/23 ;CREATE_FN: AND FAT_ATTR.NoDIRnoVolID LD (.TMP),A LD (.PATH0),HL - CALL GETWORD + CALL SetPath_GetName RET C ; [ ] 26/06/2024 CALL CHECK_64kb_CLUSTER diff --git a/DSS/API/Cursor.asm b/DSS/API/Cursor.asm new file mode 100644 index 0000000..69354c4 --- /dev/null +++ b/DSS/API/Cursor.asm @@ -0,0 +1,10 @@ +;/////////////////////////////////////////////////////////////////////// +; Функция #53. Узнать положение курсора. +; +; вход: нет +; выход: D - строка курсора +; E - колонка курсора +;/////////////////////////////////////////////////////////////////////// +CURSOR: LD C,BIOS.LP_GET_PLACE + JP ToBIOS +;/////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/DSS/API/Delete.asm b/DSS/API/Delete.asm index 8c032f4..7f4b863 100644 --- a/DSS/API/Delete.asm +++ b/DSS/API/Delete.asm @@ -17,7 +17,7 @@ DEL_FN: ;!TEST POP HL RET C ; -.old_EXE: CALL GETWORD ; тест на допуст. имя и настр. на диск +.old_EXE: CALL SetPath_GetName ; тест на допуст. имя и настр. на диск RET C ; [ ] 26/06/2024 CALL CHECK_64kb_CLUSTER diff --git a/DSS/API/Execute.ASM b/DSS/API/Execute.ASM index 7f22599..e663ac3 100644 --- a/DSS/API/Execute.ASM +++ b/DSS/API/Execute.ASM @@ -96,7 +96,7 @@ EXEC_1: ;LD (CMDLINE),HL LD HL,(CMDLINE) LD A,FAT_ATTR.READ_ONLY LD (OPEN_FN.TMP),A - CALL GETWORD + CALL SetPath_GetName RET C ; LD HL,TMPNAME ; LD DE,MASKARE @@ -407,7 +407,7 @@ FRC000: LD A,(DE) CALL MOVE_FP ; LD SP,#403F ;R02 ;!HARDCODE STACK before start EXE. Устанавливается когда воткнуты SHARED_PAGE -_ret+1: JP 0 +_ret+1: JP 0 ;EXEC02.RET1 или _RET_2 _TST_PROC_2: LD SP,(CORE_BUFFERS.EXEBUFF.SP_REG) LD HL,(CORE_BUFFERS.EXEBUFF.LD_ADDR) diff --git a/DSS/API/Find.asm b/DSS/API/Find.asm index 3aeef59..398de00 100644 --- a/DSS/API/Find.asm +++ b/DSS/API/Find.asm @@ -30,7 +30,7 @@ F_FIRST_FN: CALL F_FIRST.INIT_VARS JR F_FIRST.begin ; F_FIRST: CALL .INIT_VARS -.begin: CALL GETWORD +.begin: CALL SetPath_GetName ;CALL LOADDIR RET C CALL MASK diff --git a/DSS/API/GetVMod.asm b/DSS/API/GetVMod.asm new file mode 100644 index 0000000..db35484 --- /dev/null +++ b/DSS/API/GetVMod.asm @@ -0,0 +1,14 @@ +;/////////////////////////////////////////////////////////////////////// +; Функция #51. Получить текущий режим экрана. +; +; вход: нет +; выход: A - текущий режим экрана +; B - страница экрана 0/1 +;/////////////////////////////////////////////////////////////////////// +GETVMOD: + IN A,(SCREEN_SWITCH) + LD B,A + LD A,(VMODE) + AND A + RET +;/////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/DSS/API/Locate.asm b/DSS/API/Locate.asm new file mode 100644 index 0000000..b0c96a2 --- /dev/null +++ b/DSS/API/Locate.asm @@ -0,0 +1,10 @@ +;/////////////////////////////////////////////////////////////////////// +; Функция #52. Установить положение курсора. +; +; вход: D - строка курсора +; E - колонка курсора +; выход: нет +;/////////////////////////////////////////////////////////////////////// +LOCATE: LD C,BIOS.LP_SET_PLACE + JP ToBIOS +;/////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/DSS/API/MkDir.asm b/DSS/API/MkDir.asm index 581ec75..d4a04e1 100644 --- a/DSS/API/MkDir.asm +++ b/DSS/API/MkDir.asm @@ -32,7 +32,7 @@ MKDIR: POP AF RET ; -.START: CALL GETWORD ; тест на допуст. имя и настр. на диск +.START: CALL SetPath_GetName ; тест на допуст. имя и настр. на диск RET C ; [ ] 26/06/2024 CALL CHECK_64kb_CLUSTER @@ -40,7 +40,7 @@ MKDIR: ; CALL MASK RET C - ;!TEST optimization ранее GETWORD уже загрузил директорию + ;!TEST optimization ранее SetPath_GetName уже загрузил директорию ;CALL LOADDIR ; прочитать список каталога ; CALL SEARCH.Dir ; поиск записи каталога в списке диска diff --git a/DSS/API/Move_FP.asm b/DSS/API/Move_FP.asm new file mode 100644 index 0000000..829277e --- /dev/null +++ b/DSS/API/Move_FP.asm @@ -0,0 +1,41 @@ +; HL:IX - OFFSET POINTER +; A - FILE MANIPULATOR +MOVE_FP: CALL SET_FM + RET C + INC B + DJNZ .B_1 + ;from Start File + ; B=0 +.F_start: LD C,B + LD D,B + LD E,B + JP .DO + ; +.B_1: DJNZ .B_2 + ;from Current Position +.F_current: LD C,(IY+_sFM.F_POSITION) + LD B,(IY+_sFM.F_POSITION+1) + LD E,(IY+_sFM.F_POSITION+2) + LD D,(IY+_sFM.F_POSITION+3) +.DO: ADD IX,BC + ADC HL,DE + LD D,XH + LD E,XL + LD (IY+_sFM.F_POSITION),E + LD (IY+_sFM.F_POSITION+1),D + LD (IY+_sFM.F_POSITION+2),L + LD (IY+_sFM.F_POSITION+3),H + XOR A + RET + ; +.B_2: DJNZ .error + ;from End File +.B_end: LD C,(IY + _sFM.FS_REC.F_SIZE) + LD B,(IY + _sFM.FS_REC.F_SIZE+1) + LD E,(IY + _sFM.FS_REC.F_SIZE+2) + LD D,(IY + _sFM.FS_REC.F_SIZE+3) + JP .DO + ; B > 2 +.error: LD A,DSS_Error.sys.INVALID_FUNCTION + SCF + RET diff --git a/DSS/API/Open.asm b/DSS/API/Open.asm index d0393f2..3972010 100644 --- a/DSS/API/Open.asm +++ b/DSS/API/Open.asm @@ -29,7 +29,7 @@ OPEN_FN: ;!TEST Current Dir ;[x] 15/10/23 .old_EXE: ;JR .start ;!FIXIT сделать как в mkdir или rmdir? ;R008 ; -.start: CALL GETWORD +.start: CALL SetPath_GetName RET C CALL MASK RET C diff --git a/DSS/API/PChars.asm b/DSS/API/PChars.asm new file mode 100644 index 0000000..abad0f8 --- /dev/null +++ b/DSS/API/PChars.asm @@ -0,0 +1,14 @@ +;/////////////////////////////////////////////////////////////////////// +; Функция #5C. Вывод строки на экран. +; +; вход: HL - указатель на строку символов +; выход: HL - указатель на следующую строку символов +; PRINT NULL-TERMINATED CHARS STRING +;/////////////////////////////////////////////////////////////////////// +PCHARS: LD A,(HL) + INC HL + OR A + RET Z + CALL PUTCHAR + JP PCHARS +;/////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/DSS/API/PutChar.asm b/DSS/API/PutChar.asm new file mode 100644 index 0000000..13cf58b --- /dev/null +++ b/DSS/API/PutChar.asm @@ -0,0 +1,98 @@ +;/////////////////////////////////////////////////////////////////////// +; Функция #5B. Вывод символа на экран в тек. позиции. +; +; вход: A - символ +; выход: нет +;/////////////////////////////////////////////////////////////////////// +PUTCHAR: ;CALL .NO_SCROLL + CP #0E + JR C,.control_characters + ; + LD BC,1*256 + BIOS.LP_PRINT_SYM + ;[x] CR+LF+SCROLL + RST ToBIOS + ; + ; проверка на переход курсора в самое начало (X:Y == 0:0) + CALL CURSOR + LD A,D + OR E + RET NZ + ; +.LFF: PUSH HL + LD BC,1*256 + BIOS.LP_SCROLL_UD + LD DE,#0020 + RST ToBIOS + LD DE,#1F00 + CALL LOCATE + LD A,' ' + LD BC,#50*256 + BIOS.LP_PRINT_SYM + RST ToBIOS + LD DE,#1F00 + CALL LOCATE + POP HL + RET +.TB_: CALL CURSOR + IF TABisSPACES + LD B,E + LD A,E + AND #F8 + ADD A,8 + SUB B + LD B,A + LD A,' ' + LD C,BIOS.LP_PRINT_SYM + JP ToBIOS + ELSE + LD A,E + ADD A,8 + AND #78 ;????? глянуть, что будет если координаты курсора в конце строки почти + LD E,A + JP LOCATE + ENDIF +.BK_: CALL CURSOR + XOR A + CP E + RET Z + DEC E + JP LOCATE + ; +.LF_: CALL CURSOR + LD A,D + CP #1F + JR NC,.LFF + INC D + IFN EnoughtOnly_LF + JP LOCATE + ELSE + CALL LOCATE + ; !!!! НЕ разрывать LF_ и CR_ !!!! + ENDIF +.CR_: CALL CURSOR + LD E,0 + JP LOCATE + ; +.control_characters: + CP "\r" + JR Z,.CR_ + CP "\n" + JR Z,.LF_ + CP "\t" ; tab + JR Z,.TB_ + CP "\b" ; backspace + JR Z,.BK_ + CP "\a" ; [x] Beep in PChars/PUTCHAR + RET NZ + ; [x] Beep in PChars/PUTCHAR +.BELL: LD DE,1200 + PUSH HL + LD HL,4 + CALL BEEP + POP HL + RET + ; +; [x] -bug with Vasil's version of cursor +.NO_SCROLL: CP #0E + JR C,.control_characters +._CHAR: LD BC,1*256 + BIOS.LP_PRINT_SYM + JP ToBIOS +;/////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/DSS/API/RdChar.asm b/DSS/API/RdChar.asm new file mode 100644 index 0000000..5619238 --- /dev/null +++ b/DSS/API/RdChar.asm @@ -0,0 +1,15 @@ +;/////////////////////////////////////////////////////////////////////// +; Функция #57. Прочитать символ с экрана. +; +; вход: D - строка +; E - колонка +; выход: A - символ +; B - атрибут +;/////////////////////////////////////////////////////////////////////// +RDCHAR: XOR A + LD C,BIOS.WIN_GET_SYM + RST ToBIOS + LD A,L + LD B,H + RET +;/////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/DSS/API/Rename.asm b/DSS/API/Rename.asm index 4acb58f..2363f36 100644 --- a/DSS/API/Rename.asm +++ b/DSS/API/Rename.asm @@ -25,7 +25,7 @@ RENAME: ;!TEST Current Dir ;[x] 15/10/23 RET C ; .old_EXE: ; - ; !TODO воткнуть тут GETWORD, чтоб можно было удалять по относительным путям? + ; !TODO воткнуть тут SetPath_GetName, чтоб можно было удалять по относительным путям? ; ; [ ] 26/06/2024 PUSH HL diff --git a/DSS/API/RmDir.asm b/DSS/API/RmDir.asm index 4df8bfd..772e8f3 100644 --- a/DSS/API/RmDir.asm +++ b/DSS/API/RmDir.asm @@ -28,7 +28,7 @@ RMDIR: ;!TEST Current Dir ;[x] 15/10/23 POP AF RET ; -.START: CALL GETWORD +.START: CALL SetPath_GetName RET C ; [ ] 26/06/2024 CALL CHECK_64kb_CLUSTER diff --git a/DSS/API/Scroll.asm b/DSS/API/Scroll.asm new file mode 100644 index 0000000..dd7793d --- /dev/null +++ b/DSS/API/Scroll.asm @@ -0,0 +1,105 @@ +;/////////////////////////////////////////////////////////////////////// +; Функция #55. Скроллинг экрана. +; +; вход: D - строка левого верхнего угла окна +; E - колонка левого верхнего угла окна +; H - высота окна +; L - ширина окна +; B = 1 - прокрутка вверх +; B = 2 - прокрутка вниз +; A = 0 - очищать строку +; выход: нет +;/////////////////////////////////////////////////////////////////////// +SCROLL: DJNZ .SCR_DW ;!TODO заменить на BIOS.LP_SCROLL_UD и посмотреть, что шустрее + ;[x] 04/04/23 + ;LD B,A + ;LD C,H + ;PUSH BC + PUSH AF + ; + PUSH DE + PUSH HL + LD XH,D + LD XL,E + INC D + DEC H + LD C,BIOS.WIN_MOVE + ;[x] 29/9/23 + LD A,R + PUSH AF + ; + XOR A + DI ;[x] 29/9/23 + RST ToBIOS + ;[x] 29/9/23 + POP AF + JP PO,.skip_EI + EI +.skip_EI: + POP HL + POP DE + ;[x] 04/04/23 + ;POP BC + POP AF + ;XOR A + ;CP B + AND A + ; + RET NZ + LD A,D + ADD A,H + DEC A ;R101 + LD D,A +.print: PUSH DE ;R101 + CALL LOCATE + LD A,' ' + LD B,L + LD C,BIOS.LP_PRINT_SYM + RST ToBIOS + POP DE ;R101 + JP LOCATE ;R101 + ;AND A + ;RET +.SCR_DW: + DJNZ .SCR_ERR + ;[x] 04/04/23 + ;LD B,A + ;LD C,H + ;PUSH BC + PUSH AF + ; + PUSH DE + PUSH HL + LD XH,D + LD XL,E + INC XH + DEC H + LD C,BIOS.WIN_MOVE + ;[x] 29/9/23 + LD A,R + PUSH AF + ; + XOR A + DI ;[x] 29/9/23 + RST ToBIOS + ; [x] 29/9/23 + POP AF + JP PO,.skip2_EI: + EI +.skip2_EI: + POP HL + POP DE + ;[x] 29/9/23 + ;POP BC + POP AF + ;XOR A + ;CP B + AND A + ; + RET NZ + JP SCROLL.print +.SCR_ERR: + LD A,DSS_Error.sys.INVALID_FUNCTION + SCF + RET +;/////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/DSS/API/SelPage.asm b/DSS/API/SelPage.asm new file mode 100644 index 0000000..acb30ac --- /dev/null +++ b/DSS/API/SelPage.asm @@ -0,0 +1,20 @@ +;/////////////////////////////////////////////////////////////////////// +; Функция #54. Выбрать активную страницу экрана. +; +; вход: B - страница экрана 0/1 +; выход: A - код ошибки, если CF=1 +;/////////////////////////////////////////////////////////////////////// +SELPAGE: + LD A,(VMODE) + ;BIT 7,A + CP %1000'0000 + JR NC,.SEL2 + PUSH BC + LD C,A + CALL SETVMOD.TEXT_M + POP BC +.SEL2: LD A,B + AND #01 + OUT (SCREEN_SWITCH),A + RET +;/////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/DSS/API/SetVMod.asm b/DSS/API/SetVMod.asm new file mode 100644 index 0000000..aef9699 --- /dev/null +++ b/DSS/API/SetVMod.asm @@ -0,0 +1,246 @@ +;/////////////////////////////////////////////////////////////////////// +; Функция #50. Выбор режима экрана. +; +; вход: A - режим экрана +; #02 - текстовый 40x32x16 цветов +; #03 - текстовый 80x32x16 цветов +; #81 - графический 320x256x256 цветов +; #82 - графический 640x256x16 цветов +; B - страница экрана 0/1 +; выход: A - код ошибки, если CF=1 +;/////////////////////////////////////////////////////////////////////// +SETVMOD: CP %1000'0000 + LD C,A + JR NC,.GRAPH +.TEXT_M: LD IX,BACKTXT + PUSH IX + EX AF,AF' + LD A,(VMODE) + LD (BACKTXT.VMODE),A + EX AF,AF' + OR A + JR Z,.NOMODE + DEC A + JR Z,.NOMODE + DEC A + LD HL,TAB_40x32 + JR Z,.SET_TXT_MODE + DEC A + LD HL,TAB_80x32 + JR Z,.SET_TXT_MODE +.NOMODE: POP IX + LD A,DSS_Error.sys.INVALID_VIDEO_MODE + SCF + RET + +; Установка граф. режимов +.GRAPH: CALL SAVETXT + AND #7F + JR Z,.G320_16 ; !TODO ? - пока отрабатывает как ошибка + DEC A + JR Z,.G320_56 + DEC A + JR Z,.G640_16 + ;DEC A + ;JP Z,.G640_56 ; !TODO ? - пока отрабатывает как ошибка +.G320_16: LD A,DSS_Error.sys.INVALID_VIDEO_MODE + SCF + RET + ; +.SET_TXT_MODE: PUSH BC + LD A,B + RLCA + RLCA + RLCA + RLCA + OR B + AND #11 + XOR #10 + LD E,A +.SETMODE_END: CALL SETMODE + POP BC + LD A,C + LD (VMODE),A + LD A,B + AND #01 + OUT (SCREEN_SWITCH),A + LD A,(VMODE) + LD C,Dss.Mouse.SetVideoMode + RST ToDSS.Mouse + SAFE_PORTY + XOR A + RET + ; +.G320_56: PUSH BC + LD HL,TAB_320x256_0 + LD E,#11 + CALL SETMODE + LD HL,TAB_320x256_1 + LD E,#00 + JP .SETMODE_END + ; +.G640_16: PUSH BC + LD HL,TAB_640x256_0 + LD E,#11 + CALL SETMODE + LD HL,TAB_640x256_1 + LD E,#00 + JP .SETMODE_END + ; +VMODE: DB #03 + +;----------------------------------------------------------------------- +; Открыть окно +; вход: hl=описатель окна +; e=флаги окна +; +;02h - TEXT 40 x 32 (16 colors) +;03h - TEXT 80 x 32 (16 colors) +;80h - GRAF 320 x 256 (16 colors) +;81h - GRAF 320 x 256 (256 colors) +;82h - GRAF 640 x 256 (16 colors) +;83h - GRAF 640 x 256 (256 colors) UNUSED +;----------------------------------------------------------------------- +SETMODE: PUSH DE + LD DE,SYS_PAGE.SHARED_BUFFER_32b ; грязный хак. кидает данные в буфер служебной страницы биоса. + LD BC,ScreenDescriptorTable.Size ; БИОС при использовании IX предполагает, что он указывает + IN A,(SLOT3) ; на адрес ниже #C000 и вставляет в третью банку страницу #FE + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LDIR + EX AF,AF' + OUT (SLOT3),A +.skip_EI: POP DE + LD IX,SYS_PAGE.SHARED_BUFFER_32b ; грязный хак. + LD C,BIOS.WIN_OPEN + RST ToBIOS + SAFE_PORTY + XOR A + RET + +;IX+0 ;HORIZONTAL +;IX+1 ;VERTICAL +;IX+2 ;X - COORD +;IX+3 ;Y - COORD +;IX+4 ;MODE +;IX+5 ;EXT MODE +;IX+6 ;VIDEO RAM X OFFSET (SIGNPLACES) +;IX+7 ;VIDEO RAM Y OFFSET (SIGNPLACES) + +; +;....................................................................... +;+0 X размер окна в знакоместах +;+1 Y размер окна в знакоместах +;+2 X полож. окна на экране +;+3 Y полож. окна на экране +;+4 режим знакоместа +;+5 доп. режим знакоместа (bit0=1 спек. адресация экрана) +;+6 X полож. в поле графики (в знакоместах) +;+7 Y полож. в поле графики (в знакоместах) +ScreenDescriptorTable EQU $ +; 80x32. текстовое, знакоместо 16x8, #0B - номер знакоген. +TAB_80x32 DB #28,#20,#00,#00,#1B,#00,#00,#00 ;1 +; 40x32. текстовое, знакоместо 8x8, #0B - номер знакоген. +TAB_40x32 DB #28,#20,#00,#00,#3B,#00,#00,#00 ;2 +; 640x256. графическое, 0-й экран +TAB_640x256_0 DB #28,#20,#00,#00,#00,#00,#00,#00 ;3 +; 320x256. графическое, 0-й экран +TAB_320x256_0 DB #28,#20,#00,#00,#20,#00,#00,#00 ;4 +; 640x256. графическое, 1-й экран +TAB_640x256_1 DB #28,#20,#00,#00,#40,#00,#28,#00 ;5 +; 320x256. графическое, 1-й экран +TAB_320x256_1 DB #28,#20,#00,#00,#60,#00,#28,#00 ;6 +ScreenDescriptorTable.Size EQU ($ - ScreenDescriptorTable)/6 +;....................................................................... +; + +;----------------------------------------------------------------------- +; Сохранить экран текст. режима. +; Для буфера экрана исп. 2-я банка расширения ДОС. +SAVETXT: PUSH AF + LD A,(VMODE) + ;BIT 7,A + CP %1000'0000 + JR NC,.NOSAVET + SUB #02 + JR C,.NOSAVET + ; + PUSH BC + PUSH DE + PUSH HL + PUSH IX + ; + PUSH AF + LD C,BIOS.LP_GET_PLACE + RST ToBIOS + LD (BACKTXT.CURS),DE + POP AF + LD IX,#C000 + LD HL,#2050 + OR A + JR NZ,.SVTEXT1 + LD L,#28 +.SVTEXT1: LD (BACKTXT.WinMax),HL + LD DE,#0000 + LD A,(BANKTBL+TXTPAGE) + LD B,A + + LD C,BIOS.WIN_COPY + ;[x] 29/9/23 + LD A,R + PUSH AF + ; + XOR A + DI + RST ToBIOS + ;[x] 29/9/23 + POP AF + JP PO,.skip_EI + EI +.skip_EI: ; + POP IX + POP HL + POP DE + POP BC +.NOSAVET: POP AF + RET +;----------------------------------------------------------------------- + +BACKTXT: PUSH AF +.VMODE+1: LD A,#00 + ;BIT 7,A + CP %1000'0000 + JR C,.NOBACKT + ; + PUSH BC + PUSH DE + PUSH HL + PUSH IX + LD IX,#C000 +.WinMax+1: LD HL,#2050 + LD DE,#0000 + LD A,(BANKTBL+TXTPAGE) + LD B,A + LD C,BIOS.WIN_RESTORE + ;[x] 29/9/23 + LD A,R + PUSH AF + ; + XOR A + DI + RST ToBIOS + ;[x] 29/9/23 + POP AF + JP PO,.no_ei + EI +.no_ei: ; +.CURS+1: LD DE,#0000 + CALL LOCATE + POP IX + POP HL + POP DE + POP BC +.NOBACKT: POP AF + RET +;/////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/DSS/API/Time.asm b/DSS/API/Time.asm index 5bad9af..65fc5dd 100644 --- a/DSS/API/Time.asm +++ b/DSS/API/Time.asm @@ -14,6 +14,7 @@ SYSTIME: LD C,BIOS.CMOS_TEST RST ToBIOS JP C,.NOCMOS + ; LD D,CMOS.Register.date CALL RCMOS PUSH AF diff --git a/DSS/API/WinCopy.asm b/DSS/API/WinCopy.asm new file mode 100644 index 0000000..dd59a68 --- /dev/null +++ b/DSS/API/WinCopy.asm @@ -0,0 +1,23 @@ +;/////////////////////////////////////////////////////////////////////// +; Функция #59. Сохранить окно экрана. +; +; вход: D - строка +; E - колонка левого верхнего угла окна +; H - высота окна +; L - ширина окна +; B - страница буфера, если IX >= #C000 +; IX - адрес буфера +; выход: нет +;/////////////////////////////////////////////////////////////////////// +WINCOPY: AND A + LD A,R ;R102 + PUSH AF ;R102 + XOR A + LD C,BIOS.WIN_COPY + DI ;R102 + RST ToBIOS + POP AF ;R102 + RET PO ;R102 + EI ;R102 + RET +;/////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/DSS/API/WinRest.asm b/DSS/API/WinRest.asm new file mode 100644 index 0000000..325dc97 --- /dev/null +++ b/DSS/API/WinRest.asm @@ -0,0 +1,23 @@ +;/////////////////////////////////////////////////////////////////////// +; Функция #5A. Восстановить окно экрана. +; +; вход: D - строка +; E - колонка левого верхнего угла окна +; H - высота окна +; L - ширина окна +; B - страница буфера, если IX >= #C000 +; IX - адрес буфера +; выход: нет +;/////////////////////////////////////////////////////////////////////// +WINREST: AND A + LD A,R ;R102 + PUSH AF ;R102 + XOR A + DI ;R102 + LD C,BIOS.WIN_RESTORE + RST ToBIOS + POP AF ;R102 + RET PO ;R102 + EI ;R102 + RET +;/////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/DSS/API/WrChar.asm b/DSS/API/WrChar.asm new file mode 100644 index 0000000..3aeb172 --- /dev/null +++ b/DSS/API/WrChar.asm @@ -0,0 +1,23 @@ +;/////////////////////////////////////////////////////////////////////// +; Функция #58. Вывести символ на экран. +; Управляющие символы выводятся как обычные символы. +; +; вход: D - строка +; E - колонка +; A - символ +; B - атрибут +; выход: нет +;!FIXIT slow как без WIN_GET_SYM тут обойтись? +;/////////////////////////////////////////////////////////////////////// +WRCHAR: LD C,A + PUSH BC + PUSH DE + XOR A + LD C,BIOS.WIN_GET_SYM + RST ToBIOS + POP DE + POP HL + XOR A + LD C,BIOS.WIN_PUT_SYM + JP ToBIOS +;/////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/DSS/DOS_FM.ASM b/DSS/DOS_FM.ASM deleted file mode 100644 index 693bf5e..0000000 --- a/DSS/DOS_FM.ASM +++ /dev/null @@ -1,207 +0,0 @@ - -;[BEGIN] -;//MODULE: DOS_FM -;//CREATE: 19-05-1998 AUTHOR: Denis Parinov -;//UPDATE: 24-10-1999 DNS Restore module -;--------------------------------------------------------------- -;Rev Date Name Description -;--------------------------------------------------------------- -; -;--------------------------------------------------------------- - -;FMS DB FMCOUNT - -;ACCESS MODE: -; 00 - READ/WRITE -; 01 - READ -; 02 - WRITE -;FM_BUF: -;File Manipulator (FM) - ; BYTE '. ' ;+00 NAME - ; BYTE ' ' ;+08 EXT - ; BYTE #10 ;+11 ATTRIBUT - ; BYTE 0 ;+12 RESERVED; !TODO следующий кластер для чтения - ; BYTE 0 ;+13 RESERVED; !TODO следующий кластер для записи - ; BLOCK 8,0 ;+14 RESERVED - ; WORD #0000 ;+22 TIME - ; WORD #0000 ;+24 DATE - ; WORD #0000 ;+26 START CLUSTER - ; DWORD #0000 ;+28 SIZE FILE - ; DWORD #0000 ;+32 FILE POSITION (FP) - ; WORD #0000 ;+36 DIRECTORY CLUSTER - ; WORD #0000 ;+38 HANDLE NUMBER - ; BYTE #00 ;+40 DRIVE OR CURRENT - ; BYTE #00 ;+41 ACCESS MODE - ; BYTE #00 ;+42 TASK - ; BYTE #00 ;+43 EMPTY -/* -;!TEST -FM_BUF: _sFM -.Size EQU _sFM - BLOCK (FMCOUNT-1)*FM_BUF.Size, 0 -*/ - -; на выходе без ошибок IY указывает на файловый манипулятор -; MACRO _mFM_FIND -; CP FMCOUNT+1 -; CCF -; RET C -; PUSH DE - -; LD IY,CORE_BUFFERS.FM_BUF -; LD DE,CORE_BUFFERS.FM_BUF.Size -; AND A -; JR Z,.endLoop -; .loop: ADD IY,DE -; DEC A -; JR NZ,.loop -; .endLoop: -; POP DE -; ; A=0 -; OR (IY) ;+00 NAME -; RET -; ENDM -//////////////////////////////////////////////////////////////////////// - -; на выходе без ошибок IY указывает на файловый манипулятор -FM_FIND: CP FMCOUNT+1 - JR NC,.error - ; - PUSH DE - LD IY,CORE_BUFFERS.FM_BUF - LD DE,CORE_BUFFERS.FM_BUF.Size - AND A - JR Z,.endLoop -.loop: ADD IY,DE - DEC A - JR NZ,.loop -.endLoop: POP DE - ; A=0 - OR (IY) ;+00 NAME - RET - ; -.error: XOR A - LD A,DSS_Error.sys.INVALID_HANDLE - RET - -SET_FM: CALL FM_FIND - ; error - ;LD A,DSS_Error.sys.INVALID_HANDLE - ; CF = 1 - SCF - RET Z - ; no error - XOR A ;LD A,DSS_Error.sys.NO_ERROR - ; CF = 0 - RET - - -RES_FM: CALL FM_FIND - ; error - ; LD A,DSS_Error.sys.INVALID_HANDLE - SCF - RET Z - ; no error - XOR A - LD (IY + _sFM.FS_REC.NAME),A - RET -; -GET_FM: LD B,FMCOUNT - LD C,#FF - LD IY,CORE_BUFFERS.FM_BUF - CORE_BUFFERS.FM_BUF.Size - LD DE,CORE_BUFFERS.FM_BUF.Size -.loop: ADD IY,DE - INC C - LD A,(IY + _sFM.FS_REC.NAME) - OR A - RET Z - DJNZ .loop - LD A,DSS_Error.sys.NO_HANDLES - SCF - RET -/* - ;!TODO CHECK LOCKING 10/11/2023 -GET_FM: LD IY,0 - LD (.freeHandle),IY - ; - LD B,FMCOUNT - LD C,#FF - LD IY,CORE_BUFFERS.FM_BUF - CORE_BUFFERS.FM_BUF.Size - LD DE,CORE_BUFFERS.FM_BUF.Size -.loop: ADD IY,DE - INC C - ; CHECK LOCKING - - ; -.cont: LD A,(IY+0) - OR A - RET Z - DJNZ .loop - LD A,DSS_Error.sys.NO_HANDLES - SCF - RET -*/ - - -; HL:IX - OFFSET POINTER -; A - FILE MANIPULATOR -MOVE_FP: CALL SET_FM - RET C - INC B - DJNZ .B_1 - ;from Start File - ; B=0 -.F_start: LD C,B - LD D,B - LD E,B - JP .DO - ; -.B_1: DJNZ .B_2 - ;from Current Position -.F_current: LD C,(IY+_sFM.F_POSITION) - LD B,(IY+_sFM.F_POSITION+1) - LD E,(IY+_sFM.F_POSITION+2) - LD D,(IY+_sFM.F_POSITION+3) -.DO: ADD IX,BC - ADC HL,DE - LD D,XH - LD E,XL - LD (IY+_sFM.F_POSITION),E - LD (IY+_sFM.F_POSITION+1),D - LD (IY+_sFM.F_POSITION+2),L - LD (IY+_sFM.F_POSITION+3),H - XOR A - RET - ; -.B_2: DJNZ .error - ;from End File -.B_end: LD C,(IY + _sFM.FS_REC.F_SIZE) - LD B,(IY + _sFM.FS_REC.F_SIZE+1) - LD E,(IY + _sFM.FS_REC.F_SIZE+2) - LD D,(IY + _sFM.FS_REC.F_SIZE+3) - JP .DO - ; B > 2 -.error: LD A,DSS_Error.sys.INVALID_FUNCTION - SCF - RET -;;;;;;;;; - - - -;FP COMPARE -; CY - FILE POINTER > SIZE -; NC - FILE POINTER < SIZE -MOVE_CP: - LD L,(IY + _sFM.FS_REC.F_SIZE) - LD H,(IY + _sFM.FS_REC.F_SIZE+1) - LD E,(IY + _sFM.F_POSITION) - LD D,(IY + _sFM.F_POSITION+1) - AND A - SBC HL,DE - LD L,(IY + _sFM.FS_REC.F_SIZE+2) - LD H,(IY + _sFM.FS_REC.F_SIZE+3) - LD E,(IY + _sFM.F_POSITION+2) - LD D,(IY + _sFM.F_POSITION+3) - SBC HL,DE - RET -; \ No newline at end of file diff --git a/DSS/DOS_Proc.asm b/DSS/DOS_Proc.asm index 0ff063e..8be4c0b 100644 --- a/DSS/DOS_Proc.asm +++ b/DSS/DOS_Proc.asm @@ -7,8 +7,8 @@ ;--------------------------------------------------------------- ;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 +;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 @@ -86,10 +86,12 @@ GetName: LD BC,#08FF ;!HARDCODE ;----------------------------------------------------------------------; +; old GETWORD ; Тест на допустимое имя и настроиться на диск. ; вход: hl=строка имени ; выход: (TMPNAME) -GETWORD: ; !TEST +SetPath_GetName: + ; !TEST INC HL LD A,(HL) DEC HL @@ -297,16 +299,17 @@ MASK: LD HL,TMPNAME CP ' '+1 CCF RET NC - CP '"' - JR Z,.MASK_ERR + ; CP '*' JR Z,.MASK3 + CP '.' + JR Z,.MASK5 + CP '"' + JR Z,.MASK_ERR CP '+' JR Z,.MASK_ERR CP ',' JR Z,.MASK_ERR - CP '.' - JR Z,.MASK5 CP '/' JR Z,.MASK_ERR CP ':' @@ -327,11 +330,6 @@ MASK: LD HL,TMPNAME 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 @@ -340,36 +338,34 @@ MASK: LD HL,TMPNAME .MASK_ERR: LD A,DSS_Error.sys.INVALID_NAME SCF - RET + RET + ; .MASK3: LD A,'?' INC HL DJNZ .MASK6 - LD A,DSS_Error.sys.INVALID_NAME - SCF - RET + JR .MASK_ERR + ; .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 + JR NZ,.MASK1 + JR .MASK_ERR + ; .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 + JR NZ,.MASK1 + JR .MASK_ERR ;----------------------------------------------------------------------; @@ -445,7 +441,7 @@ DIR_PATH_CHECK: LD A,(HL) LD A,DSS_Error.sys.PATH_NOT_FOUND RET C LD HL,CORE_BUFFERS.CurrentPath - JP GETWORD + JP SetPath_GetName ; .end: CP (HL) RET Z @@ -469,3 +465,115 @@ CHECK_NAME: SCF RET ;----------------------------------------------------------------------; + + +;----------------------------------------------------------------------; +;FMS DB FMCOUNT + +;ACCESS MODE: +; 00 - READ/WRITE +; 01 - READ +; 02 - WRITE +;FM_BUF: +;File Manipulator (FM) + ; BYTE '. ' ;+00 NAME + ; BYTE ' ' ;+08 EXT + ; BYTE #10 ;+11 ATTRIBUT + ; BYTE 0 ;+12 RESERVED; !TODO следующий кластер для чтения + ; BYTE 0 ;+13 RESERVED; !TODO следующий кластер для записи + ; BLOCK 8,0 ;+14 RESERVED + ; WORD #0000 ;+22 TIME + ; WORD #0000 ;+24 DATE + ; WORD #0000 ;+26 START CLUSTER + ; DWORD #0000 ;+28 SIZE FILE + ; DWORD #0000 ;+32 FILE POSITION (FP) + ; WORD #0000 ;+36 DIRECTORY CLUSTER + ; WORD #0000 ;+38 HANDLE NUMBER + ; BYTE #00 ;+40 DRIVE OR CURRENT + ; BYTE #00 ;+41 ACCESS MODE + ; BYTE #00 ;+42 TASK + ; BYTE #00 ;+43 EMPTY +/* +;!TEST +FM_BUF: _sFM +.Size EQU _sFM + BLOCK (FMCOUNT-1)*FM_BUF.Size, 0 +*/ +//////////////////////////////////////////////////////////////////////// + +; на выходе без ошибок IY указывает на файловый манипулятор +FM_FIND: CP FMCOUNT+1 + JR NC,.error + ; + PUSH DE + LD IY,CORE_BUFFERS.FM_BUF + LD DE,CORE_BUFFERS.FM_BUF.Size + AND A + JR Z,.endLoop +.loop: ADD IY,DE + DEC A + JR NZ,.loop +.endLoop: POP DE + ; A=0 + OR (IY) ;+00 NAME + RET + ; +.error: XOR A + LD A,DSS_Error.sys.INVALID_HANDLE + RET + +SET_FM: CALL FM_FIND + ; error + ;LD A,DSS_Error.sys.INVALID_HANDLE + ; CF = 1 + SCF + RET Z + ; no error + XOR A ;LD A,DSS_Error.sys.NO_ERROR + ; CF = 0 + RET + + +RES_FM: CALL FM_FIND + ; error + ; LD A,DSS_Error.sys.INVALID_HANDLE + SCF + RET Z + ; no error + XOR A + LD (IY + _sFM.FS_REC.NAME),A + RET +; +;!TODO CHECK LOCKING +GET_FM: LD B,FMCOUNT + LD C,#FF + LD IY,CORE_BUFFERS.FM_BUF - CORE_BUFFERS.FM_BUF.Size + LD DE,CORE_BUFFERS.FM_BUF.Size +.loop: ADD IY,DE + INC C + LD A,(IY + _sFM.FS_REC.NAME) + OR A + RET Z + DJNZ .loop + LD A,DSS_Error.sys.NO_HANDLES + SCF + RET + +;FP COMPARE +; CY - FILE POINTER > SIZE +; NC - FILE POINTER < SIZE +MOVE_CP: + LD L,(IY + _sFM.FS_REC.F_SIZE) + LD H,(IY + _sFM.FS_REC.F_SIZE+1) + LD E,(IY + _sFM.F_POSITION) + LD D,(IY + _sFM.F_POSITION+1) + AND A + SBC HL,DE + LD L,(IY + _sFM.FS_REC.F_SIZE+2) + LD H,(IY + _sFM.FS_REC.F_SIZE+3) + LD E,(IY + _sFM.F_POSITION+2) + LD D,(IY + _sFM.F_POSITION+3) + SBC HL,DE + RET +; +;----------------------------------------------------------------------; \ No newline at end of file diff --git a/DSS/DSS-MAIN.ASM b/DSS/DSS-MAIN.ASM index e3ba28f..51b6249 100644 --- a/DSS/DSS-MAIN.ASM +++ b/DSS/DSS-MAIN.ASM @@ -397,14 +397,10 @@ ADRST10: ;DS 512 ;,0 ;[INCLUDE] ;!TODO заменить по-максимому всё в KEYINTER.ASM на вызовы биоса INCLUDE "KEYINTER.ASM" - INCLUDE "VIDEO.ASM" INCLUDE "API.ASM" INCLUDE "DOS_Proc.asm" - INCLUDE "FS/FAT/FAT.ASM" - INCLUDE "FS/FAT/FAT_X.ASM" - INCLUDE "DOS_FM.ASM" + INCLUDE "FS_Module.asm" INCLUDE "Procedures.asm" - INCLUDE "Kernel_Panic.asm" ; [ ] 26/06/2024& read only 64kb cluster ; !TODO cluster 64kb diff --git a/DSS/FS/CDFS.ASM b/DSS/FS/CDFS.ASM new file mode 100644 index 0000000..f8dda64 --- /dev/null +++ b/DSS/FS/CDFS.ASM @@ -0,0 +1,3 @@ +; +; +; \ No newline at end of file diff --git a/DSS/FS/FAT/FAT_X.asm b/DSS/FS/FAT.asm similarity index 56% rename from DSS/FS/FAT/FAT_X.asm rename to DSS/FS/FAT.asm index 0ee5739..5f10e2d 100644 --- a/DSS/FS/FAT/FAT_X.asm +++ b/DSS/FS/FAT.asm @@ -1,17 +1,1215 @@ -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -; FAT 12-16-32 -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - ;[BEGIN] -;//MODULE: FAT_X +;//MODULE: FAT ;//CREATE: 19-05-1998 AUTHOR: Denis Parinov ;//UPDATE: 24-10-1999 DNS Restore module ;--------------------------------------------------------------- ;Rev Date Name Description ;--------------------------------------------------------------- +;R08 14-11-2002 DNS IMPROVE BPB-FUNCTION +;R07 17-12-1999 DNS BUG FIX SIGNATURE #55AA AT 510 OFFSET ;RY01 16-11-1999 DNS ERROR READING FAT CHAIN ;RX01 10-02-1999 DNS UPGRADE FAT CASH ;--------------------------------------------------------------- +; [ ] RST_FS +;----------------------------------------------------------------------; + +SET_FSInfo: LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) + CP FAT_TYPE.x32 + RET NZ + ; + LD A,(CORE_BUFFERS.FatBuffer.UPD_FSINFO) + OR A + RET Z + ; + ; Делаем FSInfo сектор + ; чистим сектор + LD HL,CORE_BUFFERS.SECTOR_BUFFER + LD DE,CORE_BUFFERS.SECTOR_BUFFER+1 + LD (HL),0 + LD BC,512 - 1 ;!HARDCODE размер сектора + LDIR + ; LEAD_SIGNATURE + LD HL,#5252 + LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.LEAD_SIGNATURE),HL + LD HL,#4161 + LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.LEAD_SIGNATURE + 2),HL + ; DATA_SIGNATURE + LD HL,#7272 + LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.DATA_SIGNATURE),HL + LD HL,#6141 + LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.DATA_SIGNATURE + 2),HL + ; SECTOR_SIGNATURE + LD HL,#AA55 + LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.SECTOR_SIGNATURE),HL + ; FREE_CLUSTERS_COUNT + LD HL,(CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_L) + LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FREE_CLUSTERS_COUNT),HL + LD HL,(CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_H) + LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FREE_CLUSTERS_COUNT+2),HL + ; FIRST_FREE_CLUSTER + LD HL,(G_CLUST.low) + LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FIRST_FREE_CLUSTER),HL + LD HL,(G_CLUST.high) + LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FIRST_FREE_CLUSTER+2),HL + ; Пишем его на винт + XOR A + LD (CORE_BUFFERS.FatBuffer.UPD_FSINFO),A + JR WRITE_FSinfo +; ; +; Прочитать BPB в SECTOR_BUFFER +READ_BPB: LD C,Dss.DRV.GetBPB + JR RW_SECTOR +; Записать FSinfo из SECTOR_BUFFER +WRITE_FSinfo: LD IX,(CORE_BUFFERS.FatBuffer.FSINFO_Sector) + LD HL,0 + ;JR WRITE_SECTOR +; Записать сектор из SECTOR_BUFFER +; Вход: HL:IX = Logical Block (sector) +WRITE_SECTOR: LD BC,1*256 + Dss.DRV.Write + JR RW_SECTOR +; Прочитать FSinfo в SECTOR_BUFFER +READ_FSinfo: LD IX,(CORE_BUFFERS.FatBuffer.FSINFO_Sector) + LD HL,0 +; Прочитать сектор в SECTOR_BUFFER +; Вход: HL:IX = Logical Block (sector) +READ_SECTOR: LD BC,1*256 + Dss.DRV.Read + ; +RW_SECTOR: IN A,(SLOT3) + PUSH AF + IN A,(SLOT0) + OUT (SLOT3),A + ; + LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + LD DE,CORE_BUFFERS.SECTOR_BUFFER+#C000 + RST ToDSS.DRV + EX AF,AF' + ; + POP AF + OUT (SLOT3),A + EX AF,AF' + RET +; + +; [ ] удаление записи LFN +; +; вход: IX = текущая запись в странице с каталогом FAT для которой +; надо удалить записи LFS +DELETE_LFN_RECORDS: + PUSH IX + LD A,XH + AND #C0 + SUB 1 + LD C,A + ; В регистре C маска для определения выхода за пределы страницы + ; +.find_LFN: LD DE, -(FAT_DIRECTORY_RECORD) + LD A,FAT_ATTR.LFS_Entry + ; +.loop: ADD IX,DE + LD A,XH + CP C + JR Z,.beyond_boundaries + ; + LD A,FAT_ATTR.LFS_Entry + CP (IX+FAT_DIRECTORY_RECORD.ATTRIBUT) + JR NZ,.exit + LD (IX+FAT_DIRECTORY_RECORD.NAME),#E5 + JR .loop + ; +.exit: AND A +.beyond_boundaries: ; !TODO подгрузка другой части каталога. пока заглушка + POP IX + RET +;----------------------------------------------------------------------; + + +; Поиск записи каталога в списке каталога +; +; вход: a = атрибут записи +; выход: de = индекс записи в списке каталога +; (HANDBUF) = file's direcory record +; CF - каталог не найден +SEARCH: +.Dir: ;LD A,FAT_ATTR.DIRECTORY + LD A,FAT_ATTR.HiddenSysDir + CALL .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 record index + ; оптимизация для индекса записи в списке каталога. + ; Понадобится вернуть для перебора каталога > #4000 байт + ; EXX + ; LD DE,0 + ; EXX + ; +.loop: LD A,(IX+FAT_DIRECTORY_RECORD.NAME) + OR A + JR Z,.error_file_not_found + CP #E5 ;!HARDCODE #E5 - запись в директории свободна, так как файл/директория были удалены + JR Z,.next_record + LD A,(IX+FAT_DIRECTORY_RECORD.ATTRIBUT) + 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 + ; + LD D,XH + LD E,XL + ;!TEST 9/11/23 record index + ; EXX + ; PUSH DE + ; EXX + PUSH IX + ; + LD HL,HANDBUF + EX DE,HL + LD BC,HANDBUF.SIZE + LDIR + ;!TEST 9/11/23 record index + POP DE + ; + EX AF,AF' + OUT (SLOT3),A + EX AF,AF' + AND A + RET +.next_record: + LD DE,FAT_DIRECTORY_RECORD + ;!TEST 9/11/23 record index + ; EXX + ; INC DE + ; EXX + ; + ADD IX,DE + JR NC,.loop +.error_too_many_files: + EX AF,AF' + OUT (SLOT3),A + LD A,DSS_Error.sys.TOO_MANY_FILES_IN_DIR + SCF + RET + ; +.error_file_not_found: + 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,FAT_DIRECTORY_RECORD +;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 +; [x] fat32 ;!TEST +; выход: IY:DE - cluster number +FINDDIR: + SET_PAGE_X DIRPAGE + ; + PUSH AF + LD IX,DIRPAGE.buffer +.big_loop: + LD A,(IX + FAT_DIRECTORY_RECORD.NAME) + OR A + JR Z,.error + CP #E5 + JR Z,.next_step + LD A,(IX + FAT_DIRECTORY_RECORD.ATTRIBUT) + AND FAT_ATTR.DIRECTORY + 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 + FAT_DIRECTORY_RECORD.NAME) + CP "." + JP NZ,.ADDSPEC + LD A,(IX + FAT_DIRECTORY_RECORD.NAME + 1) + CP "." + JP NZ,.IT_DIR + LD HL,CORE_BUFFERS.WorkDirectory + LD D,H + LD E,L + INC HL + LD BC,CORE_BUFFERS.WorkDirectory.DEPTH + XOR A + CPIR + JP PO,.error ;[x] 20/11/23 проверка на выход за границы + DEC HL ;R009 + DEC HL + LD BC,CORE_BUFFERS.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,FAT_DIRECTORY_RECORD + 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,CORE_BUFFERS.WorkDirectory+1 + LD BC,CORE_BUFFERS.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:; fat32 + LD E,(IX + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_H) + LD D,(IX + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_H+1) + LD YH,D + LD YL,E + LD E,(IX + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_L) + LD D,(IX + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_L+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 + LD (HL),0 + ;INC HL + RET +;----------------------------------------------------------------------; + +CHECK_ROOT_CLUSTER: + EX DE,HL + LD HL,(CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L) ;R005 + LD A,L + OR H + LD HL,(CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H) + OR L + OR H + EX DE,HL + RET + +;----------------------------------------------------------------------; +; вход: HL - имя директории +; [x] fat32 ;!TEST + +OPENDIR: LD IY,CORE_BUFFERS.FM_BUF + LD A,(HL) + OR A + JR NZ,.SUBDIR + ; +.REROOT: LD DE,0 + LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),DE + LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H),DE + CALL LOADDIR + ; CF=0 + LD HL,CORE_BUFFERS.WorkDirectory + LD (HL),'\' + INC HL + LD (HL),#00 + ;AND A + RET + ; +.SUBDIR: CP "." + JR NZ,.SUBDIR2 + ; fat32 + CALL CHECK_ROOT_CLUSTER + JR NZ,.no_root ;R005 + ; "cd ." or "cd .." + ;R005 + INC HL + LD A,(HL) + OR A + DEC HL + JR Z,.REROOT + ; +.no_root: 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 + ; fat32 +.SUBDIR3: CALL FINDDIR + RET C + EX DE,HL + LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),HL ; fat32 + LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H),IY ; fat32 + LD HL,#4000 ;!HARDCODE + LD (CORE_BUFFERS.FM_BUF.FS_REC.F_SIZE),HL +;-------------; EX DE,HL +; JP LOADDIR + +; Прочитать список каталога +; [x] fat32 ;!TEST +LOADDIR: ;!TODO optimize + CALL LOAD_SAVE_DIR_PREPARE + PUSH AF + EX AF,AF' + JR NZ,.read_dir + LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) + CP FAT_TYPE.x32 + JR NZ,.LoadRootDir + ; fat32 + LD HL,(CORE_BUFFERS.FatBuffer.RootDirStartCluster_L) + LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),HL + LD HL,(CORE_BUFFERS.FatBuffer.RootDirStartCluster_H) + LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H),HL + + ;LD HL,(CORE_BUFFERS.FatBuffer.BytesPerCluster) ; !FIXIT вычитывать полностью каталог + LD HL,#4000 ; размер директории ;!HARDCODE + LD (CORE_BUFFERS.FM_BUF.FS_REC.F_SIZE),HL + ; +.read_dir: LD HL,DIRPAGE.buffer ; куда + LD DE,#4000 ; сколько + XOR A ; дескриптор + CALL READ ; чтение из файла + LD (SAVEDIR.DIRSIZE),DE ; число прочит. байтов + POP AF + OUT (SLOT3),A + RET + ; +.LoadRootDir: LD HL,(CORE_BUFFERS.FatBuffer.RootDirFirstSector_H) ;!TODO возможно, хватит LD HL,0 + LD IX,(CORE_BUFFERS.FatBuffer.RootDirFirstSector_L) ; номер лог. сектора + LD A,(CORE_BUFFERS.FatBuffer.DirSizeInSectors) + LD B,32 ; !HARDCODE sector size 512. 16384/(sector 512). размер root-каталога + CP B + JR NC,.RTD1 + LD B,A ; число секторов +.RTD1: LD A,(CORE_BUFFERS.FatBuffer.DRIVE) ; номер диска + LD DE,DIRPAGE.buffer ; буфер + LD C,Dss.DRV.Read ; чтение секторов + RST ToDSS.DRV + POP AF + OUT (SLOT3),A + RET +;----------------------------------------------------------------------; + + +;!TODO FAT procedures +;----------------------------------------------------------------------; + +LOAD_SAVE_DIR_PREPARE: + ;!TODO optimize + XOR A ; FILE MANIPULATOR = 0 + LD H,A + LD L,A + LD IX,0 + LD B,A ; от начала файла + CALL MOVE_FP + ; + SET_PAGE_X DIRPAGE + AND A + EX AF,AF' + ; + LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + LD (IY+_sFM.DRIVE),A + ;!FIXIT переделать на работу без IY + LD A,(IY+_sFM.FS_REC.FIRST_CLUSTER_L) + OR (IY+_sFM.FS_REC.FIRST_CLUSTER_L+1) + OR (IY+_sFM.FS_REC.FIRST_CLUSTER_H) + OR (IY+_sFM.FS_REC.FIRST_CLUSTER_H+1) + ; + EX AF,AF' + RET + +;----------------------------------------------------------------------; + +; скопировать запись в список диска (каталога) de ix iy +; и сбросить кеш каталога на диск +; вход: (HANDBUF) - запись каталога +WRT_HND: + SET_PAGE_X DIRPAGE + EX AF,AF' + LD HL,DIRPAGE.buffer + ;!TEST 9/11/23 record index + ; EXX + ; LD DE,0 + ; EXX + ; + LD BC,FAT_DIRECTORY_RECORD +.loop: ;LD A,(IX+00) + LD A,(HL) + OR A + JR Z,.WRT_HN2 + CP #E5 + JR Z,.WRT_HN2 + ;ADD IX,BC + ADD HL,BC + JR NC,.loop ;!FIXIT количество записей каталога = страница + ; + EX AF,AF' + OUT (SLOT3),A + LD A,DSS_Error.sys.ROOT_OVERFLOW + SCF + RET + ; +.WRT_HN2: ;LD D,XH + ;LD E,XL + EX DE,HL + 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,(CORE_BUFFERS.FatBuffer.BytesPerCluster) + ADD HL,BC + LD (SAVEDIR.DIRSIZE),HL + AND A + ;JP SAVEDIR +;----------------------------------------------------------------------; +; Сбросить кеш каталога на диск. +; вход: iy=структура дескриптора +; [x] fat32 ;!TEST +SAVEDIR: ;!TODO optimize + CALL LOAD_SAVE_DIR_PREPARE + PUSH AF + EX AF,AF' + JR NZ,.save_dir + ; + LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) + CP FAT_TYPE.x32 + JR NZ,.SaveRootDir + ; fat32 + LD HL,(CORE_BUFFERS.FatBuffer.RootDirStartCluster_L) + LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),HL + LD HL,(CORE_BUFFERS.FatBuffer.RootDirStartCluster_H) + LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H),HL + ; +.save_dir: LD HL,DIRPAGE.buffer + ; размер списка каталога size_cash_directory + ;!FIXIT если она нужна, то проверить на баги (например, размер дирректории меньше при открытии и больше после правок) + ; когда будет чтение кусками каталога в кэш, тут ещё счётчик прикрутить +.DIRSIZE+1: LD DE,0 + XOR A + CALL WRITE + POP AF + OUT (SLOT3),A + RET + ; +.SaveRootDir: LD HL,(CORE_BUFFERS.FatBuffer.RootDirFirstSector_H) ;!TODO возможно, хватит LD HL,0 + LD IX,(CORE_BUFFERS.FatBuffer.RootDirFirstSector_L) + LD A,(CORE_BUFFERS.FatBuffer.DirSizeInSectors) + LD B,32 ;!HARDCODE sector size 512, Root Dir max size in sectors + SUB B + JR NC,.RTD1S + ADD A,B + LD B,A +.RTD1S: LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + LD DE,DIRPAGE.buffer + LD C,Dss.DRV.Write + RST ToDSS.DRV + POP AF + OUT (SLOT3),A + RET +;----------------------------------------------------------------------; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +; [x] fat32 ;!TEST +RD_BPB: ; LD C,SLOT3 + ; IN B,(C) + ; PUSH BC + ; IN A,(SLOT0) + ; OUT (SLOT3),A + ; LD A,(CORE_BUFFERS.FatBuffer.DRIVE) + ; LD DE,CORE_BUFFERS.SECTOR_BUFFER+#C000 ;R08 + ; LD C,Dss.DRV.GetBPB + ; RST ToDSS.DRV + ; POP BC + ; OUT (C),B + CALL READ_BPB + JP C,DOS_X_Error.Not_ready + ; + LD DE,#AA55 ; сигнатура ;R05 + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.MBR_SIGNATURE) ;R08 ;R07 + ;[ ] CDFS + ;R05 + AND A + SBC HL,DE + JP NZ,DOS_X_Error.UnknownBPB + ; + ; ;R08 ; [x] fat32 + ; LD HL,CORE_BUFFERS.SECTOR_BUFFER + ; LD DE,CORE_BUFFERS.BootSector + ; LD BC,_sBOOT_SECTOR_PARAMS_FAT32 ; size + ; LDIR + ; + LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.DRIVE_TYPE) + CP #F0 + JP C,DOS_X_Error.UnknownBPB + ; + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.BytesPerSector) + LD (CORE_BUFFERS.FatBuffer.BytesPerSector),HL + LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.SectorsPerCluster) + LD (CORE_BUFFERS.FatBuffer.SectorsPerCluster),A + ; calc. first sector FAT + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.RESERVED_SECTORS) + LD (CORE_BUFFERS.FatBuffer.FAT1_SEC_L),HL ; low word first sector FAT #1 + LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_L),HL ; low word first sector FAT #2 + ;[ ] fat32 + XOR A + LD B,A + LD C,A + LD (CORE_BUFFERS.FatBuffer.FAT1_SEC_H),BC ; high word first sector FAT #1 ; [ ] fat32 + LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_H),BC ; high word first sector FAT #1 ; [ ] fat32 + LD (CORE_BUFFERS.FatBuffer.RootDirFirstSector_H),BC + LD (CORE_BUFFERS.FatBuffer.SectorsPerFAT_H),A ; [ ] fat32 + ;LD (CORE_BUFFERS.FatBuffer.END_CHAIN_CLUSTER_H),BC ; [ ] fat32 reset variables + ; + ; + EXX + LD H,A + LD L,A + LD D,A + LD E,A + EXX + LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.SectorsPerFAT16) + LD A,E + OR D + JR NZ,.skip_high + ; + EXX + LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.SectorsPerFAT32 + 2) + LD A,E + EXX + ; + LD (CORE_BUFFERS.FatBuffer.SectorsPerFAT_H),A + LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.SectorsPerFAT32) + ; +.skip_high: LD (CORE_BUFFERS.FatBuffer.SectorsPerFAT_L),DE + LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.Number_of_FATs) ; amount FATs + LD (CORE_BUFFERS.FatBuffer.Number_Of_FATs),A + CP 1 + JR Z,.one_FAT + DEC A + ADD HL,DE + LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_L),HL + EXX + ADC HL,DE + LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_H),HL + EXX + ;JR NC,.no_inc_BC + ;INC BC +.no_inc_BC:;LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_H),BC +.one_FAT: ; +.loop1: ADD HL,DE + ;JR NC,.loop1_1 + ;INC BC + EXX + ADC HL,DE + EXX +.loop1_1: DEC A + JR NZ,.loop1 + ; + LD (CORE_BUFFERS.FatBuffer.RootDirFirstSector_L),HL ; first sector DIR + EXX + ; можно сразу тут загнать старший байт, потому-что дла FAT32 следующий расчёт - это прибавление нуля. + LD (CORE_BUFFERS.FatBuffer.FirstDataSector_H),HL + EXX + ;LD (CORE_BUFFERS.FatBuffer.FirstDataSector_H),BC + ; + LD BC,(CORE_BUFFERS.FatBuffer.BytesPerSector) + LD A,B + AND A + ; + RL C + RLA + RL C + RLA + RL C + RLA + ; + LD C,A + LD B,0 ; BC - File handels per sector + ;;;; + IF COMPILE_UNUSED_CODE + LD (CORE_BUFFERS.FatBuffer.FilesPerSector),A + ENDIF + ; + EX DE,HL + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FilesInRootDIR) ; 0 for fat32 + ; [ ]fat32 ;!TEST + LD A,H + OR L + JR Z,.skip_loop2 + ; + DEC HL + XOR A + ;NEXTAD2 +.loop2: INC A + JP Z,DOS_X_Error.UnknownBPB + SBC HL,BC + JR NC,.loop2 + ; +.skip_loop2: EX DE,HL + LD C,A ; A - sectors in DIR + LD B,0 + LD (CORE_BUFFERS.FatBuffer.DirSizeInSectors),A + + ADD HL,BC ; Start DATA area + LD (CORE_BUFFERS.FatBuffer.FirstDataSector_L),HL + ; B = 0 + ; + LD HL,(CORE_BUFFERS.FatBuffer.BytesPerSector) + LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster) + ;!TODO FATcacheSize + ; calc. cluster size + XOR 1 + JR Z,.loop3.end + RRA +.loop3: ADD HL,HL + RRA + JP NC,.loop3 +.loop3.end: ; + LD (CORE_BUFFERS.FatBuffer.BytesPerCluster),HL + ;LD DE,#8001 ; проверка на размер кластера больше 32 кб - не поддерживается ; !TODO + ;AND A + ;SBC HL,DE + ;JP NC,DOS_X_Error.UnknownBPB ; [ ] fixed bug, thanks to @Romychs (Roman Boykov) +//////////////////////////////////////////////////////////////////////// +;!TODO не используется значения вычисляемые и сохраняемые в FatBuffer +; EX DE,HL +; LD HL,#3FFF ;!HARDCODE ;!TODO FATcacheSize +; XOR A +; ;NEXTAD4 ;!FIXIT оптимизировать когда понадобится +;.loop4: INC A +; JP Z,DOS_X_Error.UnknownBPB +; SBC HL,DE +; JR NC,.loop4 +; LD (CORE_BUFFERS.FatBuffer.ClustersPerBank),A ; A - Clusters per bank (16k) +; +; LD HL,0 +; LD BC,(CORE_BUFFERS.SECTOR_BUFFER + _sBOOT_SECTOR_PARAMS.SectorsPerTrack) ; Sector per track +; LD A,(CORE_BUFFERS.SECTOR_BUFFER + _sBOOT_SECTOR_PARAMS.HEADS) +;.BPB_L1: ; calc. sector per cylinder +; ADD HL,BC +; DEC A +; JR NZ,.BPB_L1 +; LD (CORE_BUFFERS.FatBuffer.S_X_H),HL +//////////////////////////////////////////////////////////////////////// + ; [ ] fat32 + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.SectorsPerDrive) + LD A,H + OR L + LD DE,(CORE_BUFFERS.FatBuffer.FirstDataSector_L) + JP NZ,.HDDSMAL + ; + EXX + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.BPB_BIG_TOTAL_SECTORS_H) + PUSH HL ; Total Sectors high + LD DE,(CORE_BUFFERS.FatBuffer.FirstDataSector_H) + EXX + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.BPB_BIG_TOTAL_SECTORS_L) + PUSH HL ; Total Sectors low + AND A + SBC HL,DE + EXX + SBC HL,DE + PUSH HL + EXX + POP BC + ;JP NC,.HDDBIG + ;DEC BC + JP .HDDBIG + ; +.HDDSMAL: ; CF = 0 + LD BC,0 + PUSH BC ; Total Sectors high + PUSH HL ; Total Sectors low + SBC HL,DE + ; +.HDDBIG: CALL SectorToCluster +; LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster) +; SCF +; .loop7: RRA +; JR C,.loop7_exit +; RR B +; RR C +; RR H +; RR L +; JP .loop7 + ; +.loop7_exit: INC HL + LD (CORE_BUFFERS.FatBuffer.MaxClusterLow),HL + LD A,L + OR H + JR NZ,.no_inc_bc + INC BC +.no_inc_bc: LD (CORE_BUFFERS.FatBuffer.MaxClusterHigh),BC + ; + XOR A + LD H,A + LD L,A + LD (CORE_BUFFERS.FatBuffer.CacheBlock),HL + LD (CORE_BUFFERS.FatBuffer.CacheUpdated),A + ; A = 0 + LD HL,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_H) + LD H,A + EX DE,HL + LD HL,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_L) + ; DE:HL = SectorsPerFAT + ; + LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.Number_of_FATs) + LD B,A + DEC A + JR Z,.loop_mul_end + ; .Number_of_FATs * .SectorsPerFAT +.loop_mul: ADD HL,HL + EX DE,HL + ADC HL,HL + EX DE,HL + DJNZ .loop_mul +.loop_mul_end: ; .DirSizeInSectors + .Number_of_FATs * .SectorsPerFAT + LD B,0 + LD A,(CORE_BUFFERS.FatBuffer.DirSizeInSectors) + LD C,A + ADD HL,BC + JR NC,.no_inc_DE + INC DE +.no_inc_DE: ; .RESERVED_SECTORS + .DirSizeInSectors + .Number_of_FATs * .SectorsPerFAT + LD BC,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.RESERVED_SECTORS) + ADD HL,BC + JR NC,.no_inc_de + INC DE +.no_inc_de: ; Total_Sectors - (.RESERVED_SECTORS + .DirSizeInSectors + .Number_of_FATs * .SectorsPerFAT) + AND A + LD B,D + LD C,E + POP DE ; Total Sectors low + EX DE,HL + SBC HL,DE + EX (SP),HL ; Total Sectors high + SBC HL,BC + POP DE ; Total Sectors low + ; HL:DE = DataSec + ; + LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster) + ; HL:DE / A => DE:BC, H=0, L - остаток + CALL DIV_by_Shifts + ; выясняем разрядность FAT + LD A,D + OR E + JR NZ,.its_FAT32 + ; + LD HL,4084 + SBC HL,BC + JR NC,.its_FAT12 + ; + LD HL,65524 + SBC HL,BC + JR C,.its_FAT32 + ; + ; It's FAT16 + LD HL,#FFFF + LD A,FAT_TYPE.x16 +.set_vars: EXX + LD HL,0 + LD (CORE_BUFFERS.FatBuffer.END_CHAIN_CLUSTER_H),HL + LD (CORE_BUFFERS.FatBuffer.RootDirStartCluster_L),HL + LD (CORE_BUFFERS.FatBuffer.RootDirStartCluster_H),HL + LD HL,CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT.LABEL + EXX + LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT.SERIAL_NUMBER) + LD BC,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT.SERIAL_NUMBER+2) + JR .SET_VARS + ; +.its_FAT12: LD HL,#0FFF + LD A,FAT_TYPE.x12 + JR .set_vars + ; +.its_FAT32: LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.MainFATnumber) + CP #80 + JR C,.mirrored_FATs ;если все копии FAT используются + ; используется только одна копия FAT + LD HL,(CORE_BUFFERS.FatBuffer.FAT1_SEC_H) + LD DE,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_H) + LD D,0 + EXX + LD HL,(CORE_BUFFERS.FatBuffer.FAT1_SEC_L) + LD DE,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_L) + AND #0F + JR Z,.first_FAT_active + LD B,A + ; +.fat_calc_loop: ADD HL,DE + EXX + ADC HL,DE + EXX + DJNZ .fat_calc_loop + ; +.first_FAT_active: + LD (CORE_BUFFERS.FatBuffer.FAT1_SEC_L),HL + LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_L),HL + EXX + LD (CORE_BUFFERS.FatBuffer.FAT1_SEC_H),HL + LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_H),HL + ; +.mirrored_FATs: LD HL,CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT32.LABEL + ; + EXX + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.RootDirStartCluster) + LD (CORE_BUFFERS.FatBuffer.RootDirStartCluster_L),HL + LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.RootDirStartCluster+2) + LD (CORE_BUFFERS.FatBuffer.RootDirStartCluster_H),DE + ; + CALL CLUSTER_TO_SECTOR.no_prepare + LD (CORE_BUFFERS.FatBuffer.RootDirFirstSector_L),IX + LD (CORE_BUFFERS.FatBuffer.RootDirFirstSector_H),HL + ; + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FSINFO_Sector) + LD (CORE_BUFFERS.FatBuffer.FSINFO_Sector),HL + ; + LD A,FAT_TYPE.x32 + LD HL,#0FFF + LD (CORE_BUFFERS.FatBuffer.END_CHAIN_CLUSTER_H),HL + LD H,L + LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT32.SERIAL_NUMBER) + LD BC,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT32.SERIAL_NUMBER+2) + ; +.SET_VARS: LD (CORE_BUFFERS.FatBuffer.FAT_TYPE),A + LD (CORE_BUFFERS.FatBuffer.END_CHAIN_CLUSTER_L),HL + LD (CORE_BUFFERS.FatBuffer.BPB_SERIAL_NUMBER),DE + LD (CORE_BUFFERS.FatBuffer.BPB_SERIAL_NUMBER+2),BC + EXX + LD DE,CORE_BUFFERS.FatBuffer.BPB_LABEL + LD BC,11 ;!HARDCODE + LDIR + ; + SET_PAGE_X FATPAGE + PUSH AF + LD DE,0 + CALL READ_FAT_TABLE + POP AF + OUT (SLOT3),A + ; + ; Установить начальный кластер для чтения + LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) + CP FAT_TYPE.x32 + JR Z,.set_FSinfo + ; + LD HL,#0001 + LD (G_CLUST.low),HL + DEC L + LD (G_CLUST.high),HL + ; + DEC HL + LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_L),HL + LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_H),HL + XOR A + RET + ; +.set_FSinfo: CALL READ_FSinfo + ; !FIXIT проверка на ошибку + ; + ; проверка одной из сотни сраных сигнатур + LD HL,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.DATA_SIGNATURE) + LD DE,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.DATA_SIGNATURE + 2) + LD BC,#7272 + SBC HL,BC + JR NZ,.error + EX DE,HL + LD DE,#6141 + SBC HL,DE + JR NZ,.error + ; FREE_CLUSTERS_COUNT + LD BC,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FREE_CLUSTERS_COUNT) + LD DE,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FREE_CLUSTERS_COUNT+2) + ; CF = 0 + CALL .check_cluster + JR NC,.skip_FFFF + ; + LD B,#FF + LD C,B + LD D,B + LD E,B + ; +.skip_FFFF: LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_L),BC + LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_H),DE + ; + ; FIRST_FREE_CLUSTER + LD BC,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FIRST_FREE_CLUSTER) + LD DE,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FIRST_FREE_CLUSTER+2) + ; CF = 0 + CALL .check_cluster + JR C,.error + ; + LD (G_CLUST.high),DE + LD (G_CLUST.low),BC + XOR A +.error: LD (CORE_BUFFERS.FatBuffer.UPD_FSINFO),A + RET Z + ;!TODO FREE_CLUSTERS_COUNT + ;LD HL,#FFFF + ;LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_L),HL + ;LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_H),HL + ; + XOR A + LD H,A + LD L,2 + LD (G_CLUST.low),HL + LD L,H + LD (G_CLUST.high),HL + RET + ; + ;!TODO MaxCluster - максимально допустимый или на 1 больше максимально допустимого? +.check_cluster: LD HL,(CORE_BUFFERS.FatBuffer.MaxClusterLow) + SBC HL,BC + LD HL,(CORE_BUFFERS.FatBuffer.MaxClusterHigh) + SBC HL,DE + RET +;;;;;;;; + +; --> BC:HL - Sector +; <-- BC:HL - Cluster +SectorToCluster: + LD A,B + AND #0F + LD B,A + LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster) + SCF +.loop: RRA + RET C + RR B + RR C + RR H + RR L + JP .loop +; + +DOS_X_Error: +.UnknownBPB: 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' +.DRIVE: DB #FF +.FAT_TYPE: DB #00 ; TYPE FAT (12 - 12bit, 16 - 16bit, 32 - 32bit) ; [x] fat32 +.CacheBlock: DW #00 +.CacheUpdated: DB #00 +;.SectorsPerBank: DB #00 +.RootDirStartCluster_L: DW #0000 +.RootDirStartCluster_H: DW #0000 ; [ ] fat32 +.FAT1_SEC_L: DW #0000 ; MSD_FAT_SEC first sector FAT (FAT_FRM) +.FAT1_SEC_H: DW #0000 ; [ ] fat32 +.FAT2_SEC_L: DW #0000 +.FAT2_SEC_H: DW #0000 ; [ ] fat32 +.SectorsPerFAT_L DW #0000 +.SectorsPerFAT_H DB #00 +.RootDirFirstSector_L: DW #0000 ; MSD_CAT_SEC first sector DIR +.RootDirFirstSector_H: DW #0000 ; MSD_CAT_SEC first sector DIR ; !TODO ограничение в 32 Гига ;!FIXIT не используется +.DirSizeInSectors: DB #00 ; DIR_SEC_SIZE +.FirstDataSector_L: DW #0000 ; MSD_DAT_SEC low +.FirstDataSector_H: DW #0000 ; MSD_DAT_SEC high ; [ ] fat32 было ограничение в 32 Гига +.BytesPerCluster: DW #0000 ; CLUSTER_LEN +.END_CHAIN_CLUSTER_L: DW #FFFF +.END_CHAIN_CLUSTER_H: DW #0FFF ; [ ] fat3 +.MaxClusterLow: DW #0000 ; макс. число кластеров (без служ.) +.MaxClusterHigh: DW #0000 ; макс. число кластеров (без служ.) +; +.BytesPerSector DW #0000 +.SectorsPerCluster DB #00 +.BPB_SERIAL_NUMBER DW 0,0 +.BPB_LABEL BLOCK 11,' ' ; 11 для FAT, 31 для CDFS + IF COMPILE_UNUSED_CODE +.FilesPerSector: DB #00 ; число файловых записей в секторе +.ClustersPerBank: DB #00 ; A - Clusters per bank (16k) (число кластеров на блок ОЗУ) ; ????? это используется? + ENDIF +;.READ_PG: DB #00 ;!TODO не используются некоторые значения, но задумка неплохая))) +;.S_X_H: DW #0000 ; количество секторов на цилиндре ; ????? это используется? +; +*/ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + +;███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████; +; FAT_X 12-16-32 +;███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████; ; Удаляет запись в каталоге и освобождает занятую цепочку кластеров ; Вход: IX - указатель на удаляемую запись в DIRPAGE diff --git a/DSS/FS/FAT/FAT.asm b/DSS/FS/FAT/FAT.asm deleted file mode 100644 index c577793..0000000 --- a/DSS/FS/FAT/FAT.asm +++ /dev/null @@ -1,1199 +0,0 @@ -;[BEGIN] -;//MODULE: FAT -;//CREATE: 19-05-1998 AUTHOR: Denis Parinov -;//UPDATE: 24-10-1999 DNS Restore module -;--------------------------------------------------------------- -;Rev Date Name Description -;--------------------------------------------------------------- -;R08 14-11-2002 DNS IMPROVE BPB-FUNCTION -;R07 17-12-1999 DNS BUG FIX SIGNATURE #55AA AT 510 OFFSET -;--------------------------------------------------------------- -;----------------------------------------------------------------------; - -SET_FSInfo: LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) - CP FAT_TYPE.x32 - RET NZ - ; - LD A,(CORE_BUFFERS.FatBuffer.UPD_FSINFO) - OR A - RET Z - ; - ; Делаем FSInfo сектор - ; чистим сектор - LD HL,CORE_BUFFERS.SECTOR_BUFFER - LD DE,CORE_BUFFERS.SECTOR_BUFFER+1 - LD (HL),0 - LD BC,512 - 1 ;!HARDCODE размер сектора - LDIR - ; LEAD_SIGNATURE - LD HL,#5252 - LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.LEAD_SIGNATURE),HL - LD HL,#4161 - LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.LEAD_SIGNATURE + 2),HL - ; DATA_SIGNATURE - LD HL,#7272 - LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.DATA_SIGNATURE),HL - LD HL,#6141 - LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.DATA_SIGNATURE + 2),HL - ; SECTOR_SIGNATURE - LD HL,#AA55 - LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.SECTOR_SIGNATURE),HL - ; FREE_CLUSTERS_COUNT - LD HL,(CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_L) - LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FREE_CLUSTERS_COUNT),HL - LD HL,(CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_H) - LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FREE_CLUSTERS_COUNT+2),HL - ; FIRST_FREE_CLUSTER - LD HL,(G_CLUST.low) - LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FIRST_FREE_CLUSTER),HL - LD HL,(G_CLUST.high) - LD (CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FIRST_FREE_CLUSTER+2),HL - ; Пишем его на винт - XOR A - LD (CORE_BUFFERS.FatBuffer.UPD_FSINFO),A - JR WRITE_FSinfo -; ; -; Прочитать BPB в SECTOR_BUFFER -READ_BPB: LD C,Dss.DRV.GetBPB - JR RW_SECTOR -; Записать FSinfo из SECTOR_BUFFER -WRITE_FSinfo: LD IX,(CORE_BUFFERS.FatBuffer.FSINFO_Sector) - LD HL,0 - ;JR WRITE_SECTOR -; Записать сектор из SECTOR_BUFFER -; Вход: HL:IX = Logical Block (sector) -WRITE_SECTOR: LD BC,1*256 + Dss.DRV.Write - JR RW_SECTOR -; Прочитать FSinfo в SECTOR_BUFFER -READ_FSinfo: LD IX,(CORE_BUFFERS.FatBuffer.FSINFO_Sector) - LD HL,0 -; Прочитать сектор в SECTOR_BUFFER -; Вход: HL:IX = Logical Block (sector) -READ_SECTOR: LD BC,1*256 + Dss.DRV.Read - ; -RW_SECTOR: IN A,(SLOT3) - PUSH AF - IN A,(SLOT0) - OUT (SLOT3),A - ; - LD A,(CORE_BUFFERS.FatBuffer.DRIVE) - LD DE,CORE_BUFFERS.SECTOR_BUFFER+#C000 - RST ToDSS.DRV - EX AF,AF' - ; - POP AF - OUT (SLOT3),A - EX AF,AF' - RET -; - -; [ ] удаление записи LFN -; -; вход: IX = текущая запись в странице с каталогом FAT для которой -; надо удалить записи LFS -DELETE_LFN_RECORDS: - PUSH IX - LD A,XH - AND #C0 - SUB 1 - LD C,A - ; В регистре C маска для определения выхода за пределы страницы - ; -.find_LFN: LD DE, -(FAT_DIRECTORY_RECORD) - LD A,FAT_ATTR.LFS_Entry - ; -.loop: ADD IX,DE - LD A,XH - CP C - JR Z,.beyond_boundaries - ; - LD A,FAT_ATTR.LFS_Entry - CP (IX+FAT_DIRECTORY_RECORD.ATTRIBUT) - JR NZ,.exit - LD (IX+FAT_DIRECTORY_RECORD.NAME),#E5 - JR .loop - ; -.exit: AND A -.beyond_boundaries: ; !TODO подгрузка другой части каталога. пока заглушка - POP IX - RET -;----------------------------------------------------------------------; - - -; Поиск записи каталога в списке каталога -; -; вход: a = атрибут записи -; выход: de = индекс записи в списке каталога -; (HANDBUF) = file's direcory record -; CF - каталог не найден -SEARCH: -.Dir: ;LD A,FAT_ATTR.DIRECTORY - LD A,FAT_ATTR.HiddenSysDir - CALL .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 record index - ; оптимизация для индекса записи в списке каталога. - ; Понадобится вернуть для перебора каталога > #4000 байт - ; EXX - ; LD DE,0 - ; EXX - ; -.loop: LD A,(IX+FAT_DIRECTORY_RECORD.NAME) - OR A - JR Z,.error_file_not_found - CP #E5 ;!HARDCODE #E5 - запись в директории свободна, так как файл/директория были удалены - JR Z,.next_record - LD A,(IX+FAT_DIRECTORY_RECORD.ATTRIBUT) - 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 - ; - LD D,XH - LD E,XL - ;!TEST 9/11/23 record index - ; EXX - ; PUSH DE - ; EXX - PUSH IX - ; - LD HL,HANDBUF - EX DE,HL - LD BC,HANDBUF.SIZE - LDIR - ;!TEST 9/11/23 record index - POP DE - ; - EX AF,AF' - OUT (SLOT3),A - EX AF,AF' - AND A - RET -.next_record: - LD DE,FAT_DIRECTORY_RECORD - ;!TEST 9/11/23 record index - ; EXX - ; INC DE - ; EXX - ; - ADD IX,DE - JR NC,.loop -.error_too_many_files: - EX AF,AF' - OUT (SLOT3),A - LD A,DSS_Error.sys.TOO_MANY_FILES_IN_DIR - SCF - RET - ; -.error_file_not_found: - 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,FAT_DIRECTORY_RECORD -;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 -; [x] fat32 ;!TEST -; выход: IY:DE - cluster number -FINDDIR: - SET_PAGE_X DIRPAGE - ; - PUSH AF - LD IX,DIRPAGE.buffer -.big_loop: - LD A,(IX + FAT_DIRECTORY_RECORD.NAME) - OR A - JR Z,.error - CP #E5 - JR Z,.next_step - LD A,(IX + FAT_DIRECTORY_RECORD.ATTRIBUT) - AND FAT_ATTR.DIRECTORY - 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 + FAT_DIRECTORY_RECORD.NAME) - CP "." - JP NZ,.ADDSPEC - LD A,(IX + FAT_DIRECTORY_RECORD.NAME + 1) - CP "." - JP NZ,.IT_DIR - LD HL,CORE_BUFFERS.WorkDirectory - LD D,H - LD E,L - INC HL - LD BC,CORE_BUFFERS.WorkDirectory.DEPTH - XOR A - CPIR - JP PO,.error ;[x] 20/11/23 проверка на выход за границы - DEC HL ;R009 - DEC HL - LD BC,CORE_BUFFERS.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,FAT_DIRECTORY_RECORD - 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,CORE_BUFFERS.WorkDirectory+1 - LD BC,CORE_BUFFERS.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:; fat32 - LD E,(IX + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_H) - LD D,(IX + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_H+1) - LD YH,D - LD YL,E - LD E,(IX + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_L) - LD D,(IX + FAT_DIRECTORY_RECORD.FIRST_CLUSTER_L+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 - LD (HL),0 - ;INC HL - RET -;----------------------------------------------------------------------; - -CHECK_ROOT_CLUSTER: - EX DE,HL - LD HL,(CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L) ;R005 - LD A,L - OR H - LD HL,(CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H) - OR L - OR H - EX DE,HL - RET - -;----------------------------------------------------------------------; -; вход: HL - имя директории -; [x] fat32 ;!TEST -OPENDIR: LD IY,CORE_BUFFERS.FM_BUF - LD A,(HL) - OR A - JR NZ,.SUBDIR - ; -.REROOT: LD DE,0 - LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),DE - LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H),DE - CALL LOADDIR - ; CF=0 - LD HL,CORE_BUFFERS.WorkDirectory - LD (HL),'\' - INC HL - LD (HL),#00 - ;AND A - RET - ; -.SUBDIR: CP "." - JR NZ,.SUBDIR2 - ; fat32 - CALL CHECK_ROOT_CLUSTER - JR NZ,.no_root ;R005 - ; "cd ." or "cd .." - ;R005 - INC HL - LD A,(HL) - OR A - DEC HL - JR Z,.REROOT - ; -.no_root: 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 - ; fat32 -.SUBDIR3: CALL FINDDIR - RET C - EX DE,HL - LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),HL ; fat32 - LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H),IY ; fat32 - LD HL,#4000 ;!HARDCODE - LD (CORE_BUFFERS.FM_BUF.FS_REC.F_SIZE),HL -;-------------; EX DE,HL -; JP LOADDIR -; Прочитать список каталога -; [x] fat32 ;!TEST -LOADDIR: ;!TODO optimize - CALL LOAD_SAVE_DIR_PREPARE - PUSH AF - EX AF,AF' - JR NZ,.read_dir - LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) - CP FAT_TYPE.x32 - JR NZ,.LoadRootDir - ; fat32 - LD HL,(CORE_BUFFERS.FatBuffer.RootDirStartCluster_L) - LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),HL - LD HL,(CORE_BUFFERS.FatBuffer.RootDirStartCluster_H) - LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H),HL - - ;LD HL,(CORE_BUFFERS.FatBuffer.BytesPerCluster) ; !FIXIT вычитывать полностью каталог - LD HL,#4000 ; размер директории - LD (CORE_BUFFERS.FM_BUF.FS_REC.F_SIZE),HL - ; -.read_dir: LD HL,DIRPAGE.buffer ; куда - LD DE,#4000 ; сколько - XOR A ; дескриптор - CALL READ ; чтение из файла - LD (SAVEDIR.DIRSIZE),DE ; число прочит. байтов - POP AF - OUT (SLOT3),A - RET - ; -.LoadRootDir: LD HL,(CORE_BUFFERS.FatBuffer.RootDirFirstSector_H) ;!TODO возможно, хватит LD HL,0 - LD IX,(CORE_BUFFERS.FatBuffer.RootDirFirstSector_L) ; номер лог. сектора - LD A,(CORE_BUFFERS.FatBuffer.DirSizeInSectors) - LD B,32 ; !HARDCODE sector size 512. 16384/(sector 512). размер root-каталога - CP B - JR NC,.RTD1 - LD B,A ; число секторов -.RTD1: LD A,(CORE_BUFFERS.FatBuffer.DRIVE) ; номер диска - LD DE,DIRPAGE.buffer ; буфер - LD C,Dss.DRV.Read ; чтение секторов - RST ToDSS.DRV - POP AF - OUT (SLOT3),A - RET -;----------------------------------------------------------------------; - - -;!TODO FAT procedures -;----------------------------------------------------------------------; - -LOAD_SAVE_DIR_PREPARE: - ;!TODO optimize - XOR A ; FILE MANIPULATOR = 0 - LD H,A - LD L,A - LD IX,0 - LD B,A ; от начала файла - CALL MOVE_FP - ; - SET_PAGE_X DIRPAGE - AND A - EX AF,AF' - ; - LD A,(CORE_BUFFERS.FatBuffer.DRIVE) - LD (IY+_sFM.DRIVE),A - ;!FIXIT переделать на работу без IY - LD A,(IY+_sFM.FS_REC.FIRST_CLUSTER_L) - OR (IY+_sFM.FS_REC.FIRST_CLUSTER_L+1) - OR (IY+_sFM.FS_REC.FIRST_CLUSTER_H) - OR (IY+_sFM.FS_REC.FIRST_CLUSTER_H+1) - ; - EX AF,AF' - RET - -;----------------------------------------------------------------------; -; скопировать запись в список диска (каталога) de ix iy -; и сбросить кеш каталога на диск -; вход: (HANDBUF) - запись каталога -WRT_HND: - SET_PAGE_X DIRPAGE - EX AF,AF' - LD HL,DIRPAGE.buffer - ;!TEST 9/11/23 record index - ; EXX - ; LD DE,0 - ; EXX - ; - LD BC,FAT_DIRECTORY_RECORD -.loop: ;LD A,(IX+00) - LD A,(HL) - OR A - JR Z,.WRT_HN2 - CP #E5 - JR Z,.WRT_HN2 - ;ADD IX,BC - ADD HL,BC - JR NC,.loop ;!FIXIT количество записей каталога = страница - ; - EX AF,AF' - OUT (SLOT3),A - LD A,DSS_Error.sys.ROOT_OVERFLOW - SCF - RET - ; -.WRT_HN2: ;LD D,XH - ;LD E,XL - EX DE,HL - 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,(CORE_BUFFERS.FatBuffer.BytesPerCluster) - ADD HL,BC - LD (SAVEDIR.DIRSIZE),HL - AND A - ;JP SAVEDIR -;----------------------------------------------------------------------; -; Сбросить кеш каталога на диск. -; вход: iy=структура дескриптора -; [x] fat32 ;!TEST -SAVEDIR: ;!TODO optimize - CALL LOAD_SAVE_DIR_PREPARE - PUSH AF - EX AF,AF' - JR NZ,.save_dir - ; - LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) - CP FAT_TYPE.x32 - JR NZ,.SaveRootDir - ; fat32 - LD HL,(CORE_BUFFERS.FatBuffer.RootDirStartCluster_L) - LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_L),HL - LD HL,(CORE_BUFFERS.FatBuffer.RootDirStartCluster_H) - LD (CORE_BUFFERS.FM_BUF.FS_REC.FIRST_CLUSTER_H),HL - ; -.save_dir: LD HL,DIRPAGE.buffer - ; размер списка каталога size_cash_directory - ;!FIXIT если она нужна, то проверить на баги (например, размер дирректории меньше при открытии и больше после правок) - ; когда будет чтение кусками каталога в кэш, тут ещё счётчик прикрутить -.DIRSIZE+1: LD DE,0 - XOR A - CALL WRITE - POP AF - OUT (SLOT3),A - RET - ; -.SaveRootDir: LD HL,(CORE_BUFFERS.FatBuffer.RootDirFirstSector_H) ;!TODO возможно, хватит LD HL,0 - LD IX,(CORE_BUFFERS.FatBuffer.RootDirFirstSector_L) - LD A,(CORE_BUFFERS.FatBuffer.DirSizeInSectors) - LD B,32 ;!HARDCODE sector size 512, Root Dir max size in sectors - SUB B - JR NC,.RTD1S - ADD A,B - LD B,A -.RTD1S: LD A,(CORE_BUFFERS.FatBuffer.DRIVE) - LD DE,DIRPAGE.buffer - LD C,Dss.DRV.Write - RST ToDSS.DRV - POP AF - OUT (SLOT3),A - RET -;----------------------------------------------------------------------; - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -; [x] fat32 ;!TEST -RD_BPB: ; LD C,SLOT3 - ; IN B,(C) - ; PUSH BC - ; IN A,(SLOT0) - ; OUT (SLOT3),A - ; LD A,(CORE_BUFFERS.FatBuffer.DRIVE) - ; LD DE,CORE_BUFFERS.SECTOR_BUFFER+#C000 ;R08 - ; LD C,Dss.DRV.GetBPB - ; RST ToDSS.DRV - ; POP BC - ; OUT (C),B - CALL READ_BPB - JP C,DOS_X_Error.Not_ready - ; - LD DE,#AA55 ; сигнатура ;R05 - LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.MBR_SIGNATURE) ;R08 ;R07 - ;R05 - AND A - SBC HL,DE - JP NZ,DOS_X_Error.UnknownBPB - ; - ; ;R08 ; [x] fat32 - ; LD HL,CORE_BUFFERS.SECTOR_BUFFER - ; LD DE,CORE_BUFFERS.BootSector - ; LD BC,_sBOOT_SECTOR_PARAMS_FAT32 ; size - ; LDIR - ; - LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.DRIVE_TYPE) - CP #F0 - JP C,DOS_X_Error.UnknownBPB - ; - LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.BytesPerSector) - LD (CORE_BUFFERS.FatBuffer.BytesPerSector),HL - LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.SectorsPerCluster) - LD (CORE_BUFFERS.FatBuffer.SectorsPerCluster),A - ; calc. first sector FAT - LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.RESERVED_SECTORS) - LD (CORE_BUFFERS.FatBuffer.FAT1_SEC_L),HL ; low word first sector FAT #1 - LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_L),HL ; low word first sector FAT #2 - ;[ ] fat32 - XOR A - LD B,A - LD C,A - LD (CORE_BUFFERS.FatBuffer.FAT1_SEC_H),BC ; high word first sector FAT #1 ; [ ] fat32 - LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_H),BC ; high word first sector FAT #1 ; [ ] fat32 - LD (CORE_BUFFERS.FatBuffer.RootDirFirstSector_H),BC - LD (CORE_BUFFERS.FatBuffer.SectorsPerFAT_H),A ; [ ] fat32 - ;LD (CORE_BUFFERS.FatBuffer.END_CHAIN_CLUSTER_H),BC ; [ ] fat32 reset variables - ; - ; - EXX - LD H,A - LD L,A - LD D,A - LD E,A - EXX - LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.SectorsPerFAT16) - LD A,E - OR D - JR NZ,.skip_high - ; - EXX - LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.SectorsPerFAT32 + 2) - LD A,E - EXX - ; - LD (CORE_BUFFERS.FatBuffer.SectorsPerFAT_H),A - LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.SectorsPerFAT32) - ; -.skip_high: LD (CORE_BUFFERS.FatBuffer.SectorsPerFAT_L),DE - LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.Number_of_FATs) ; amount FATs - LD (CORE_BUFFERS.FatBuffer.Number_Of_FATs),A - CP 1 - JR Z,.one_FAT - DEC A - ADD HL,DE - LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_L),HL - EXX - ADC HL,DE - LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_H),HL - EXX - ;JR NC,.no_inc_BC - ;INC BC -.no_inc_BC:;LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_H),BC -.one_FAT: ; -.loop1: ADD HL,DE - ;JR NC,.loop1_1 - ;INC BC - EXX - ADC HL,DE - EXX -.loop1_1: DEC A - JR NZ,.loop1 - ; - LD (CORE_BUFFERS.FatBuffer.RootDirFirstSector_L),HL ; first sector DIR - EXX - ; можно сразу тут загнать старший байт, потому-что дла FAT32 следующий расчёт - это прибавление нуля. - LD (CORE_BUFFERS.FatBuffer.FirstDataSector_H),HL - EXX - ;LD (CORE_BUFFERS.FatBuffer.FirstDataSector_H),BC - ; - LD BC,(CORE_BUFFERS.FatBuffer.BytesPerSector) - LD A,B - AND A - ; - RL C - RLA - RL C - RLA - RL C - RLA - ; - LD C,A - LD B,0 ; BC - File handels per sector - ;;;; - IF COMPILE_UNUSED_CODE - LD (CORE_BUFFERS.FatBuffer.FilesPerSector),A - ENDIF - ; - EX DE,HL - LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FilesInRootDIR) ; 0 for fat32 - ; [ ]fat32 ;!TEST - LD A,H - OR L - JR Z,.skip_loop2 - ; - DEC HL - XOR A - ;NEXTAD2 -.loop2: INC A - JP Z,DOS_X_Error.UnknownBPB - SBC HL,BC - JR NC,.loop2 - ; -.skip_loop2: EX DE,HL - LD C,A ; A - sectors in DIR - LD B,0 - LD (CORE_BUFFERS.FatBuffer.DirSizeInSectors),A - - ADD HL,BC ; Start DATA area - LD (CORE_BUFFERS.FatBuffer.FirstDataSector_L),HL - ; B = 0 - ; - LD HL,(CORE_BUFFERS.FatBuffer.BytesPerSector) - LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster) - ;!TODO FATcacheSize - ; calc. cluster size - XOR 1 - JR Z,.loop3.end - RRA -.loop3: ADD HL,HL - RRA - JP NC,.loop3 -.loop3.end: ; - LD (CORE_BUFFERS.FatBuffer.BytesPerCluster),HL - ;LD DE,#8001 ; проверка на размер кластера больше 32 кб - не поддерживается ; !TODO - ;AND A - ;SBC HL,DE - ;JP NC,DOS_X_Error.UnknownBPB ; [ ] fixed bug, thanks to @Romychs (Roman Boykov) -//////////////////////////////////////////////////////////////////////// -;!TODO не используется значения вычисляемые и сохраняемые в FatBuffer -; EX DE,HL -; LD HL,#3FFF ;!HARDCODE ;!TODO FATcacheSize -; XOR A -; ;NEXTAD4 ;!FIXIT оптимизировать когда понадобится -;.loop4: INC A -; JP Z,DOS_X_Error.UnknownBPB -; SBC HL,DE -; JR NC,.loop4 -; LD (CORE_BUFFERS.FatBuffer.ClustersPerBank),A ; A - Clusters per bank (16k) -; -; LD HL,0 -; LD BC,(CORE_BUFFERS.SECTOR_BUFFER + _sBOOT_SECTOR_PARAMS.SectorsPerTrack) ; Sector per track -; LD A,(CORE_BUFFERS.SECTOR_BUFFER + _sBOOT_SECTOR_PARAMS.HEADS) -;.BPB_L1: ; calc. sector per cylinder -; ADD HL,BC -; DEC A -; JR NZ,.BPB_L1 -; LD (CORE_BUFFERS.FatBuffer.S_X_H),HL -//////////////////////////////////////////////////////////////////////// - ; [ ] fat32 - LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.SectorsPerDrive) - LD A,H - OR L - LD DE,(CORE_BUFFERS.FatBuffer.FirstDataSector_L) - JP NZ,.HDDSMAL - ; - EXX - LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.BPB_BIG_TOTAL_SECTORS_H) - PUSH HL ; Total Sectors high - LD DE,(CORE_BUFFERS.FatBuffer.FirstDataSector_H) - EXX - LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.BPB_BIG_TOTAL_SECTORS_L) - PUSH HL ; Total Sectors low - AND A - SBC HL,DE - EXX - SBC HL,DE - PUSH HL - EXX - POP BC - ;JP NC,.HDDBIG - ;DEC BC - JP .HDDBIG - ; -.HDDSMAL: ; CF = 0 - LD BC,0 - PUSH BC ; Total Sectors high - PUSH HL ; Total Sectors low - SBC HL,DE - ; -.HDDBIG: CALL SectorToCluster -; LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster) -; SCF -; .loop7: RRA -; JR C,.loop7_exit -; RR B -; RR C -; RR H -; RR L -; JP .loop7 - ; -.loop7_exit: INC HL - LD (CORE_BUFFERS.FatBuffer.MaxClusterLow),HL - LD A,L - OR H - JR NZ,.no_inc_bc - INC BC -.no_inc_bc: LD (CORE_BUFFERS.FatBuffer.MaxClusterHigh),BC - ; - XOR A - LD H,A - LD L,A - LD (CORE_BUFFERS.FatBuffer.CacheBlock),HL - LD (CORE_BUFFERS.FatBuffer.CacheUpdated),A - ; A = 0 - LD HL,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_H) - LD H,A - EX DE,HL - LD HL,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_L) - ; DE:HL = SectorsPerFAT - ; - LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.Number_of_FATs) - LD B,A - DEC A - JR Z,.loop_mul_end - ; .Number_of_FATs * .SectorsPerFAT -.loop_mul: ADD HL,HL - EX DE,HL - ADC HL,HL - EX DE,HL - DJNZ .loop_mul -.loop_mul_end: ; .DirSizeInSectors + .Number_of_FATs * .SectorsPerFAT - LD B,0 - LD A,(CORE_BUFFERS.FatBuffer.DirSizeInSectors) - LD C,A - ADD HL,BC - JR NC,.no_inc_DE - INC DE -.no_inc_DE: ; .RESERVED_SECTORS + .DirSizeInSectors + .Number_of_FATs * .SectorsPerFAT - LD BC,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.RESERVED_SECTORS) - ADD HL,BC - JR NC,.no_inc_de - INC DE -.no_inc_de: ; Total_Sectors - (.RESERVED_SECTORS + .DirSizeInSectors + .Number_of_FATs * .SectorsPerFAT) - AND A - LD B,D - LD C,E - POP DE ; Total Sectors low - EX DE,HL - SBC HL,DE - EX (SP),HL ; Total Sectors high - SBC HL,BC - POP DE ; Total Sectors low - ; HL:DE = DataSec - ; - LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster) - ; HL:DE / A => DE:BC, H=0, L - остаток - CALL DIV_by_Shifts - ; выясняем разрядность FAT - LD A,D - OR E - JR NZ,.its_FAT32 - ; - LD HL,4084 - SBC HL,BC - JR NC,.its_FAT12 - ; - LD HL,65524 - SBC HL,BC - JR C,.its_FAT32 - ; - ; It's FAT16 - LD HL,#FFFF - LD A,FAT_TYPE.x16 -.set_vars: EXX - LD HL,0 - LD (CORE_BUFFERS.FatBuffer.END_CHAIN_CLUSTER_H),HL - LD (CORE_BUFFERS.FatBuffer.RootDirStartCluster_L),HL - LD (CORE_BUFFERS.FatBuffer.RootDirStartCluster_H),HL - LD HL,CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT.LABEL - EXX - LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT.SERIAL_NUMBER) - LD BC,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT.SERIAL_NUMBER+2) - JR .SET_VARS - ; -.its_FAT12: LD HL,#0FFF - LD A,FAT_TYPE.x12 - JR .set_vars - ; -.its_FAT32: LD A,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.MainFATnumber) - CP #80 - JR C,.mirrored_FATs ;если все копии FAT используются - ; используется только одна копия FAT - LD HL,(CORE_BUFFERS.FatBuffer.FAT1_SEC_H) - LD DE,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_H) - LD D,0 - EXX - LD HL,(CORE_BUFFERS.FatBuffer.FAT1_SEC_L) - LD DE,(CORE_BUFFERS.FatBuffer.SectorsPerFAT_L) - AND #0F - JR Z,.first_FAT_active - LD B,A - ; -.fat_calc_loop: ADD HL,DE - EXX - ADC HL,DE - EXX - DJNZ .fat_calc_loop - ; -.first_FAT_active: - LD (CORE_BUFFERS.FatBuffer.FAT1_SEC_L),HL - LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_L),HL - EXX - LD (CORE_BUFFERS.FatBuffer.FAT1_SEC_H),HL - LD (CORE_BUFFERS.FatBuffer.FAT2_SEC_H),HL - ; -.mirrored_FATs: LD HL,CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT32.LABEL - ; - EXX - LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.RootDirStartCluster) - LD (CORE_BUFFERS.FatBuffer.RootDirStartCluster_L),HL - LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.RootDirStartCluster+2) - LD (CORE_BUFFERS.FatBuffer.RootDirStartCluster_H),DE - ; - CALL CLUSTER_TO_SECTOR.no_prepare - LD (CORE_BUFFERS.FatBuffer.RootDirFirstSector_L),IX - LD (CORE_BUFFERS.FatBuffer.RootDirFirstSector_H),HL - ; - LD HL,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FSINFO_Sector) - LD (CORE_BUFFERS.FatBuffer.FSINFO_Sector),HL - ; - LD A,FAT_TYPE.x32 - LD HL,#0FFF - LD (CORE_BUFFERS.FatBuffer.END_CHAIN_CLUSTER_H),HL - LD H,L - LD DE,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT32.SERIAL_NUMBER) - LD BC,(CORE_BUFFERS.SECTOR_BUFFER + BOOT_SECTOR.FAT32.SERIAL_NUMBER+2) - ; -.SET_VARS: LD (CORE_BUFFERS.FatBuffer.FAT_TYPE),A - LD (CORE_BUFFERS.FatBuffer.END_CHAIN_CLUSTER_L),HL - LD (CORE_BUFFERS.FatBuffer.BPB_SERIAL_NUMBER),DE - LD (CORE_BUFFERS.FatBuffer.BPB_SERIAL_NUMBER+2),BC - EXX - LD DE,CORE_BUFFERS.FatBuffer.BPB_LABEL - LD BC,11 ;!HARDCODE - LDIR - ; - SET_PAGE_X FATPAGE - PUSH AF - LD DE,0 - CALL READ_FAT_TABLE - POP AF - OUT (SLOT3),A - ; - ; Установить начальный кластер для чтения - LD A,(CORE_BUFFERS.FatBuffer.FAT_TYPE) - CP FAT_TYPE.x32 - JR Z,.set_FSinfo - ; - LD HL,#0001 - LD (G_CLUST.low),HL - DEC L - LD (G_CLUST.high),HL - ; - DEC HL - LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_L),HL - LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_H),HL - XOR A - RET - ; -.set_FSinfo: CALL READ_FSinfo - ; !FIXIT проверка на ошибку - ; - ; проверка одной из сотни сраных сигнатур - LD HL,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.DATA_SIGNATURE) - LD DE,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.DATA_SIGNATURE + 2) - LD BC,#7272 - SBC HL,BC - JR NZ,.error - EX DE,HL - LD DE,#6141 - SBC HL,DE - JR NZ,.error - ; FREE_CLUSTERS_COUNT - LD BC,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FREE_CLUSTERS_COUNT) - LD DE,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FREE_CLUSTERS_COUNT+2) - ; CF = 0 - CALL .check_cluster - JR NC,.skip_FFFF - ; - LD B,#FF - LD C,B - LD D,B - LD E,B - ; -.skip_FFFF: LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_L),BC - LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_H),DE - ; - ; FIRST_FREE_CLUSTER - LD BC,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FIRST_FREE_CLUSTER) - LD DE,(CORE_BUFFERS.SECTOR_BUFFER + _sFSinfo.FIRST_FREE_CLUSTER+2) - ; CF = 0 - CALL .check_cluster - JR C,.error - ; - LD (G_CLUST.high),DE - LD (G_CLUST.low),BC - XOR A -.error: LD (CORE_BUFFERS.FatBuffer.UPD_FSINFO),A - RET Z - ;!TODO FREE_CLUSTERS_COUNT - ;LD HL,#FFFF - ;LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_L),HL - ;LD (CORE_BUFFERS.FatBuffer.FREE_CLUSTERS_COUNT_H),HL - ; - XOR A - LD H,A - LD L,2 - LD (G_CLUST.low),HL - LD L,H - LD (G_CLUST.high),HL - RET - ; - ;!TODO MaxCluster - максимально допустимый или на 1 больше максимально допустимого? -.check_cluster: LD HL,(CORE_BUFFERS.FatBuffer.MaxClusterLow) - SBC HL,BC - LD HL,(CORE_BUFFERS.FatBuffer.MaxClusterHigh) - SBC HL,DE - RET -;;;;;;;; - -; --> BC:HL - Sector -; <-- BC:HL - Cluster -SectorToCluster: - LD A,B - AND #0F - LD B,A - LD A,(CORE_BUFFERS.FatBuffer.SectorsPerCluster) - SCF -.loop: RRA - RET C - RR B - RR C - RR H - RR L - JP .loop -; - -DOS_X_Error: -.UnknownBPB: 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' -.DRIVE: DB #FF -.FAT_TYPE: DB #00 ; TYPE FAT (12 - 12bit, 16 - 16bit, 32 - 32bit) ; [x] fat32 -.CacheBlock: DW #00 -.CacheUpdated: DB #00 -;.SectorsPerBank: DB #00 -.RootDirStartCluster_L: DW #0000 -.RootDirStartCluster_H: DW #0000 ; [ ] fat32 -.FAT1_SEC_L: DW #0000 ; MSD_FAT_SEC first sector FAT (FAT_FRM) -.FAT1_SEC_H: DW #0000 ; [ ] fat32 -.FAT2_SEC_L: DW #0000 -.FAT2_SEC_H: DW #0000 ; [ ] fat32 -.SectorsPerFAT_L DW #0000 -.SectorsPerFAT_H DB #00 -.RootDirFirstSector_L: DW #0000 ; MSD_CAT_SEC first sector DIR -.RootDirFirstSector_H: DW #0000 ; MSD_CAT_SEC first sector DIR ; !TODO ограничение в 32 Гига ;!FIXIT не используется -.DirSizeInSectors: DB #00 ; DIR_SEC_SIZE -.FirstDataSector_L: DW #0000 ; MSD_DAT_SEC low -.FirstDataSector_H: DW #0000 ; MSD_DAT_SEC high ; [ ] fat32 было ограничение в 32 Гига -.BytesPerCluster: DW #0000 ; CLUSTER_LEN -.END_CHAIN_CLUSTER_L: DW #FFFF -.END_CHAIN_CLUSTER_H: DW #0FFF ; [ ] fat3 -.MaxClusterLow: DW #0000 ; макс. число кластеров (без служ.) -.MaxClusterHigh: DW #0000 ; макс. число кластеров (без служ.) -; -.BytesPerSector DW #0000 -.SectorsPerCluster DB #00 -.BPB_SERIAL_NUMBER DW 0,0 -.BPB_LABEL BLOCK 11,' ' ; 11 для FAT, 31 для CDFS - IF COMPILE_UNUSED_CODE -.FilesPerSector: DB #00 ; число файловых записей в секторе -.ClustersPerBank: DB #00 ; A - Clusters per bank (16k) (число кластеров на блок ОЗУ) ; ????? это используется? - ENDIF -;.READ_PG: DB #00 ;!TODO не используются некоторые значения, но задумка неплохая))) -;.S_X_H: DW #0000 ; количество секторов на цилиндре ; ????? это используется? -; -*/ -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/DSS/FS_Module.asm b/DSS/FS_Module.asm new file mode 100644 index 0000000..da9d44a --- /dev/null +++ b/DSS/FS_Module.asm @@ -0,0 +1,8 @@ + INCLUDE "FS/FAT.ASM" + INCLUDE "FS/CDFS.ASM" + +/* + +READ_BPB ; Прочитать BPB в SECTOR_BUFFER + +*/ \ No newline at end of file diff --git a/DSS/Kernel_Panic.asm b/DSS/Kernel_Panic.asm deleted file mode 100644 index 8c5c791..0000000 --- a/DSS/Kernel_Panic.asm +++ /dev/null @@ -1,81 +0,0 @@ -; - MACRO PRINT_LINE_KERNEL_PANIC coordY, txtString, txtStringSize, txtColor - LD HL,txtString - LD BC,txtColor*256 + txtStringSize - LD DE,coordY * 256 + (80 - txtStringSize)/2 - CALL .PRINT_LINE - ENDM ; 12 bytes -; -;-----------------------[] -; HL - сообщение -; E - координата X на текстовом экране -; BC - длина сообщения -KERNEL_PANIC: - DI - ; - PUSH DE - PUSH HL - PUSH BC - ; - LD E,1 - LD BC,BIOS.LP_OPEN_S.TXT_80x32_Default - RST ToBIOS - ; - LD HL,#2050 - LD DE,0 - LD BC,256*COLORS.CGA.PAPER.BLUE + BIOS.LP_CLS_WIN - RST ToBIOS - ; - LD A,1 - OUT (SCREEN_SWITCH),A ; set scr-2 - ; - PRINT_LINE_KERNEL_PANIC 13, .kernel_panic, .kernel_panic.size, +(COLORS.CGA.FLASH + COLORS.CGA.PAPER.BLUE + COLORS.CGA.INK.RED) - PRINT_LINE_KERNEL_PANIC 18, .press_CAD, .press_CAD.size, +(COLORS.CGA.PAPER.BLUE + COLORS.CGA.INK.WHITE) - ; - POP BC - POP HL - LD DE,#A000 - LD A,C - LDIR - ; - POP DE - LD D,15 - LD C,BIOS.LP_SET_PLACE - RST ToBIOS - ; - LD HL,#A000 - LD DE,0*256 + COLORS.CGA.PAPER.BLUE + COLORS.CGA.INK.WHITE - LD B,A - LD C,BIOS.LP_PRINT_LINE3 - RST ToBIOS - ; -.loop: DI - HALT - JR .loop - ; -.PRINT_LINE: - PUSH BC - PUSH DE - LD DE,#A000 - LD B,E - LD A,C - LDIR - ; - POP DE - LD C,BIOS.LP_SET_PLACE - RST ToBIOS - ; - POP DE - LD E,D - LD HL,#A000 - LD D,L - LD B,A - LD C,BIOS.LP_PRINT_LINE3 - JP ToBIOS - ; -.kernel_panic: DZ "KERNEL PANIC!" -.kernel_panic.size EQU $-.kernel_panic -; -.press_CAD: DZ "Press Ctrl+Alt+Del or RESET." -.press_CAD.size EQU $-.press_CAD -;-----------------------[] \ No newline at end of file diff --git a/DSS/Procedures.asm b/DSS/Procedures.asm index 8356e6b..cf7ecdd 100644 --- a/DSS/Procedures.asm +++ b/DSS/Procedures.asm @@ -265,7 +265,6 @@ BCD2HEX: ;!TODO hardware ;----------------------------------------------------------------------; -;!FIXIT переделать по доке на Даллас и запись в ячейки часов ; Запись регистров CMOS ; вход: d=номер регистра WCMOS: CALL HEX2BCD @@ -343,4 +342,87 @@ DIV_by_Shifts: LD H,0 LD L,A RET -;----------------------------------------------------------------------; \ No newline at end of file +;----------------------------------------------------------------------; + +;=============================================================================================================================== + MACRO PRINT_LINE_KERNEL_PANIC coordY, txtString, txtStringSize, txtColor + LD HL,txtString + LD BC,txtColor*256 + txtStringSize + LD DE,coordY * 256 + (80 - txtStringSize)/2 + CALL .PRINT_LINE + ENDM ; 12 bytes +; +;-----------------------[] +; HL - сообщение +; E - координата X на текстовом экране +; BC - длина сообщения +KERNEL_PANIC: + DI + ; + PUSH DE + PUSH HL + PUSH BC + ; + LD E,1 + LD BC,BIOS.LP_OPEN_S.TXT_80x32_Default + RST ToBIOS + ; + LD HL,#2050 + LD DE,0 + LD BC,256*COLORS.CGA.PAPER.BLUE + BIOS.LP_CLS_WIN + RST ToBIOS + ; + LD A,1 + OUT (SCREEN_SWITCH),A ; set scr-2 + ; + PRINT_LINE_KERNEL_PANIC 13, .kernel_panic, .kernel_panic.size, +(COLORS.CGA.FLASH + COLORS.CGA.PAPER.BLUE + COLORS.CGA.INK.RED) + PRINT_LINE_KERNEL_PANIC 18, .press_CAD, .press_CAD.size, +(COLORS.CGA.PAPER.BLUE + COLORS.CGA.INK.WHITE) + ; + POP BC + POP HL + LD DE,#A000 + LD A,C + LDIR + ; + POP DE + LD D,15 + LD C,BIOS.LP_SET_PLACE + RST ToBIOS + ; + LD HL,#A000 + LD DE,0*256 + COLORS.CGA.PAPER.BLUE + COLORS.CGA.INK.WHITE + LD B,A + LD C,BIOS.LP_PRINT_LINE3 + RST ToBIOS + ; +.loop: DI + HALT + JR .loop + ; +.PRINT_LINE: + PUSH BC + PUSH DE + LD DE,#A000 + LD B,E + LD A,C + LDIR + ; + POP DE + LD C,BIOS.LP_SET_PLACE + RST ToBIOS + ; + POP DE + LD E,D + LD HL,#A000 + LD D,L + LD B,A + LD C,BIOS.LP_PRINT_LINE3 + JP ToBIOS + ; +.kernel_panic: DZ "KERNEL PANIC!" +.kernel_panic.size EQU $-.kernel_panic +; +.press_CAD: DZ "Press Ctrl+Alt+Del or RESET." +.press_CAD.size EQU $-.press_CAD +;-----------------------[] +;=============================================================================================================================== \ No newline at end of file diff --git a/DSS/VIDEO.ASM b/DSS/VIDEO.ASM deleted file mode 100644 index f1bdb0a..0000000 --- a/DSS/VIDEO.ASM +++ /dev/null @@ -1,696 +0,0 @@ - -;[BEGIN] -;//MODULE: VIDEO -;//CREATE: 19-05-1998 AUTHOR: Denis Parinov -;//UPDATE: 24-10-1999 DNS Restore module -;--------------------------------------------------------------- -;Rev Date Name Description -;--------------------------------------------------------------- -;R02 07-11-2002 DNS CORRECT FN. WINCOPY & WINREST, ADD "DI+EI" -;R01 07-11-2002 DNS FIX BUG WITH SCROLLUP FN. (A=0) -;--------------------------------------------------------------- - -;///////////////////////////////////////////////////////////////////// -; Функция #56. Очистить окно. -; -; вход: D - строка левого верхнего угла окна -; E - столбец левого верхнего угла окна -; H - высота окна -; L - ширина окна -; A - символ заполнитель -; B - атрибут заполнитель -; выход: нет -;///////////////////////////////////////////////////////////////////// -CLEAR: LD C,BIOS.LP_CLS_WIN2 - JP ToBIOS - ;AND A - ;RET -; -;///////////////////////////////////////////////////////////////////// -; Функция #5C. Вывод строки на экран. -; -; вход: HL - указатель на строку символов -; выход: HL - указатель на следующую строку символов -; PRINT NULL-TERMINATED CHARS STRING -;///////////////////////////////////////////////////////////////////// -PCHARS: LD A,(HL) - INC HL - OR A - RET Z - CALL PUTCHAR - JP PCHARS - -;///////////////////////////////////////////////////////////////////// -; Функция #5B. Вывод символа на экран в тек. позиции. -; -; вход: A - символ -; выход: нет -;///////////////////////////////////////////////////////////////////// -PUTCHAR: - ;CALL .NO_SCROLL - CP #0E - JR C,.control_characters - ; - LD BC,1*256 + BIOS.LP_PRINT_SYM - ;[x] CR+LF+SCROLL - RST ToBIOS - ; - ; проверка на переход курсора в самое начало (X:Y == 0:0) - CALL CURSOR - LD A,D - OR E - RET NZ - ; -.LFF: PUSH HL - LD BC,1*256 + BIOS.LP_SCROLL_UD - LD DE,#0020 - RST ToBIOS - LD DE,#1F00 - CALL LOCATE - LD A,' ' - LD BC,#50*256 + BIOS.LP_PRINT_SYM - RST ToBIOS - LD DE,#1F00 - CALL LOCATE - POP HL - RET -.TB_: CALL CURSOR - IF TABisSPACES - LD B,E - LD A,E - AND #F8 - ADD A,8 - SUB B - LD B,A - LD A,' ' - LD C,BIOS.LP_PRINT_SYM - JP ToBIOS - ELSE - LD A,E - ADD A,8 - AND #78 ;????? глянуть, что будет если координаты курсора в конце строки почти - LD E,A - JP LOCATE - ENDIF -.BK_: CALL CURSOR - XOR A - CP E - RET Z - DEC E - JP LOCATE - ; -.LF_: CALL CURSOR - LD A,D - CP #1F - JR NC,.LFF - INC D - IFN EnoughtOnly_LF - JP LOCATE - ELSE - CALL LOCATE - ; !!!! НЕ разрывать LF_ и CR_ !!!! - ENDIF -.CR_: CALL CURSOR - LD E,0 - JP LOCATE - ; -.control_characters: - CP #0D - JR Z,.CR_ - CP #0A - JR Z,.LF_ - CP #09 - JR Z,.TB_ - CP #08 - JR Z,.BK_ - CP #07 ; [x] Beep in PChars/PUTCHAR - RET NZ - ; [x] Beep in PChars/PUTCHAR -.BELL: LD DE,1200 - PUSH HL - LD HL,4 - CALL BEEP - POP HL - RET - ; -; [x] -bug with Vasil's version of cursor -.NO_SCROLL: - CP #0E - JR C,.control_characters -._CHAR: LD BC,1*256 + BIOS.LP_PRINT_SYM - JP ToBIOS - ; - -;-----[] -; -; - -;///////////////////////////////////////////////////////////////////// -; Функция #52. Установить положение курсора. -; -; вход: D - строка курсора -; E - колонка курсора -; выход: нет -;///////////////////////////////////////////////////////////////////// -LOCATE: LD C,BIOS.LP_SET_PLACE - JP ToBIOS - -;///////////////////////////////////////////////////////////////////// -; Функция #53. Узнать положение курсора. -; -; вход: нет -; выход: D - строка курсора -; E - колонка курсора -;///////////////////////////////////////////////////////////////////// -CURSOR: LD C,BIOS.LP_GET_PLACE - JP ToBIOS - -;///////////////////////////////////////////////////////////////////// -; Функция #57. Прочитать символ с экрана. -; -; вход: D - строка -; E - колонка -; выход: A - символ -; B - атрибут -;///////////////////////////////////////////////////////////////////// -RDCHAR: XOR A - LD C,BIOS.WIN_GET_SYM - RST ToBIOS - LD A,L - LD B,H - ;AND A - RET - -;///////////////////////////////////////////////////////////////////// -; Функция #58. Вывести символ на экран. -; Управляющие символы выводятся как обычные символы. -; -; вход: D - строка -; E - колонка -; A - символ -; B - атрибут -; выход: нет -;!FIXIT slow как без WIN_GET_SYM тут обойтись? -;///////////////////////////////////////////////////////////////////// -WRCHAR: LD C,A - PUSH BC - PUSH DE - XOR A - LD C,BIOS.WIN_GET_SYM - RST ToBIOS - POP DE - POP HL - XOR A - LD C,BIOS.WIN_PUT_SYM - JP ToBIOS - ;AND A - ;RET - -;///////////////////////////////////////////////////////////////////// -; Функция #59. Сохранить окно экрана. -; -; вход: D - строка -; E - колонка левого верхнего угла окна -; H - высота окна -; L - ширина окна -; B - страница буфера, если IX >= #C000 -; IX - адрес буфера -; выход: нет -;///////////////////////////////////////////////////////////////////// -WINCOPY: AND A - LD A,R ;R02 - PUSH AF ;R02 - XOR A - LD C,BIOS.WIN_COPY - DI ;R02 - RST ToBIOS - POP AF ;R02 - RET PO ;R02 - EI ;R02 - RET - -;///////////////////////////////////////////////////////////////////// -; Функция #5A. Восстановить окно экрана. -; -; вход: D - строка -; E - колонка левого верхнего угла окна -; H - высота окна -; L - ширина окна -; B - страница буфера, если IX >= #C000 -; IX - адрес буфера -; выход: нет -;///////////////////////////////////////////////////////////////////// -WINREST: AND A - LD A,R ;R02 - PUSH AF ;R02 - XOR A - DI ;R02 - LD C,BIOS.WIN_RESTORE - RST ToBIOS - POP AF ;R02 - RET PO ;R02 - EI ;R02 - RET -;///////////////////////////////////////////////////////////////////// -; Функция #55. Скроллинг экрана. -; -; вход: D - строка левого верхнего угла окна -; E - колонка левого верхнего угла окна -; H - высота окна -; L - ширина окна -; B = 1 - прокрутка вверх -; B = 2 - прокрутка вниз -; A = 0 - очищать строку -; выход: нет -;///////////////////////////////////////////////////////////////////// -SCROLL: DJNZ .SCR_DW ;!TODO заменить на BIOS.LP_SCROLL_UD и посмотреть, что шустрее - ;[x] 04/04/23 - ;LD B,A - ;LD C,H - ;PUSH BC - PUSH AF - ; - PUSH DE - PUSH HL - LD XH,D - LD XL,E - INC D - DEC H - LD C,BIOS.WIN_MOVE - ;[x] 29/9/23 - LD A,R - PUSH AF - ; - XOR A - DI ;[x] 29/9/23 - RST ToBIOS - ;[x] 29/9/23 - POP AF - JP PO,.skip_EI - EI -.skip_EI: - POP HL - POP DE - ;[x] 04/04/23 - ;POP BC - POP AF - ;XOR A - ;CP B - AND A - ; - RET NZ - LD A,D - ADD A,H - DEC A ;R01 - LD D,A -.print: PUSH DE ;R01 - CALL LOCATE - LD A,' ' - LD B,L - LD C,BIOS.LP_PRINT_SYM - RST ToBIOS - POP DE ;R01 - JP LOCATE ;R01 - ;AND A - ;RET -.SCR_DW: - DJNZ .SCR_ERR - ;[x] 04/04/23 - ;LD B,A - ;LD C,H - ;PUSH BC - PUSH AF - ; - PUSH DE - PUSH HL - LD XH,D - LD XL,E - INC XH - DEC H - LD C,BIOS.WIN_MOVE - ;[x] 29/9/23 - LD A,R - PUSH AF - ; - XOR A - DI ;[x] 29/9/23 - RST ToBIOS - ; [x] 29/9/23 - POP AF - JP PO,.skip2_EI: - EI -.skip2_EI: - POP HL - POP DE - ;[x] 29/9/23 - ;POP BC - POP AF - ;XOR A - ;CP B - AND A - ; - RET NZ - JP SCROLL.print -.SCR_ERR: - LD A,DSS_Error.sys.INVALID_FUNCTION - SCF - RET - -;///////////////////////////////////////////////////////////////////// -; Функция #54. Выбрать активную страницу экрана. -; -; вход: B - страница экрана 0/1 -; выход: A - код ошибки, если CF=1 -;///////////////////////////////////////////////////////////////////// -SELPAGE: - LD A,(VMODE) - ;BIT 7,A - CP %1000'0000 - JR NC,.SEL2 - PUSH BC - LD C,A - CALL SETVMOD.TEXT_M - POP BC -.SEL2: LD A,B - AND #01 - OUT (SCREEN_SWITCH),A - RET - -;///////////////////////////////////////////////////////////////////// -; Функция #51. Получить текущий режим экрана. -; -; вход: нет -; выход: A - текущий режим экрана -; B - страница экрана 0/1 -;///////////////////////////////////////////////////////////////////// -GETVMOD: - IN A,(SCREEN_SWITCH) - LD B,A - LD A,(VMODE) - AND A - RET - -;///////////////////////////////////////////////////////////////////// -; Функция #50. Выбор режима экрана. -; -; вход: A - режим экрана -; #02 - текстовый 40x32x16 цветов -; #03 - текстовый 80x32x16 цветов -; #81 - графический 320x256x256 цветов -; #82 - графический 640x256x16 цветов -; B - страница экрана 0/1 -; выход: A - код ошибки, если CF=1 -;///////////////////////////////////////////////////////////////////// -SETVMOD:; - CP %1000'0000 - LD C,A - JR NC,GRAPH -.TEXT_M: LD IX,BACKTXT - PUSH IX - EX AF,AF' - LD A,(VMODE) - LD (BACKTXT.VMODE),A - EX AF,AF' - OR A - JR Z,.NOMODE - DEC A - JR Z,.NOMODE - DEC A - LD HL,TAB_40x32 - JR Z,T_40_32 - DEC A - LD HL,TAB_80x32 - JR Z,T_80_32 -.NOMODE: POP IX - LD A,DSS_Error.sys.INVALID_VIDEO_MODE - SCF - RET - -; Установка граф. режимов -GRAPH: CALL SAVETXT - AND #7F - JR Z,G320_16 ; !TODO ? - пока отрабатывает как ошибка - DEC A - JR Z,G320_56 - DEC A - JR Z,G640_16 -; DEC A -; JP Z,G640_56 ; !TODO ? - пока отрабатывает как ошибка -G320_16: LD A,DSS_Error.sys.INVALID_VIDEO_MODE - SCF - RET - -T_80_32: -T_40_32: PUSH BC -; LD HL,TAB2 - LD A,B - RLCA - RLCA - RLCA - RLCA - OR B - AND #11 - XOR #10 - LD E,A -GRAPH_NEXT: - CALL SETMODE - POP BC - LD A,C - LD (VMODE),A - LD A,B - AND #01 - OUT (SCREEN_SWITCH),A - LD A,(VMODE) - LD C,Dss.Mouse.SetVideoMode - RST ToDSS.Mouse - SAFE_PORTY - XOR A - RET - -; T_80_32 PUSH BC -; LD HL,TAB1 -; LD A,B -; RLCA -; RLCA -; RLCA -; RLCA -; OR B -; AND #11 -; XOR #10 -; LD E,A -; CALL SETMODE -; POP BC -; LD A,C -; LD (VMODE),A -; LD A,B -; AND #01 -; OUT (SCREEN_SWITCH),A -; LD A,(VMODE) -; LD C,#81 -; RST #30 -; SAFE_PORTY -; XOR A -; RET - -G320_56 PUSH BC - LD HL,TAB_320x256_0 - LD E,#11 - CALL SETMODE - LD HL,TAB_320x256_1 - LD E,#00 - JP GRAPH_NEXT - ; CALL SETMODE - ; POP BC - ; LD A,C - ; LD (VMODE),A - ; LD A,B - ; AND #01 - ; OUT (SCREEN_SWITCH),A - ; LD A,(VMODE) - ; LD C,#81 - ; RST #30 - ; SAFE_PORTY - ; XOR A - ; RET - -G640_16 PUSH BC - LD HL,TAB_640x256_0 - LD E,#11 - CALL SETMODE - LD HL,TAB_640x256_1 - LD E,#00 - JP GRAPH_NEXT - - ; CALL SETMODE - ; POP BC - ; LD A,C - ; LD (VMODE),A - ; LD A,B - ; AND #01 - ; OUT (SCREEN_SWITCH),A - ; LD A,(VMODE) - ; LD C,#81 - ; RST #30 - ; SAFE_PORTY - ; XOR A - ; RET -VMODE: DB #03 - -;----------------------------------------------------------------------- -; Открыть окно -; вход: hl=описатель окна -; e=флаги окна -; -;02h - TEXT 40 x 32 (16 colors) -;03h - TEXT 80 x 32 (16 colors) -;80h - GRAF 320 x 256 (16 colors) -;81h - GRAF 320 x 256 (256 colors) -;82h - GRAF 640 x 256 (16 colors) -;83h - GRAF 640 x 256 (256 colors) UNUSED -;----------------------------------------------------------------------- -SETMODE: PUSH DE - LD DE,SYS_PAGE.SHARED_BUFFER_32b ; грязный хак. кидает данные в буфер служебной страницы биоса. - LD BC,ScreenDescriptorTable.Size ; БИОС при использовании IX предполагает, что он указывает - IN A,(SLOT3) ; на адрес ниже #C000 и вставляет в третью банку страницу #FE - EX AF,AF' - LD A,SYS_PAGE - OUT (SLOT3),A - LDIR - EX AF,AF' - OUT (SLOT3),A -.skip_EI: POP DE - LD IX,SYS_PAGE.SHARED_BUFFER_32b ; грязный хак. - LD C,BIOS.WIN_OPEN - RST ToBIOS - SAFE_PORTY - XOR A - RET - -;IX+0 ;HORIZONTAL -;IX+1 ;VERTICAL -;IX+2 ;X - COORD -;IX+3 ;Y - COORD -;IX+4 ;MODE -;IX+5 ;EXT MODE -;IX+6 ;VIDEO RAM X OFFSET (SIGNPLACES) -;IX+7 ;VIDEO RAM Y OFFSET (SIGNPLACES) - -; -;....................................................................... -;+0 X размер окна в знакоместах -;+1 Y размер окна в знакоместах -;+2 X полож. окна на экране -;+3 Y полож. окна на экране -;+4 режим знакоместа -;+5 доп. режим знакоместа (bit0=1 спек. адресация экрана) -;+6 X полож. в поле графики (в знакоместах) -;+7 Y полож. в поле графики (в знакоместах) -ScreenDescriptorTable EQU $ -; 80x32. текстовое, знакоместо 16x8, #0B - номер знакоген. -TAB_80x32 DB #28,#20,#00,#00,#1B,#00,#00,#00 ;1 -; 40x32. текстовое, знакоместо 8x8, #0B - номер знакоген. -TAB_40x32 DB #28,#20,#00,#00,#3B,#00,#00,#00 ;2 -; 640x256. графическое, 0-й экран -TAB_640x256_0 DB #28,#20,#00,#00,#00,#00,#00,#00 ;3 -; 320x256. графическое, 0-й экран -TAB_320x256_0 DB #28,#20,#00,#00,#20,#00,#00,#00 ;4 -; 640x256. графическое, 1-й экран -TAB_640x256_1 DB #28,#20,#00,#00,#40,#00,#28,#00 ;5 -; 320x256. графическое, 1-й экран -TAB_320x256_1 DB #28,#20,#00,#00,#60,#00,#28,#00 ;6 -ScreenDescriptorTable.Size EQU ($ - ScreenDescriptorTable)/6 -;....................................................................... -; - -;---------------------------------------------------------------------- -; Сохранить экран текст. режима. -; Для буфера экрана исп. 2-я банка расширения ДОС. -SAVETXT: PUSH AF - LD A,(VMODE) - ;BIT 7,A - CP %1000'0000 - JR NC,.NOSAVET - SUB #02 - JR C,.NOSAVET - ; - PUSH BC - PUSH DE - PUSH HL - PUSH IX - ; - PUSH AF - LD C,BIOS.LP_GET_PLACE - RST ToBIOS - LD (BACKTXT.CURS),DE - POP AF - LD IX,#C000 - LD HL,#2050 - OR A - JR NZ,.SVTEXT1 - LD L,#28 -.SVTEXT1: LD (BACKTXT.WinMax),HL - LD DE,#0000 - LD A,(BANKTBL+TXTPAGE) - LD B,A - - LD C,BIOS.WIN_COPY - ;[x] 29/9/23 - LD A,R - PUSH AF - ; - XOR A - DI - RST ToBIOS - ;[x] 29/9/23 - POP AF - JP PO,.skip_EI - EI -.skip_EI: ; - POP IX - POP HL - POP DE - POP BC -.NOSAVET: POP AF - RET -;---------------------------------------------------------------------- - -BACKTXT: PUSH AF -.VMODE+1: LD A,#00 - ;BIT 7,A - CP %1000'0000 - JR C,.NOBACKT - ; - PUSH BC - PUSH DE - PUSH HL - PUSH IX - LD IX,#C000 -.WinMax+1: LD HL,#2050 - LD DE,#0000 - LD A,(BANKTBL+TXTPAGE) - LD B,A - LD C,BIOS.WIN_RESTORE - ;[x] 29/9/23 - LD A,R - PUSH AF - ; - XOR A - DI - RST ToBIOS - ;[x] 29/9/23 - POP AF - JP PO,.no_ei - EI -.no_ei: ; -.CURS+1: LD DE,#0000 - CALL LOCATE - POP IX - POP HL - POP DE - POP BC -.NOBACKT: POP AF - RET -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; -;//MODULE: VIDEO -;[END] \ No newline at end of file diff --git a/DSS/drivers/media/ReScanDRV.ASM b/DSS/drivers/media/ReScanDRV.ASM new file mode 100644 index 0000000..29d977b --- /dev/null +++ b/DSS/drivers/media/ReScanDRV.ASM @@ -0,0 +1,495 @@ +;!TODO код дико костыльный и будет переделан вместе с процедурой INITDVC +ReScanDRV: +.NUMBER_OF_SUBTABLES EQU 2 ;количество таблиц второго уровня (LOGDRV, RMDRIVE) +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; +; 0. запоминаем бут-диск +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; + LD A,B + LD (.old_letter),A +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; +; 1. копируем в буфер таблицы DEVICE, LOGDRV, RAMDTBL +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; + LD HL,DEVICE + LD DE,OLD_TABLES.DEVICE + LD BC,OLD_TABLES.DEVICE - DEVICE + LDIR + ; + LD A,.NUMBER_OF_SUBTABLES + LD (Fill_if_Exists.tbl),A +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; +; 2. вызываем инициализацию драйвов +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; + CALL INITDVC_RET_DRIVE + LD (DRV_PAGE.LDRIVE),A +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; +; 3. сравниваем записи старых таблиц с новыми: +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; + LD HL,OLD_TABLES.DEVICE + LD B,DSS_MAX_DRIVES_AMOUNT +.tbl_scanNew_mainLoop: + PUSH BC + PUSH HL + ; получаем номер процедуры для этой буквы диска + LD A,(HL) + ; + CP #FF + JR Z,.nextN + ; + LD B,A + INC HL + LD A,(HL) + INC HL + LD H,(HL) + LD L,A + ; [ищем что за драйв] + EX DE,HL + ; FDD? + LD HL,FDD_DRV.API_TABLE + AND A + SBC HL,DE + JR Z,.nextN ; пропуск FDD драйвов + ; HDD? + LD HL,HDDRIVE + AND A + SBC HL,DE + ; HDD! Сверка по таблице LOGDRV + JP Z,SCAN_TABLES.HARD_DRV + ; RD? + LD HL,RMDRIVE + AND A + SBC HL,DE + ; RAM Drive! Сверка по таблице RAMDTBL + JP Z,SCAN_TABLES.RAM_DRV + ; CD/DVD? + ;LD HL,CDDRIVE + ;AND A + ;SUB HL,DE + ; CD/DVD! + ; JR Z,SCAN_TABLES.CD_ROM + + ; следующий виток +.nextN: POP HL +.nextN2: + INC HL + INC HL + INC HL + POP BC + DJNZ .tbl_scanNew_mainLoop +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; +; 4. сравниваем запись новых таблиц со старыми +; а. если драйв только в новой: +; а1) втыкаем его в первую свободную запись в DEVICE (или ставим после последнего драйва) +; +; ВХОД: IX - OLD_TABLES.DEVICE +; HL - OLD_TABLES.DEVICE.End +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; + INC HL + LD (OLD_TABLES_CURRENT),HL + EXX + LD HL,OLD_TABLES.LOGDRV - LOGDRV + LD B,DSS_MAX_DRIVES_AMOUNT + EXX + ; находим в старой DEVICE первую свободную ячейку (проверяем с конца в начало) + LD IX,OLD_TABLES.DEVICE + OLD_TABLES.DEVICE.Size - OLD_TABLES.DEVICE.TBL_Entry + LD IY,LOGDRV + LD DE,-OLD_TABLES.DEVICE.TBL_Entry ; двигаемся по таблице назад + LD B,DSS_MAX_DRIVES_AMOUNT + ; +.loop1: LD A,#FF + CP (IX+0) + JR NZ,.loop2_start + ADD IX,DE + DJNZ .loop1 +.loop1_exit: + LD A,C ; закончили считать переменную LDRIVE + LD (DRV_PAGE.LDRIVE),A +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; + +; 5. проверяем, не грохнулся ли бут-диск. +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; +.old_letter+1: + LD A,0 + _CALC_DEVICE_ENTRY OLD_TABLES.DEVICE + LD A,(HL) + INC A + SCF + ;JP Z,ERROR_BOOTDRV_DIES + RET Z +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; + +; 6. заменяем новые таблицы на модифицированные старые +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; + LD HL,OLD_TABLES.DEVICE + LD DE,DEVICE + LD BC,OLD_TABLES.DEVICE - DEVICE + LDIR + ; +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; + +;7. выход +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; + LD A,(DRV_PAGE.LDRIVE) + AND A + RET +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; + +;-----------------------[] +.loop2_start: + LD C,B ; начинаем считать переменную LDRIVE + LD A,DSS_MAX_DRIVES_AMOUNT + SUB B ; сколько шагов вперёд по таблице осталось + LD B,A + ; +.loop2: LD DE,DEVICE.TBL_Entry ; теперь двигаемся по таблице вперёд + ADD IX,DE + ; тут указатель показывает на первую свободную ячейку после блока с данными драйвов + PUSH IX + PUSH BC + CALL Fill_if_Exists + POP BC + POP IX + ; NC: + ; DE = адрес процедуры обработчика таблицы + ; A = логический номер устройства в таблице обработчика + ; + ; CF - нет больше новых записей + JR C,.loop1_exit + + LD (IX+0),A + LD (IX+1),E + LD (IX+2),D + ; + INC C ; добавили драйв + ; + DJNZ .loop2 + JR .loop1_exit +;-----------------------[] + +;-----------------------[] +Fill_if_Exists: +.tbl+1: LD B,ReScanDRV.NUMBER_OF_SUBTABLES + DJNZ 1F + ; B=1, RAMDTBL + LD A,RAMDTBL.TBL_Entry + LD IY,RAMDTBL + CALL .RUN + LD DE,RMDRIVE + RET NC + LD A,(.tbl) + DEC A ;!!!!! может быть переполнение + LD (.tbl),A + RET + ; +1: DJNZ 1F + ; B=2, LOGDRV + LD A,LOGDRV.TBL_Entry + LD IY,LOGDRV + CALL .RUN + LD DE,HDDRIVE + RET NC + ; переходим на другую таблицу - RAMDTBL + LD A,(.tbl) + DEC A ;!!!!! может быть переполнение + LD (.tbl),A + LD HL,OLD_TABLES.RAMDTBL + LD (OLD_TABLES_CURRENT),HL + EXX + LD B,MAX_RAMDRIVES + EXX + JR Fill_if_Exists + ; +1: SCF ; unknown table number + RET +; +.RUN: EXX + ; + LD D,0 + LD E,A + PUSH DE + ; + LD A,#FE ; Так поиск закончится либо на номере драйва, либо по концу таблицы + PUSH BC + CALL Find_Record.loop1 ; ищет в новой таблице новую запись + POP BC + JR NC,1F + ; + POP DE + EXX + RET + ; +1: PUSH IY ; сохраняем текущий адрес новой таблицы + ; + LD IY,(OLD_TABLES_CURRENT) + ; + LD A,#FF ; Так поиск закончится либо на пустой записи, либо по концу таблицы + LD C,D ; номер записи в таблице. D=0 + PUSH BC + CALL Find_Record.loop2 + LD A,C + POP BC + JR NC,1F + ; + POP DE + POP DE + EXX + RET + ; +1: EX (SP),IY ; переключение со старой на новую таблицу + PUSH IY + EXX + ; перекидываем запись из новой в старую + POP HL + POP DE + POP BC + LDIR + + LD (IY),#FF ; грохаем только что перекинутую запись из новой таблицы + AND A + RET +OLD_TABLES_CURRENT: WORD 0 +;-----------------------[] + +;-----------------------[] +; ВХОД: A - Маска для сравнения +; DE - Длина одной записи +; IY - Адрес данных в таблице +; ВЫХОД: NC: +; IY - начало подходящей записи +; C - номер новой записи в старой таблице +; CF - Не найдено, таблица закончилась +Find_Record: +.loop1: CP (IY) + RET NC + ADD IY,DE + INC C + DJNZ .loop1 + ; таблицу прошерстили + SCF + RET +.loop2: CP (IY) + RET Z + ADD IY,DE + INC C + DJNZ .loop2 + ; таблицу прошерстили + SCF + RET +;-----------------------[] + +;-----------------------[] +; ERROR_BOOTDRV_DIES: +; DI +; LD E,1 +; LD BC,BIOS.LP_OPEN_S.TXT_80x32_Default +; RST ToBIOS +; ; +; LD HL,#2050 +; LD DE,0 +; LD BC,256*COLORS.CGA.PAPER.BLUE + BIOS.LP_CLS_WIN +; RST ToBIOS +; ; +; LD A,1 +; OUT (SCREEN_SWITCH),A ; set scr-2 +; ; +; LD HL,.ERROR_MSG +; LD DE,#A000 +; LD BC,.ERROR_MSG.size +; LD A,C +; LDIR +; ; +; LD DE,16*256 + (80-.ERROR_MSG.size)/2 ;X=0, Y=16 +; LD C,BIOS.LP_SET_PLACE +; RST ToBIOS +; ; +; LD HL,#A000 +; LD DE,0*256 + COLORS.CGA.FLASH + COLORS.CGA.PAPER.BLUE + COLORS.CGA.INK.WHITE +; LD B,A +; LD C,BIOS.LP_PRINT_LINE3 +; RST ToBIOS +; ; +; .loop: DI +; HALT +; JR .loop +; ; +; .ERROR_MSG: DZ "Kernel panic! Boot disk lost. Press Ctrl+Alt+Del or RESET." +; .ERROR_MSG.size EQU $-.ERROR_MSG +;-----------------------[] + + +;-----------------------[] +; НЕ ГРОХАТЬ HL! +; а. если драйв есть в новой и старой, то затираем в новой +; таблице совпавший драйв +; б. если драйв есть только в старой, то: +; б1) грохаем файловые манипуляторы с его номером + MODULE SCAN_TABLES +; вход: B - лог.номер драйва, DE +RAM_DRV: + ; Получаем номер рамдиска в OLD_TABLES.RAMDTBL + LD A,B + LD BC,OLD_TABLES.RAMDTBL + CALL GET_RAMDRV_NUM.skip_tbl + LD (.cur_drv),BC + AND #0F + LD C,A ; номер рамдиска + ; Ищем в новой такой же номер рамдиска + LD B,MAX_RAMDRIVES + LD DE,RAMDTBL +.loop: LD A,(DE) + SUB C + JR Z,.found + INC DE + INC DE + DJNZ .loop + ; ЗАПИСЬ НЕ НАЙДЕНА + ; Достаём положение в OLD_TABLES.DEVICE + POP HL + ; Достаём шаг общего цикла для получения лог.номера драйва в KILL_FM + POP BC + PUSH BC + ; Грохаем ФМ и запись в OLD_TABLES.DEVICE + CALL KILL_FM + ; грохаем в старой RAMDTBL этот драйв + EX DE,HL +.cur_drv+1: + LD HL,0 + LD (HL),#FF + DEC HL + LD (HL),#FF + EX DE,HL + JP ReScanDRV.nextN2 + ; +.found: DEC A + ; затираем в новой таблице совпавший драйв (чтоб легче было парсить оставшееся) + LD (DE),A + DEC DE + LD (DE),A + JP ReScanDRV.nextN +;-----[] +HARD_DRV: + LD L,B + LOGDRV_ENTRY_FIND OLD_TABLES.LOGDRV + LD IX,LOGDRV + LD DE,LOGDRV.TBL_Entry + LD B,DSS_MAX_DRIVES_AMOUNT + ; +.loop: LD A,(IY+LOGDRV.PHISICAL_DRV_NUMBER) + ;CP #FF + ;JR Z,.skip + CP (IX+LOGDRV.PHISICAL_DRV_NUMBER) + JR NZ,.skip + ; + LD A,(IY+LOGDRV.SECTOR_OFFSET) + CP (IX+LOGDRV.SECTOR_OFFSET) + JR NZ,.skip + LD A,(IY+LOGDRV.SECTOR_OFFSET+1) + CP (IX+LOGDRV.SECTOR_OFFSET+1) + JR NZ,.skip + LD A,(IY+LOGDRV.SECTOR_OFFSET+2) + CP (IX+LOGDRV.SECTOR_OFFSET+2) + JR NZ,.skip + LD A,(IY+LOGDRV.SECTOR_OFFSET+3) + CP (IX+LOGDRV.SECTOR_OFFSET+3) + JR NZ,.skip + LD A,(IY+LOGDRV.SIZE_IN_SECTORS) + CP (IX+LOGDRV.SIZE_IN_SECTORS) + JR NZ,.skip + LD A,(IY+LOGDRV.SIZE_IN_SECTORS+1) + CP (IX+LOGDRV.SIZE_IN_SECTORS+1) + JR NZ,.skip + LD A,(IY+LOGDRV.SIZE_IN_SECTORS+2) + CP (IX+LOGDRV.SIZE_IN_SECTORS+2) + JR NZ,.skip + LD A,(IY+LOGDRV.SIZE_IN_SECTORS+3) + CP (IX+LOGDRV.SIZE_IN_SECTORS+3) + JR Z,.found + ; +.skip: ADD IX,DE + DJNZ .loop + ; ЗАПИСЬ НЕ НАЙДЕНА + ; Грохаем старую запись в OLD_TABLES.LOGDRV + LD A,#FF + LD (IY+LOGDRV.PHISICAL_DRV_NUMBER),A + ; Достаём положение в OLD_TABLES.DEVICE + POP HL + ; Достаём шаг общего цикла для получения лог.номера драйва в KILL_FM + POP BC + PUSH BC + ; Грохаем ФМ и запись в OLD_TABLES.DEVICE + CALL KILL_FM + ; + JP ReScanDRV.nextN2 + ; +.found: ; затираем в новой таблице совпавший драйв (чтоб легче было парсить оставшееся) + LD (IX+LOGDRV.PHISICAL_DRV_NUMBER),#FF + JP ReScanDRV.nextN + ; +; CD_ROM: +; JP ReScanDRV.nextN +;-----[] +; ВХОД: HL - текущая запись в таблице DEVICE +; B - шаг общего цикла +KILL_FM:; + LD A,DSS_MAX_DRIVES_AMOUNT + SUB B + LD C,A + ; втыкаем страницу ядра с таблицей файловых манипуляторов + PUSH BC + LD A,(PORTAL.out_DRV.RETBANK) + LD B,A + LD C,SLOT3 + IN A,(SLOT3) + OUT (C),B + POP BC + PUSH AF + ; Шерстим манипуляторы на наличие в них грохнутого драйва + LD IY,CORE_BUFFERS.FM_BUF + #C000 ; - CORE_BUFFERS.FM_BUF.Size + LD B,FMCOUNT - 1 ; пропускаем служебный нулевой манипулятор + LD DE,CORE_BUFFERS.FM_BUF.Size +.loop_fm: + ADD IY,DE + LD A,(IY+_sFM.DRIVE) + CP C + JR NZ,.skip + XOR A + LD (IY+_sFM.FS_REC.NAME),A ; грохаем манипулятор +.skip: DJNZ .loop_fm + ; + POP AF + OUT (SLOT3),A + ; + ; грохаем в OLD_TABLES.DEVICE убитый драйв + LD (HL),#FF + ; + RET + ENDMODULE +;-----------------------[] + +/* +[DRIVE TABLES] .Size == DEVICE.Size + LOGDRV.Size + RAMDTBL.Size == 78+1 + 416 + 32 == 526 + +; логический номер устройства + адрес обработчика. +; Порядковый номер * 3 = буква диска + "A" +DEVICE EQU $ +.TBL_Entry EQU 3 +.End EQU 1 + $ + DSS_MAX_DRIVES_AMOUNT * .TBL_Entry ; для стоп-байта #FF +.Size EQU .End - $ + +;+00 BYTE MASTER/SLAVE PHISICAL DRIVE NUMBER #80/#81/... +;+01 LONG SECTOR OFFSET +;+05 LONG SIZE IN SECTORS +;+09 LONG Volume Serial Number in HEX ; [ ] ;!TODO +;+13 WORD FREE +;+15 BYTE FREE +; Логический номер раздела. +;Номер группы = логический номер раздела HDD из DEVICE +LOGDRV EQU DEVICE + DEVICE.Size +.TBL_Entry EQU 16 +.Size EQU DSS_MAX_DRIVES_AMOUNT * .TBL_Entry + +; ТАБЛИЦА СООТВЕТСТВИЯ МЕЖДУ ФИЗИЧЕСКИМ НОМЕРОМ РАМДИСКА И ЕГО RAM-DISK ID +; Log Number: DB RAM_DRIVE_NUMBER, RAM_DRIVE_ID +RAMDTBL EQU $ + DEVICE.Size + LOGDRV.Size +.TBL_Entry EQU 2 +.Size EQU .TBL_Entry * MAX_RAMDRIVES +*/ \ No newline at end of file diff --git a/DSS/drivers/media/fdd-drv.asm b/DSS/drivers/media/fdd-drv.asm new file mode 100644 index 0000000..11c3129 --- /dev/null +++ b/DSS/drivers/media/fdd-drv.asm @@ -0,0 +1,417 @@ + +; Disk Driver Specification ver. 2.00 +;[]===========================================================[0] +;Procedure : Initialization +; +;Function : Initialization device(s) +; +;Input : C = 00h +; IX - Environment +;Output : A = Amount drive support +; HL = Size driver +;[]===========================================================[] +;[]===========================================================[1] +;Procedure : Open +; +;Function : Open disk +; +;Input : C = 01h +; A - Drive +;Output : None +; +;[]===========================================================[] +;[]===========================================================[2] +;Procedure : Close +; +;Function : Close disk +; +;Input : C = 02h +; A - Drive +;Output : None +; +;[]===========================================================[] +;[]===========================================================[3] +;Procedure : Media check +; +;Function : Checking change line +; +;Input : C = 03h +; A - Drive +;Output : A = 00h disk no changed +; A = 0FFh disk changed +; +;[]===========================================================[] +;[]===========================================================[4] +;Procedure : Get BPB +; +;Function : Get Block Parameters BIOS +; +;Input : C = 04h +; DE - Address +;Output : None +; +;[]===========================================================[] +;[]===========================================================[5] +;Procedure : Input +; +;Function : Input from disk +; +;Input : C = 05h +; HL:IX - Logical Block (sector) +; DE - Address +; B - Sector count +;Output : None +; +;[]===========================================================[] +;[]===========================================================[6] +;Procedure : Output +; +;Function : Output to disk +; +;Input : C = 06h +; HL:IX - Logical Block (sector) +; DE - Address +; B - Sector count +;Output : None +; +;[]===========================================================[] +;[]===========================================================[7] +;Procedure : Removable +; +;Function : Checking change line +; +;Input : C = 07h +; A - Drive +;Output : A = 00h Removable +; A = FFh Nonremovable +; +;[]===========================================================[] +;[]===========================================================[8] +;Procedure : Generic IOCTL +; +;Function : Generic Input Output Control +; +;Input : C = 08h +; B - Subcommand +; DE = 55AAh Magic Number +; Subcommand +;---------------------- +; 00h - Get Device Parameters +; 01h - Read track +; 02h - Test track +; 80h - Set Device Parameters +; 81h - Write track +; 82h - Format track +;Output : +; +;[]===========================================================[] +; +; Errors: +; 0 (00h) - NO ERRORS +; 1 (01h) - BAD COMMAND +; 2 (02h) - BAD DRIVE NUMBER +; 3 (03h) - UNKNOW FORMAT +; 4 (04h) - NOT READY +; 5 (05h) - SEEK ERROR +; 6 (06h) - SECTOR NOT FOUND +; 7 (07h) - CRC ERROR +; 8 (08h) - WRITE PROTECT +; 9 (09h) - READ ERROR +; 10 (0Ah) - WRITE ERROR +; 11 (0Bh) - FAILURE +; 12 (0Ch) - BUSY (DEVICE OPENED) +; 13 (0Dh) - RESERVED + +; R_COM EQU #0F ;Command/Status +; R_TRK EQU #3F ;Track +; R_SEC EQU #5F ;Sector +; R_DAT EQU #7F ;Data +; R_DSK EQU #FF ;Drive Control +; COM_B EQU #1B + + + +//////////////////////////////////////////////////////////////////////// + MODULE FDD_DRV +//////////////////////////////////////////////////////////////////////// + + + +;------------------------------------------------- +; Обработчик FDD (rst 18h) +;------------------------------------------------- +API_TABLE: INC C + DEC C + JP Z,Init ;#00 Init + DEC C + JP Z,Open ;#01 Open + DEC C + JP Z,Close ;#02 Close + DEC C + JP Z,MediaCheck ;#03 MediaCheck + DEC C + JP Z,GetBPB ;#04 GetBPB + DEC C + JP Z,Read ;#05 Read + DEC C + JP Z,Write ;#06 Write + DEC C + JP Z,Removable ;#07 Removable + DEC C + JP Z,GenIOCTL ;#08 GenIOCTL + DEC C + JP Z,Reserved ;#09 + ; +Reserved: LD A,DSS_Error.drv.INVALID_COMMAND + SCF + RET + + +;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Commands for restart #18 ; +;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; +Init: LD A,2 ;количество FDD в компе ;!FIXIT а если отключу в БИОС? + AND A + RET +; ; ; + +; +Open: LD C,BIOS.DRV_RESET + RST ToBIOS + RET +; ; ; + +; +Close: XOR A + RET +; ; ; + + +;!FIXIT проверять ВГ93 когда это станет возможным +MediaCheck: IF NON_REMOVABLE_FDD + XOR A + ELSE + LD A,#FF + OR A + ENDIF + RET +; ; ; + + +;DE - ADDRESS +GetBPB: LD IX,0 + LD HL,0 + PUSH DE + PUSH AF + LD BC,1*256 + BIOS.DRV_READ + RST ToBIOS + POP DE + POP HL + RET C + LD BC,BOOT_SECTOR.SectorsPerTrack + ADD HL,BC + LD E,(HL) + PUSH DE + LD A,D + LD C,BIOS.DRV_GET_PAR + RST ToBIOS + LD A,H + POP HL + PUSH HL + LD H,A + POP AF + LD C,BIOS.DRV_SET_PAR + RST ToBIOS + XOR A + RET +; ; ; + + +; !TODO read track? +;READTR: XOR A +; RET +; ; ; + +; +Read: LD C,BIOS.DRV_READ + RST ToBIOS + RET +; ; ; + +; +Write: LD C,BIOS.DRV_WRITE + RST ToBIOS + RET +; ; ; + + +; 00 - GET DEVICE PARAMETERS +; 01 - READ TRACK +; 02 - TEST TRACK +; 80 - SET DEVICE PARAMETERS +; 81 - WRITE TRACK +; 82 - FORMAT TRACK +GenIOCTL: BIT 7,B + JR NZ,.O_CTL_F + INC B + DEC B + JP Z,.GetParams + ;!TODO + ;DEC B + ;JP Z,.ReadTrack + ;DEC B + ;JP Z,.TestTRK + ; + LD A,DSS_Error.drv.INVALID_COMMAND + SCF + RET + ; +.O_CTL_F: RES 7,B + INC B + DEC B + JP Z,.SetParams + ;!TODO + ;DEC B + ;JP Z,.WriteTRK + ;DEC B + ;JP Z,.FormatTRK + ; + LD A,DSS_Error.drv.INVALID_COMMAND + SCF + RET +; ; ; + + +; Вход: - A - Drive number +; Выход: +; HL:DE - SECTORS ON LOGICAL DISK +; C - PARTITION RECORD NUMBER IN DRIVE MBR. 0 for fdd ;[x] 17.12.2023 загрузка с активного раздела, а не с первого +; HL' - CYLINDERS ON PHISICAL DISK +; DE' - HEADS ON PHISICAL DISK +; BC' - SECTORS PER TRACK ON PHISICAL DISK +; A' - PHISICAL DRIVE NUMBER +; A - EXTENDED INFORMATION +; D1..D3 - "0" RESERVED (MAY BE OTHER) +; D4 - DEVICE MASTER/SLAVE +; D5 - "1" RESERVED +; D6 - ADDRESSING MODE LBA/CHS +; D7 - "1" RESERVED +.GetParams: EX DE,HL + LD BC,#55AA + AND #0F + SBC HL,BC + JR Z,.next + ; + LD A,DSS_Error.drv.GENERAL_FAILURE + SCF + RET + ; +.next: PUSH AF + LD C,BIOS.DRV_GET_PAR + RST ToBIOS + JR C,.NONE_FDD + PUSH HL + PUSH DE + LD A,H + LD H,0 + ; +.mull_loop1: ADD HL,HL + DEC A + JR NZ,.mull_loop1 + ; + ; HL - SECTOR PER CYLLINDER + ; A=0 ZF=0 CF=0 + LD B,H + LD C,L + ;LD HL,0 + ;XOR A + LD H,A + LD L,A + EX AF,AF' + ; +.mull_loop2: EX AF,AF' + ADD HL,BC + ADC A,0 + DEC DE + EX AF,AF' + LD A,D + OR E + JR NZ,.mull_loop2 + ; + ; A=0 DE=0 ZF=0 CF=0 + EX AF,AF' + LD E,A + EX DE,HL + ; H=0 + LD C,H ;[x] 17.12.2023 загрузка с активного раздела, а не с первого + EXX + POP DE + POP HL + POP AF + EX AF,AF' + ; A=0 ZF=0 CF=0 + LD B,0 + LD C,L + LD L,H + LD H,B + EX DE,HL + EXX + AND A + RET + ; +.NONE_FDD: POP BC + LD A,DSS_Error.drv.INVALID_DRIVE + ; CF=1 + RET +; ; ; + + +; HL:DE - SECTORS ON LOGICAL DISK +; HL' - CYLINDERS ON PHISICAL DISK +; DE' - HEADS ON PHISICAL DISK +; BC' - SECTORS PER TRACK ON PHISICAL DISK +; A' - EXTENDED INFORMATION +; D0...D3 - "0" RESERVED (MAY BE OTHER) +; D4 - DEVICE MASTER/SLAVE +; D5 - "1" RESERVED +; D6 - ADDRESSING MODE LBA/CHS +; D7 - "1" RESERVED +.SetParams: PUSH AF + EXX + EX DE,HL + LD H,L + LD L,C + POP AF + AND #0F + PUSH AF + PUSH HL + PUSH DE + LD C,BIOS.DRV_GET_PAR + RST ToBIOS + POP DE + POP HL + JR C,.NONE_FDD + POP AF + LD C,BIOS.DRV_SET_PAR + JP ToBIOS + ;RST ToBIOS + ;RET C + ;AND A + ;RET +; ; ; + + +Removable: ; LD A,1 + ; AND A + XOR A + INC A + RET +; ; ; + +;============================================== + + ENDMODULE ; FDD_DRV + +//////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/DSS/drivers/media/ide-drv.asm b/DSS/drivers/media/ide-drv.asm new file mode 100644 index 0000000..306d487 --- /dev/null +++ b/DSS/drivers/media/ide-drv.asm @@ -0,0 +1,715 @@ +;!TODO привести к общему виду в одну инструкцию, проверить корректность +;--------------------------------------------------------------- +;Rev Date Name Description +;--------------------------------------------------------------- +;R02 06-08-2001 DNS Secondary IDE +;R01 06-08-2001 DNS Fixed BUG with partitions on Second hard disk +;--------------------------------------------------------------- +; +; Disk Driver Specification ver. 2.20 +;[]===========================================================[0] +;Procedure: Initialization +; +;Function: Initialization device(s) +; +;Input: C = #00 +; IX = Environment +; +;Output: A = Amount drive support +;[]===========================================================[0] + +;[]===========================================================[1] +;Procedure: Open +; +;Function: Open disk +; +;Input: C = #01 +; A = Drive +; +;Output: None +;[]===========================================================[1] + +;[]===========================================================[2] +;Procedure: Close +; +;Function: Close disk +; +;Input: C = #02 +; A = Drive +; +;Output: None +;[]===========================================================[2] + +;[]===========================================================[3] +;Procedure: Media check +; +;Function: Checking change line +; +;Input: C = #03 +; A = Drive +; +;Output: A = #00 disk no changed +; #FF disk changed +;[]===========================================================[3] + +;[]===========================================================[4] +;Procedure: Get BPB +; +;Function: Get Block Parameters BIOS +; +;Input: C = #04 +; A = Drive +; DE = Address +; +;Output: None +;[]===========================================================[4] + +;[]===========================================================[5] +;Procedure: Read +; +;Function: Read from disk +; +;Input: C = #05 +; HL:IX = Logical Block (sector) +; DE = Address +; B = Sector count +; A = Drive +; +;Output: None +;[]===========================================================[5] + +;[]===========================================================[6] +;Procedure: Write +; +;Function: Write to disk +; +;Input: C = #06 +; HL:IX = Logical Block (sector) +; DE = Address +; B = Sector count +; +;Output: None +;[]===========================================================[6] + +;[]===========================================================[7] +;Procedure: Removable +; +;Function: Checking change line +; +;Input: C = #07 +; A = Drive +; +;Output: A = #00 Removable +; A = #FF Non-removable +;[]===========================================================[7] + +;[]===========================================================[8] +;Procedure: Generic IOCTL +; +;Function: Generic Input Output Control +; +;Input: C = #08 +; B = Subcommand +; DE = #55AA Magic Number +; A = Drive +; +;Subcommands: #00 - Get Device Parameters +; #01 - Read track +; #02 - Test track +; #80 - Set Device Parameters +; #81 - Write track +; #82 - Format track +;Output: +;[]===========================================================[8] + +;[]===========================================================[9] +;Procedure: Read Long +; +;Function: Reading sectors from disk +; +;Input: C = #0A +; HL:IX = Logical Block (sector) +; DE = Address +; B = Sector count +; A' = Page +; +;Output: A' = Next Page +; HL:IX = Next Logical Block (sector) +; DE = Next Address +;[]===========================================================[9] + +;[]===========================================================[10] +;Procedure: Write Long +; +;Function: Writing sectors to disk +; +;Input: C = #0B +; HL:IX = Logical Block (sector) +; DE = Address +; B = Sector count +; A' = Page +; +;Output: A' = Next Page +; HL:IX = Next Logical Block (sector) +; DE = Next Address +;[]===========================================================[10] + +; +; Errors: +; 0 (#00) - NO ERRORS +; 1 (#01) - BAD COMMAND +; 2 (#02) - BAD DRIVE NUMBER +; 3 (#03) - UNKNOW FORMAT +; 4 (#04) - NOT READY +; 5 (#05) - SEEK ERROR +; 6 (#06) - SECTOR NOT FOUND +; 7 (#07) - CRC ERROR +; 8 (#08) - WRITE PROTECT +; 9 (#09) - READ ERROR +; 10 (#0A) - WRITE ERROR +; 11 (#0B) - FAILURE +; 12 (#0C) - BUSY (DEVICE OPENED) +; 13 (#0D) - RESERVED + +; IDE0 EQU #0C1C0 +; IDE1 EQU #0C1C8 +PARTITION_BUFFER _sBOOT_SECTOR = #C000 ; EQU #C000 _sBOOT_SECTOR + +HDDRIVE: INC C + DEC C + JP Z,INIT_H ; c=0 Initialization + DEC C + JP Z,RESE_H ; c=1 open + DEC C + JP Z,STAT_H ; c=2 close + DEC C + JP Z,CHEK_H ; c=3 media check (смена носителя) + DEC C + JP Z,GBPB_H ; c=4 get BPB + DEC C + JP Z,READH ; c=5 read (чтение секторов) + DEC C + JP Z,WRITEH ; c=6 write (запись секторов) + DEC C + JP Z,REMOV_H ; c=7 Removable + DEC C + JP Z,IOCTL_H ; c=8 узнать геометрию диска Generic IOCTL + DEC C + JP Z,.Reserved ; c=9 Reserved + DEC C + JP Z,LREADH ; c=10 Read Long + DEC C + JP Z,LWRITEH ; c=11 Write Long + ; +.Reserved: LD A,DSS_Error.drv.INVALID_COMMAND + SCF + RET + + +//////////////////////////////////////////////////////////////////////// +// Commands for restart #18 // +//////////////////////////////////////////////////////////////////////// + +;--------------------------------------------------------------------[v] +; c=0 Initialization +INIT_H: PUSH IY + ;!TEST ;[ ] для rescanDRV + XOR A + LD (DRVCLC.count),A + ; + LD HL,LOGDRV + LD (OFFSECT),HL + + LD IX,SYS_PAGE.TMP_BUFFER + LD C,BIOS.DRV_LIST + RST ToBIOS + ; DRV_LIST: + ; +0 LEN + ; +1 FDD COUNT + ; +2 HDD COUNT + ; +3 CDROM COUNT + ; +4 RESERVED (28) + ; + IN A,(SLOT3) + LD C,A + LD A,SYS_PAGE + OUT (SLOT3),A + XOR A + LD B,(IX+2) ;количество HDD для процедуры NX_DVCI + CP B + LD A,C + OUT (SLOT3),A + JR Z,NO_HARDS + LD C,#80 ;!HARDCODE - ID винта для процедуры BIOS.DRV_DETECT + +NX_DVCI: PUSH BC + LD A,C + LD (DRV_NUM),A + LD C,BIOS.DRV_DETECT + RST ToBIOS + ;JR C,.NO_DRIVE + CALL NC,DEFINE_PARTITIONS.BEGIN + POP BC + INC C + JR C,NX_DVCI + DJNZ NX_DVCI + ; +NO_HARDS: + POP IY + ;!TEST + ; LD HL,(OFFSECT) + ; LD DE,LOGDRV + ; XOR A + ; SBC HL,DE + ; RET Z + ; LD DE,LOGDRV.TBL_Entry +DRVCLC: ; INC A + ; SBC HL,DE + ; JR NZ,DRVCLC + ; +.count+1: LD A,0 + ; + AND A + RET +;---------------------------------------------------------------------[^] + +; ;+00 BYTE MASTER/SLAVE PHISICAL DRIVE NUMBER #80/#81/... +; ;+01 DWORD SECTOR OFFSET +; ;+05 DWORD SIZE IN SECTORS +; ;+09 FREE +; ;+15 +; LOGDRV: BLOCK .TBL_Entry * LD_DSK,0 +; .TBL_Entry EQU 16 +; .Size EQU $-LOGDRV +SELHDD: PUSH DE + PUSH HL + ; + LD L,A + LOGDRV_ENTRY_FIND LOGDRV + ; !HARDCODE + LD E,(IY+1) + LD D,(IY+2) + ADD IX,DE + LD E,(IY+3) + LD D,(IY+4) + POP HL + ADC HL,DE + LD A,(IY+0) ;DRIVE NUMBER + POP DE + RET + +; 00 - GET DEVICE PARAMETERS +; 01 - READ TRACK +; 02 - TEST TRACK +; 80 - SET DEVICE PARAMETERS +; 81 - WRITE TRACK +; 82 - FORMAT TRACK +IOCTL_H BIT 7,B + JR NZ,O_CTL_H + INC B + DEC B + JP Z,HGETPRM + DEC B + JP Z,HRDTRAC + DEC B + JP Z,HCHTRAC + LD A,DSS_Error.drv.INVALID_COMMAND + SCF + RET + +O_CTL_H RES 7,B + INC B + DEC B + JP Z,HSETPRM + DEC B + JP Z,HWRTRAC + DEC B + JP Z,HFRTRAC + LD A,DSS_Error.drv.INVALID_COMMAND + SCF + RET + +HRDTRAC LD A,DSS_Error.drv.GENERAL_FAILURE + SCF + RET + +HCHTRAC LD B,L + CALL CHECKH + RET + +HSETPRM AND A + RET + +HWRTRAC LD A,DSS_Error.drv.GENERAL_FAILURE + SCF + RET + +HFRTRAC LD A,DSS_Error.drv.GENERAL_FAILURE + SCF + RET + +; HL:DE - SECTORS ON LOGICAL DISK +; C - PARTITION RECORD NUMBER IN DRIVE MBR. if #FF - then not supported ;[x] 17.12.2023 загрузка с активного раздела, а не с первого +; HL' - CYLINDERS ON PHISICAL DISK +; DE' - HEADS ON PHISICAL DISK +; BC' - SECTORS PER TRACK ON PHISICAL DISK +; A' - PHISICAL DRIVE NUMBER +; A - DRIVE/HEAD REGISTER PHISICAL DISK: +; bit7 - reserved "1" +; bit6 - ADDRESSING MODE LBA/CHS +; bit5 - reserved "1" +; bit4 - DEVICE MASTER/SLAVE +; bit3 - reserved "0" (MAY BE OTHER) +; bit2 - reserved "0" (MAY BE OTHER) +; bit1 - reserved "0" (MAY BE OTHER) +; bit0 - Primary/Secondary Chanel +HGETPRM: + EX DE,HL + LD BC,#55AA + AND A + SBC HL,BC + LD L,A + LD A,DSS_Error.drv.GENERAL_FAILURE + SCF + RET NZ + ; + PUSH IX + PUSH IY + ; + LOGDRV_ENTRY_FIND LOGDRV + ; + LD A,(IY+LOGDRV.PHISICAL_DRV_NUMBER) ;MASTER/SLAVE PHISICAL DRIVE NUMBER #80/#81/... + PUSH IY + LD C,BIOS.DRV_GET_PAR + RST ToBIOS + POP IY + LD A,DSS_Error.drv.INVALID_DRIVE + JR C,.error + ; перетасовка регистров с результатом от BIOS + EX DE,HL + LD C,E + LD E,D + LD D,0 + LD A,B + LD B,D + EXX + ; SECTORS ON LOGICAL DISK + LD E,(IY+LOGDRV.SIZE_IN_SECTORS+0) + LD D,(IY+LOGDRV.SIZE_IN_SECTORS+1) + LD L,(IY+LOGDRV.SIZE_IN_SECTORS+2) + LD H,(IY+LOGDRV.SIZE_IN_SECTORS+3) + ; + ;[x] 17.12.2023 загрузка с активного раздела, а не с первого + LD C,(IY+LOGDRV.PARTITION_RECORD_NUM) ; номер партиции в MBR диска + ; + EX AF,AF' + LD A,(IY+LOGDRV.PHISICAL_DRV_NUMBER) ;MASTER/SLAVE PHISICAL DRIVE NUMBER #80/#81/... + EX AF,AF' + ; + AND A +.error: POP IY + POP IX + RET + +REMOV_H: + LD A,1 + AND A + RET + + + +RESE_H: XOR A + RET + +STAT_H: XOR A + RET + +CHEK_H: ;LD A,#FF + XOR A + ;AND A + RET + + +; DE - ADDRESS +; A - DRIVE +GBPB_H: PUSH IY + PUSH DE + LD L,A + ; + LOGDRV_ENTRY_FIND LOGDRV + ; !HARDCODE + LD E,(IY+1) + LD D,(IY+2) + LD L,(IY+3) + LD H,(IY+4) + LD XL,E + LD XH,D + LD A,(IY+0) + POP DE + POP IY + LD BC,1*256 + BIOS.DRV_READ + JP ToBIOS + + +;HL:IX - SECTOR +; DE - ADDRESS +; B - COUNTER +; A'- PAGE +; A - HDD LOG NUMBER +;READ SECTOR +LREADH: PUSH IY + CALL SELHDD + LD C,BIOS.DRV_READ_LONG + RST ToBIOS + POP IY + RET + +;HL:IX - SECTOR +; DE - ADDRESS +; B - COUNTER +; A'- PAGE +; A - HDD LOG NUMBER +;WRITE SECTOR +LWRITEH: + PUSH IY + CALL SELHDD + LD C,BIOS.DRV_WRITE_LONG + RST ToBIOS + POP IY + RET + +;HL:IX - SECTOR +; DE - ADDRESS +; B - COUNTER +; A - HDD LOG NUMBER +;WRITE SECTOR +WRITEH: PUSH IY + CALL SELHDD + LD C,BIOS.DRV_WRITE + RST ToBIOS + POP IY + RET + +;HL:IX - SECTOR +; DE - ADDRESS +; B - COUNTER +; A - HDD LOG NUMBER +;READ SECTOR +READH: PUSH IY + CALL SELHDD + LD C,BIOS.DRV_READ + RST ToBIOS + POP IY + RET + +;HL:IX - SECTOR +; DE - ADDRESS +; B - COUNTER +; A - HDD LOG NUMBER +;CHECK SECTOR +CHECKH: PUSH IY + CALL SELHDD + LD C,BIOS.DRV_VERIFY + RST ToBIOS + POP IY + RET + +;------------------------------[ PARTIT ]------------------------------; +DEFINE_PARTITIONS: +.FAT32_DOS: ; +.EASYDOS: ; +.MEDIDOS: ; +.HIGHDOS: ; + LD E,(IY + BOOT_SECTOR.Partition.Start_LBA + 0) + LD D,(IY + BOOT_SECTOR.Partition.Start_LBA + 1) + LD L,(IY + BOOT_SECTOR.Partition.Start_LBA + 2) + LD H,(IY + BOOT_SECTOR.Partition.Start_LBA + 3) + LD IX,(CURRENT_SECTOR_L) + ADD IX,DE + LD DE,(CURRENT_SECTOR_H) + ADC HL,DE + LD D,XH + LD E,XL + ;BPB SECTOR + LD IX,(OFFSECT) + LD (IX + LOGDRV.SECTOR_OFFSET + 0),E + LD (IX + LOGDRV.SECTOR_OFFSET + 1),D + LD (IX + LOGDRV.SECTOR_OFFSET + 2),L + LD (IX + LOGDRV.SECTOR_OFFSET + 3),H + LD E,(IY + BOOT_SECTOR.Partition.Size_LBA + 0) + LD D,(IY + BOOT_SECTOR.Partition.Size_LBA + 1) + LD L,(IY + BOOT_SECTOR.Partition.Size_LBA + 2) + LD H,(IY + BOOT_SECTOR.Partition.Size_LBA + 3) + ;SIZE DISK + LD (IX + LOGDRV.SIZE_IN_SECTORS + 0),E + LD (IX + LOGDRV.SIZE_IN_SECTORS + 1),D + LD (IX + LOGDRV.SIZE_IN_SECTORS + 2),L + LD (IX + LOGDRV.SIZE_IN_SECTORS + 3),H + ;[x] 17.12.2023 загрузка с активного раздела, а не с первого +.ExtendedPartitionFlag+1: + LD A,0 + OR A ; !TODO загрузка с расширенного раздела не поддерживается + LD A,#FF + JR NZ,.not_supported ; если расширенный раздел, то облом + ; + POP BC + PUSH BC + LD A,+(_sMBR_PARTITION_TABLE / _sMBR_PARTITION_RECORD) ; Number of entries in the partition table + SUB B +.not_supported: LD (IX + LOGDRV.PARTITION_RECORD_NUM),A + ; + ;!TEST Подстраховка от переполнения таблицы LOGDRV + LD A,(DRVCLC.count) + INC A + CP DSS_MAX_DRIVES_AMOUNT+1 + RET NC + LD (DRVCLC.count),A + ; + LD A,(DRV_NUM) + LD (IX + LOGDRV.PHISICAL_DRV_NUMBER),A + LD DE,LOGDRV.TBL_Entry ;DSKITEM + ADD IX,DE + LD (OFFSECT),IX + JP .NextPartition + ; +.NotExtended: CP PartitionSysTypes.FAT16 + JR Z,.HIGHDOS + CP PartitionSysTypes.FAT16_LBA + JR Z,.HIGHDOS + CP PartitionSysTypes.FAT16_32Mb + JR Z,.MEDIDOS + CP PartitionSysTypes.FAT12 + JR Z,.EASYDOS + ;[ ] fat32 + CP PartitionSysTypes.FAT32 + JP Z,.FAT32_DOS + CP PartitionSysTypes.FAT32_LBA + JP Z,.FAT32_DOS + ; + CP PartitionSysTypes.Win_Ext_LBA + JR Z,.SubLevel + ;[x] 17/12/23 пропуск разделов с неизвестными ФС, оптимизация детекта + ;OR A ;PartitionSysTypes.Empty + ;JR NZ,NXTPART + JR .NextPartition ; раздел не поддерживается + ;POP BC ; баланс стека + ;RET + ;POP BC + ;OR A + ;RET Z + ;NODEFIN: + ;SCF + ;RET + ; +.BEGIN: IN A,(SLOT3) + PUSH AF + LD A,SHARED_PAGE + OUT (SLOT3),A + CALL .Start + POP AF + OUT (SLOT3),A + RET +.Start: LD IX,0 + LD DE,0 + LD (EXTDOSL),DE ;R01 + LD (EXTDOSH),IX ;R01 + ; +.LOOP: LD (CURRENT_SECTOR_L),DE + LD (CURRENT_SECTOR_H),IX + CALL .LOAD_SECTOR + ; + LD HL,(PARTITION_BUFFER.MBR_SIGNATURE) + LD DE,#AA55 + AND A + SBC HL,DE + ;[x] 17/12/23 пропуск разделов с неизвестными ФС, оптимизация перебора разделов + ;JR NZ,NODEFIN + SCF + RET NZ + ; + LD IY,PARTITION_BUFFER.PARTITION_TABLE ; Offset of partition table in the MBR + LD B,+(_sMBR_PARTITION_TABLE / _sMBR_PARTITION_RECORD) ; Number of entries in the partition table +.DOSAGA: PUSH BC + LD A,(IY+_sMBR_PARTITION_RECORD.FS_ID) + CP PartitionSysTypes.Extended + JR Z,.SubLevel + CP PartitionSysTypes.Win_Ext_LBA + JR NZ,.NotExtended + ; +.SubLevel: PUSH IY + LD DE,(CURRENT_SECTOR_L) + LD IX,(CURRENT_SECTOR_H) + PUSH DE + PUSH IX + ;[x] 17/12/23 пропуск разделов с неизвестными ФС, оптимизация перебора разделов + LD A,(.ExtendedPartitionFlag) + INC A + LD (.ExtendedPartitionFlag),A ; !TODO загрузка с расширенного раздела не поддерживается + ; + CALL .ParseExtended + ;[x] 17/12/23 пропуск разделов с неизвестными ФС, оптимизация перебора разделов + LD A,(.ExtendedPartitionFlag) + DEC A + LD (.ExtendedPartitionFlag),A ; !TODO загрузка с расширенного раздела не поддерживается + ; + POP IX + POP DE + LD (CURRENT_SECTOR_L),DE + LD (CURRENT_SECTOR_H),IX + CALL .LOAD_SECTOR + POP IY +.NextPartition: LD DE,_sMBR_PARTITION_RECORD ;Size of a partition table entry + ADD IY,DE + POP BC + DJNZ .DOSAGA + AND A + RET + ; +.ParseExtended: LD HL,(EXTDOSL) + LD DE,(EXTDOSH) + LD A,L + OR H + OR E + OR D + LD E,(IY + _sMBR_PARTITION_RECORD.Start_LBA + 0) + LD D,(IY + _sMBR_PARTITION_RECORD.Start_LBA + 1) + LD L,(IY + _sMBR_PARTITION_RECORD.Start_LBA + 2) + LD H,(IY + _sMBR_PARTITION_RECORD.Start_LBA + 3) + JP NZ,.ext_in_ext + LD (EXTDOSL),DE + LD (EXTDOSH),HL + PUSH DE + JR .set_regs + ; +.ext_in_ext: LD IX,(EXTDOSL) + ADD IX,DE + LD DE,(EXTDOSH) + ADC HL,DE + PUSH IX +.set_regs: PUSH HL + POP IX + POP DE + JP .LOOP + ; +.LOAD_SECTOR: PUSH IY + LD IX,(CURRENT_SECTOR_L) + LD HL,(CURRENT_SECTOR_H) + LD DE,PARTITION_BUFFER + LD A,(DRV_NUM) + LD BC,1*256 + BIOS.DRV_READ + RST ToBIOS + POP IY + RET +;----------------------------------------------------------------------; +; + +;======================================================================= +; PHISICAL DRIVE NUMBER +; #80/#81 - primary мастер/слейв, #82/#83 - secondary мастер/слейв +DRV_NUM: DB #00 +CURRENT_SECTOR_L: DW #0000 +CURRENT_SECTOR_H: DW #0000 +EXTDOSL: DW #0000 ;CURRENT PARTITION TABLE +EXTDOSH: DW #0000 +OFFSECT: DW LOGDRV ;POINTER ON CURRENT DISK RECORD +;======================================================================= \ No newline at end of file diff --git a/DSS/drivers/media/ram_disk-drv.asm b/DSS/drivers/media/ram_disk-drv.asm new file mode 100644 index 0000000..b9b5480 --- /dev/null +++ b/DSS/drivers/media/ram_disk-drv.asm @@ -0,0 +1,533 @@ + + +; SYSPAGE EQU #FE +; SLOT1 EQU #A2 +; SLOT2 EQU #C2 +; SLOT3 EQU #E2 + +; ORG #3CDB +; Disk Driver Specification ver. 2.20 +;[]===========================================================[ 0] +;Procedure : Initialization +; +;Function : Initialization device(s) +; +;Input : C = 00h +; IX - Environment +;Output : A = Amount drive support +; HL = Size driver +;[]===========================================================[ 0] + + +;[]===========================================================[ 1] +;Procedure : Open +; +;Function : Open disk +; +;Input : C = 01h +; A - Drive +;Output : None +; +;[]===========================================================[ 1] + + +;[]===========================================================[ 2] +;Procedure : Close +; +;Function : Close disk +; +;Input : C = 02h +; A - Drive +;Output : None +; +;[]===========================================================[ 2] + + +;[]===========================================================[ 3] +;!TODO +;Procedure : Media check +; +;Function : Checking change line +; +;Input : C = 03h +; A - Drive +;Output : A = 00h disk no changed +; A = 0FFh disk changed +; +;[]===========================================================[ 3] + + +;[]===========================================================[ 4] +;Procedure : Get BPB +; +;Function : Get Block Parameters BIOS +; +;Input : C = 04h +; DE - Address +;Output : None +; +;[]===========================================================[ 4] + + +;[]===========================================================[ 5] +;Procedure : Input +; +;Function : Input from disk +; +;Input : C = 05h +; HL:IX - Logical Block (sector) +; DE - Address +; B - Sector count +;Output : None +; +;[]===========================================================[ 5] + + +;[]===========================================================[ 6] +;Procedure : Output +; +;Function : Output to disk +; +;Input : C = 06h +; HL:IX - Logical Block (sector) +; DE - Address +; B - Sector count +;Output : None +; +;[]===========================================================[ 6] + + +;[]===========================================================[ 7] +;!TODO +;Procedure : Removable +; +;Function : Checking change line +; +;Input : C = 07h +; A - Drive +;Output : A = 00h Removable +; A = FFh Nonremovable +; +;[]===========================================================[ 7] + + +;[]===========================================================[ 8] +;Procedure : Generic IOCTL +; +;Function : Generic Input Output Control +; +;Input : C = 08h +; B - Subcommand +; DE = 55AAh Magic Number +; Subcommand +;---------------------- +; 00h - Get Device Parameters +; 01h - Read track +; 02h - Test track +; 80h - Set Device Parameters +; 81h - Write track +; 82h - Format track +;Output : +; +;[]===========================================================[ 8] + + +;[]===========================================================[ 9] +; RESERVED +;[]===========================================================[ 9] + + +;[]===========================================================[ 10] +;!TODO +;Procedure : Read Long +; +;Function : Reading sectors from disk +; +;Input : C = 0Ah +; HL:IX - Logical Block (sector) +; DE - Address +; B - Sector count +; A'- Page +;Output : A'- Next Page +; HL:IX - Next Logical Block (sector) +; DE - Next Address +; +;[]===========================================================[ 10] + + +;[]===========================================================[ 11] +;!TODO +;Procedure : Write Long +; +;Function : Writing sectors to disk +; +;Input : C = 0Bh +; HL:IX - Logical Block (sector) +; DE - Address +; B - Sector count +; A'- Page +;Output : A'- Next Page +; HL:IX - Next Logical Block (sector) +; DE - Next Address +; +;[]===========================================================[ 11] +; +; Errors: +; 0 (00h) - NO ERRORS +; 1 (01h) - BAD COMMAND +; 2 (02h) - BAD DRIVE NUMBER +; 3 (03h) - UNKNOW FORMAT +; 4 (04h) - NOT READY +; 5 (05h) - SEEK ERROR +; 6 (06h) - SECTOR NOT FOUND +; 7 (07h) - CRC ERROR +; 8 (08h) - WRITE PROTECT +; 9 (09h) - READ ERROR +; 10 (0Ah) - WRITE ERROR +; 11 (0Bh) - FAILURE +; 12 (0Ch) - BUSY (DEVICE OPENED) +; 13 (0Dh) - RESERVED + + +; MACRO CALL GET_RAMDRV_NUM +; LD BC,RAMDTBL +; SLA A +; ADD A,C +; LD C,A +; LD A,0 +; ADC A,B +; LD B,A +; INC BC +; LD A,(BC) +; OR #60 ;!HARDCODE сделать номера разных устройств через метки +; ENDM + + +; parser +RMDRIVE: INC C + DEC C + JP Z,INIT_RD ; 0 + DEC C + JR Z,RESET_RD ; 1 + DEC C + JR Z,STATUS_RD ; 2 + DEC C + JR Z,CHEK_RD ; 3 + DEC C + JR Z,GBPB_RD ; 4 + DEC C + JR Z,READ_RD ; 5 + DEC C + JR Z,WRITE_RD ; 6 + DEC C + JR Z,REMOV_RD ; 7 + DEC C + JP Z,IOCTL_RD ; 8 + DEC C + JP Z,.error ; 9 RESR_H + DEC C + JP Z,LREAD_RD ; 10 + DEC C + JP Z,LWRITE_RD ; 11 +.error: + LD A,DSS_Error.drv.INVALID_COMMAND + SCF + RET + +REMOV_RD: +RESET_RD: +STATUS_RD: XOR A + RET + +;!FIXIT сделать в SYS_PAGE для рамдисков переменные и брать оттуда значение + ;!FIXIT как-то определять смену RMD? + ; [x] 18/08/2024 пока немного костыльно и опасно +CHEK_RD: ;LD A,#FF + ;AND A + XOR A + ; + RET + +;DE - ADDRESS +GBPB_RD: LD IX,0 + LD HL,0 + LD B,#01 + ;JP READ_RD +;READ SECTORS +; HL:IX - SECTOR +; DE - ADDRESS +; B - COUNT +; A - DRIVE +READ_RD: PUSH BC + CALL GET_RAMDRV_NUM + POP BC + LD C,BIOS.DRV_READ + JP ToBIOS + ; RST ToBIOS + ; XOR A + ; RET +LREAD_RD: + PUSH BC + CALL GET_RAMDRV_NUM + POP BC + LD C,BIOS.DRV_READ_LONG + JP ToBIOS + ; RST ToBIOS + ; XOR A + ; RET + +;WRITE SECTORS +; HL:IX - SECTOR +; DE - ADDRESS +; B - COUNT +; A - DRIVE +WRITE_RD: + PUSH BC + CALL GET_RAMDRV_NUM + POP BC + LD C,BIOS.DRV_WRITE + JP ToBIOS + ; RST ToBIOS + ; XOR A + ; RET + +LWRITE_RD: + PUSH BC + CALL GET_RAMDRV_NUM + POP BC + LD C,BIOS.DRV_WRITE_LONG + JP ToBIOS + ; RST ToBIOS + ; XOR A + ; RET + +; +;; +;;; +;----------------------------------------------------------------------;!TEST +; ;S_P_P DB #00 +; INIT_RD: +; ; .SectorSize EQU 512 ;!HARDCODE +; ; LD HL,.SectorSize +; ; LD A,#80 +; ; .loop: SRL A +; ; RR H +; ; JR NC,.loop +; ; LD (S_P_P),A + +; LD BC,#0*256 + BIOS.GET_RAMD_ST ; Получение идентификатора блока, назначенного на RAM-Disk +; LD DE,RAMDTBL +; .initLoop: +; PUSH BC +; LD A,B +; PUSH DE +; RST ToBIOS +; POP DE +; OR A +; JR Z,.noDRV + +; LD (DE),A +; INC DE +; POP BC +; LD A,B +; LD (DE),A +; INC DE +; JP 1F +; .noDRV: POP BC +; 1: INC B +; LD A,RAMDTBL.Size / RAMDTBL.TBL_Entry +; CP B +; JR NZ,.initLoop + +; LD HL,RAMDTBL ;!FIXIT LD HL,-RAMDTBL +; EX DE,HL +; AND A ;!FIXIT ---- +; SBC HL,DE ;!FIXIT ADD HL,DE +; SRL L +; LD A,L +; ; LD HL,ENDDRVR +; AND A +; RET +;----------------------------------------------------------------------;!TEST +;;; +;; +; + +; +;; +;;; +;----------------------------------------------------------------------;!TEST +;S_P_P DB #00 +INIT_RD: +; .SectorSize EQU 512 ;!HARDCODE +; LD HL,.SectorSize +; LD A,#80 +; .loop: SRL A +; RR H +; JR NC,.loop +; LD (S_P_P),A + + LD BC,0*256+BIOS.GET_RAMD_ST ; Получение идентификатора блока, назначенного на RAM-Disk + LD DE,RAMDTBL +.initLoop: PUSH BC + LD A,B + PUSH DE + RST ToBIOS + POP DE + OR A + JR Z,.noDRV + ; + INC DE + LD (DE),A + DEC DE + ; + POP BC + LD A,B + LD (DE),A + INC DE + INC DE + JP .skip_pop + ; +.noDRV: POP BC +.skip_pop: INC B + LD A,RAMDTBL.Size/RAMDTBL.TBL_Entry + CP B + JR NZ,.initLoop + + LD HL,RAMDTBL ;!FIXIT LD HL,-RAMDTBL + EX DE,HL + AND A ;!FIXIT ---- + SBC HL,DE ;!FIXIT ADD HL,DE + SRL L + LD A,L + ; LD HL,ENDDRVR + AND A + RET +;----------------------------------------------------------------------;!TEST +;;; +;; +; + +; ; +; ; ТАБЛИЦА СООТВЕТСТВИЯ МЕЖДУ ФИЗИЧЕСКИМ НОМЕРОМ РАМДИСКА И ЕГО RAM-DISK ID +; ; Log Number: DB RAM_DRIVE_ID, RAM_DRIVE_NUMBER +; RAMDTBL.TBL_Entry EQU 2 +; RAMDTBL: DUP MAX_RAMDRIVES * RAMDTBL.TBL_Entry +; DB #FF +; EDUP +; .Size EQU $-RAMDTBL +; ; + + +; 00 - GET DEVICE PARAMETERS +; 01 - READ TRACK +; 02 - TEST TRACK +; 80 - SET DEVICE PARAMETERS +; 81 - WRITE TRACK +; 82 - FORMAT TRACK +IOCTL_RD: + BIT 7,B + JR NZ,.O_CTL_F + INC B + DEC B + JP Z,.RGETPRM + ;DEC B + ;JP Z,FRDTRAC + ;DEC B + ;JP Z,FCHTRAC + LD A,DSS_Error.drv.INVALID_COMMAND + SCF + RET + +.O_CTL_F: ;RES 7,B + ;INC B + ;DEC B + ;JP Z,.RSETPRM + ;DEC B + ;JP Z,FWRTRAC + ;DEC B + ;JP Z,FFRTRAC + LD A,DSS_Error.drv.INVALID_COMMAND + SCF + RET + +; C - PARTITION RECORD NUMBER IN DRIVE MBR must be 0 here ;[x] 17.12.2023 загрузка с активного раздела, а не с первого +; HL:DE - SECTORS ON LOGICAL DISK +; HL' - CYLINDERS ON PHISICAL DISK +; DE' - HEADS ON PHISICAL DISK +; BC' - SECTORS PER TRACK ON PHISICAL DISK +; A' - PHISICAL DRIVE NUMBER +; A - EXTENDED INFORMATION +; D0...D3 - "0" RESERVED (MAY BE OTHER) +; D4 - DEVICE MASTER/SLAVE +; D5 - "1" RESERVED +; D6 - ADDRESSING MODE LBA/CHS +; D7 - "1" RESERVED +.RGETPRM: EX DE,HL + LD BC,#55AA + AND A + SBC HL,BC + LD L,A + LD A,DSS_Error.drv.GENERAL_FAILURE + SCF + RET NZ + ; + EX AF,AF' + LD A,L + CALL GET_RAMDRV_NUM + PUSH AF + PUSH AF + EX AF,AF' + + POP AF + LD C,BIOS.DRV_GET_PAR + RST ToBIOS + + PUSH HL ;число головок, число секторов (на целиндр) + PUSH DE ;количество цилиндров + EXX + POP HL ;количество цилиндров + POP BC ;число секторов (на целиндр) + LD D,0 + LD E,B ;число головок + LD B,D + EXX + + LD A,L + + RRA + JR C,.end +.loopShift: SLA E + RL D + RRA + JR NC,.loopShift + ; +.end: EX AF,AF' + POP AF + EX AF,AF' + XOR A + LD L,A + LD H,L + LD C,A ;[x] 17.12.2023 загрузка с активного раздела, а не с первого + LD A,%10100000 + RET + +; !TODO +; !FIXIT +; .RSETPRM: AND A +; RET + +GET_RAMDRV_NUM: LD BC,RAMDTBL +.skip_tbl: ADD A,A + ADD A,C + LD C,A + LD A,0 + ADC A,B + LD B,A + ;INC BC + LD A,(BC) + OR #60 ;!HARDCODE сделать номера разных устройств через метки + RET +; +;ENDDRVR EQU $ +; \ No newline at end of file diff --git a/DSS/drivers/media/shared-drv.asm b/DSS/drivers/media/shared-drv.asm new file mode 100644 index 0000000..97f01cc --- /dev/null +++ b/DSS/drivers/media/shared-drv.asm @@ -0,0 +1,290 @@ +;[BEGIN] +;//MODULE: Shared AUTHOR: Denis Parinov +;//CREATE: A LONG TIME AGO :) +;--------------------------------------------------------------- +;Rev Date Name Description +;R01 17-04-2023 BAO Добавлена процедура INITDVC_RET_DRIVE и изменена INTDISK для поддержки рескана драйвов +;--------------------------------------------------------------- + + + +; DISK DRIVER SPECIFICATION +; !FIXIT некорректная! +;--------------------------------------------- +; COMMAND 00h (INITIALIZATION) +; +; INPUT: A - DRIVE LETTER +; IX - ENVIRONMENT +; RETURN: A - AMOUNT DRIVE SUPPORT +; HL - LENGTH DRIVER +;--------------------------------------------- +; COMMAND 01h (OPEN) +; +; INPUT: A - DRIVE +; +;--------------------------------------------- +; COMMAND 02h (CLOSE) +; +; INPUT: A - DRIVE +; RETURN: A - +;--------------------------------------------- +; COMMAND 03h (MEDIA CHECK) +; +; INPUT: A - DRIVE +; RETURN: A - 00h - OLD DISK, 0FFh - NEW DISK +;--------------------------------------------- +; COMMAND 04h (GET BPB) +; +; INPUT: HL - ADDRESS +; A - DRIVE +;--------------------------------------------- +; COMMAND 05h (INPUT) +; +; INPUT: IX:DE - ABSOLUTE SECTOR +; HL - MEMORY ADDRESS +; B - SECTORS COUNT +; A - DRIVE +;--------------------------------------------- +; COMMAND 06h (OUTPUT) +; +; INPUT: IX:DE - ABSOLUTE SECTOR +; HL - MEMORY ADDRESS +; B - SECTORS COUNT +; A - DRIVE +;--------------------------------------------- +; COMMAND 07h (REMOVABLE) +; +; INPUT: A - DRIVE +; RETURN: A = 0 - REMOVABLE +; A = 1 - NONREMOVABLE +;--------------------------------------------- +; COMMAND 08h (GENERIC IOCTL) +; +; INPUT: A - DRIVE +; B - SUBCOMMAND +; DE - MAGIC NUMBER (55AAh) +; SUBCOMMAND +;---------------------- +; 00 - GET DEVICE PARAMETERS +; 01 - READ TRACK +; 02 - TEST TRACK +; 80 - SET DEVICE PARAMETERS +; 81 - WRITE TRACK +; 82 - FORMAT TRACK +;--------------------------------------------- +; +; ERRORS: +; 0 - NO ERRORS +; 1 - BAD COMMAND +; 2 - BAD DRIVE NUMBER +; 3 - UNKNOW FORMAT +; 4 - NOT READY +; 5 - SEEK ERROR +; 6 - SECTOR NOT FOUND +; 7 - CRC ERROR +; 8 - WRITE PROTECT +; 9 - READ ERROR +; 10 - WRITE ERROR +; 11 - FAILURE +; 12 - BUSY (DEVICE OPENED) +; 13 - RESERVED + +;INTDISK PUSH HL +; PUSH BC +; LD HL,DEVICE +; INC A +;INTD001 DEC A +; JP Z,YEP +; LD C,(HL) +; INC C +; INC HL +; INC HL +; INC HL +; JP NZ,INTD001 +; POP BC +; POP HL +; LD A,2 +; SCF +; RET + +;YEP LD A,(HL) +; INC HL +; LD C,(HL) +; INC HL +; LD H,(HL) +; LD L,C +; POP BC +; EX (SP),HL +; RET + + +;----------------------------------------------------------- +; Просканировать систему на FDD/HDD девайсы и RAM-диски +;----------------------------------------------------------- +INITDVC: XOR A + LD (DRV_PAGE.LDRIVE),A ; сбр. ячейку + LD HL,DEVICE + LD (PDEVICE),HL ; восст. ячейку + ; Зачистка таблиц. Необязательно, но мало ли чё будет дальше... ;[ ] + LD HL,DEVICE + LD (HL),#FF + LD DE,DEVICE+1 + LD BC,DEVICE.Size + LOGDRV.Size + RAMDTBL.Size - 1 + LDIR + ; FDD девайсы + CALL FDD_DRV.Init ; узнать число FDD-девайсов + LD DE,FDD_DRV.API_TABLE ; адрес обработчика тек. девайса + CALL MAKEDVC ; иниц. таблицу переходов + ; HDD девайсы +.if_old: CALL INIT_H ; если на старте версия BIOS не подходит, то грузиться можно только с дискеты, для этого тут замена кода на XOR A : RET + LD DE,HDDRIVE + CALL MAKEDVC + ; RAM-диски + CALL INIT_RD + LD DE,RMDRIVE + CALL MAKEDVC + XOR A + RET + +; Инициировать таблицу переходов девайса. +; вход: de=адрес обработчика девайса +; a=число девайсов (0=нет) +MAKEDVC: LD C,A + LD HL,DRV_PAGE.LDRIVE ; ячейка номера посл. диска + ADD A,(HL) + LD (HL),A + ;!TEST ;[ ] оптимизировать было лень + CP DSS_MAX_DRIVES_AMOUNT+1 + JR C,1F + LD (HL),DSS_MAX_DRIVES_AMOUNT + SUB DSS_MAX_DRIVES_AMOUNT + NEG + ADD C + JP 2F + ; +1: LD A,C + OR A + RET Z ; нет девайсов +2: LD C,0 ; сбр. + LD HL,(PDEVICE) ; тек. полож. в таблице +.loop: LD (HL),C ; номер лог.драйва этого устройства + INC HL + LD (HL),E ; de=адрес обработчика + INC HL + LD (HL),D + INC HL + INC C ; ++номер драйва + DEC A + JR NZ,.loop + LD (PDEVICE),HL + DEC A + LD (HL),A + RET + + +;!FIXIT попеределывать тут вызовы через точки входа типа RST или вызовы типа LD C,0 : CALL HDDRIVE на прямые +;------------------------------------------------- +; RST 18h. Вектор дисковых устройств +; вход: a=номер устройства (0-25) +;------------------------------------------------- +INTDISK: + ;R01 + CP #FF + JR NZ,.noNeedRescan + CP C + ;JR Z,INITDVC_RET_DRIVE + JR Z,ReScanDRV +.noNeedRescan: + ; + PUSH HL + PUSH BC + _CALC_DEVICE_ENTRY DEVICE + LD A,(HL) + CP #FF + JR Z,NODEV + INC HL + LD C,(HL) + INC HL + LD H,(HL) + LD L,C + POP BC + EX (SP),HL + RET +NODEV: POP BC + POP HL + LD A,DSS_Error.drv.INVALID_DRIVE + SCF + RET + +PDEVICE DW DEVICE +; DEVICE: BLOCK DSS_MAX_DRIVES_AMOUNT * .TBL_Entry,#FF +; .Size: DB #FF +; .TBL_Entry EQU 3 + +FLOPPY EQU #0001 +FIXED EQU #0002 +CDROM EQU #0004 +NETWORK EQU #0008 + +;DISKS: DB 27 ;LENGTH DISK INFO +; DW FLOPPY ;DISK TYPE +; DB 2,"A:" ;DISK NAME +; DB 11,"NO NAME " +; DB 8,"FAT12 " +; DB #00 ;PHISICAL DRIVE NUMBER +; +; DB 27 ;LENGTH DISK INFO +; DW FLOPPY ;DISK TYPE +; DB 2,"B:" ;DISK NAME +; DB 11,"NO NAME " +; DB 8,"FAT12 " +; DB #01 ;PHISICAL DRIVE NUMBER +; +; DB 27 ;LENGTH DISK INFO +; DW FIXED ;DISK TYPE +; DB 2,"C:" ;DISK NAME +; DB 11,"NO NAME " +; DB 8,"FAT16 " +; DB #80 ;PHISICAL DRIVE NUMBER +; +; DB #00 ;END OF TABLE +;----------------------------------------------------------------------- + + ;R01 +; INITDVC_RET_DRIVE: +; CALL INITDVC +; LD A,(DRV_PAGE.LDRIVE) +; AND A +; RET + ; + + + +//////////////////////////////////////////////////////////////////////// +// NEW RESCAN // +//////////////////////////////////////////////////////////////////////// + INCLUDE 'ReScanDRV.ASM' +//////////////////////////////////////////////////////////////////////// + + +;DEVICE DB #00 +; DW FDDRIVE ; FDD A +; DB #01 +; DW FDDRIVE ; FDD B +; DB #00 +; DW HDDRIVE ; HDD C +; DB #01 +; DW HDDRIVE ; HDD D +; DB #02 +; DW HDDRIVE ; HDD E +; DB #03 +; DW HDDRIVE ; HDD F +; DB #04 +; DW HDDRIVE ; HDD G +; DB #05 +; DW HDDRIVE ; HDD H +; DB #06 +; DW HDDRIVE ; HDD I +; DB #07 +; DW HDDRIVE ; HDD J +; DB #FF \ No newline at end of file