;[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 ; SCF RET 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' /////////////////////////// [ DRIVE TABLES ] \\\\\\\\\\\\\\\\\\\\\\\\\\\; ; ;------------------------[shared-drv.asm table]------------------------; DEVICE EQU $ .TBL_Entry EQU 3 .Size EQU DSS_MAX_DRIVES_AMOUNT * .TBL_Entry .End EQU DEVICE.Size + 1 ; для стоп-байта #FF ;----------------------------------------------------------------------; ; ; ;-------------------------[ IDE-DRV.ASM table]-------------------------; ;+00 BYTE MASTER/SLAVE PHISICAL DRIVE NUMBER #80/#81/... ;+01 LONG SECTOR OFFSET ;+05 LONG SIZE IN SECTORS ;+09 FREE ;+15 LOGDRV EQU DEVICE + DEVICE.End .TBL_Entry EQU 16 .Size EQU DSS_MAX_DRIVES_AMOUNT * .TBL_Entry ; ВХОД: L - логический номер в таблице ; ВЫХОД: IY - начало записи ; ПОРТИТ: HL, IY. HL<-->DE ; MACRO LOGDRV_ENTRY_FIND tbl_addr ; LD H,0 ; ADD HL,HL ; ADD HL,HL ; ADD HL,HL ; ADD HL,HL ; ;LD B,H ; ;LD C,L ; EX DE,HL ; LD IY,tbl_addr ; ADD IY,DE ; ENDM ;----------------------------------------------------------------------; ; ; ;-----------------------[ram_disk-drv.asm table]-----------------------; ; ТАБЛИЦА СООТВЕТСТВИЯ МЕЖДУ ФИЗИЧЕСКИМ НОМЕРОМ РАМДИСКА И ЕГО RAM-DISK ID ; Log Number: DB RAM_Drive_Log_Number, RAM_Drive_ID ;(BIOS 0-15), (Block ID for BIOS) RAMDTBL EQU LOGDRV + LOGDRV.Size .TBL_Entry EQU 2 .Size EQU .TBL_Entry * MAX_RAMDRIVES ; RAMDTBL: DUP MAX_RAMDRIVES * RAMDTBL.TBL_Entry ; DB #FF ; EDUP ; .Size EQU $-RAMDTBL ;----------------------------------------------------------------------; ; ////////////////////////////////////////////////////////////////////////; ///////////////////////// [ DRIVE TABLES COPY] \\\\\\\\\\\\\\\\\\\\\\\\\; MODULE OLD_TABLES ; ;------------------------[shared-drv.asm table]------------------------; DEVICE EQU @RAMDTBL + @RAMDTBL.Size .TBL_Entry EQU @DEVICE.TBL_Entry .Size: EQU @DEVICE.Size .End EQU @DEVICE.End ;----------------------------------------------------------------------; ; ; ;-------------------------[ IDE-DRV.ASM table]-------------------------; ;+00 BYTE MASTER/SLAVE PHISICAL DRIVE NUMBER #80/#81/... ;+01 LONG SECTOR OFFSET ;+05 LONG SIZE IN SECTORS ;+09 FREE ;+15 LOGDRV EQU DEVICE + DEVICE.End .TBL_Entry EQU @LOGDRV.TBL_Entry .Size EQU @LOGDRV.Size ;----------------------------------------------------------------------; ; ; ;-----------------------[ram_disk-drv.asm table]-----------------------; ; ТАБЛИЦА СООТВЕТСТВИЯ МЕЖДУ ФИЗИЧЕСКИМ НОМЕРОМ РАМДИСКА И ЕГО RAM-DISK ID ; Log Number: DB RAM_Drive_Log_Number, RAM_Drive_ID ;(BIOS 0-15), (Block ID for BIOS) RAMDTBL EQU LOGDRV + LOGDRV.Size .TBL_Entry EQU @RAMDTBL.TBL_Entry .Size EQU @RAMDTBL.Size ; RAMDTBL: DUP MAX_RAMDRIVES * RAMDTBL.TBL_Entry ; DB #FF ; EDUP ; .Size EQU $-RAMDTBL ;----------------------------------------------------------------------; ; ENDMODULE ////////////////////////////////////////////////////////////////////////; DISPLAY "DEVICE start: ", /H, DEVICE DISPLAY "Old DEVICE start: ", /H, OLD_TABLES.DEVICE DISPLAY "LOGDRV start: ", /H, LOGDRV DISPLAY "Old LOGDRV start: ", /H, OLD_TABLES.LOGDRV DISPLAY "RAMDTBL start: ", /H, RAMDTBL DISPLAY "Old RAMDTBL start: ", /H, OLD_TABLES.RAMDTBL ; ;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]