⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _vflat.asm

📁 BIOS emulator and interface to Realmode X86 Emulator Library Can emulate a PCI Graphic Controller V
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;****************************************************************************;*;*					SciTech OS Portability Manager Library;*;*  ========================================================================;*;*    The contents of this file are subject to the SciTech MGL Public;*    License Version 1.0 (the "License"); you may not use this file;*    except in compliance with the License. You may obtain a copy of;*    the License at http://www.scitechsoft.com/mgl-license.txt;*;*    Software distributed under the License is distributed on an;*    "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or;*    implied. See the License for the specific language governing;*    rights and limitations under the License.;*;*    The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.;*;*    The Initial Developer of the Original Code is SciTech Software, Inc.;*    All Rights Reserved.;*;*  ========================================================================;*;* 			  Based on original code Copyright 1994 Otto Chrons;*;* Language:	80386 Assembler, TASM 4.0 or later;* Environment:	IBM PC 32 bit protected mode;*;* Description:	Low level page fault handler for virtual linear framebuffers.;*;****************************************************************************		IDEAL		JUMPSinclude "scitech.mac"			; Memory model macrosheader      _vflat              ; Set up memory modelVFLAT_START		EQU 0F0000000hVFLAT_END		EQU 0F03FFFFFhPAGE_PRESENT 	EQU 1PAGE_NOTPRESENT EQU 0PAGE_READ 		EQU 0PAGE_WRITE		EQU 2ifdef	DOS4GW;----------------------------------------------------------------------------; DOS4G/W flat linear framebuffer emulation.;----------------------------------------------------------------------------begdataseg  _vflat; Near pointers to the page directory base and our page tables. All of; this memory is always located in the first Mb of DOS memory.PDBR            dd 	0            	; Page directory base register (CR3)accessPageAddr  dd 	0accessPageTable dd 	0; CauseWay page directory & 1st page table linear addresses.CauseWayDIRLinear dd 0CauseWay1stLinear dd 0; Place to store a copy of the original Page Table Directory before we; intialised our virtual buffer code.pageDirectory:	resd 1024   		; Saved page table directoryValidCS			dw	0				; Valid CS for page faultsRing0CS			dw	0				; Our ring 0 code selectorLastPage		dd	0				; Last page we mapped inBankFuncBuf:	resb 101 			; Place to store bank switch codeBankFuncPtr		dd	offset BankFuncBufINT14Gate:INT14Offset     dd      0  			; eip of original vectorINT14Selector   dw      0			; cs of original vector		cextern	_PM_savedDS,USHORT		cextern	VF_haveCauseWay,BOOLenddataseg  _vflatbegcodeseg  _vflat              ; Start of code segment		cextern	VF_malloc,FPTR;----------------------------------------------------------------------------; PF_handler64k - Page fault handler for 64k banks;----------------------------------------------------------------------------; The handler below is a 32 bit ring 0 page fault handler.  It receives; control immediately after any page fault or after an IRQ6 (hardware; interrupt). This provides the fastest possible handling of page faults; since it jump directly here.  If this is a page fault, the number; immediately on the stack will be an error code, at offset 4 will be; the eip of the faulting instruction, at offset 8 will be the cs of the; faulting instruction.  If it is a hardware interrupt, it will not have; the error code and the eflags will be at offset 8.;----------------------------------------------------------------------------cprocfar	PF_handler64k; Check if this is a processor exeception or a page fault		push	eax		mov		ax,[cs:ValidCS]		; Use CS override to access data		cmp		[ss:esp+12],ax		; Is this a page fault?		jne 	@@ToOldHandler		; Nope, jump to the previous handler; Get address of page fault and check if within our handlers range		mov     eax,cr2             ; EBX has page fault linear address		cmp     eax,VFLAT_START		; Is the fault less than ours?		jb 		@@ToOldHandler		; Yep, go to previous handler		cmp     eax,VFLAT_END		; Is the fault more than ours?		jae		@@ToOldHandler		; Yep, go to previous handler; This is our page fault, so we need to handle it		pushad		push	ds		push    es		mov		ebx,eax				; EBX := page fault address		and		ebx,invert 0FFFFh	; Mask to 64k bank boundary		mov		ds,[cs:_PM_savedDS]; Load segment registers		mov     es,[cs:_PM_savedDS]; Map in the page table for our virtual framebuffer area for modification		mov     edi,[PDBR]      	; EDI points to page directory		mov     edx,ebx            	; EDX = linear address		shr     edx,22              ; EDX = offset to page directory		mov     edx,[edx*4+edi]     ; EDX = physical page table address		mov     eax,edx		mov     edx,[accessPageTable]		or      eax,7		mov     [edx],eax		mov     eax,cr3		mov     cr3,eax				; Update page table cache; Mark all pages valid for the new page fault area		mov		esi,ebx				; ESI := linear address for page		shr     esi,10		and     esi,0FFFh           ; Offset into page table		add		esi,[accessPageAddr]ifdef	USE_NASM%assign off	0%rep 16		or    	[DWORD esi+off],0000000001h	; Enable pages%assign off	off+4%endrepelseoff = 0REPT	16		or    	[DWORD esi+off],0000000001h	; Enable pagesoff = off+4ENDMendif; Mark all pages invalid for the previously mapped area		xchg	esi,[LastPage]		; Save last page for next page fault		test	esi,esi		jz		@@DoneMapping		; Dont update if first time roundifdef	USE_NASM%assign off	0%rep 16		or    	[DWORD esi+off],0FFFFFFFEh	; Disable pages%assign off	off+4%endrepelseoff = 0REPT	16		and		[DWORD esi+off],0FFFFFFFEh	; Disable pagesoff = off+4ENDMendif@@DoneMapping:		mov     eax,cr3		mov     cr3,eax           	; Flush the TLB; Now program the new SuperVGA starting bank address		mov		eax,ebx				; EAX := page fault address		shr     eax,16		and		eax,0FFh			; Mask to 0-255		call    [BankFuncPtr]		; Call the bank switch function		pop     es		pop     ds		popad		pop		eax		add     esp,4             	; Pop the error code from stack		iretd                      	; Return to faulting instruction@@ToOldHandler:		pop		eaxifdef	USE_NASM		jmp far dword [cs:INT14Gate]; Chain to previous handlerelse		jmp		[FWORD cs:INT14Gate]; Chain to previous handlerendifcprocend;----------------------------------------------------------------------------; PF_handler4k  - Page fault handler for 4k banks;----------------------------------------------------------------------------; The handler below is a 32 bit ring 0 page fault handler.  It receives; control immediately after any page fault or after an IRQ6 (hardware; interrupt). This provides the fastest possible handling of page faults; since it jump directly here.  If this is a page fault, the number; immediately on the stack will be an error code, at offset 4 will be; the eip of the faulting instruction, at offset 8 will be the cs of the; faulting instruction.  If it is a hardware interrupt, it will not have; the error code and the eflags will be at offset 8.;----------------------------------------------------------------------------cprocfar	PF_handler4k; Fill in when we have tested all the 64Kb codeifdef	USE_NASM		jmp far dword [cs:INT14Gate]; Chain to previous handlerelse		jmp		[FWORD cs:INT14Gate]; Chain to previous handlerendifcprocend;----------------------------------------------------------------------------; void InstallFaultHandler(void *baseAddr,int bankSize);----------------------------------------------------------------------------; Installes the page fault handler directly int the interrupt descriptor; table for maximum performance. This of course requires ring 0 access,; but none of this stuff will run without ring 0!;----------------------------------------------------------------------------cprocstart	InstallFaultHandler		ARG     baseAddr:ULONG, bankSize:UINT		enter_c		mov		[DWORD LastPage],0	; No pages have been mapped		mov		ax,cs		mov		[ValidCS],ax		; Save CS value for page faults; Put address of our page fault handler into the IDT directly		sub		esp,6               ; Allocate space on stackifdef	USE_NASM		sidt 	[ss:esp]			; Store pointer to IDTelse		sidt	[FWORD ss:esp]		; Store pointer to IDTendif		pop     ax               	; add esp,2		pop     eax                 ; Absolute address of IDT		add     eax,14*8          	; Point to Int #14; Note that Interrupt gates do not have the high and low word of the; offset in adjacent words in memory, there are 4 bytes separating them.		mov     ecx,[eax]   		; Get cs and low 16 bits of offset		mov     edx,[eax+6]         ; Get high 16 bits of offset in dx		shl     edx,16		mov     dx,cx             	; edx has offset		mov     [INT14Offset],edx	; Save offset		shr     ecx,16		mov     [INT14Selector],cx	; Save original cs		mov     [eax+2],cs          ; Install new cs		mov     edx,offset PF_handler64k		cmp		[UINT bankSize],4		jne		@@1		mov		edx,offset PF_handler4k@@1:	mov     [eax],dx          	; Install low word of offset		shr     edx,16		mov     [eax+6],dx          ; Install high word of offset		leave_c		retcprocend;----------------------------------------------------------------------------; void RemoveFaultHandler(void);----------------------------------------------------------------------------; Closes down the virtual framebuffer services and restores the previous; page fault handler.;----------------------------------------------------------------------------cprocstart	RemoveFaultHandler		enter_c; Remove page fault handler from IDT		sub		esp,6               ; Allocate space on stackifdef	USE_NASM		sidt 	[ss:esp]			; Store pointer to IDTelse		sidt	[FWORD ss:esp]		; Store pointer to IDTendif		pop     ax               	; add esp,2		pop     eax                 ; Absolute address of IDT		add     eax,14*8          	; Point to Int #14		mov     cx,[INT14Selector]		mov     [eax+2],cx          ; Restore original CS		mov     edx,[INT14Offset]		mov     [eax],dx          	; Install low word of offset		shr     edx,16		mov     [eax+6],dx          ; Install high word of offset		leave_c		retcprocend;----------------------------------------------------------------------------; void InstallBankFunc(int codeLen,void *bankFunc);----------------------------------------------------------------------------; Installs the bank switch function by relocating it into our data segment; and making it into a callable function. We do it this way to make the; code identical to the way that the VflatD devices work under Windows.;----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -