home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************
- ** MuFastRom **
- ** **
- ** A MMU-Library compatible ROM remapper **
- ** Version 1.07 21.08.1999 © THOR-Software, by Thomas Richter **
- *****************************************************************/
-
- /// Includes
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <exec/ports.h>
- #include <dos/dos.h>
- #include <mmu/mmubase.h>
- #include <mmu/context.h>
- #include <mmu/mmutags.h>
- #include <workbench/startup.h>
-
- #include <proto/exec.h>
- #include <proto/mmu.h>
- #include <proto/dos.h>
- #include <proto/icon.h>
- #include <string.h>
- ///
- /// Defines
- #define STRINGDATE "21.8.99"
- #define STRINGVERSION "40.7"
- #define ROMEND 0x01000000L
- #define MAGIC_ROMEND 0x14L
- #define CACHEFLAGS (MAPP_CACHEINHIBIT|MAPP_COPYBACK|MAPP_NONSERIALIZED|MAPP_IMPRECISE)
- #define TEMPLATE "ON=FASTROM/S,OFF=NOFASTROM/S,HEAD/S,PROTECT/S,NOPROTECT/S"
-
- #define OPT_ON 0
- #define OPT_OFF 1
- #define OPT_HEAD 2
- #define OPT_PROTECT 3
- #define OPT_NOPROTECT 4
- #define OPT_WINDOW 5
- #define OPT_COUNT 6
- ///
- /// Statics
- struct MMUBase *MMUBase;
- struct DosLibrary *DOSBase;
- struct ExecBase *SysBase;
- struct Library *IconBase;
- ///
- /// Protos
- int __asm __saveds main(void);
- int BuildFastRom(LONG head,LONG protect,LONG noprotect);
- int RemoveFastRom(void);
- int MapToRom(struct MMUContext *ctx,ULONG source,ULONG mem,ULONG size);
- int RemapToRam(struct MMUContext *ctx,ULONG source,ULONG pmem,ULONG mem,ULONG size,LONG protect,LONG noprotect,ULONG cacheflags);
- struct RDArgs *ReadTTArgs(struct WBStartup *msg,LONG args[],struct RDArgs **tmp);
- ///
- /// Strukturen
- struct FastRomPort {
- struct MsgPort frp_Port;
- UBYTE frp_NoProtect;
- UBYTE frp_Protect;
- void *frp_Logical; /* Logical address of the remapped ROM */
- void *frp_Physical; /* Physical location of the RAM used for remapping */
- void *frp_RomStart;
- ULONG frp_Size; /* size of the allocated memory */
- struct Library *frp_Base; /* Keep the library open */
- ULONG frp_CacheFlags; /* keeps the cache mode of the remapped ROM */
- char frp_Name[32]; /* keeps the name of the port */
- };
- ///
-
- char version[]="$VER: MuFastRom " STRINGVERSION " (" STRINGDATE ") © THOR";
-
- /// main
- int __asm __saveds main(void)
- {
- LONG args[OPT_COUNT];
- struct RDArgs *rd,*myrd;
- struct Process *proc;
- int rc=20;
- LONG err;
- struct WBStartup *msg;
- BPTR oldout;
- struct MsgPort *oldconsole;
-
-
-
- SysBase=*((struct ExecBase **)(4L));
-
- memset(args,0,sizeof(LONG)*OPT_COUNT);
- /* Wait for the workbench startup, if any */
- proc=(struct Process *)FindTask(NULL);
-
- if (!(proc->pr_CLI)) {
- WaitPort(&(proc->pr_MsgPort));
- msg=(struct WBStartup *)GetMsg(&(proc->pr_MsgPort));
- } else msg=NULL;
-
- if (DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",37L)) {
- if (MMUBase=(struct MMUBase *)OpenLibrary("mmu.library",0L)) {
-
- err=ERROR_REQUIRED_ARG_MISSING;
-
- myrd=NULL; /* reset the temporary ReadArgs */
- oldout=NULL;
- oldconsole=NULL;
- if (msg) {
- oldout=SelectOutput(NULL);
- oldconsole=SetConsoleTask(NULL);
- rd=ReadTTArgs(msg,args,&myrd);
- } else rd=ReadArgs(TEMPLATE,args,NULL);
-
- if (rd) {
- if (!GetMMUType()) {
- Printf("MuFastRom requires a working MMU.\n");
- err=10;
- } else {
- /* Argument parser worked, call main routine */
- if ((args[OPT_ON]) || (!args[OPT_OFF])) /* ON is the default if OFF is not given */
- err=BuildFastRom(args[OPT_HEAD],args[OPT_PROTECT],args[OPT_NOPROTECT]);
-
- if (args[OPT_OFF])
- err=RemoveFastRom();
- }
-
- FreeArgs(rd);
- if (myrd) FreeDosObject(DOS_RDARGS,myrd);
- if (msg) Close(SelectOutput(NULL));
- } else err=IoErr();
-
- if (msg) {
- SelectOutput(oldout);
- SetConsoleTask(oldconsole);
- }
-
- if (err<64) {
- rc=err;
- err=0;
- } else {
- if (!msg) PrintFault(err,"MuFastRom failed");
- rc=10;
- }
- SetIoErr(err);
-
- CloseLibrary((struct Library *)MMUBase);
- } else PrintFault(ERROR_OBJECT_NOT_FOUND,"MuFastRom requires the mmu.library");
- CloseLibrary((struct Library *)DOSBase);
- }
-
- return rc;
- }
- ///
- /// ReadTTArgs
- struct RDArgs *ReadTTArgs(struct WBStartup *msg,LONG args[],struct RDArgs **tmp)
- {
- struct WBArg *wbarg;
- struct DiskObject *dop;
- char **tt; /* ToolTypes array */
- char *wbstr; /* Our self-made workbench argument string */
- char *here;
- BPTR oldlock;
- ULONG len;
- struct RDArgs *rd=NULL,*myrd=NULL;
- LONG err=0;
- BPTR newout;
-
- if (IconBase=OpenLibrary("icon.library",37L)) {
- if (wbarg=msg->sm_ArgList) {
- /* use a project icon if there is one... */
- if (msg->sm_NumArgs > 1) wbarg++;
-
- /* go into the directory */
- oldlock=CurrentDir(wbarg->wa_Lock);
-
- if (dop=GetDiskObject(wbarg->wa_Name)) {
- if (tt=dop->do_ToolTypes) {
- /* Read a special tool type for the output window */
-
- /* Calc the size of the argument string */
-
- len = 3; /* reserve space for SPC,LF,NUL */
- while (*tt) {
- len += strlen(*tt)+1; /* string, plus space */
- tt++;
- }
-
- if (wbstr=AllocVec(len,MEMF_PUBLIC)) {
- /* Now copy the arguments into this string, one by one
- and check whether the argument string is still valid. */
-
- tt=dop->do_ToolTypes;
- here=wbstr;
- do{
- *here='\0'; /* terminate string */
- /* Check whether this tool type is
- commented out. Just ignore it in this case */
- if (*tt) {
- if (**tt=='(' || **tt==';')
- continue;
-
- strcpy(here,*tt); /* Add TT string */
- }
- len=strlen(here);
- here[len]='\n';
- here[len+1]='\0'; /* terminate string */
-
- /* Now try to ReadArg' this string */
-
- /* release old arguments left over from last loop */
- if (rd) FreeArgs(rd);
- if (myrd) FreeDosObject(DOS_RDARGS,myrd);
- rd=NULL;
- memset(args,0,sizeof(LONG)*OPT_COUNT);
-
- if (myrd=AllocDosObject(DOS_RDARGS,NULL)) {
- /* Allocate and setup the ReadArgs source */
- myrd->RDA_Source.CS_Buffer=wbstr;
- myrd->RDA_Source.CS_Length=strlen(wbstr);
-
- if (rd=ReadArgs(TEMPLATE ",WINDOW/K",args,myrd)) {
- /* Is this still valid? */
- here[len]=' ';
- here+=len+1;
- /* if so, accept this argument and go on */
- } else {
- err=IoErr();
- if (err==ERROR_NO_FREE_STORE) break;
- else err=0; /* Ignore unknown or invalid arguments silently */
- }
- } else {
- err=ERROR_NO_FREE_STORE;
- break;
- }
- }while(*tt++);
-
- FreeVec(wbstr);
- } else err=ERROR_NO_FREE_STORE;
- } else err=ERROR_REQUIRED_ARG_MISSING; /* Huh, how should this happen ? */
- FreeDiskObject(dop);
- } else err=IoErr();
- CurrentDir(oldlock);
- } else err=ERROR_REQUIRED_ARG_MISSING; /* This should not happen either */
- CloseLibrary(IconBase);
- } else err=ERROR_OBJECT_NOT_FOUND; /* This should not happen */
-
- /* Open an output stream */
-
- if (err==0) {
- if (newout=Open((args[OPT_WINDOW])?((char *)args[OPT_WINDOW]):("NIL:"),MODE_NEWFILE)) {
- SelectOutput(newout);
- /* Hack in the output console. Well, well... */
- SetConsoleTask(((struct FileHandle *)(BADDR(newout)))->fh_Type);
- } else err=IoErr();
- }
-
- if (err) {
- if (rd) FreeArgs(rd);
- if (myrd) FreeDosObject(DOS_RDARGS,myrd);
- SetIoErr(err);
- rd=NULL;
- myrd=NULL;
- }
-
- *tmp=myrd;
- return rd;
- }
- ///
- /// BuildFastRom
- int BuildFastRom(LONG head,LONG protect,LONG noprotect)
- {
- void *mem,*source,*pmem;
- ULONG size,psize;
- ULONG props;
- struct FastRomPort *port;
- struct MMUContext *ctx,*sctx; /* default context, supervisorcontext */
- int err=ERROR_NO_FREE_STORE;
-
-
- Forbid(); /* Shut up PatchWork */
-
- /* If this is already installed, warn and return. */
-
- if (FindPort("« MuFastRom »")) {
- Permit();
- Printf("MuFastRom already running.\n");
- return 5;
- }
-
- Permit();
-
- ctx=DefaultContext(); /* get the default context */
- sctx=SuperContext(ctx); /* get the supervisor context for this one */
-
- /* Read the size of the ROM */
- size=*((ULONG *)(ROMEND-MAGIC_ROMEND));
-
- /* The start of the ROM */
- source=((UBYTE *)ROMEND)-size;
-
- props=GetProperties(sctx,(ULONG)source,TAG_DONE);
- props|=GetProperties(ctx,(ULONG)source,TAG_DONE);
-
- if (props & MAPP_REMAPPED) {
- Printf("The ROM is already remapped to RAM.\n");
- return 5;
- }
-
-
- /* now allocate the memory for the ROM image. To keep the
- MMU tables as effective as possible, we try to align
- this */
-
- /* We request FAST here, explicitly. Taking chip memory for the
- ROM image doesn't make sense, this isn't fast either... */
-
- mem=AllocAligned(size,(head)?(MEMF_PUBLIC|MEMF_FAST):(MEMF_REVERSE|MEMF_PUBLIC|MEMF_FAST),RemapSize(ctx));
- if (mem) {
-
- pmem=mem;
- psize=size;
- PhysicalLocation(ctx,&pmem,&psize);
- if (psize!=size) {
- Printf("The destination memory is fragmentated, unsupported.\n");
- } else {
-
- /* Read the cache flags */
- props=GetProperties(ctx,(ULONG)mem,TAG_DONE) & CACHEFLAGS;
-
- /* Copy the ROM */
- CopyMemQuick(source,mem,size);
-
- /* Write it out, really */
- CacheClearU();
-
- port=AllocMem(sizeof(struct FastRomPort),MEMF_PUBLIC|MEMF_CLEAR);
- if (port) {
- if (!RemapToRam(ctx,(ULONG)source,(ULONG)pmem,(ULONG)mem,size,protect,noprotect,props)) {
- if (!RemapToRam(sctx,(ULONG)source,(ULONG)pmem,(ULONG)mem,size,protect,noprotect,props)) {
-
- /* we're done now */
- port->frp_Port.mp_Node.ln_Type=NT_MSGPORT;
- port->frp_Port.mp_Node.ln_Name=port->frp_Name;
- strcpy(port->frp_Name,"« MuFastRom »");
- port->frp_Port.mp_Flags=PA_IGNORE;
- NewList(&(port->frp_Port.mp_MsgList));
-
- port->frp_RomStart=source;
- port->frp_Physical=pmem;
- port->frp_Logical=mem;
- port->frp_Size=size;
- port->frp_NoProtect=noprotect;
- port->frp_Protect=protect;
- port->frp_CacheFlags=props;
- port->frp_Base=OpenLibrary("mmu.library",0L);
- AddPort(&(port->frp_Port));
-
- /* Do not release the memory or the port */
- mem=NULL;
- port=NULL;
-
- err=0;
- } else {
- /* The first call failed. Let's see if we can
- undo the first modification */
- if (MapToRom(ctx,(ULONG)source,(ULONG)mem,size)) {
- err=32;
- Printf("Failed to build FastROM, failed to restore old properties.");
- /* We can't release the memory here, simply because
- it is still in use. Urghl. */
- mem=NULL;
- }
- }
- }
- if (port) FreeMem(port,sizeof(struct FastRomPort));
- }
- }
- if (mem) FreeMem(mem,size);
- }
-
- return err;
- }
- ///
- /// RemoveFastRom
- int RemoveFastRom(void)
- {
- struct MMUContext *ctx,*sctx;
- struct FastRomPort *port;
- ULONG size,props;
- void *mem,*pmem,*source;
- int err=ERROR_NO_FREE_STORE;
-
-
- Forbid(); /* Shut up PatchWork */
-
- /* If this is not installed, warn and return. */
-
- port=(struct FastRomPort *)FindPort("« MuFastRom »");
-
- if (port==NULL) {
- Permit();
- Printf("MuFastRom not installed.\n");
- return 5;
- }
- /* Remove it, to ensure nobody else tries to remove it */
- RemPort(&(port->frp_Port));
- Permit();
-
- ctx=DefaultContext(); /* get the default context */
- sctx=SuperContext(ctx); /* get the supervisor context for this one */
-
- size=port->frp_Size;
- pmem=port->frp_Physical;
- mem=port->frp_Logical;
- source=port->frp_RomStart;
- props=port->frp_CacheFlags;
-
- /* Remove the properties right here... */
-
- if (!MapToRom(ctx,(ULONG)source,(ULONG)mem,size)) {
- if (!MapToRom(sctx,(ULONG)source,(ULONG)mem,size)) {
- FreeMem(mem,size);
-
- /* Close the mmu.lib so it can be flushed... */
-
- if (port->frp_Base)
- CloseLibrary(port->frp_Base);
-
- FreeMem(port,sizeof(struct FastRomPort));
- err=0;
- } else {
- /* Failed. We should try to restore the settings */
- RemapToRam(ctx,(ULONG)source,(ULONG)pmem,(ULONG)mem,size,(LONG)(port->frp_Protect),(LONG)(port->frp_NoProtect),props);
- /* In case this doesn't work, tough luck. */
- }
- }
-
- if (err) {
- /* Better luck next time... */
- AddPort(&(port->frp_Port));
- Printf("Can't remove the FastRom node, sorry.\n");
- }
-
- return err;
- }
- ///
- /// RemapToRam
- int RemapToRam(struct MMUContext *ctx,ULONG source,ULONG pmem,ULONG mem,ULONG size,LONG protect,LONG noprotect,ULONG cacheflags)
- {
- struct MinList *ctxl;
- ULONG oldprops;
- ULONG rommask,mirrormask;
-
- if (ctxl=GetMapping(ctx)) {
- /* get the properties of the ROM */
- oldprops=GetProperties(ctx,source,TAG_DONE);
-
- oldprops |= MAPP_REMAPPED;
- rommask=MAPP_REMAPPED|MAPP_COPYBACK; /* Define these bits for the ROM image */
- mirrormask=0; /* ...and these for the RAM mirror */
-
- /* Protection enabled? */
- if (protect) {
- /* active or passive protection? */
- if (oldprops & MAPP_WRITEPROTECTED) {
- /* here aggressive, enable protection
- and allow MuForce to repair access faults */
- rommask |= MAPP_WRITEPROTECTED|MAPP_REPAIRABLE;
- mirrormask |= MAPP_WRITEPROTECTED|MAPP_REPAIRABLE;
- } else {
- rommask |= MAPP_ROM;
- mirrormask |= MAPP_ROM;
- oldprops |= MAPP_ROM;
- }
- } else if (noprotect) {
- /* disable all kinds of protection */
- oldprops &= ~(MAPP_ROM|MAPP_WRITEPROTECTED);
- rommask |= MAPP_ROM | MAPP_WRITEPROTECTED;
- mirrormask |= MAPP_ROM | MAPP_WRITEPROTECTED;
- }
-
- /* Enter caching mode */
- oldprops &= ~CACHEFLAGS;
- oldprops |= cacheflags;
- rommask |= CACHEFLAGS;
-
- if (SetProperties(ctx,oldprops,rommask,source,size,MAPTAG_DESTINATION,pmem,TAG_DONE)) {
- if (SetProperties(ctx,oldprops,mirrormask,mem,size,TAG_DONE)) {
- if (RebuildTree(ctx)) {
- ReleaseMapping(ctx,ctxl);
- return 0; /* Everything worked fine */
- } /* the MMU tree could not be build. It is unmodified in this case */
- }
- } /* the modifications could not be made */
- /* Re-install the old properties. This can't fail. */
- SetPropertyList(ctx,ctxl);
- ReleaseMapping(ctx,ctxl);
- }
-
- return ERROR_NO_FREE_STORE;
- }
- ///
- /// MapToRom
- int MapToRom(struct MMUContext *ctx,ULONG source,ULONG mem,ULONG size)
- {
- struct MinList *ctxl;
-
- if (ctxl=GetMapping(ctx)) {
- if (SetProperties(ctx,0,MAPP_REMAPPED|CACHEFLAGS,source,size,TAG_DONE)) {
- if (SetProperties(ctx,0,MAPP_ROM|MAPP_WRITEPROTECTED|MAPP_REPAIRABLE,mem,size,TAG_DONE)) {
- if (RebuildTree(ctx)) {
- ReleaseMapping(ctx,ctxl);
- return 0; /* Everything worked fine */
- } /* the MMU tree could not be build. It is unmodified in this case */
- }
- } /* the modifications could not be made */
- /* Re-install the old properties. This can't fail. */
- SetPropertyList(ctx,ctxl);
- ReleaseMapping(ctx,ctxl);
- }
-
- return ERROR_NO_FREE_STORE;
- }
- ///
-
-
-
-
-
-
-