diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index edbc1686..26164941 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -15,36 +15,23 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + + #include #include #include #include "dosbox.h" #include "mem.h" -#define MEM_MAXSIZE 16 /* The Size of memory used to get size of page table */ -#define memsize 8 /* 8 mb of memory */ -#define EMM_HANDLECOUNT 250 +HostPt memory; +HostPt ReadHostTable[MAX_PAGES]; +HostPt WriteHostTable[MAX_PAGES]; +MEMORY_ReadHandler ReadHandlerTable[MAX_PAGES]; +MEMORY_WriteHandler WriteHandlerTable[MAX_PAGES]; -EMM_Handle EMM_Handles[EMM_HANDLECOUNT]; -PageEntry * PageEntries[MEM_MAXSIZE*1024*16]; /* Number of pages */ -Bit8u * memory=0; - -bool MEMORY_TestSpecial(PhysPt off) { - return (PageEntries[off >> 12]>0); -} - -void MEMORY_SetupHandler(Bit32u page,Bit32u pages,PageEntry * entry) { - for (Bit32u i=page;i> 12]; - if (!entry) { writeb(memory+off,val);return; } - switch (entry->type) { - case MEMORY_RELOCATE: - writeb(entry->relocate+(off-entry->base),val); - break; - case MEMORY_HANDLER: - entry->handler.write(off-entry->base,val); - break; - default: - E_Exit("Write to Illegal Memory Address %4x",off); - } -} - -void mem_writew(PhysPt off,Bit16u val) { - PageEntry * entry=PageEntries[off >> 12]; - if (!entry) { writew(memory+off,val);return; } - switch (entry->type) { - case MEMORY_RELOCATE: - writew(entry->relocate+(off-entry->base),val); - break; - case MEMORY_HANDLER: - entry->handler.write(off-entry->base,(val & 0xFF)); - entry->handler.write(off-entry->base+1,(val >> 8)); - break; - default: - E_Exit("Write to Illegal Memory Address %4x",off); - } -} - -void mem_writed(PhysPt off,Bit32u val) { - PageEntry * entry=PageEntries[off >> 12]; - if (!entry) { writed(memory+off,val);return; } - switch (entry->type) { - case MEMORY_RELOCATE: - writed(entry->relocate+(off-entry->base),val); - break; - case MEMORY_HANDLER: - entry->handler.write(off-entry->base, (Bit8u)(val & 0xFF)); - entry->handler.write(off-entry->base+1,(Bit8u)(val >> 8) & 0xFF); - entry->handler.write(off-entry->base+2,(Bit8u)(val >> 16) & 0xFF); - entry->handler.write(off-entry->base+3,(Bit8u)(val >> 24) & 0xFF); - break; - default: - E_Exit("Write to Illegal Memory Address %4x",off); - } -} - -Bit8u mem_readb(PhysPt off) { - PageEntry * entry=PageEntries[off >> 12]; - if (!entry) { return readb(memory+off);} - switch (entry->type) { - case MEMORY_RELOCATE: - return readb(entry->relocate+(off-entry->base)); - case MEMORY_HANDLER: - return entry->handler.read(off-entry->base); - break; - default: - E_Exit("Read from Illegal Memory Address %4x",off); - } - return 0; /* Keep compiler happy */ -} - -Bit16u mem_readw(PhysPt off) { - PageEntry * entry=PageEntries[off >> 12]; - if (!entry) { return readw(memory+off);} - switch (entry->type) { - case MEMORY_RELOCATE: - return readw(entry->relocate+(off-entry->base)); - case MEMORY_HANDLER: - return entry->handler.read(off-entry->base) | - (entry->handler.read(off-entry->base+1) << 8); - break; - default: - E_Exit("Read from Illegal Memory Address %4x",off); - } - return 0; /* Keep compiler happy */ -} - -Bit32u mem_readd(PhysPt off) { - PageEntry * entry=PageEntries[off >> 12]; - if (!entry) { return readd(memory+off);} - switch (entry->type) { - case MEMORY_RELOCATE: - return readd(entry->relocate+(off-entry->base)); - case MEMORY_HANDLER: - return entry->handler.read(off-entry->base) | - (entry->handler.read(off-entry->base+1) << 8) | - (entry->handler.read(off-entry->base+2) << 16)| - (entry->handler.read(off-entry->base+3) << 24); - break; - default: - E_Exit("Read from Illegal Memory Address %4x",off); - } - return 0; /* Keep compiler happy */ -} - -/* The EMM Allocation Part */ - -/* If this returns 0 we got and error since 0 is always taken */ -static Bit16u EMM_GetFreeHandle(void) { - Bit16u i=0; - while (i*maxblock) *maxblock=EMM_Handles[index].size; - *total+=EMM_Handles[index].size; - } - if (EMM_Handles[index].next) index=EMM_Handles[index].next; - else break; +/* Could only be called when the pt host entry is 0 ah well :) */ +static Bit8u Default_ReadHandler(PhysPt pt) { + return readb(WriteHostTable[pt >> PAGE_SHIFT]+pt); +} +static void Default_WriteHandler(PhysPt pt,Bit8u val) { + writeb(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); +} + + +void MEM_SetupPageHandlers(Bitu startpage,Bitu pages,MEMORY_ReadHandler read,MEMORY_WriteHandler write) { + if (startpage+pages>=LOW_PAGE_LIMIT) E_Exit("Memory:Illegal page for handler"); + for (Bitu i=startpage;isize) { - Bit16u newindex=EMM_GetFreeHandle(); - EMM_Handles[newindex].active=true; - EMM_Handles[newindex].phys_base=EMM_Handles[newindex].phys_base+size*4096; - EMM_Handles[newindex].size=EMM_Handles[index].size-size; - EMM_Handles[newindex].free=true; - EMM_Handles[newindex].next=EMM_Handles[index].next; - EMM_Handles[index].next=newindex; - EMM_Handles[index].free=false; - EMM_Handles[index].size=size; - *handle=index; - break; - } - } - if (EMM_Handles[index].next) index=EMM_Handles[index].next; - else break; + +void MEM_ClearPageHandlers(Bitu startpage,Bitu pages) { + if (startpage+pages>=LOW_PAGE_LIMIT) E_Exit("Memory:Illegal page for handler"); + for (Bitu i=startpage;i=MAX_PAGE_LIMIT) E_Exit("Memory:Illegal page for handler"); + HostPt base=(HostPt)(data)-startpage*PAGE_SIZE; + if (!base) LOG_DEBUG("MEMORY:Unlucky memory allocation"); + for (Bitu i=startpage;i=MAX_PAGE_LIMIT) E_Exit("Memory:Illegal page for handler"); + for (Bitu i=startpage;i> 8) & 0xff) ); +} + +static void HandlerWrited(Bitu page,PhysPt pt,Bit32u val) { + WriteHandlerTable[page](pt+0,(Bit8u)(val & 0xff)); + WriteHandlerTable[page](pt+1,(Bit8u)((val >> 8) & 0xff) ); + WriteHandlerTable[page](pt+2,(Bit8u)((val >> 16) & 0xff) ); + WriteHandlerTable[page](pt+3,(Bit8u)((val >> 24) & 0xff) ); +} + +void mem_writeb(PhysPt pt,Bit8u val) { + if (WriteHostTable[pt >> PAGE_SHIFT]) writeb(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); + else { + WriteHandlerTable[pt >> PAGE_SHIFT](pt,val); + } +} + +void mem_writew(PhysPt pt,Bit16u val) { + if (!WriteHostTable[pt >> PAGE_SHIFT]) { +// HandlerWritew(pt >> PAGE_SHIFT,pt,val); + WriteHandlerTable[pt >> PAGE_SHIFT](pt+0,(Bit8u)(val & 0xff)); + WriteHandlerTable[pt >> PAGE_SHIFT](pt+1,(Bit8u)((val >> 8) & 0xff) ); + } else writew(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); +} + +void mem_writed(PhysPt pt,Bit32u val) { + if (!WriteHostTable[pt >> PAGE_SHIFT]) { +// HandlerWrited(pt >> PAGE_SHIFT,pt,val); + WriteHandlerTable[pt >> PAGE_SHIFT](pt+0,(Bit8u)(val & 0xff)); + WriteHandlerTable[pt >> PAGE_SHIFT](pt+1,(Bit8u)((val >> 8) & 0xff) ); + WriteHandlerTable[pt >> PAGE_SHIFT](pt+2,(Bit8u)((val >> 16) & 0xff) ); + WriteHandlerTable[pt >> PAGE_SHIFT](pt+3,(Bit8u)((val >> 24) & 0xff) ); + } else writed(WriteHostTable[pt >> PAGE_SHIFT]+pt,val); } -PageEntry HMA_PageEntry; +static Bit16u HandlerReadw(Bitu page,PhysPt pt) { + return (ReadHandlerTable[page](pt+0)) | + (ReadHandlerTable[page](pt+1)) << 8; +} + +static Bit32u HandlerReadd(Bitu page,PhysPt pt) { + return (ReadHandlerTable[page](pt+0)) | + (ReadHandlerTable[page](pt+1)) << 8 | + (ReadHandlerTable[page](pt+2)) << 16 | + (ReadHandlerTable[page](pt+3)) << 24; +} + +Bit8u mem_readb(PhysPt pt) { + if (ReadHostTable[pt >> PAGE_SHIFT]) return readb(ReadHostTable[pt >> PAGE_SHIFT]+pt); + else { + return ReadHandlerTable[pt >> PAGE_SHIFT](pt); + } +} + +Bit16u mem_readw(PhysPt pt) { + if (!ReadHostTable[pt >> PAGE_SHIFT]) { +// return HandlerReadw(pt >> PAGE_SHIFT,pt); + return + (ReadHandlerTable[pt >> PAGE_SHIFT](pt+0)) | + (ReadHandlerTable[pt >> PAGE_SHIFT](pt+1)) << 8; + } else return readw(ReadHostTable[pt >> PAGE_SHIFT]+pt); +} + +Bit32u mem_readd(PhysPt pt){ + if (ReadHostTable[pt >> PAGE_SHIFT]) return readd(ReadHostTable[pt >> PAGE_SHIFT]+pt); + else { +// return HandlerReadd(pt >> PAGE_SHIFT,pt); + return + (ReadHandlerTable[pt >> PAGE_SHIFT](pt+0)) | + (ReadHandlerTable[pt >> PAGE_SHIFT](pt+1)) << 8 | + (ReadHandlerTable[pt >> PAGE_SHIFT](pt+2)) << 16 | + (ReadHandlerTable[pt >> PAGE_SHIFT](pt+3)) << 24; + } +} +#endif + + void MEM_Init(void) { - memset((void *)&PageEntries,0,sizeof(PageEntries)); - memory=(Bit8u *)malloc(memsize*1024*1024); + /* Init all tables */ + Bitu i; + i=MAX_PAGES; + for (i=0;i1) { - EMM_Handles[1].size=(memsize-1)*256-16; - } else { - EMM_Handles[0].size=0;; - } - EMM_Handles[1].active=true; - EMM_Handles[1].free=true; - EMM_Handles[1].phys_base=0x110000; -}; + /* Setup tables for first mb */ + MEM_SetupMapping(0,PAGE_COUNT(1024*1024),memory); + /* Setup tables for HMA Area */ + MEM_SetupMapping(PAGE_COUNT(1024*1024),PAGE_COUNT(64*1024),memory); +}