Paging tables/functions changed somewhat
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1356
This commit is contained in:
parent
708eee4f86
commit
e712e7dc9c
2 changed files with 282 additions and 640 deletions
|
@ -23,169 +23,165 @@
|
|||
#include "dosbox.h"
|
||||
#include "mem.h"
|
||||
#include "paging.h"
|
||||
#include "../hardware/vga.h"
|
||||
|
||||
#include "regs.h"
|
||||
|
||||
#define LINK_TOTAL (64*1024)
|
||||
|
||||
static PageLink link_list[LINK_TOTAL];
|
||||
struct PagingBlock paging;
|
||||
PagingBlock paging;
|
||||
static Bit32u mapfirstmb[LINK_START];
|
||||
|
||||
class PageDirChange : public PageChange {
|
||||
public:
|
||||
PageDirChange(PageDirectory * mydir) { dir=mydir;}
|
||||
void Changed(PageLink * link,Bitu start,Bitu end) {
|
||||
start>>=2;end>>=2;
|
||||
for (;start<=end;start++) {
|
||||
dir->InvalidateTable(start);
|
||||
}
|
||||
}
|
||||
private:
|
||||
PageDirectory * dir;
|
||||
Bitu PageHandler::readb(PhysPt addr) {
|
||||
E_Exit("No byte handler for read from %d",addr);
|
||||
return 0;
|
||||
}
|
||||
Bitu PageHandler::readw(PhysPt addr) {
|
||||
return
|
||||
(readb(addr+0) << 0) |
|
||||
(readb(addr+1) << 8);
|
||||
}
|
||||
Bitu PageHandler::readd(PhysPt addr) {
|
||||
return
|
||||
(readb(addr+0) << 0) |
|
||||
(readb(addr+1) << 8) |
|
||||
(readb(addr+2) << 16) |
|
||||
(readb(addr+3) << 24);
|
||||
}
|
||||
|
||||
void PageHandler::writeb(PhysPt addr,Bitu val) {
|
||||
E_Exit("No byte handler for write to %d",addr);
|
||||
};
|
||||
|
||||
class PageTableChange : public PageChange {
|
||||
void PageHandler::writew(PhysPt addr,Bitu val) {
|
||||
writeb(addr+0,(Bit8u) (val >> 0));
|
||||
writeb(addr+1,(Bit8u) (val >> 8));
|
||||
}
|
||||
void PageHandler::writed(PhysPt addr,Bitu val) {
|
||||
writeb(addr+0,(Bit8u) (val >> 0));
|
||||
writeb(addr+1,(Bit8u) (val >> 8));
|
||||
writeb(addr+2,(Bit8u) (val >> 16));
|
||||
writeb(addr+3,(Bit8u) (val >> 24));
|
||||
};
|
||||
|
||||
HostPt PageHandler::GetHostPt(Bitu phys_page) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
class InitPageHandler : public PageHandler {
|
||||
public:
|
||||
PageTableChange(PageDirectory * mydir) { dir=mydir;}
|
||||
void Changed(PageLink * link,Bitu start,Bitu end) {
|
||||
start>>=2;end>>=2;
|
||||
for (;start<=end;start++) {
|
||||
dir->InvalidateLink(link->data.table,start);
|
||||
}
|
||||
InitPageHandler() {flags=0;}
|
||||
void AddPageLink(Bitu lin_page, Bitu phys_page) {
|
||||
assert(0);
|
||||
}
|
||||
Bitu readb(PhysPt addr) {
|
||||
InitPage(addr);
|
||||
return mem_readb(addr);
|
||||
}
|
||||
Bitu readw(PhysPt addr) {
|
||||
InitPage(addr);
|
||||
return mem_readw(addr);
|
||||
}
|
||||
Bitu readd(PhysPt addr) {
|
||||
InitPage(addr);
|
||||
return mem_readd(addr);
|
||||
}
|
||||
void writeb(PhysPt addr,Bitu val) {
|
||||
InitPage(addr);
|
||||
mem_writeb(addr,val);
|
||||
}
|
||||
void writew(PhysPt addr,Bitu val) {
|
||||
InitPage(addr);
|
||||
mem_writew(addr,val);
|
||||
}
|
||||
void writed(PhysPt addr,Bitu val) {
|
||||
InitPage(addr);
|
||||
mem_writed(addr,val);
|
||||
}
|
||||
void InitPage(Bitu addr) {
|
||||
Bitu lin_page=addr >> 12;
|
||||
Bitu phys_page;
|
||||
if (paging.enabled) {
|
||||
E_Exit("No paging support");
|
||||
} else {
|
||||
if (lin_page<LINK_START) phys_page=mapfirstmb[lin_page];
|
||||
else phys_page=lin_page;
|
||||
}
|
||||
PAGING_LinkPage(lin_page,phys_page);
|
||||
}
|
||||
private:
|
||||
PageDirectory * dir;
|
||||
};
|
||||
|
||||
|
||||
|
||||
PageDirectory::PageDirectory() {
|
||||
entry_init.data.dir=this;
|
||||
entry_init.type=ENTRY_INIT;
|
||||
link_init.read=0;
|
||||
link_init.write=0;
|
||||
link_init.entry=&entry_init;
|
||||
table_change = new PageTableChange(this);
|
||||
dir_change = new PageDirChange(this);
|
||||
}
|
||||
PageDirectory::~PageDirectory() {
|
||||
delete table_change;
|
||||
delete dir_change;
|
||||
}
|
||||
void PageDirectory::ClearDirectory(void) {
|
||||
Bitu i;
|
||||
for (i=0;i<1024*1024;i++) links[i]=&link_init;
|
||||
for (i=0;i<1024;i++) {
|
||||
tables[i]=0;
|
||||
}
|
||||
}
|
||||
void PageDirectory::SetBase(PhysPt page) {
|
||||
base_page=page;
|
||||
ClearDirectory();
|
||||
/* Setup handler for PageDirectory changes */
|
||||
link_dir=MEM_LinkPage(base_page,0);
|
||||
if (!link_dir) E_Exit("PAGING:Directory setup on illegal address");
|
||||
link_dir->data.dir=this;
|
||||
link_dir->change=dir_change;
|
||||
MEM_CheckLinks(link_dir->entry);
|
||||
}
|
||||
void PageDirectory::LinkPage(Bitu lin_page,Bitu phys_page) {
|
||||
if (links[lin_page] != &link_init) MEM_UnlinkPage(links[lin_page]);
|
||||
PageLink * link=MEM_LinkPage(phys_page,lin_page*4096);
|
||||
if (link) links[lin_page]=link;
|
||||
else links[lin_page]=&link_init;
|
||||
}
|
||||
|
||||
bool PageDirectory::InitPage(Bitu lin_address) {
|
||||
Bitu lin_page=lin_address >> 12;
|
||||
Bitu table=lin_page >> 10;
|
||||
Bitu index=lin_page & 0x3ff;
|
||||
/* Check if there already is table linked */
|
||||
if (!tables[table]) {
|
||||
X86PageEntry table_entry;
|
||||
table_entry.load=phys_page_readd(base_page,0);
|
||||
if (!table_entry.block.p) {
|
||||
LOG(LOG_PAGING,LOG_ERROR)("NP TABLE");
|
||||
return false;
|
||||
}
|
||||
PageLink * link=MEM_LinkPage(table_entry.block.base,table_entry.block.base);
|
||||
if (!link) return false;
|
||||
link->data.table=table;
|
||||
link->change=table_change;
|
||||
MEM_CheckLinks(link->entry);
|
||||
tables[table]=link;
|
||||
}
|
||||
X86PageEntry entry;
|
||||
entry.load=phys_page_readd(tables[table]->lin_base,index);
|
||||
if (!entry.block.p) {
|
||||
LOG(LOG_PAGING,LOG_ERROR)("NP PAGE");
|
||||
return false;
|
||||
}
|
||||
PageLink * link=MEM_LinkPage(entry.block.base,lin_page*4096);
|
||||
if (!link) return false;
|
||||
links[lin_page]=link;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PageDirectory::InitPageLinear(Bitu lin_address) {
|
||||
Bitu phys_page=lin_address >> 12;
|
||||
PageLink * link=MEM_LinkPage(phys_page,phys_page*4096);
|
||||
if (link) {
|
||||
/* Set the page entry in our table */
|
||||
links[phys_page]=link;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PageDirectory::InvalidateTable(Bitu table) {
|
||||
if (tables[table]) {
|
||||
MEM_UnlinkPage(tables[table]);
|
||||
tables[table]=0;
|
||||
for (Bitu i=(table*1024);i<(table+1)*1024;i++) {
|
||||
if (links[i]!=&link_init) {
|
||||
MEM_UnlinkPage(links[i]);
|
||||
links[i]=&link_init;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PageDirectory::InvalidateLink(Bitu table,Bitu index) {
|
||||
Bitu i=(table*1024)+index;
|
||||
if (links[i]!=&link_init) {
|
||||
MEM_UnlinkPage(links[i]);
|
||||
links[i]=&link_init;
|
||||
}
|
||||
}
|
||||
static InitPageHandler init_page_handler;
|
||||
|
||||
|
||||
Bitu PAGING_GetDirBase(void) {
|
||||
return paging.cr3;
|
||||
}
|
||||
|
||||
void PAGING_ClearTLB(void) {
|
||||
LOG(LOG_PAGING,LOG_NORMAL)("Clearing TLB");
|
||||
Bitu i;
|
||||
for (i=0;i<LINK_START;i++) {
|
||||
paging.tlb.read[i]=0;
|
||||
paging.tlb.write[i]=0;
|
||||
paging.tlb.handler[i]=&init_page_handler;
|
||||
}
|
||||
MEM_UnlinkPages();
|
||||
}
|
||||
|
||||
void PAGING_InitTLB(void) {
|
||||
for (Bitu i=0;i<TLB_SIZE;i++) {
|
||||
paging.tlb.read[i]=0;
|
||||
paging.tlb.write[i]=0;
|
||||
paging.tlb.handler[i]=&init_page_handler;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void PAGING_ClearTLBEntries(Bitu pages,Bit32u * entries) {
|
||||
for (;pages>0;pages--) {
|
||||
Bitu page=*entries++;
|
||||
paging.tlb.read[page]=0;
|
||||
paging.tlb.write[page]=0;
|
||||
paging.tlb.handler[page]=&init_page_handler;
|
||||
}
|
||||
}
|
||||
|
||||
void PAGING_LinkPage(Bitu lin_page,Bitu phys_page) {
|
||||
|
||||
PageHandler * handler=MEM_GetPageHandler(phys_page);
|
||||
Bitu lin_base=lin_page << 12;
|
||||
|
||||
HostPt host_mem=handler->GetHostPt(phys_page);
|
||||
paging.tlb.phys_page[lin_page]=phys_page;
|
||||
if (handler->flags & PFLAG_READABLE) paging.tlb.read[lin_page]=host_mem-lin_base;
|
||||
else paging.tlb.read[lin_page]=0;
|
||||
if (handler->flags & PFLAG_WRITEABLE) paging.tlb.write[lin_page]=host_mem-lin_base;
|
||||
else paging.tlb.write[lin_page]=0;
|
||||
|
||||
handler->AddPageLink(lin_page,phys_page);
|
||||
paging.tlb.handler[lin_page]=handler;
|
||||
}
|
||||
|
||||
void PAGING_MapPage(Bitu lin_page,Bitu phys_page) {
|
||||
if (lin_page<LINK_START) {
|
||||
mapfirstmb[lin_page]=phys_page;
|
||||
paging.tlb.read[lin_page]=0;
|
||||
paging.tlb.write[lin_page]=0;
|
||||
paging.tlb.handler[lin_page]=&init_page_handler;
|
||||
} else {
|
||||
PAGING_LinkPage(lin_page,phys_page);
|
||||
}
|
||||
}
|
||||
|
||||
void PAGING_SetDirBase(Bitu cr3) {
|
||||
paging.cr3=cr3;
|
||||
Bitu base_page=cr3 >> 12;
|
||||
LOG(LOG_PAGING,LOG_NORMAL)("CR3:%X Base %X",cr3,base_page);
|
||||
|
||||
paging.base.page=cr3 >> 12;
|
||||
paging.base.addr=cr3 & ~4095;
|
||||
LOG(LOG_PAGING,LOG_NORMAL)("CR3:%X Base %X",cr3,paging.base.page);
|
||||
if (paging.enabled) {
|
||||
/* Check if we already have this one cached */
|
||||
PageDirectory * dir=paging.cache;
|
||||
while (dir) {
|
||||
if (dir->base_page==base_page) {
|
||||
paging.dir=dir;
|
||||
return;
|
||||
}
|
||||
dir=dir->next;
|
||||
}
|
||||
/* Couldn't find cached directory, make a new one */
|
||||
dir=new PageDirectory();
|
||||
dir->next=paging.cache;
|
||||
paging.cache=dir;
|
||||
dir->SetBase(base_page);
|
||||
paging.dir=dir;
|
||||
PAGING_ClearTLB();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,7 +191,6 @@ void PAGING_Enable(bool enabled) {
|
|||
paging.enabled=enabled;
|
||||
if (!enabled) {
|
||||
LOG(LOG_PAGING,LOG_NORMAL)("Disabled");
|
||||
paging.dir=MEM_DefaultDirectory();
|
||||
} else {
|
||||
LOG(LOG_PAGING,LOG_NORMAL)("Enabled");
|
||||
#if !(C_DEBUG)
|
||||
|
@ -203,51 +198,20 @@ void PAGING_Enable(bool enabled) {
|
|||
#endif
|
||||
PAGING_SetDirBase(paging.cr3);
|
||||
}
|
||||
PAGING_ClearTLB();
|
||||
}
|
||||
|
||||
bool PAGING_Enabled(void) {
|
||||
return paging.enabled;
|
||||
}
|
||||
|
||||
|
||||
void PAGING_FreePageLink(PageLink * link) {
|
||||
MEM_UnlinkPage(link);
|
||||
PAGING_AddFreePageLink(link);
|
||||
}
|
||||
|
||||
void PAGING_LinkPage(PageDirectory * dir,Bitu lin_page,Bitu phys_page) {
|
||||
PageLink * link=MEM_LinkPage(phys_page,lin_page*4096);
|
||||
/* Only replace if we can */
|
||||
if (link) {
|
||||
PAGING_FreePageLink(dir->links[lin_page]);
|
||||
dir->links[lin_page]=link;
|
||||
void PAGING_Init(Section * sec) {
|
||||
/* Setup default Page Directory, force it to update */
|
||||
paging.enabled=false;
|
||||
PAGING_InitTLB();
|
||||
Bitu i;
|
||||
for (i=0;i<LINK_START;i++) {
|
||||
mapfirstmb[i]=i;
|
||||
}
|
||||
}
|
||||
|
||||
void PAGING_AddFreePageLink(PageLink * link) {
|
||||
link->read=0;
|
||||
link->write=0;
|
||||
link->change=0;
|
||||
link->next=paging.free_link;
|
||||
link->entry=0;
|
||||
paging.free_link=link;
|
||||
}
|
||||
|
||||
PageLink * PAGING_GetFreePageLink(void) {
|
||||
PageLink * ret;
|
||||
if (paging.free_link) ret=paging.free_link;
|
||||
else E_Exit("PAGING:Ran out of PageEntries");
|
||||
paging.free_link=ret->next;
|
||||
ret->next=0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PAGING_Init(Section * sec) {
|
||||
Bitu i;
|
||||
/* Setup the free pages tables for fast page allocation */
|
||||
paging.cache=0;
|
||||
paging.free_link=0;
|
||||
for (i=0;i<LINK_TOTAL;i++) PAGING_AddFreePageLink(&link_list[i]);
|
||||
/* Setup default Page Directory, force it to update */
|
||||
paging.enabled=true;PAGING_Enable(false);
|
||||
}
|
|
@ -30,20 +30,26 @@
|
|||
|
||||
#define PAGES_IN_BLOCK ((1024*1024)/MEM_PAGE_SIZE)
|
||||
#define MAX_MEMORY 64
|
||||
#define MAX_PAGE_ENTRIES (MAX_MEMORY*1024*1024/4096)
|
||||
#define LFB_PAGES 512
|
||||
|
||||
static Bit8u controlport_data;
|
||||
static bool a20_enabled;
|
||||
#define MAX_LINKS ((MAX_MEMORY*1024/4)+4096) //Hopefully enough
|
||||
|
||||
struct AllocBlock {
|
||||
Bit8u data[PAGES_IN_BLOCK*4096];
|
||||
AllocBlock * next;
|
||||
};
|
||||
|
||||
struct LinkBlock {
|
||||
Bit8u used;
|
||||
Bit32u pages[MAX_LINKS];
|
||||
};
|
||||
|
||||
static struct MemoryBlock {
|
||||
Bitu pages;
|
||||
Bitu free_pages;
|
||||
PageEntry * entries;
|
||||
Bitu pages;
|
||||
PageHandler * * phandlers;
|
||||
HostPt * hostpts;
|
||||
MemHandle * mhandles;
|
||||
LinkBlock links;
|
||||
struct {
|
||||
Bitu pages;
|
||||
HostPt cur_page;
|
||||
|
@ -54,172 +60,94 @@ static struct MemoryBlock {
|
|||
Bitu end_page;
|
||||
Bitu pages;
|
||||
HostPt address;
|
||||
PageEntry entries[LFB_PAGES];
|
||||
} lfb;
|
||||
struct {
|
||||
HostPt ram_bases[128/4];
|
||||
HostPt map_base;
|
||||
VGA_RANGES range;
|
||||
} vga;
|
||||
PageDirectory dir;
|
||||
bool enabled;
|
||||
Bit8u controlport;
|
||||
} a20;
|
||||
} memory;
|
||||
|
||||
Bit8u ENTRY_readb(PageEntry * pentry,PhysPt address) {
|
||||
switch(pentry->type) {
|
||||
case ENTRY_VGA:
|
||||
return (*vga.config.readhandler)(pentry->data.vga_base+(address & 4095));
|
||||
case ENTRY_NA:
|
||||
if (pentry->data.dir->InitPageLinear(address)) return mem_readb(address);
|
||||
break;
|
||||
case ENTRY_INIT:
|
||||
if (pentry->data.dir->InitPage(address)) return mem_readb(address);
|
||||
break;
|
||||
class IllegalPageHandler : public PageHandler {
|
||||
public:
|
||||
void AddPageLink(Bitu lin_page, Bitu phys_page) {
|
||||
|
||||
default:
|
||||
LOG(LOG_PAGING,LOG_ERROR)("Entry read from %X with illegal type %d",address,pentry->type);
|
||||
}
|
||||
IllegalPageHandler() {
|
||||
flags=0;
|
||||
}
|
||||
};
|
||||
|
||||
class RAMPageHandler : public PageHandler {
|
||||
public:
|
||||
void AddPageLink(Bitu lin_page, Bitu phys_page) {
|
||||
/* Always clear links in first MB on TLB change */
|
||||
if (lin_page<LINK_START) return;
|
||||
if (memory.links.used<MAX_LINKS) {
|
||||
memory.links.pages[memory.links.used++]=lin_page;
|
||||
} else E_Exit("MEM:Ran out of page links");
|
||||
}
|
||||
RAMPageHandler() {
|
||||
flags=PFLAG_READABLE|PFLAG_WRITEABLE;
|
||||
}
|
||||
HostPt GetHostPt(Bitu phys_page) {
|
||||
if (!memory.hostpts[phys_page]) {
|
||||
memory.hostpts[phys_page]=MEM_GetBlockPage();
|
||||
}
|
||||
return memory.hostpts[phys_page];
|
||||
}
|
||||
};
|
||||
|
||||
class ROMPageHandler : public RAMPageHandler {
|
||||
public:
|
||||
ROMPageHandler() {
|
||||
flags=PFLAG_READABLE|PFLAG_HASROM;
|
||||
}
|
||||
};
|
||||
|
||||
class LFBPageHandler : public RAMPageHandler {
|
||||
public:
|
||||
LFBPageHandler() {
|
||||
flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE;
|
||||
}
|
||||
HostPt GetHostPt(Bitu phys_page) {
|
||||
return memory.lfb.address+(phys_page-memory.lfb.start_page)*4096;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static IllegalPageHandler illegal_page_handler;
|
||||
static RAMPageHandler ram_page_handler;
|
||||
static ROMPageHandler rom_page_handler;
|
||||
static LFBPageHandler lfb_page_handler;
|
||||
|
||||
void MEM_SetLFB(Bitu page,Bitu pages,HostPt pt) {
|
||||
memory.lfb.address=pt;
|
||||
memory.lfb.start_page=page;
|
||||
memory.lfb.end_page=page+pages;
|
||||
memory.lfb.pages=pages;
|
||||
PAGING_ClearTLB();
|
||||
}
|
||||
|
||||
PageHandler * MEM_GetPageHandler(Bitu phys_page) {
|
||||
if (phys_page<memory.pages) {
|
||||
return memory.phandlers[phys_page];
|
||||
} else if ((phys_page>=memory.lfb.start_page) && (phys_page<memory.lfb.end_page)) {
|
||||
return &lfb_page_handler;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Bit16u ENTRY_readw(PageEntry * pentry,PhysPt address) {
|
||||
switch(pentry->type) {
|
||||
case ENTRY_VGA:
|
||||
{
|
||||
VGA_ReadHandler * handler=vga.config.readhandler;
|
||||
address=pentry->data.vga_base + (address & 4095);
|
||||
return (*handler)(address) |
|
||||
((*handler)(address+1) << 8);
|
||||
}
|
||||
case ENTRY_NA:
|
||||
if (pentry->data.dir->InitPageLinear(address)) return mem_readw(address);
|
||||
break;
|
||||
case ENTRY_INIT:
|
||||
if (pentry->data.dir->InitPage(address)) return mem_readw(address);
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_PAGING,LOG_ERROR)("Entry read from %X with illegal type %d",address,pentry->type);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Bit32u ENTRY_readd(PageEntry * pentry,PhysPt address) {
|
||||
switch(pentry->type) {
|
||||
case ENTRY_VGA:
|
||||
{
|
||||
VGA_ReadHandler * handler=vga.config.readhandler;
|
||||
address=pentry->data.vga_base + (address & 4095);
|
||||
return (*handler)(address) |
|
||||
((*handler)(address+1) << 8) |
|
||||
((*handler)(address+2) << 16) |
|
||||
((*handler)(address+3) << 24);
|
||||
}
|
||||
case ENTRY_NA:
|
||||
if (pentry->data.dir->InitPageLinear(address)) return mem_readd(address);
|
||||
break;
|
||||
case ENTRY_INIT:
|
||||
if (pentry->data.dir->InitPage(address)) return mem_readd(address);
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_PAGING,LOG_ERROR)("Entry read from %X with illegal type %d",address,pentry->type);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ENTRY_writeb(PageEntry * pentry,PhysPt address,Bit8u val) {
|
||||
switch(pentry->type) {
|
||||
case ENTRY_VGA:
|
||||
(*vga.config.writehandler)(pentry->data.vga_base+(address&4095),val);
|
||||
break;
|
||||
case ENTRY_NA:
|
||||
if (pentry->data.dir->InitPageLinear(address)) mem_writeb(address,val);
|
||||
break;
|
||||
case ENTRY_INIT:
|
||||
if (pentry->data.dir->InitPage(address)) mem_writeb(address,val);
|
||||
break;
|
||||
case ENTRY_ROM:
|
||||
LOG(LOG_PAGING,LOG_WARN)("Write %X to ROM at %X",val,address);
|
||||
break;
|
||||
case ENTRY_CHANGES:
|
||||
writeb(pentry->data.mem+(address&4095),val);
|
||||
{
|
||||
Bitu start=address&4095;Bitu end=start;
|
||||
for (PageLink * link=pentry->links;link;link=link->next)
|
||||
if (link->change) link->change->Changed(link,start,end);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_PAGING,LOG_ERROR)("Entry write %X to %X with illegal type %d",val,address,pentry->type);
|
||||
void MEM_SetPageHandler(Bitu phys_page,Bitu pages,PageHandler * handler) {
|
||||
for (;pages>0;pages--) {
|
||||
memory.phandlers[phys_page]=handler;
|
||||
phys_page++;
|
||||
}
|
||||
}
|
||||
|
||||
void ENTRY_writew(PageEntry * pentry,PhysPt address,Bit16u val) {
|
||||
switch(pentry->type) {
|
||||
case ENTRY_VGA:
|
||||
{
|
||||
VGA_WriteHandler * handler=vga.config.writehandler;
|
||||
address=pentry->data.vga_base+(address&4095);
|
||||
(*handler)(address,(Bit8u)val);
|
||||
(*handler)(address+1,(Bit8u)(val>>8));
|
||||
}
|
||||
break;
|
||||
case ENTRY_NA:
|
||||
if (pentry->data.dir->InitPageLinear(address)) mem_writew(address,val);
|
||||
break;
|
||||
case ENTRY_INIT:
|
||||
if (pentry->data.dir->InitPage(address)) mem_writew(address,val);
|
||||
break;
|
||||
case ENTRY_ROM:
|
||||
LOG(LOG_PAGING,LOG_WARN)("Write %X to ROM at %X",val,address);
|
||||
break;
|
||||
case ENTRY_CHANGES:
|
||||
writew(pentry->data.mem+(address&4095),val);
|
||||
{
|
||||
Bitu start=address&4095;Bitu end=start+1;
|
||||
for (PageLink * link=pentry->links;link;link=link->next)
|
||||
if (link->change) link->change->Changed(link,start,end);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_PAGING,LOG_ERROR)("Entry write %X to %X with illegal type %d",val,address,pentry->type);
|
||||
}
|
||||
void MEM_UnlinkPages(void) {
|
||||
PAGING_ClearTLBEntries(memory.links.used,memory.links.pages);
|
||||
}
|
||||
|
||||
|
||||
void ENTRY_writed(PageEntry * pentry,PhysPt address,Bit32u val) {
|
||||
switch(pentry->type) {
|
||||
case ENTRY_VGA:
|
||||
{
|
||||
VGA_WriteHandler * handler=vga.config.writehandler;
|
||||
address=pentry->data.vga_base+(address&4095);
|
||||
(*handler)(address,(Bit8u)val);
|
||||
(*handler)(address+1,(Bit8u)(val>>8));
|
||||
(*handler)(address+2,(Bit8u)(val>>16));
|
||||
(*handler)(address+3,(Bit8u)(val>>24));
|
||||
}
|
||||
break;
|
||||
case ENTRY_NA:
|
||||
if (pentry->data.dir->InitPageLinear(address)) mem_writed(address,val);
|
||||
break;
|
||||
case ENTRY_INIT:
|
||||
if (pentry->data.dir->InitPage(address)) mem_writed(address,val);
|
||||
break;
|
||||
case ENTRY_ROM:
|
||||
LOG(LOG_PAGING,LOG_WARN)("Write %X to ROM at %X",val,address);
|
||||
break;
|
||||
case ENTRY_CHANGES:
|
||||
writed(pentry->data.mem+(address&4095),val);
|
||||
{
|
||||
Bitu start=address&4095;Bitu end=start+3;
|
||||
for (PageLink * link=pentry->links;link;link=link->next)
|
||||
if (link->change) link->change->Changed(link,start,end);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_PAGING,LOG_ERROR)("Entry write %X to %X with illegal type %d",val,address,pentry->type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Bitu mem_strlen(PhysPt pt) {
|
||||
Bitu x=0;
|
||||
while (x<1024) {
|
||||
|
@ -270,193 +198,11 @@ Bitu MEM_TotalPages(void) {
|
|||
return memory.pages;
|
||||
}
|
||||
|
||||
void MEM_UnlinkPage(PageLink * plink) {
|
||||
PageLink * checker=plink->entry->links;
|
||||
PageLink * * last=&plink->entry->links;
|
||||
while (checker) {
|
||||
if (checker == plink) {
|
||||
*last=plink->next;
|
||||
PAGING_AddFreePageLink(plink);
|
||||
return;
|
||||
}
|
||||
last=&checker->next;
|
||||
checker=checker->next;
|
||||
}
|
||||
E_Exit("Unlinking unlinked link");
|
||||
|
||||
}
|
||||
|
||||
PageLink * MEM_LinkPage(Bitu phys_page,PhysPt lin_base) {
|
||||
PageEntry * entry;
|
||||
/* Check if it's in a valid memory range */
|
||||
if (phys_page<memory.pages) {
|
||||
entry=&memory.entries[phys_page];
|
||||
/* Check if it's in the lfb range */
|
||||
} else if (phys_page>=memory.lfb.start_page && phys_page<memory.lfb.end_page) {
|
||||
entry=&memory.lfb.entries[phys_page-memory.lfb.start_page];
|
||||
} else {
|
||||
/* Invalid memory */
|
||||
LOG(LOG_PAGING,LOG_NORMAL)("Trying to link invalid page %X",phys_page);
|
||||
return 0;
|
||||
}
|
||||
PageLink * link=PAGING_GetFreePageLink();
|
||||
link->lin_base=lin_base;
|
||||
link->change=0;
|
||||
/* Check what kind of handler we need to give the page */
|
||||
switch (entry->type) {
|
||||
case ENTRY_RAM:
|
||||
link->read=entry->data.mem - lin_base;
|
||||
link->write=link->read;
|
||||
break;
|
||||
case ENTRY_ROM:
|
||||
link->read=entry->data.mem - lin_base;
|
||||
link->write=0;
|
||||
break;
|
||||
case ENTRY_VGA:
|
||||
link->read=0;
|
||||
link->write=0;
|
||||
break;
|
||||
case ENTRY_LFB:
|
||||
link->read=entry->data.mem - lin_base;
|
||||
link->write=link->read;
|
||||
break;
|
||||
case ENTRY_ALLOC:
|
||||
entry->type=ENTRY_RAM;
|
||||
entry->data.mem=MEM_GetBlockPage();
|
||||
link->read=entry->data.mem - lin_base;
|
||||
link->write=link->read;
|
||||
break;
|
||||
case ENTRY_CHANGES:
|
||||
link->read=entry->data.mem - lin_base;
|
||||
link->write=0;
|
||||
break;
|
||||
default:
|
||||
E_Exit("LinkPage:Illegal type %d",entry->type);
|
||||
}
|
||||
/* Place the entry in the link */
|
||||
link->entry=entry;
|
||||
link->next=entry->links;
|
||||
entry->links=link;
|
||||
return link;
|
||||
}
|
||||
|
||||
|
||||
void MEM_CheckLinks(PageEntry * theentry) {
|
||||
if (theentry->type!=ENTRY_RAM && theentry->type!=ENTRY_CHANGES) {
|
||||
LOG(LOG_PAGING,LOG_NORMAL)("Checking links on type %d",theentry->type);
|
||||
return;
|
||||
}
|
||||
bool haschange=false;PageLink * link;
|
||||
for (link=theentry->links;link;link=link->next) {
|
||||
if (link->change) {
|
||||
haschange=true;break;
|
||||
}
|
||||
}
|
||||
if (haschange) {
|
||||
theentry->type=ENTRY_CHANGES;
|
||||
for (link=theentry->links;link;link=link->next) {
|
||||
link->read=theentry->data.mem - link->lin_base;
|
||||
link->write=0;
|
||||
}
|
||||
} else {
|
||||
theentry->type=ENTRY_RAM;
|
||||
for (link=theentry->links;link;link=link->next) {
|
||||
link->read=theentry->data.mem - link->lin_base;
|
||||
link->write=link->read;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MEM_AllocLinkMemory(PageEntry * theentry) {
|
||||
//TODO Maybe check if this is a LINK_ALLOC type
|
||||
HostPt themem=MEM_GetBlockPage();
|
||||
theentry->data.mem=themem;
|
||||
theentry->type=ENTRY_RAM;
|
||||
theentry->links=0;
|
||||
}
|
||||
|
||||
void MEM_SetLFB(Bitu page,Bitu pages,HostPt pt) {
|
||||
if (pages>LFB_PAGES) E_Exit("MEM:LFB to large");
|
||||
LOG(LOG_PAGING,LOG_NORMAL)("LFB Base at address %X,page %X",page*4096,page);
|
||||
memory.lfb.pages=pages;
|
||||
memory.lfb.start_page=page;
|
||||
memory.lfb.end_page=page+pages;
|
||||
memory.lfb.address=pt;
|
||||
for (Bitu i=0;i<pages;i++) {
|
||||
memory.lfb.entries[i].data.mem=pt+(i*4096);
|
||||
memory.lfb.entries[i].type=ENTRY_LFB;
|
||||
}
|
||||
//TODO Maybe free the linked pages, but doubht that will be necessary
|
||||
}
|
||||
|
||||
void MEM_SetupVGA(VGA_RANGES range,HostPt base) {
|
||||
Bitu i;
|
||||
memory.vga.map_base=base;
|
||||
/* If it's another range, first clear the old one */
|
||||
if (memory.vga.range!=range) {
|
||||
Bitu start,end;
|
||||
switch (memory.vga.range) {
|
||||
case VGA_RANGE_A000:start=0;end=16;break;
|
||||
case VGA_RANGE_B000:start=16;end=24;break;
|
||||
case VGA_RANGE_B800:start=24;end=32;break;
|
||||
}
|
||||
for (i=start;i<end;i++) {
|
||||
PageEntry * theentry=&memory.entries[i+0xa0];
|
||||
HostPt themem=memory.vga.ram_bases[i];
|
||||
theentry->data.mem=themem;
|
||||
theentry->type=ENTRY_LFB;
|
||||
PageLink * link=theentry->links;
|
||||
while (link) {
|
||||
link->read=themem - link->lin_base;
|
||||
link->write=link->read;
|
||||
link=link->next;
|
||||
}
|
||||
}
|
||||
memory.vga.range=range;
|
||||
}
|
||||
/* Setup the new range, check if it's gonna handler based */
|
||||
Bitu start,end;
|
||||
switch (range) {
|
||||
case VGA_RANGE_A000:start=0;end=16;break;
|
||||
case VGA_RANGE_B000:start=16;end=24;break;
|
||||
case VGA_RANGE_B800:start=24;end=32;break;
|
||||
}
|
||||
if (base) {
|
||||
/* If it has an address it's a mapping */
|
||||
for (i=start;i<end;i++) {
|
||||
PageEntry * theentry=&memory.entries[i+0xa0];
|
||||
HostPt themem=base+(i-start)*4096;
|
||||
theentry->type=ENTRY_LFB;
|
||||
theentry->data.mem=themem;
|
||||
PageLink * link=theentry->links;
|
||||
while (link) {
|
||||
link->read=themem - link->lin_base;
|
||||
link->write=link->read;
|
||||
link=link->next;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* No address, so it'll be a handler */
|
||||
for (i=start;i<end;i++) {
|
||||
PageEntry * theentry=&memory.entries[i+0xa0];
|
||||
theentry->type=ENTRY_VGA;
|
||||
PhysPt thebase=(i-start)*4096;
|
||||
PageLink * link=theentry->links;
|
||||
theentry->data.vga_base=thebase;
|
||||
while (link) {
|
||||
link->read=0;
|
||||
link->write=0;
|
||||
link=link->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Bitu MEM_FreeLargest(void) {
|
||||
Bitu size=0;Bitu largest=0;
|
||||
Bitu index=XMS_START;
|
||||
while (index<memory.pages) {
|
||||
if (!memory.entries[index].next_handle) {
|
||||
if (!memory.mhandles[index]) {
|
||||
size++;
|
||||
} else {
|
||||
if (size>largest) largest=size;
|
||||
|
@ -472,7 +218,7 @@ Bitu MEM_FreeTotal(void) {
|
|||
Bitu free=0;
|
||||
Bitu index=XMS_START;
|
||||
while (index<memory.pages) {
|
||||
if (!memory.entries[index].next_handle) free++;
|
||||
if (!memory.mhandles[index]) free++;
|
||||
index++;
|
||||
}
|
||||
return free;
|
||||
|
@ -483,7 +229,7 @@ Bitu MEM_AllocatedPages(MemHandle handle)
|
|||
Bitu pages = 0;
|
||||
while (handle>0) {
|
||||
pages++;
|
||||
handle=memory.entries[handle].next_handle;
|
||||
handle=memory.mhandles[handle];
|
||||
}
|
||||
return pages;
|
||||
}
|
||||
|
@ -499,12 +245,12 @@ INLINE Bitu BestMatch(Bitu size) {
|
|||
/* Check if we are searching for first free page */
|
||||
if (!first) {
|
||||
/* Check if this is a free page */
|
||||
if (!memory.entries[index].next_handle) {
|
||||
if (!memory.mhandles[index]) {
|
||||
first=index;
|
||||
}
|
||||
} else {
|
||||
/* Check if this still is used page */
|
||||
if (memory.entries[index].next_handle) {
|
||||
if (memory.mhandles[index]) {
|
||||
Bitu pages=index-first;
|
||||
if (pages==size) {
|
||||
return first;
|
||||
|
@ -535,7 +281,7 @@ MemHandle MEM_AllocatePages(Bitu pages,bool sequence) {
|
|||
MemHandle * next=&ret;
|
||||
while (pages) {
|
||||
*next=index;
|
||||
next=&memory.entries[index].next_handle;
|
||||
next=&memory.mhandles[index];
|
||||
index++;pages--;
|
||||
}
|
||||
*next=-1;
|
||||
|
@ -545,9 +291,9 @@ MemHandle MEM_AllocatePages(Bitu pages,bool sequence) {
|
|||
while (pages) {
|
||||
Bitu index=BestMatch(1);
|
||||
if (!index) E_Exit("MEM:corruption during allocate");
|
||||
while (pages && (!memory.entries[index].next_handle)) {
|
||||
while (pages && (!memory.mhandles[index])) {
|
||||
*next=index;
|
||||
next=&memory.entries[index].next_handle;
|
||||
next=&memory.mhandles[index];
|
||||
index++;pages--;
|
||||
}
|
||||
*next=-1; //Invalidate it in case we need another match
|
||||
|
@ -558,8 +304,8 @@ MemHandle MEM_AllocatePages(Bitu pages,bool sequence) {
|
|||
|
||||
void MEM_ReleasePages(MemHandle handle) {
|
||||
while (handle>0) {
|
||||
MemHandle next=memory.entries[handle].next_handle;
|
||||
memory.entries[handle].next_handle=0;
|
||||
MemHandle next=memory.mhandles[handle];
|
||||
memory.mhandles[handle]=0;
|
||||
handle=next;
|
||||
}
|
||||
}
|
||||
|
@ -580,22 +326,22 @@ bool MEM_ReAllocatePages(MemHandle & handle,Bitu pages,bool sequence) {
|
|||
while (index>0) {
|
||||
old_pages++;
|
||||
last=index;
|
||||
index=memory.entries[index].next_handle;
|
||||
index=memory.mhandles[index];
|
||||
}
|
||||
if (old_pages == pages) return true;
|
||||
if (old_pages > pages) {
|
||||
/* Decrease size */
|
||||
pages--;index=handle;old_pages--;
|
||||
while (pages) {
|
||||
index=memory.entries[index].next_handle;
|
||||
index=memory.mhandles[index];
|
||||
pages--;old_pages--;
|
||||
}
|
||||
MemHandle next=memory.entries[index].next_handle;
|
||||
memory.entries[index].next_handle=-1;
|
||||
MemHandle next=memory.mhandles[index];
|
||||
memory.mhandles[index]=-1;
|
||||
index=next;
|
||||
while (old_pages) {
|
||||
next=memory.entries[index].next_handle;
|
||||
memory.entries[index].next_handle=0;
|
||||
next=memory.mhandles[index];
|
||||
memory.mhandles[index]=0;
|
||||
index=next;
|
||||
old_pages--;
|
||||
}
|
||||
|
@ -606,17 +352,17 @@ bool MEM_ReAllocatePages(MemHandle & handle,Bitu pages,bool sequence) {
|
|||
if (sequence) {
|
||||
index=last+1;
|
||||
Bitu free=0;
|
||||
while ((index<memory.pages) && !memory.entries[index].next_handle) {
|
||||
while ((index<(MemHandle)memory.pages) && !memory.mhandles[index]) {
|
||||
index++;free++;
|
||||
}
|
||||
if (free>=need) {
|
||||
/* Enough space allocate more pages */
|
||||
index=last;
|
||||
while (need) {
|
||||
memory.entries[index].next_handle=index+1;
|
||||
memory.mhandles[index]=index+1;
|
||||
need--;index++;
|
||||
}
|
||||
memory.entries[index].next_handle=-1;
|
||||
memory.mhandles[index]=-1;
|
||||
return true;
|
||||
} else {
|
||||
/* Not Enough space allocate new block and copy */
|
||||
|
@ -630,63 +376,38 @@ bool MEM_ReAllocatePages(MemHandle & handle,Bitu pages,bool sequence) {
|
|||
} else {
|
||||
MemHandle rem=MEM_AllocatePages(need,false);
|
||||
if (!rem) return false;
|
||||
memory.entries[last].next_handle=rem;
|
||||
memory.mhandles[last]=rem;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void MEM_UnmapPages(Bitu phys_page,Bitu pages) {
|
||||
for (;pages;pages--) {
|
||||
memory.dir.LinkPage(phys_page,phys_page);
|
||||
phys_page++;
|
||||
}
|
||||
}
|
||||
|
||||
void MEM_MapPagesHandle(Bitu lin_page,MemHandle mem,Bitu mem_page,Bitu pages) {
|
||||
for (;mem_page;mem_page--) {
|
||||
if (mem<=0) E_Exit("MEM:MapPages:Fault in memory tables");
|
||||
mem=memory.entries[mem].next_handle;
|
||||
}
|
||||
for (;pages;pages--) {
|
||||
if (mem<=0) E_Exit("MEM:MapPages:Fault in memory tables");
|
||||
memory.dir.LinkPage(lin_page++,mem);
|
||||
mem=memory.entries[mem].next_handle;
|
||||
}
|
||||
}
|
||||
|
||||
void MEM_MapPagesDirect(Bitu lin_page,Bitu phys_page,Bitu pages) {
|
||||
for (;pages;pages--) {
|
||||
memory.dir.LinkPage(lin_page++,phys_page++);
|
||||
}
|
||||
}
|
||||
|
||||
MemHandle MEM_NextHandle(MemHandle handle) {
|
||||
return memory.entries[handle].next_handle;
|
||||
return memory.mhandles[handle];
|
||||
}
|
||||
|
||||
MemHandle MEM_NextHandleAt(MemHandle handle,Bitu where) {
|
||||
while (where) {
|
||||
where--;
|
||||
handle=memory.mhandles[handle];
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
A20 line handling,
|
||||
Basically maps the 4 pages at the 1mb to 0mb in the default page directory
|
||||
*/
|
||||
bool MEM_A20_Enabled(void) {
|
||||
return a20_enabled;
|
||||
return memory.a20.enabled;
|
||||
}
|
||||
|
||||
void MEM_A20_Enable(bool enabled) {
|
||||
a20_enabled=enabled;
|
||||
Bitu i;
|
||||
if (!enabled) {
|
||||
for (i=0x0;i<0x10;i++) {
|
||||
memory.dir.LinkPage(0x100+i,i);
|
||||
}
|
||||
} else {
|
||||
for (i=0x0;i<0x10;i++) {
|
||||
memory.dir.LinkPage(0x100+i,0x100+i);
|
||||
}
|
||||
}
|
||||
Bitu phys_base=enabled ? (1024/4) : 0;
|
||||
for (Bitu i=0;i<16;i++) PAGING_MapPage((1024/4)+i,phys_base+i);
|
||||
memory.a20.enabled=enabled;
|
||||
}
|
||||
|
||||
|
||||
|
@ -742,20 +463,11 @@ void mem_writed(PhysPt address,Bit32u val) {
|
|||
}
|
||||
|
||||
void phys_writeb(PhysPt addr,Bit8u val) {
|
||||
Bitu page=addr>>12;
|
||||
if (page>=memory.pages) E_Exit("physwrite:outside of physical range");
|
||||
PageEntry * theentry=&memory.entries[page];
|
||||
switch (theentry->type) {
|
||||
case ENTRY_ALLOC:
|
||||
MEM_AllocLinkMemory(theentry);
|
||||
break;
|
||||
case ENTRY_RAM:
|
||||
case ENTRY_ROM:
|
||||
break;
|
||||
default:
|
||||
E_Exit("physwrite:illegal type %d",theentry->type);
|
||||
HostPt block=memory.hostpts[addr >> 12];
|
||||
if (!block) {
|
||||
block=memory.hostpts[addr >> 12]=MEM_GetBlockPage();
|
||||
}
|
||||
writeb(theentry->data.mem+(addr & 4095),val);
|
||||
host_writeb(block+(addr & 4095),val);
|
||||
}
|
||||
|
||||
void phys_writew(PhysPt addr,Bit16u val) {
|
||||
|
@ -771,17 +483,6 @@ void phys_writed(PhysPt addr,Bit32u val) {
|
|||
}
|
||||
|
||||
Bit32u phys_page_readd(Bitu page,Bitu index) {
|
||||
if (page>=memory.pages) E_Exit("physwrite:outside of physical range");
|
||||
PageEntry * theentry=&memory.entries[page];
|
||||
switch (theentry->type) {
|
||||
case ENTRY_CHANGES:
|
||||
case ENTRY_RAM:
|
||||
case ENTRY_ROM:
|
||||
return readd(memory.entries[page].data.mem+index*4);
|
||||
break;
|
||||
default:
|
||||
E_Exit("pageread:illegal type %d",theentry->type);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -789,19 +490,15 @@ Bit32u phys_page_readd(Bitu page,Bitu index) {
|
|||
static void write_p92(Bit32u port,Bit8u val) {
|
||||
// Bit 0 = system reset (switch back to real mode)
|
||||
if (val&1) E_Exit("XMS: CPU reset via port 0x92 not supported.");
|
||||
controlport_data = val & ~2;
|
||||
memory.a20.controlport = val & ~2;
|
||||
MEM_A20_Enable((val & 2)>0);
|
||||
}
|
||||
|
||||
static Bit8u read_p92(Bit32u port) {
|
||||
return controlport_data | (a20_enabled ? 0x02 : 0);
|
||||
return memory.a20.controlport | (memory.a20.enabled ? 0x02 : 0);
|
||||
}
|
||||
|
||||
|
||||
PageDirectory * MEM_DefaultDirectory(void) {
|
||||
return &memory.dir;
|
||||
}
|
||||
|
||||
HostPt MEM_GetBlockPage(void) {
|
||||
HostPt ret;
|
||||
if (memory.block.pages) {
|
||||
|
@ -847,36 +544,17 @@ void MEM_Init(Section * sec) {
|
|||
memsize=MAX_MEMORY;
|
||||
}
|
||||
memory.pages=(memsize*1024*1024)/4096;
|
||||
if (memory.pages>0x110) memory.free_pages=memory.pages-0x110;
|
||||
else memory.free_pages=0;
|
||||
|
||||
memory.entries= new PageEntry[memory.pages];
|
||||
/* Allocate the data for the different page information blocks */
|
||||
memory.hostpts=new HostPt[memory.pages];
|
||||
memory.phandlers=new PageHandler * [memory.pages];
|
||||
memory.mhandles=new MemHandle [memory.pages];
|
||||
for (i=0;i<memory.pages;i++) {
|
||||
memory.entries[i].type=ENTRY_ALLOC;
|
||||
memory.entries[i].data.mem=0;
|
||||
memory.entries[i].links=0;
|
||||
memory.entries[i].next_handle=0; //Set to 0 for memory allocation
|
||||
}
|
||||
/* Setup 128kb of memory for the VGA segments */
|
||||
for (i=0;i<128/4;i++) {
|
||||
memory.vga.ram_bases[i]=MEM_GetBlockPage();
|
||||
memory.entries[0xa0+i].type=ENTRY_LFB;
|
||||
memory.entries[0xa0+i].data.mem=memory.vga.ram_bases[i];
|
||||
}
|
||||
memory.vga.range=VGA_RANGE_B800;
|
||||
/* Setup the default page mapping */
|
||||
memory.dir.entry_init.type=ENTRY_NA; //Setup to use NA by default
|
||||
memory.dir.ClearDirectory();
|
||||
/* All pages now pointing to NA handler that will check on first access */
|
||||
/* Setup the ROM Areas */
|
||||
for (i=0xc0;i<0xd0;i++) {
|
||||
MEM_AllocLinkMemory(&memory.entries[i]);
|
||||
memory.entries[i].type=ENTRY_ROM;
|
||||
}
|
||||
for (i=0xf0;i<0x100;i++) {
|
||||
MEM_AllocLinkMemory(&memory.entries[i]);
|
||||
memory.entries[i].type=ENTRY_ROM;
|
||||
memory.hostpts[i]=0; //0 handler is allocate memory
|
||||
memory.phandlers[i]=&ram_page_handler;
|
||||
memory.mhandles[i]=0; //Set to 0 for memory allocation
|
||||
}
|
||||
/* Reset some links */
|
||||
memory.links.used=0;
|
||||
// A20 Line - PS/2 system control port A
|
||||
IO_RegisterWriteHandler(0x92,write_p92,"Control Port");
|
||||
IO_RegisterReadHandler(0x92,read_p92,"Control Port");
|
||||
|
|
Loading…
Add table
Reference in a new issue