;[BEGIN] ;//MODULE: DRV-MAIN AUTHOR: Denis Parinov ;//CREATE: 2003-03-12 ;--------------------------------------------------------------- ;Rev Date Name Description ;--------------------------------------------------------------- ;R00 2003-03-19 DNS Initial version ;--------------------------------------------------------------- ; ORG #0000 ;PAGEDRV EQU 0 ;===============; ;!FIXIT в процедуре которая будет отвечать за переход из этой страницы обратно в MAIN для вызова функций ; ДСС и, возможно, повторному заходу в эту страницу через RST #18 из других страниц (которых пока нет) ; сделать нечто подобное с программным стеком страниц. Эта процедура их сохраняет, примерно такая же ; должна восстанавливать. ; PUSH HL ;.SP+1: LD HL,DRV_PAGE.RSTx18_RET_PAGES ; LD (HL),A ; DEC L ; Не HL, а L - чтоб закольцевать область ; LD (.SP),HL ; POP HL ;===============; ;!TODO ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; ; <[NOT USED]> ; A0000: JP RST_00 ; ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; ; ; RST_00: LD A,DSS_Error.drv.INVALID_COMMAND SCF RET ; ; ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; ; <[BIOS API]> ; BLOCK 8-$,#C7 ; #C7 - "RST 0" opcode A0008: PUSH AF ; LD A,SYS_PORT.PAGE8; OUT (SYS_PORT.ON),A ; POP AF ; RET ; ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; ; ;!FIXIT ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; ; <[DSS API]> ; BLOCK #10-$,#C7 ; #C7 - "RST 0" opcode A0010: ;JP DRV_PAGE.RST_10 ; DI : HALT ; ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; ; ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; ; <[DRIVE API]> ; BLOCK #18-$,#C7 ; #C7 - "RST 0" opcode ;A0018 JP INTDISK ; A0018: PUSH AF ; PUSH BC ; DRV_PAGE.MAIN_PAGE_NUMBER+2: ; LD BC,0*256 + SLOT0 ; !FIXIT сюда не должны вставляться номера выделенных страниц? JP PORTAL.outDRV ; ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; ;!TODO ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; ; <[NOT USED]> ; BLOCK #20-$,#C7 ; #C7 - "RST 0" opcode A0020: JP DRV_PAGE.RST_20 ; ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; ; ; DRV_PAGE.RST_20: LD A,DSS_Error.drv.INVALID_COMMAND SCF RET ; ;!TODO ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; ; <[NOT USED]> ; BLOCK #28-$,#C7 ; #C7 - "RST 0" opcode A0028: JP DRV_PAGE.RST_28 ; ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; ; ; DRV_PAGE.RST_28: LD A,DSS_Error.drv.INVALID_COMMAND SCF RET ; ;!TODO ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; ; <[NOT USED]> ; BLOCK #30-$,#C7 ; A0030: JP RST_30 ; ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; ; ; RST_30: LD A,DSS_Error.drv.INVALID_COMMAND SCF RET ; ;!FIXIT ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; ; <[MAIN INT]> ; BLOCK #38-$,#C7 ; A0038: ; ; JP RST_38 ; ; RST_38: ; ; INT_: PUSH AF ; ; EX AF,AF' ; ; PUSH AF ; ; PUSH BC ; ; PUSH DE ; ; PUSH HL ; ; EXX ; ; PUSH BC ; ; PUSH DE ; ; PUSH HL ; ; PUSH IX ; ; PUSH IY ; ; CALL KEYSCAN ; ; LD C,#80 ; ; RST #30 ; ; POP IY ; ; POP IX ; ; POP HL ; ; POP DE ; ; POP BC ; ; EXX ; ; POP HL ; ; POP DE ; ; POP BC ; ; POP AF ; ; EX AF,AF' ; ; POP AF ; EI ; RETI ; ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; ; ; DRV_PAGE.KEYSCAN: RET ;!FIXIT ; ; ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; ; <[ NMI ]> ; DRV_PAGE.NMI: RETN ; BLOCK #66-$,#C7; A0066: JP DRV_PAGE.NMI ; ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; ; ;-------------------------------; ;ADRST10 EQU #00 ; ;!!!!! ;-------------------------------; ;!FIXIT ; DRV_PAGE.RST_10: ; PUSH HL ; LD L,C ; LD H,ADRST10/256 ; LD C,(HL) ; INC H ; LD H,(HL) ; LD L,C ; EX (SP),HL ; RET ; ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; ; <[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,SLOT0 + 0*256; .switch: OUT (C),B ; ASSERT $!=84,'-> Portal error!'; ;Entry point from DSS main page LD (.RETBANK),A ; POP BC ; POP AF ; ADCALL+1: CALL DISPATCH ; патчится на INTDISK JP PORTAL.out_DRV ; ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; ; ;!FIXIT чёт не то тут ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; LD B,#00; ; OUT (C),A ; ;--- ; POP BC ; RET ; PORTAL.outDRV: ; RET ; ;' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '; ; ; /* ; !!! ВЫЗЫВАТЬ ТОЛЬКО ЧЕРЕЗ 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 INITDVC_RET_DRIVE: CALL INITDVC LD A,(DRV_PAGE.LDRIVE) AND A RET INCLUDE 'dss/media_drivers/shared-drv.asm' INCLUDE 'dss/media_drivers/ide-drv.asm' INCLUDE 'dss/media_drivers/fdd-drv.asm' INCLUDE 'dss/media_drivers/ram_disk-drv.asm' DEVICE_CFG: DRV_TEMP_BUFFER: ; ; ;---------[256 bytes stack for return pages of RST #18 callers]--------; ; #3F00 - #3FFF DRV_PAGE.RSTx18_RET_PAGES EQU #3FFF ;----------------------------------------------------------------------; ASSERT ((#4000-DRV_TEMP_BUFFER-256) > (DEVICE.Size + LOGDRV.Size + RAMDTBL.Size)), "No space for DRV_TEMP_BUFFER in DRV-MAIN page" ; ENDMODULE ; OUTEND ;[END] /* ; ; NEW RESCAN ;=====================================================================[] ; логический номер устройства + адрес обработчика. ; Порядковый номер * 3 = буква диска + "A" DEVICE: BLOCK DSS_MAX_DRIVES_AMOUNT*3,#FF .Size: EQU $-DEVICE ; Логический номер раздела. ;Номер группы = логический номер раздела HDD из DEVICE LOGDRV: BLOCK 16*LD_DSK,0 .Size: EQU $-LOGDRV ;+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 ; DB RAM_DRIVE_ID, RAM_DRIVE_NUMBER 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 ;=====================================================================[] ; ; */