diff options
Diffstat (limited to 'board/MAI/bios_emulator/scitech/src/pm/dos/_vflat.asm')
-rw-r--r-- | board/MAI/bios_emulator/scitech/src/pm/dos/_vflat.asm | 652 |
1 files changed, 0 insertions, 652 deletions
diff --git a/board/MAI/bios_emulator/scitech/src/pm/dos/_vflat.asm b/board/MAI/bios_emulator/scitech/src/pm/dos/_vflat.asm deleted file mode 100644 index 34985a9..0000000 --- a/board/MAI/bios_emulator/scitech/src/pm/dos/_vflat.asm +++ /dev/null @@ -1,652 +0,0 @@ -;**************************************************************************** -;* -;* 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 - JUMPS - -include "scitech.mac" ; Memory model macros - -header _vflat ; Set up memory model - -VFLAT_START EQU 0F0000000h -VFLAT_END EQU 0F03FFFFFh -PAGE_PRESENT EQU 1 -PAGE_NOTPRESENT EQU 0 -PAGE_READ EQU 0 -PAGE_WRITE EQU 2 - -ifdef 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 0 -accessPageTable dd 0 - -; CauseWay page directory & 1st page table linear addresses. - -CauseWayDIRLinear dd 0 -CauseWay1stLinear 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 directory - -ValidCS dw 0 ; Valid CS for page faults -Ring0CS dw 0 ; Our ring 0 code selector -LastPage dd 0 ; Last page we mapped in -BankFuncBuf: resb 101 ; Place to store bank switch code -BankFuncPtr dd offset BankFuncBuf - -INT14Gate: -INT14Offset dd 0 ; eip of original vector -INT14Selector dw 0 ; cs of original vector - - cextern _PM_savedDS,USHORT - cextern VF_haveCauseWay,BOOL - -enddataseg _vflat - -begcodeseg _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 -%endrep -else -off = 0 -REPT 16 - or [DWORD esi+off],0000000001h ; Enable pages -off = off+4 -ENDM -endif - -; 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 round -ifdef USE_NASM -%assign off 0 -%rep 16 - or [DWORD esi+off],0FFFFFFFEh ; Disable pages -%assign off off+4 -%endrep -else -off = 0 -REPT 16 - and [DWORD esi+off],0FFFFFFFEh ; Disable pages -off = off+4 -ENDM -endif - -@@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 eax -ifdef USE_NASM - jmp far dword [cs:INT14Gate]; Chain to previous handler -else - jmp [FWORD cs:INT14Gate]; Chain to previous handler -endif - -cprocend - -;---------------------------------------------------------------------------- -; 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 code - -ifdef USE_NASM - jmp far dword [cs:INT14Gate]; Chain to previous handler -else - jmp [FWORD cs:INT14Gate]; Chain to previous handler -endif - -cprocend - -;---------------------------------------------------------------------------- -; 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 stack -ifdef USE_NASM - sidt [ss:esp] ; Store pointer to IDT -else - sidt [FWORD ss:esp] ; Store pointer to IDT -endif - 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 - ret - -cprocend - -;---------------------------------------------------------------------------- -; 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 stack -ifdef USE_NASM - sidt [ss:esp] ; Store pointer to IDT -else - sidt [FWORD ss:esp] ; Store pointer to IDT -endif - - 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 - ret - -cprocend - -;---------------------------------------------------------------------------- -; 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. -;---------------------------------------------------------------------------- -cprocstart InstallBankFunc - - ARG codeLen:UINT, bankFunc:DPTR - - enter_c - - mov esi,[bankFunc] ; Copy the code into buffer - mov edi,offset BankFuncBuf - mov ecx,[codeLen] - rep movsb - mov [BYTE edi],0C3h ; Terminate the function with a near ret - - leave_c - ret - -cprocend - -;---------------------------------------------------------------------------- -; int InitPaging(void) -;---------------------------------------------------------------------------- -; Initializes paging system. If paging is not enabled, builds a page table -; directory and page tables for physical memory -; -; Exit: 0 - Successful -; -1 - Couldn't initialize paging mechanism -;---------------------------------------------------------------------------- -cprocstart InitPaging - - push ebx - push ecx - push edx - push esi - push edi - -; Are we running under CauseWay? - - mov ax,0FFF9h - int 31h - jc @@NotCauseway - cmp ecx,"CAUS" - jnz @@NotCauseway - cmp edx,"EWAY" - jnz @@NotCauseway - - mov [BOOL VF_haveCauseWay],1 - mov [CauseWayDIRLinear],esi - mov [CauseWay1stLinear],edi - -; Check for DPMI - - mov ax,0ff00h - push es - int 31h - pop es - shr edi,2 - and edi,3 - cmp edi,2 - jz @@ErrExit ; Not supported under DPMI - - mov eax,[CauseWayDIRLinear] - jmp @@CopyCR3 - -@@NotCauseway: - mov ax,cs - test ax,3 ; Which ring are we running - jnz @@ErrExit ; Needs zero ring to access - ; page tables (CR3) - mov eax,cr0 ; Load CR0 - test eax,80000000h ; Is paging enabled? - jz @@ErrExit ; No, we must have paging! - - mov eax,cr3 ; Load directory address - and eax,0FFFFF000h - -@@CopyCR3: - mov [PDBR],eax ; Save it - mov esi,eax - mov edi,offset pageDirectory - mov ecx,1024 - cld - rep movsd ; Copy the original page table directory - cmp [DWORD accessPageAddr],0; Check if we have allocated page - jne @@HaveRealMem ; table already (we cant free it) - - mov eax,0100h ; DPMI DOS allocate - mov ebx,8192/16 - int 31h ; Allocate 8192 bytes - and eax,0FFFFh - shl eax,4 ; EAX points to newly allocated memory - add eax,4095 - and eax,0FFFFF000h ; Page align - mov [accessPageAddr],eax - -@@HaveRealMem: - mov eax,[accessPageAddr] ; EAX -> page table in 1st Mb - shr eax,12 - and eax,3FFh ; Page table offset - shl eax,2 - cmp [BOOL VF_haveCauseWay],0 - jz @@NotCW0 - mov ebx,[CauseWay1stLinear] - jmp @@Put1st - -@@NotCW0: - mov ebx,[PDBR] - mov ebx,[ebx] - and ebx,0FFFFF000h ; Page table for 1st megabyte - -@@Put1st: - add eax,ebx - mov [accessPageTable],eax - sub eax,eax ; No error - jmp @@Exit - -@@ErrExit: - mov eax,-1 - -@@Exit: pop edi - pop esi - pop edx - pop ecx - pop ebx - ret - -cprocend - -;---------------------------------------------------------------------------- -; void ClosePaging(void) -;---------------------------------------------------------------------------- -; Closes the paging system -;---------------------------------------------------------------------------- -cprocstart ClosePaging - - push eax - push ecx - push edx - push esi - push edi - - mov eax,[accessPageAddr] - call AccessPage ; Restore AccessPage mapping - mov edi,[PDBR] - mov esi,offset pageDirectory - mov ecx,1024 - cld - rep movsd ; Restore the original page table directory - -@@Exit: pop edi - pop esi - pop edx - pop ecx - pop eax - ret - -cprocend - -;---------------------------------------------------------------------------- -; long AccessPage(long phys) -;---------------------------------------------------------------------------- -; Maps a known page to given physical memory -; Entry: EAX - Physical memory -; Exit: EAX - Linear memory address of mapped phys mem -;---------------------------------------------------------------------------- -cprocstatic AccessPage - - push edx - mov edx,[accessPageTable] - or eax,7 - mov [edx],eax - mov eax,cr3 - mov cr3,eax ; Update page table cache - mov eax,[accessPageAddr] - pop edx - ret - -cprocend - -;---------------------------------------------------------------------------- -; long GetPhysicalAddress(long linear) -;---------------------------------------------------------------------------- -; Returns the physical address of linear address -; Entry: EAX - Linear address to convert -; Exit: EAX - Physical address -;---------------------------------------------------------------------------- -cprocstatic GetPhysicalAddress - - push ebx - push edx - mov edx,eax - shr edx,22 ; EDX is the directory offset - mov ebx,[PDBR] - mov edx,[edx*4+ebx] ; Load page table address - push eax - mov eax,edx - call AccessPage ; Access the page table - mov edx,eax - pop eax - shr eax,12 - and eax,03FFh ; EAX offset into page table - mov eax,[edx+eax*4] ; Load physical address - and eax,0FFFFF000h - pop edx - pop ebx - ret - -cprocend - -;---------------------------------------------------------------------------- -; void CreatePageTable(long pageDEntry) -;---------------------------------------------------------------------------- -; Creates a page table for specific address (4MB) -; Entry: EAX - Page directory entry (top 10-bits of address) -;---------------------------------------------------------------------------- -cprocstatic CreatePageTable - - push ebx - push ecx - push edx - push edi - mov ebx,eax ; Save address - mov eax,8192 - push eax - call VF_malloc ; Allocate page table directory - add esp,4 - add eax,0FFFh - and eax,0FFFFF000h ; Page align (4KB) - mov edi,eax ; Save page table linear address - sub eax,eax ; Fill with zero - mov ecx,1024 - cld - rep stosd ; Clear page table - sub edi,4096 - mov eax,edi - call GetPhysicalAddress - mov edx,[PDBR] - or eax,7 ; Present/write/user bit - mov [edx+ebx*4],eax ; Save physical address into page directory - mov eax,cr3 - mov cr3,eax ; Update page table cache - pop edi - pop edx - pop ecx - pop ebx - ret - -cprocend - -;---------------------------------------------------------------------------- -; void MapPhysical2Linear(ulong pAddr, ulong lAddr, int pages, int flags); -;---------------------------------------------------------------------------- -; Maps physical memory into linear memory -; Entry: pAddr - Physical address -; lAddr - Linear address -; pages - Number of 4K pages to map -; flags - Page flags -; bit 0 = present -; bit 1 = Read(0)/Write(1) -;---------------------------------------------------------------------------- -cprocstart MapPhysical2Linear - - ARG pAddr:ULONG, lAddr:ULONG, pages:UINT, pflags:UINT - - enter_c - - and [ULONG pAddr],0FFFFF000h; Page boundary - and [ULONG lAddr],0FFFFF000h; Page boundary - mov ecx,[pflags] - and ecx,11b ; Just two bits - or ecx,100b ; Supervisor bit - mov [pflags],ecx - - mov edx,[lAddr] - shr edx,22 ; EDX = Directory - mov esi,[PDBR] - mov edi,[pages] ; EDI page count - mov ebx,[lAddr] - -@@CreateLoop: - mov ecx,[esi+edx*4] ; Load page table address - test ecx,1 ; Is it present? - jnz @@TableOK - mov eax,edx - call CreatePageTable ; Create a page table -@@TableOK: - mov eax,ebx - shr eax,12 - and eax,3FFh - sub eax,1024 - neg eax ; EAX = page count in this table - inc edx ; Next table - mov ebx,0 ; Next time we'll map 1K pages - sub edi,eax ; Subtract mapped pages from page count - jns @@CreateLoop ; Create more tables if necessary - - mov ecx,[pages] ; ECX = Page count - mov esi,[lAddr] - shr esi,12 ; Offset part isn't needed - mov edi,[pAddr] -@@MappingLoop: - mov eax,esi - shr eax,10 ; EAX = offset to page directory - mov ebx,[PDBR] - mov eax,[eax*4+ebx] ; EAX = page table address - call AccessPage - mov ebx,esi - and ebx,3FFh ; EBX = offset to page table - mov edx,edi - add edi,4096 ; Next physical address - inc esi ; Next linear page - or edx,[pflags] ; Update flags... - mov [eax+ebx*4],edx ; Store page table entry - loop @@MappingLoop - mov eax,cr3 - mov cr3,eax ; Update page table cache - - leave_c - ret - -cprocend - -endcodeseg _vflat - -endif - - END ; End of module |