diff --git a/examples/.gitignore b/examples/.gitignore index 1dfaf09..2097513 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -1,2 +1,3 @@ hello hello-mui +test-mmu diff --git a/examples/Makefile b/examples/Makefile index a602cd2..8ee4357 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,11 +1,11 @@ CC = m68k-amigaos-gcc -noixemul -s CFLAGS = -Os -Wall -fomit-frame-pointer -all: hello hello-mui +all: hello hello-mui test-mmu -hello: LDLIBS = -lnix13 hello: CC += -fbaserel hello: CFLAGS += -m68000 -msmall-code +hello: LDLIBS = -lnix13 hello: hello.c hello-mui: CC += -fbaserel @@ -13,6 +13,10 @@ hello-mui: CFLAGS += -m68020 -msmall-code hello-mui: LDLIBS = -lmui hello-mui: hello-mui.c +test-mmu: CC += -fbaserel +test-mmu: CFLAGS += -m68060 -msmall-code +test-mmu: test-mmu.c + clean: - rm -f hello hello-mui + rm -f hello hello-mui test-mmu rm -f *.o *~ diff --git a/examples/test-mmu.c b/examples/test-mmu.c new file mode 100644 index 0000000..54be1c6 --- /dev/null +++ b/examples/test-mmu.c @@ -0,0 +1,156 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +long __nocommandline = 1; + +BOOL PrintMMUInfo() { + PutStr("MMU: "); + + switch (GetMMUType()) { + case MUTYPE_68851: + PutStr("68851\n"); + break; + + case MUTYPE_68030: + PutStr("68030\n"); + break; + + case MUTYPE_68040: + PutStr("68040\n"); + break; + + case MUTYPE_68060: + PutStr("68060\n"); + break; + + default: + PutStr("None\n"); + return FALSE; + } + + return TRUE; +} + +static void PrintMapping(struct MappingNode *mn) { + while (mn->map_succ) { + Printf(" 0x%08lx - 0x%08lx : ", mn->map_Lower, mn->map_Higher); + + if (mn->map_Properties & MAPP_WRITEPROTECTED) + PutStr("WriteProtected "); + if (mn->map_Properties & MAPP_USED) + PutStr("U "); + if (mn->map_Properties & MAPP_MODIFIED) + PutStr("M "); + if (mn->map_Properties & MAPP_GLOBAL) + PutStr("Global "); + if (mn->map_Properties & MAPP_TRANSLATED) + PutStr("TT "); + if (mn->map_Properties & MAPP_ROM) + PutStr("ROM "); + if (mn->map_Properties & MAPP_USERPAGE0) + PutStr("UP0 "); + if (mn->map_Properties & MAPP_USERPAGE1) + PutStr("UP1 "); + if (mn->map_Properties & MAPP_CACHEINHIBIT) + PutStr("CacheInhibit "); + if (mn->map_Properties & MAPP_IMPRECISE) + PutStr("Imprecise "); + if (mn->map_Properties & MAPP_NONSERIALIZED) + PutStr("NonSerial "); + if (mn->map_Properties & MAPP_COPYBACK) + PutStr("CopyBack "); + if (mn->map_Properties & MAPP_SUPERVISORONLY) + PutStr("SuperOnly "); + if (mn->map_Properties & MAPP_BLANK) + PutStr("Blank "); + if (mn->map_Properties & MAPP_SHARED) + PutStr("Shared "); + if (mn->map_Properties & MAPP_SINGLEPAGE) + PutStr("Single "); + if (mn->map_Properties & MAPP_REPAIRABLE) + PutStr("Repairable "); + if (mn->map_Properties & MAPP_IO) + PutStr("I/O space "); + if (mn->map_Properties & MAPP_USER0) + PutStr("U0 "); + if (mn->map_Properties & MAPP_USER1) + PutStr("U1 "); + if (mn->map_Properties & MAPP_USER2) + PutStr("U2 "); + if (mn->map_Properties & MAPP_USER3) + PutStr("U3 "); + if (mn->map_Properties & MAPP_INVALID) + Printf("Invalid (0x%08lx) ", (LONG)mn->map_un.map_UserData); + if (mn->map_Properties & MAPP_SWAPPED) + Printf("Swapped (0x%08lx) ", (LONG)mn->map_un.map_UserData); + if (mn->map_Properties & MAPP_REMAPPED) + Printf("Remapped to 0x%08lx ", (LONG)mn->map_un.map_Delta+mn->map_Lower); + if (mn->map_Properties & MAPP_BUNDLED) + Printf("Bundled to 0x%08lx ", (LONG)mn->map_un.map_Page); + if (mn->map_Properties & MAPP_INDIRECT) + Printf("Indirect at 0x%08lx ", (LONG)mn->map_un.map_Descriptor); + PutStr("\n"); + + mn = mn->map_succ; + } +} + +static void PrintMemoryLayout(struct MMUContext *ctx) { + struct MinList *list = GetMapping(ctx); + + PutStr("\n"); + PutStr("Memory layout:\n"); + PrintMapping((struct MappingNode *)(list->mlh_Head)); + ReleaseMapping(ctx, list); +} + +int main() { + if (PrintMMUInfo()) { + struct MMUContext *ctx = DefaultContext(); + struct MMUContext *privctx; + ULONG error; + + if ((privctx = CreateMMUContext(MCXTAG_COPY, (LONG)ctx, + MCXTAG_ERRORCODE, (LONG)&error, + TAG_DONE))) + { + LONG psize; + + Printf("CreateMMUContext succeeded with %ld.\n", error); + + psize = GetPageSize(privctx); + Printf("Page size: %ld\n", psize); + + EnterMMUContext(privctx, FindTask(NULL)); + PrintMemoryLayout(privctx); + + { + void *ptr = AllocAligned(psize * 16, MEMF_FAST, psize); + + PutStr("\n"); + Printf("16 pages allocated at 0x%08lx - 0x%08lx.\n", (LONG)ptr, (LONG)ptr + psize * 16 - 1); + PutStr("Let's make them CacheInhibit!\n"); + + SetProperties(privctx, MAPP_CACHEINHIBIT, MAPP_COPYBACK|MAPP_CACHEINHIBIT, (LONG)ptr, psize * 16, TAG_DONE); + RebuildTree(privctx); + PrintMemoryLayout(privctx); + + FreeMem(ptr, psize * 16); + } + + LeaveMMUContext(FindTask(NULL)); + DeleteMMUContext(privctx); + } else { + Printf("CreateMMUContext failed with %ld.\n", error); + } + } + + return 0; +}