From 663016bd1670d0bb3cedaae96b78ceba7f5c4895 Mon Sep 17 00:00:00 2001 From: Anatoliy Belyanskiy Date: Tue, 15 Aug 2023 04:41:57 +1000 Subject: [PATCH] New rescan drives feature - save bootdisk letter after rescan --- BOOT/DSSBOOT.ASM | 2 +- DSS/DOS_X.ASM | 173 ++++++++++++++++++++++- DSS/DRV-MAIN.ASM | 214 ++++++++++++++++++++++++++++- DSS/DSS_MACROSES.Z80 | 12 ++ DSS/Media_drivers/ide-drv.asm | 34 +++-- DSS/Media_drivers/ram_disk-drv.asm | 12 +- DSS/Media_drivers/shared-drv.asm | 24 ++-- DSS/build.txt | 2 +- DSS/defines.inc | 10 +- Shared_Includes | 2 +- 10 files changed, 440 insertions(+), 45 deletions(-) diff --git a/BOOT/DSSBOOT.ASM b/BOOT/DSSBOOT.ASM index b08db66..8bdf584 100644 --- a/BOOT/DSSBOOT.ASM +++ b/BOOT/DSSBOOT.ASM @@ -35,7 +35,7 @@ DRIVE: _mSYSID BIT 7,A JR Z,GOOD_DRIVE EX DE,HL - LD DE,2*256 + 21 ; если версия ниже 2.21, то ошибка + LD DE,2*256 + 21 ;!HARDCODE если версия ниже 2.21, то ошибка SBC HL,DE LD A,INCORR JR C,FAIL diff --git a/DSS/DOS_X.ASM b/DSS/DOS_X.ASM index 814c550..f3d07fb 100644 --- a/DSS/DOS_X.ASM +++ b/DSS/DOS_X.ASM @@ -161,7 +161,7 @@ FRESP2: LD D,B AND A RET -LDRIVE: DB #FF +LDRIVE: DB DSS_MAX_DRIVES_AMOUNT TDRIVE: DB #00 TCLUST: DW #0000 TCOUNT: DW #0000 @@ -426,7 +426,7 @@ RDERR1: LD A,DSS_Error.sys.NOT_READY ;SCF RET -; +;!FIXIT к буферам! FatBuffer: .MSG: DB 'FAT' .READ_PG: DB #00 @@ -527,13 +527,29 @@ BACK_CUR_PATH: ;R11 ;R12 -;///////////////////////////////////////////////////////////////////// +;/////////////////////////////////////////////////////////////////////// ; Функция #08 (DSS_RESCAN). Пересканировать девайсы системы. ; ; вход: нет ; выход: A - номер последнего лог. диска в системе -;///////////////////////////////////////////////////////////////////// +;/////////////////////////////////////////////////////////////////////// SCANDRV: +;1 [-----------] [-----------] [-----------] [-----------] [-----------] + CALL GETBOOT + LD (.old_letter),A ; bootdisk Log.number +; [-----------] + +;2 [-----------] [-----------] [-----------] [-----------] [-----------] + ; A = bootdisk Log.number + LD DE,Dss.DRV.GenIOCTL.Enter + LD BC,Dss.DRV.GenIOCTL.GetParams + RST ToDSS.DRV + EX AF,AF' + LD (.old_DRIVE_ID),A +; [-----------] + + +;3 [-----------] [-----------] [-----------] [-----------] [-----------] ;!TEST в DRV-MAIN могут быть проблемы с прерываниями ;DI LD A,Dss.DRV.RescanDRV @@ -542,7 +558,154 @@ SCANDRV: LD (LDRIVE),A ;EI ; - RET +; [-----------] + +;4 [-----------] [-----------] [-----------] [-----------] [-----------] +.old_DRIVE_ID+1: + LD A,0 + CALL SETBOOT + JR C,.ERROR_BOOTDRV_DIES + LD (.new_letter),A +; + +;5 [-----------] [-----------] [-----------] [-----------] [-----------] + AND A + LD A,R + PUSH AF + DI + ;;;;;;;; + IN A,(SLOT3) + LD (.restore_page),A + LD A,(DRV_PG_NUMBER) + OUT (SLOT3),A + ;;;;; + + ; вычисляем смещение bootdisk в новой таблице DEVICE +.new_letter+1: + LD A,0 + CALL .get_entry_addr + PUSH HL + ; сохраняем значения нового boot + LD DE,.TMP_BUFFER + LD BC,DEVICE.TBL_Entry + LDIR + ; вычисляем смещение для буквы старого bootdisk в новой таблице DEVICE +.old_letter+1: + LD A,0 + CALL .get_entry_addr + ; меняем букву диска для девайса занявшего старую букву bootdisk + POP DE + LD BC,DEVICE.TBL_Entry + LDIR + ; восстанавливаем bootdisk на старое место + DEC HL + LD DE,.TMP_BUFFER + DEVICE.TBL_Entry-1 + LD BC,DEVICE.TBL_Entry + EX DE,HL + LDDR + ; проверяем, не увеличилось ли значение LDRIVE + LD HL,.old_letter + LD A,(LDRIVE) + CP (HL) + JR NC,.no_change_LDRIVE + LD A,(HL) + LD (LDRIVE),A +.no_change_LDRIVE: + ; + ;;;;; +.restore_page+1: + LD A,0 + OUT (SLOT3),A + ;;;;;;;; + POP AF + LD A,(LDRIVE) + RET PO + EI + + RET +.ERROR_BOOTDRV_DIES: + LD BC,256*COLORS.PAPER.BLUE + BIOS.LP_OPEN_S + LD E,0 + RST ToBIOS + + LD BC,256*COLORS.PAPER.BLUE + BIOS.LP_CLS_WIN + LD DE,0 + LD HL,#2050 + RST ToBIOS + + LD A,1 + OUT (RGMOD),A ; set scr-2 + + LD HL,.ERROR_MSG + LD DE,#A000 + LD BC,.ERROR_MSG.size + LD A,C + LDIR + + LD DE,#10*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.FLASH + COLORS.PAPER.BLUE + COLORS.INC.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 +.get_entry_addr: + _CALC_DEVICE_ENTRY DEVICE + #C000 + RET +; +.TMP_BUFFER: BLOCK 3,#FF + MODULE COLORS +; +INC: +.BLACK EQU #00 +.BLUE EQU #01 +.GREEN EQU #02 +.CYAN EQU #03 +.RED EQU #04 +.MAGENTA EQU #05 +.BROWN EQU #06 +.LGRAY EQU #07 +.DGRAY EQU #08 +.LBLUE EQU #09 +.LGREEN EQU #0A +.LCYAN EQU #0B +.LRED EQU #0C +.LMAGENT EQU #0D +.YELLOW EQU #0E +.WHITE EQU #0F +PAPER: +.BLACK EQU 16*INC.BLACK +.BLUE EQU 16*INC.BLUE +.GREEN EQU 16*INC.GREEN +.CYAN EQU 16*INC.CYAN +.RED EQU 16*INC.RED +.MAGENTA EQU 16*INC.MAGENTA +.BROWN EQU 16*INC.BROWN +.LGRAY EQU 16*INC.LGRAY +.DGRAY EQU 16*INC.DGRAY +.LBLUE EQU 16*INC.LBLUE +.LGREEN EQU 16*INC.LGREEN +.LCYAN EQU 16*INC.LCYAN +.LRED EQU 16*INC.LRED +.LMAGENT EQU 16*INC.LMAGENT +.YELLOW EQU 16*INC.YELLOW +.WHITE EQU 16*INC.WHITE + +FLASH EQU #80 + ENDMODULE +; .old_letter: DB #FF +; .old_DRIVE_ID: DB #FF +; .new_letter: DB #FF +;/////////////////////////////////////////////////////////////////////// ;R12 diff --git a/DSS/DRV-MAIN.ASM b/DSS/DRV-MAIN.ASM index b4a201f..1f0eebb 100644 --- a/DSS/DRV-MAIN.ASM +++ b/DSS/DRV-MAIN.ASM @@ -191,7 +191,7 @@ A0066: JP DRV_PAGE.NMI ; ; <[DRIVE PAGE SWITCH]> ; _mInfoBLOCK PORTAL.RSTx18_SWITCH_ADDRESS-$-(PORTAL.out_DRV.switch - PORTAL.out_DRV),#C7 PORTAL.out_DRV: PUSH BC ; -.RETBANK+2: LD BC,0*256+SLOT0 ; +.RETBANK+2: LD BC,SLOT0 + 0*256; .switch: OUT (C),B ; ASSERT $!=84,'-> Portal error!'; ;Entry point from DSS main page @@ -218,6 +218,215 @@ PORTAL.outDRV: ; ; ; + +/* +; !!! ВЫЗЫВАТЬ ТОЛЬКО ЧЕРЕЗ RST #10 в DSS-MAIN !!! +RESCAN_DRV: + AND A + LD A,R + PUSH AF + DI + ;; + IN A,(SLOT3) + LD (.restore_page),A + LD A,(PORTAL.out_DRV.RETBANK) + OUT (SLOT3),A + LD A,(BOOTDRV+#C000) ; узнали лог.номер boot диска + LD (.BOOT),A ; сохранили +.restore_page+1: + LD A,0 + OUT (SLOT3),A + + LD A,(.BOOT) + CP 2 + JR C,.Change ; bootdisk - дискета? + + LD C,A + ADD A + ADD C + LD HL,DEVICE + LD C,A + XOR A + LD B,A + ADC HL,BC + LD DE,.DEVICE + LD BC,3 ;!HARDCODE длина записи в DEVICE + LDIR ; сохранили запись boot-dsk + ;!TODO тут пока работает вариант замены буквы для boot-RAM-DRV и HDD + LD DE,.DEVICE+1 + LD HL,HDDRIVE + AND A + SBC HL,DE + JR Z,.HDD_SYS + ; + LD HL,RMDRIVE + AND A + SBC HL,DE + JR NZ,.Change + ; +.RMD_SYS: + LD A,#60 + LD (.BOOT_TYPE),A + LD A,(.DEVICE) + LD HL,RAMDTBL + SLA A + ADD A,L + LD L,A + LD A,0 + ADC A,H + LD H,A + ;Тут в HL адрес первого байта записи о boot RAM-DRV + LD DE,.RAMDTBL + LD BC,RAMDTBL.TBL_Entry + LDIR ; сохранили запись о RAM-DRV + JP .Change + ; +.HDD_SYS: + LD A,#80 + LD (.BOOT_TYPE),A + ; + LD A,(.DEVICE) + ADD A,A + ADD A,A + ADD A,A + ADD A,A + LD HL,LOGDRV + ADD A,L + LD L,A + LD A,0 + ADC A,H + LD H,A + ; Тут в HL адрес первого байта записи о boot разделе + LD DE,.LOGDRV + LD BC,LOGDRV.TBL_Entry + LDIR ; сохранили запись о HDD разделе + + ;JP .Change +.Change: CALL INITDVC_RET_DRIVE + LD A,(.BOOT) + CP 2 + JR C,.exit ; bootdisk - дискета? + + ; 3. Проверить, сменилась ли буква boot-drv и выйти, если нет. + ; 4. Если boot HDD и его букву занял HDD, то меняем местами их + ; записи в таблицах DEVICE и LOGDRV. + ; Если boot HDD и его букву занял RAM Drive, то иди нахер, не может быть)). + ; Если boot FDD то нихера не случится. + ; Если boot CD-ROM, то подумаем, когда до этого доживём. + ; Если boot RAM Drive и его букву занял HDD, то нужно сменить + ; их местами в таблице DEVICE. + ; !!!!! что будет, если буква бут-диска Е, а после рескана + ; загрузочный раздел оказался единственным в системе? + ; А если сразу будут изменения с RAM дисками и HDD разделами? + + LD A,(.BOOT_TYPE) + CP #60 ;!HARDCODE ram drive + JR NZ,.restore_HDD +.restore_RMD: + LD A,(.RAMDTBL+1) + LD HL,RAMDTBL+1 + LD B,RAMDTBL.Size / RAMDTBL.TBL_Entry + +.loop_RMD: + CP (HL) + JR Z,.found_RMD ; ZF - нашли в новой RAMDTBL bootdisk по его физическому номеру + INC HL + INC HL + DJNZ .loop_RMD + JP .BIG_ERROR ; bootdisk died... + +.found_RMD: + LD A,RAMDTBL.Size / RAMDTBL.TBL_Entry + SUB B + LD (.DEVICE),A ; new bootdisk log.number in RAMDTBL + DEC HL + LD A,(HL) ; логический номер для поиска в DEVICE + LD (.DEVICE_NEW),A ; сохраняем + + ; поиск номера записи по её логическому диску + процедуре обработчика + LD HL,DEVICE-DEVICE.TBL_Entry + LD DE,DEVICE.TBL_Entry + LD BC,DEVICE.Size / DEVICE.TBL_Entry +.found_RMD.nxt: + AND A + ADC HL,DE + PUSH HL + EXX + POP HL + LD DE,.DEVICE + LD B,DEVICE.TBL_Entry + CALL COMPARE_BYTES + EXX + JR Z, found entry + DJNZ NZ,.found_RMD.nxt +.BIG_ERROR: + ;;;; + + + LD BC,DEVICE.Size / DEVICE.TBL_Entry + AND A + + ; длина записи. сравниваем на полное совпадение .DEVICE с + ; одной из записей DEVICE + LD B,DEVICE.TBL_Entry +.rmd_loop_search: + LD A,(DE) + CP (HL) + JR NZ,.nxt_loop_ + INC DE + INC HL + DJNZ .rmd_loop_search + + POP BC + + + ;JP P,.BIG_ERROR ; если прошерстили за пределы таблицы + + ; + JP .exit + ; +.restore_HDD: + + ;JP .exit + ;; +.exit: LD HL,.Start_buffer + LD (HL),#FF + LD DE,.Start_buffer+1 + LD BC,.Size_buffer-1 + LDIR ; помыть за собою)) + + POP AF + LD A,(DRV_PAGE.LDRIVE) + RET PO + EI + RET +.Start_buffer: +.BOOT: DB #FF ; логический номер +.BOOT_TYPE: DB #FF ; 00, #60, #80, #C0 +.DEVICE: BLOCK 3,#FF +.DEVICE_NEW: BLOCK 3,#FF +.LOGDRV: BLOCK 16,#FF +.RAMDTBL: BLOCK 2,#FF ; лог RMD, физ RMD +.Size_buffer EQU $-.Start_buffer + +;ВХОД: HL,DE - адреса сравниваемых блоков, B - длина блока +;ВЫХОД: ZF - блоки одинаковы, в HL и DE адреса следующего байта после совпавшего блока +; NZ - блоки неодинаковы. +COMPARE_BYTES: + LD A,(DE) + CP (HL) + RET NZ + INC HL + INC DE + DJNZ COMPARE_BYTES + XOR A + RET + +*/ + + +DRV_PAGE.LDRIVE: DB #00 + DISPATCH: LD HL,INTDISK LD (ADCALL),HL @@ -226,9 +435,6 @@ INITDVC_RET_DRIVE: LD A,(DRV_PAGE.LDRIVE) AND A RET -; - -DRV_PAGE.LDRIVE: DB #00 INCLUDE 'dss/media_drivers/shared-drv.asm' INCLUDE 'dss/media_drivers/ide-drv.asm' diff --git a/DSS/DSS_MACROSES.Z80 b/DSS/DSS_MACROSES.Z80 index b4c759b..87c8c70 100644 --- a/DSS/DSS_MACROSES.Z80 +++ b/DSS/DSS_MACROSES.Z80 @@ -1,4 +1,16 @@ +; + MACRO _CALC_DEVICE_ENTRY tbl_addr + LD C,A + ADD A,A + ADD A,C + LD C,A + LD B,0 + LD HL,tbl_addr + ADD HL,BC + ENDM +; + ; MACRO SET_PAGE_X new_page IF OLD_SET_BANK diff --git a/DSS/Media_drivers/ide-drv.asm b/DSS/Media_drivers/ide-drv.asm index ced41ea..b4ba3b2 100644 --- a/DSS/Media_drivers/ide-drv.asm +++ b/DSS/Media_drivers/ide-drv.asm @@ -169,8 +169,6 @@ ; 12 (0Ch) - BUSY (DEVICE OPENED) ; 13 (0Dh) - RESERVED -LD_DSK EQU 16 ; максимальное количество логических дисков в системе - ; IDE0 EQU #0C1C0 ; IDE1 EQU #0C1C8 PART EQU #C000 @@ -304,7 +302,6 @@ DRVCLC: INC A ; DS 28 ;RESERVED - ;+00 ;SECTORS PER TRACK ;+01 ;TRACKS PER CYLLINDER ;+02 ;RESERVED @@ -315,24 +312,35 @@ DRVCLC: INC A ;+07 ;RESERVED -LOGDRV: BLOCK 16*LD_DSK,0 ;!FIXIT перенести к буферам в конец страницы ;+00 BYTE MASTER/SLAVE PHISICAL DRIVE NUMBER #80/#81/... ;+01 LONG SECTOR OFFSET ;+05 LONG SIZE IN SECTORS ;+09 FREE ;+15 -.Size EQU $-LOGDRV - +LOGDRV: BLOCK .TBL_Entry*LD_DSK,0 ;!FIXIT перенести к буферам в конец страницы +.TBL_Entry EQU 16 +.Size EQU $-LOGDRV SELHDD: PUSH DE PUSH BC PUSH HL - LD L,A - LD H,0 - ADD HL,HL - ADD HL,HL - ADD HL,HL - ADD HL,HL + ;!TEST + ;SLA A + ;RLCA + ;SLA A + ;LD L,A + ;LD H,0 + ;RL H + ;ADD HL,HL + ; + ; original + LD L,A + LD H,0 + ADD HL,HL + ADD HL,HL + ADD HL,HL + ADD HL,HL + ; EX DE,HL LD IY,LOGDRV ADD IY,DE @@ -547,7 +555,7 @@ GBPB_H: PUSH IY ; DE - ADDRESS ; B - COUNTER ; A'- PAGE -; A - HDD NUMBER +#80 +; A - HDD LOG NUMBER ;READ SECTOR LREADH: PUSH IY CALL SELHDD diff --git a/DSS/Media_drivers/ram_disk-drv.asm b/DSS/Media_drivers/ram_disk-drv.asm index 34417d1..87bb46e 100644 --- a/DSS/Media_drivers/ram_disk-drv.asm +++ b/DSS/Media_drivers/ram_disk-drv.asm @@ -332,7 +332,7 @@ INIT_RD: JP 1F .noDRV: POP BC 1: INC B - LD A,RAMDTBL.Size / 2 + LD A,RAMDTBL.Size / RAMDTBL.TBL_Entry CP B JR NZ,.initLoop @@ -345,13 +345,15 @@ INIT_RD: ; LD HL,ENDDRVR AND A RET - + +;!TODO воткнуть эти всякие таблицы в конец файла и активировать как структуры, чтоб бинарник меньше весил ; ТАБЛИЦА СООТВЕТСТВИЯ МЕЖДУ ФИЗИЧЕСКИМ НОМЕРОМ РАМДИСКА И ЕГО RAM-DISK ID -; DB RAM_DRIVE_ID, RAM_DRIVE_NUMBER -RAMDTBL: DUP MAX_RAMDRIVES * 2 +; 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 +.Size EQU $-RAMDTBL ; diff --git a/DSS/Media_drivers/shared-drv.asm b/DSS/Media_drivers/shared-drv.asm index 03acf6a..c4c3541 100644 --- a/DSS/Media_drivers/shared-drv.asm +++ b/DSS/Media_drivers/shared-drv.asm @@ -123,7 +123,6 @@ ; RST 18h. Вектор дисковых устройств ; вход: a=номер устройства (0-25) ;------------------------------------------------- -DSS_MAX_DRIVES_AMOUNT EQU 26 INTDISK: ;R01 CP #FF @@ -133,14 +132,17 @@ INTDISK: .noNeedRescan: ; PUSH HL - PUSH BC - LD C,A - ADD A,A - ADD A,C - LD C,A - LD B,0 - LD HL,DEVICE - ADD HL,BC + PUSH BC + + _CALC_DEVICE_ENTRY DEVICE + ; LD C,A + ; ADD A,A + ; ADD A,C + ; LD C,A + ; LD B,0 + ; LD HL,DEVICE + ; ADD HL,BC + LD A,(HL) INC A JR Z,NODEV @@ -153,7 +155,6 @@ INTDISK: POP BC EX (SP),HL RET - NODEV: POP BC POP HL LD A,DSS_Error.drv.INVALID_DRIVE @@ -161,8 +162,9 @@ NODEV: POP BC RET PDEVICE DW DEVICE -DEVICE: BLOCK DSS_MAX_DRIVES_AMOUNT*3,#FF +DEVICE: BLOCK DSS_MAX_DRIVES_AMOUNT*.TBL_Entry,#FF .Size: DB #FF +.TBL_Entry EQU 3 FLOPPY EQU #0001 FIXED EQU #0002 diff --git a/DSS/build.txt b/DSS/build.txt index cc4f7f3..b6e2760 100644 --- a/DSS/build.txt +++ b/DSS/build.txt @@ -1 +1 @@ -218 \ No newline at end of file +242 \ No newline at end of file diff --git a/DSS/defines.inc b/DSS/defines.inc index 045fb07..ff987ef 100644 --- a/DSS/defines.inc +++ b/DSS/defines.inc @@ -3,17 +3,19 @@ ; ; - DEFINE SHORT_RSTx10_TABLE 0 ; укороченная таблица функций rst #10. 96 функций. + DEFINE SHORT_RSTx10_TABLE 0 ; укороченная таблица функций rst #10. 96 функций. ; ; +LD_DSK EQU 16 ; максимальное количество логических HDD дисков в системе +DSS_MAX_DRIVES_AMOUNT EQU 26 DEFINE MAX_RAMDRIVES 16 DEFINE NeedSafePort_Y 1 DEFINE TABisSPACES 0 DEFINE EnoughtOnly_LF 0 DEFINE CLASSIC_CURSOR 0 DEFINE SAVE_PATH_MACRO 0 - DEFINE MINIMUM_BIOS_VERSION 2*256 + 55 ; version 2.55 + DEFINE MINIMUM_BIOS_VERSION 2*256 + 55 ; version 2.55 ; ;-------------------[MEMORY]-------------------------; DEFINE USING_MEMPAGES 4 @@ -28,7 +30,7 @@ ENVPAGE EQU 2 DRVPAGE EQU 3 ; -DIRSPEC.DEPTH EQU 256 ; '\' + 1..255 +DIRSPEC.DEPTH EQU 256 ; '\' + 1..255 ENVIRONMENT_STRING_LENGTH EQU 255 TXTADDR EQU #C000 @@ -36,7 +38,7 @@ ENVADDR EQU #E400 DIR EQU #C000 FAT EQU #C000 -FMCOUNT EQU 10 ; Количество файловых манипуляторов +FMCOUNT EQU 10 ; Количество файловых манипуляторов HANDBUF.SIZE EQU 32 ;----------------------------------------------------; ; diff --git a/Shared_Includes b/Shared_Includes index cc0bf0d..84a9262 160000 --- a/Shared_Includes +++ b/Shared_Includes @@ -1 +1 @@ -Subproject commit cc0bf0dfac766dd97e7a5441b523034921cf3830 +Subproject commit 84a92620cab98867eb5b892d1ae17cd206c2b1bd