home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
caway349.zip
/
MISC
/
LINEAR.ZIP
/
PAGING.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-10-27
|
3KB
|
122 lines
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <string.h>
#include "paging.h"
typedef struct
{
unsigned long Present : 1;
unsigned long ReadWrite : 1;
unsigned long UserSystem : 1;
unsigned long __Filler1__ : 2;
unsigned long Accessed : 1;
unsigned long Dirty : 1;
unsigned long __Filler2__ : 2;
unsigned long User : 3;
unsigned long Addr : 20;
}
PAGE_DESCRIPTOR;
const PAGE_DESCRIPTOR NullPage={0,1,1,0,0,0,0,0,0};
const PAGE_DESCRIPTOR * PageTable=(PAGE_DESCRIPTOR *)0xFFC00000LU;
#define PAGE_TABLE(Addr) PageTable+((unsigned long)(Addr) >> 12)
#define ENABLE_PAGE(Page) Page.Present=1
#define DISABLE_PAGE(Page) Page.Present=0
#define PHYSICAL_ADDRESS 0x80000000
#define PAGE_ADDRESS(Page,Ptr) {\
(Page)=NullPage;\
(Page).Addr=((unsigned long)(Ptr)) >> 12; \
}
extern int EnableLinearVideo(void);
extern void CloseLinearVideo(void);
extern unsigned long LinearVideoAddr;
extern unsigned long LinearVideoEnd;
extern unsigned long CR2AddrSEL;
extern unsigned long CR2AddrOFF;
void * GetLinearVideo(int VideoSize)
{
void * Ptr=NULL;
char far * Int01Ptr;
union REGS Regs;
int i,j;
PAGE_DESCRIPTOR * PagePtr;
if (VideoSize<1)
return(Ptr);
// Search CR2 image into the extender
Regs.w.ax=0x202;
Regs.h.bl=0x01;
int386(0x31,&Regs,&Regs);
if (Regs.w.cflag)
return(Ptr);
Regs.x.ecx&=0xffff;
Int01Ptr=MK_FP(Regs.x.ecx,Regs.x.edx);
i=0;
while(!(Int01Ptr[i+0]=='C' &&
Int01Ptr[i+1]=='a' &&
Int01Ptr[i+2]=='u' &&
Int01Ptr[i+3]=='s' &&
Int01Ptr[i+4]=='e' &&
Int01Ptr[i+5]=='W' &&
Int01Ptr[i+6]=='a' &&
Int01Ptr[i+7]=='y') && i<4096)
i++;
// Not found
if (i==4096)
return(Ptr);
CR2AddrSEL=Regs.x.ecx;
CR2AddrOFF=(unsigned long)Regs.x.edx+(unsigned long)i-10;
// Call asm exception init.
if (EnableLinearVideo())
return(Ptr);
// Allocate a dummy physical mapping for having some page descriptors.
// the physical address (0x80000000) is not important.
LinearVideoAddr=0;
Regs.w.ax=0x0800;
Regs.w.bx=PHYSICAL_ADDRESS >> 16;
Regs.w.cx=PHYSICAL_ADDRESS & 0xffff;
Regs.w.si=VideoSize << 4;
Regs.w.di=0;
int386(0x31,&Regs,&Regs);
if (!Regs.w.cflag)
{
Ptr=(void *)(((int)Regs.w.bx << 16)+(int)Regs.w.cx);
LinearVideoAddr=(unsigned long)Ptr;
LinearVideoEnd=(VideoSize << 20)+LinearVideoAddr-1;
PagePtr=PAGE_TABLE(Ptr);
// Map each 16 pages batch at 0xa0000 linear addr.
// Set all as 'not present'
for(i=0;i<VideoSize << 8;i+=16)
for(j=0;j<16;j++)
PAGE_ADDRESS(PagePtr[i+j],0xa0000+4096*j);
}
else
CloseLinearVideo();
return(Ptr);
}