/* ; !TODO запоминать прерывания, отключать на старте, восстанавливать на выходе SCANDRV: ;1 [-----------] [-----------] [-----------] [-----------] [-----------] ; LD A,(LDRIVE) ; LD (.old_ldrive),A ; LD A,(FATCASH.Update) ; OR A ; CALL NZ,WR_FAT 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 [-----------] [-----------] [-----------] [-----------] [-----------] LD A,Dss.DRV.RescanDRV LD C,Dss.DRV.RescanDRV RST ToDSS.DRV LD (LDRIVE),A ; [-----------] ;4 [-----------] [-----------] [-----------] [-----------] [-----------] .old_DRIVE_ID+1: LD A,0 CALL SETBOOT JR C,.ERROR_BOOTDRV_DIES LD (.new_letter),A ; LD A,(.old_letter) LD (BOOTDRV),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 ;!TEST LD HL,.old_letter LD A,(LDRIVE) CP (HL) JR NC,.no_change_LDRIVE LD A,(HL) LD (LDRIVE),A ; ; .old_ldrive+1: ;LD L,0 ;LD A,(LDRIVE) ;CP L ;JR NC,.no_change_LDRIVE ;LD A,L ;LD (LDRIVE),A ; .no_change_LDRIVE: ; ; DEC A ; CALL DISKINF ; LD A,(BOOTDRV) ; CALL CHNDISK ;;;;; .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.CGA.PAPER.BLUE + BIOS.LP_OPEN_S LD E,0 RST ToBIOS LD BC,256*COLORS.CGA.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.CGA.FLASH + COLORS.CGA.PAPER.BLUE + COLORS.CGA.INC.WHITE LD B,A LD C,BIOS.LP_PRINT_LINE3 RST ToBIOS .loop: DI ; .loop: LD A,R ; AND 7 ; OUT (BorderColor),A 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 ; .old_letter: DB #FF ; .old_DRIVE_ID: DB #FF ; .new_letter: DB #FF */ IF 1 SCANDRV: ; 0. запоминаем состояние прерываний ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; LD A,R DI PUSH AF ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; ; 1. запоминаем бут-диск ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; CALL GETBOOT LD (.old_letter),A ;; A = bootdisk Log.number ;;!FIXIT можно доставать из сохраненной таблицы когда понадобится ; LD DE,Dss.DRV.GenIOCTL.Enter ; LD BC,Dss.DRV.GenIOCTL.GetParams ; RST ToDSS.DRV ; EX AF,AF' ;; A = bootdisk number ; LD (.old_DRIVE_ID),A ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; ; 2. копируем в буфер таблицы DEVICE, LOGDRV, RAMDTBL ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; SET_PAGE_X DRVPAGE PUSH AF LD HL,DEVICE + #C000 LD DE,OLD_TABLES.DEVICE + #C000 LD BC,OLD_TABLES.DEVICE - DEVICE LDIR ; LD A,2 ;!HARDCODE количество таблиц второго уровня (LOGDRV, RMDRIVE) LD (Fill_if_Exists.tbl),A ;POP AF ;OUT (SLOT3),A ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; ; 3. вызываем рескан ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; LD A,Dss.DRV.RescanDRV LD C,Dss.DRV.RescanDRV RST ToDSS.DRV LD (LDRIVE),A ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; ; 4. сравниваем записи старых таблиц с новыми: ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; ;SET_PAGE_X DRVPAGE ;PUSH AF LD HL,OLD_TABLES.DEVICE + #C000 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,FDDRIVE 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 ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; ; 5. сравниваем запись новых таблиц со старыми ; а. если драйв только в новой: ; а1) втыкаем его в первую свободную запись в DEVICE (или ставим после последнего драйва) ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; ; ВХОД: IX - OLD_TABLES.DEVICE ; HL - OLD_TABLES.DEVICE.End ; HL' - разница между адресами старых и новых таблиц ; 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 + #C000 LD IY,LOGDRV + #C000 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 + #C000),A LD (LDRIVE),A ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; ; 6. проверяем, не грохнулся ли бут-диск. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; .old_letter+1: LD A,0 _CALC_DEVICE_ENTRY OLD_TABLES.DEVICE + #C000 LD A,(HL) INC A JP Z,ERROR_BOOTDRV_DIES ; .old_DRIVE_ID+1: ; LD A,0 ; CALL SETBOOT ; JR C,.ERROR_BOOTDRV_DIES ; LD (.new_letter),A ; ; ; LD A,(.old_letter) ; LD (BOOTDRV),A ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; ; 7. заменяем новые таблицы на модифицированные старые ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; LD HL,OLD_TABLES.DEVICE + #C000 LD DE,DEVICE + #C000 LD BC,OLD_TABLES.DEVICE - DEVICE LDIR POP AF OUT (SLOT3),A ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; ;8. выход ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; POP AF RET PO EI RET ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; ; .loop2_start: LD C,B ; начинаем считать переменную LDRIVE ;LD (LDRIVE),A ;LD C,A ; 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 ; ; LD A,(LDRIVE) ; INC A ; LD (LDRIVE),A INC C ; добавили драйв ; DJNZ .loop2 JR .loop1_exit ; ;;; Fill_if_Exists: .tbl+1: LD B,2 ; количество таблиц. пока 2 - LOGDRV и RAMDTBL ;!!!!! восстанавливать DJNZ 1F ; B=1, RAMDTBL LD A,RAMDTBL.TBL_Entry LD IY,RAMDTBL + #C000 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 + #C000 CALL .RUN LD DE,HDDRIVE RET NC ; переходим на другую таблицу - RAMDTBL LD A,(.tbl) DEC A ;!!!!! может быть переполнение LD (.tbl),A LD HL,OLD_TABLES.RAMDTBL + #C000 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 ; сохраняем текущий адрес новой таблицы ; ;EX DE,HL ;ADD IY,DE ;EX DE,HL 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: LD BC,256*COLORS.CGA.PAPER.BLUE + BIOS.LP_OPEN_S LD E,0 RST ToBIOS LD BC,256*COLORS.CGA.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.CGA.FLASH + COLORS.CGA.PAPER.BLUE + COLORS.CGA.INC.WHITE LD B,A LD C,BIOS.LP_PRINT_LINE3 RST ToBIOS .loop: DI ; .loop: LD A,R ; AND 7 ; OUT (BorderColor),A 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 + #C000 CALL GET_RAMDRV_NUM.skip_tbl + #C000 LD (.cur_drv),BC AND #0F LD C,A ; номер рамдиска ; Ищем в новой такой же номер рамдиска LD B,MAX_RAMDRIVES LD DE,RAMDTBL + #C000 .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 SCANDRV.nextN2 ; .found: DEC A ; затираем в новой таблице совпавший драйв (чтоб легче было парсить оставшееся) LD (DE),A DEC DE LD (DE),A JP SCANDRV.nextN HARD_DRV: LD L,B LOGDRV_ENTRY_FIND OLD_TABLES.LOGDRV + #C000 LD IX,LOGDRV + #C000 LD DE,LOGDRV.TBL_Entry LD B,DSS_MAX_DRIVES_AMOUNT ; .loop: LD A,(IY+0) ;CP #FF ;JR Z,.skip CP (IX+0) JR NZ,.skip ; LD A,(IY+1) CP (IX+1) JR NZ,.skip LD A,(IY+2) CP (IX+2) JR Z,.found ; .skip: ADD IX,DE DJNZ .loop ; ЗАПИСЬ НЕ НАЙДЕНА ; Грохаем старую запись в OLD_TABLES.LOGDRV LD A,#FF LD (IY+0),A ; Достаём положение в OLD_TABLES.DEVICE POP HL ; Достаём шаг общего цикла для получения лог.номера драйва в KILL_FM POP BC PUSH BC ; Грохаем ФМ и запись в OLD_TABLES.DEVICE CALL KILL_FM ; JP SCANDRV.nextN2 ; .found: ; затираем в новой таблице совпавший драйв (чтоб легче было парсить оставшееся) LD (IX+0),#FF JP SCANDRV.nextN ; ; CD_ROM: ; JP SCANDRV.nextN ; ВХОД: HL - текущая запись в таблице DEVICE ; B - шаг общего цикла KILL_FM: ; LD A,DSS_MAX_DRIVES_AMOUNT SUB B LD C,A ; втыкаем страницу ядра с таблицей файловых манипуляторов PUSH BC SET_PAGE_X COREPAGE POP BC PUSH AF ; Шерстим манипуляторы на наличие в них грохнутого драйва LD IY,FM_BUF-FM_BUF.Size + #C000 LD B,FMCOUNT LD DE,FM_BUF.Size .loop_fm: ADD IY,DE LD A,(IY+_sFM.DRIVE) CP C JR NZ,.skip XOR A LD (IY+_sFM.NAME),A ; грохаем манипулятор .skip: DJNZ .loop_fm ; POP AF OUT (SLOT3),A ; ; грохаем в OLD_TABLES.DEVICE убитый драйв LD (HL),#FF ; RET ENDMODULE ENDIF /* [DRIVE TABLES] .Size == DEVICE.Size + LOGDRV.Size + RAMDTBL.Size == 78 + 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 ; ; NEW RESCAN ;=====================================================================[] ; логический номер устройства + адрес обработчика. ; Порядковый номер * 3 = буква диска + "A" DEVICE: BLOCK DSS_MAX_DRIVES_AMOUNT*3,#FF .Size: EQU $-DEVICE Логический номер раздела. Номер группы = логический номер раздела HDD из DEVICE LOGDRV EQU DEVICE + DEVICE.Size .TBL_Entry EQU 16 .Size EQU DSS_MAX_DRIVES_AMOUNT * .TBL_Entry +00 BYTE MASTER/SLAVE PHISICAL DRIVE NUMBER #80/#81/... +01 LONG SECTOR OFFSET +05 LONG SIZE IN SECTORS (SECTORS ON LOGICAL DISK) +09 FREE +15 ; ТАБЛИЦА СООТВЕТСТВИЯ МЕЖДУ ФИЗИЧЕСКИМ НОМЕРОМ РАМДИСКА И ЕГО RAM-DISK ID ; Log Number: DB RAM_Drive_Log_Number, RAM_Drive_ID ;(BIOS 0-15), (Block ID for BIOS) RAMDTBL: DUP MAX_RAMDRIVES * 2 DB #FF EDUP .Size EQU $-RAMDTBL INTDISK: ;R01 CP #FF JR NZ,.noNeedRescan CP C JR Z,INITDVC_RET_DRIVE .noNeedRescan: ; PUSH HL PUSH BC ADD A,A ADD A,A LD C,A LD B,0 LD HL,DEVICE ADD HL,BC LD A,(HL) CP #FF JR Z,NODEV INC HL 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 INITDVC: XOR A LD (DRV_PAGE.LDRIVE),A ; сбр. ячейку LD HL,DEVICE LD (PDEVICE),HL ; восст. ячейку ; FDD девайсы CALL FDDRIVE.INIT ; узнать число FDD-девайсов LD DE,FDDRIVE ; адрес обработчика тек. девайса CALL MAKEDVC ; иниц. таблицу переходов ; HDD девайсы ; если на старте версия BIOS не подходит, то грузиться можно только с дискеты, для этого тут замена кода на XOR A : RET .if_old: CALL INIT_H ;CALL .CHECK_HDD LD DE,HDDRIVE CALL MAKEDVC ; RAM-диски CALL INIT_RD LD DE,RMDRIVE CALL MAKEDVC XOR A RET .CHECK_HDD: RET ;R01 INITDVC_RET_DRIVE: LD DE,DRV_TEMP_BUFFER LD HL,DEVICE LD BC,DEVICE.Size LDIR LD HL,LOGDRV LD BC,LOGDRV.Size LDIR LD HL,RAMDTBL LD BC,RAMDTBL.Size LDIR CALL INITDVC ; Сравниваем старый DEVICE буфер с новым, если в новом нет устройства, то затираем в старых буферах его LD HL,DEVICE LD DE,DRV_TEMP_BUFFER LD B,DEVICE.Size .loop_DEVICE: LD A,(DE) CP (HL) CALL NZ,.FIND_DEV INC HL INC DE DJNZ .loop_DEVICE LD A,(DRV_PAGE.LDRIVE) AND A RET ; DEVICE: BLOCK DSS_MAX_DRIVES_AMOUNT*4,#FF ;=====================================================================[] ; ; */ ; LD A,(Fill_if_Exists.tbl) ; DEC A ; LD (Fill_if_Exists.tbl),A /* ; находим в старой DEVICE первую свободную ячейку LD HL,OLD_TABLES.DEVICE + DEVICE.Size LD DE,-DEVICE.TBL_Entry LD B,DSS_MAX_DRIVES_AMOUNT LD A,#FF ; .loop1: ADD HL,DE CP (HL) JR NZ,.end_found DJNZ .loop1 .end_found: ; HL = first free record in OLD_TABLES.DEVICE LD (PDEVICE),HL ; B = last drive LD A,B LD (DRV_PAGE.LDRIVE),A ; Находим в старой LOGDRV первую свободную ячейку ; !TODO тут оптимизнуть можно EXX ; для .ldir_to_empty LD HL,LOGDRV LD B,DSS_MAX_DRIVES_AMOUNT EXX ; LD HL,OLD_TABLES.LOGDRV LD DE,LOGDRV.TBL_Entry LD B,DSS_MAX_DRIVES_AMOUNT LD A,#FF ; .loop3: CP (HL) JR NZ,.loop3_skip CALL .ldir_to_empty JR Z.loop3_exit .loop3_skip: ADD HL,DE DJNZ .loop3 .loop3_exit: ; no free space in old table or no new records in new table ; Находим в новой LOGDRV первую новую запись LD HL,LOGDRV LD DE,LOGDRV.TBL_Entry LD B,DSS_MAX_DRIVES_AMOUNT ; .loop2: LD A,(HL) INC A CALL NZ,. JR NZ, ; error - no space for new record ADD HL,DE DJNZ .loop2 ; EXX LD BC,INIT_H EXX LD HL,LOGDRV LD DE,LOGDRV.TBL_Entry LD B,DSS_MAX_DRIVES_AMOUNT .loop_logdrv: LD A,#FF CP (HL) EXX LD A,1 CALL NZ,MAKEDVC EXX ADD HL,DE DJNZ .loop_logdrv ; EXX LD BC,INIT_RD EXX LD HL,RAMDTBL LD DE,RAMDTBL.TBL_Entry LD B,MAX_RAMDRIVES .loop_logdrv: LD A,#FF CP (HL) EXX LD A,1 CALL NZ,MAKEDVC EXX ADD HL,DE DJNZ .loop_logdrv LD B,DSS_MAX_DRIVES_AMOUNT .tbl_scanOld_mainLoop: PUSH BC POP BC DJNZ .tbl_scanOld_mainLoop .ldir_to_empty: ; Находим в новой LOGDRV первую новую запись ; !TODO тут оптимизнуть можно PUSH HL EXX ; ; LD HL,LOGDRV LD DE,LOGDRV.TBL_Entry ; LD B,DSS_MAX_DRIVES_AMOUNT LD A,#FF ; .loop3: CP (HL) JR NZ,.run_ldir .loop3skip: ADD HL,DE DJNZ .loop3 ; no new records in table ; ZF = 0 ;LD A,B ;DEC A ; Set ZF = 0 EXX POP HL ; сравняли стек RET ; .run_ldir: POP DE PUSH BC LD BC,LOGDRV.TBL_Entry LDIR POP BC DJNZ .ldir_exit ; обработали последнюю запись в таблице LD A,B DEC A ; Set ZF = 0 ; .ldir_exit: EXX RET */