home *** CD-ROM | disk | FTP | other *** search
- /*
- SetCPU V1.60
- by Dave Haynie, April 13, 1990
- Released to the Public Domain
-
- MISC.C MODULE
-
- This module is responsible for managing ROM image patchs.
- */
-
- #include "setcpu.h"
-
-
- /* ====================================================================== */
-
- /* This replaces the Lattice "stricmp()" function, plus it's a better form
- for my needs here. */
-
- LONG striequ(s1,s2)
- char *s1,*s2;
- {
- LONG aok = FALSE;
-
- while (*s1 && *s2 && (aok = (*s1++ & 0xdf) == (*s2++ & 0xdf)));
- return (LONG) (!*s1 && !*s2 && aok);
- }
-
- LONG strniequ(s1,s2,n)
- char *s1,*s2;
- unsigned n;
- {
- LONG aok = FALSE;
-
- while (n-- && *s1 && *s2 && (aok = (*s1++ & 0xdf) == (*s2++ & 0xdf)));
- return aok;
- }
-
- /* ====================================================================== */
-
- /* The device I/O functions. */
-
- /* This routine turns off the motor. */
-
- void MotorOff(req)
- struct IOStdReq *req;
- {
- req->io_Length = 0L;
- req->io_Command = TD_MOTOR;
- (void)DoIO((struct IORequest *)req);
- }
-
- /* This function fills the buffer "buf" with the contents of the given
- sector number. Returns 0 if there's no error. */
-
- BYTE ReadBuf(buf,sect,req)
- char *buf;
- LONG sect;
- struct IOStdReq *req;
- {
- req->io_Length = 512L;
- req->io_Data = (APTR) buf;
- req->io_Command = CMD_READ;
- req->io_Offset = (512L * sect);
- (void)DoIO((struct IORequest *)req);
- return req->io_Error;
- }
-
- /* This function takes in a DOS name, and returns either the
- trackdisk.device unit that it corresponds to, or -1L. */
-
- LONG CheckTDDev(name)
- char *name;
- {
- char *devname;
- struct DosLibrary *dl;
- struct RootNode *dr;
- struct DosInfo *di;
- struct DeviceNode *dev;
- struct FileSysStartupMsg *start;
- struct DosEnvec *env;
-
- dl = (struct DosLibrary *)OpenLibrary("dos.library",0L);
- dr = (struct RootNode *)dl->dl_Root;
- di = (struct DosInfo *)BADDR(dr->rn_Info);
- dev = (struct DeviceNode *)BADDR(di->di_DevInfo);
- CloseLibrary((struct Library *)dl);
-
- /* Next we find the device */
- if (name[strlen(name)-1] == ':') name[strlen(name)-1] = '\0';
-
- for (; dev != NULL; dev = (struct DeviceNode *)BADDR(dev->dn_Next)) {
- if (dev->dn_Type != DLT_DEVICE) continue;
- devname = (char *)BADDR(dev->dn_Name);
- if (strniequ(name,devname+1,(unsigned)devname[0])) break;
- }
-
- /* Is it a valid trackdisk.device? */
- if (!dev) return -1L;
- if (!(start = (struct FileSysStartupMsg *)BADDR(dev->dn_Startup))) return -1L;
- env = (struct DosEnvec *)BADDR(start->fssm_Environ);
- if (env->de_BlocksPerTrack != 11L || env->de_LowCyl != 0L) return -1L;
- devname = (char *)BADDR(start->fssm_Device);
- if (!strniequ(devname+1,"trackdisk.device",16)) return -1L;
-
- return start->fssm_Unit;
- }
-
- /* ====================================================================== */
-
- /* The patch manager stuff. */
-
- /* The "JSR address" opcode used for my patches. */
-
- #define JSR_OPCODE 0x4eb9
-
- /* These are for some string patches */
-
- static char DiskS[] = "SALV to recover it! ";
-
- /* These are the V1.3 patches */
-
- struct pitem PL_345[] = {
- { PT_KEYBOARD,0,0x2528a, 0L, NULL }, /* Keyboard... */
- { PT_STRING, 0,0x3fe19, 20L, (UWORD *)DiskS }, /* "DiskDoctor" name */
- { PT_END, 0, 0, 0L, NULL }
- };
-
- struct pitem PL_33180[] = {
- { PT_KEYBOARD,0,0x2572a, 0L, NULL }, /* Keyboard... */
- { PT_STRING, 0,0x3fe11, 20L, (UWORD *)DiskS }, /* "DiskDoctor" name */
- { PT_END, 0, 0, 0L, NULL }
- };
-
- /* This is main system patch list. */
-
- struct patch SystemPatch[] = {
- { &SystemPatch[1], &PL_345[0],34,5 },
- { NULL, &PL_33180[0],33,180 }
- };
-
- /* This is a pointer to the base of the last applied patch, for making
- patch links. The structure of any applied allocated patch, such as
- a JSR patch, is a link pointer, the actual patch size, and then the
- patch code. This lets any version of SetCPU remove allocated patches
- from any other version, providing it can locate the tag. */
-
- struct MemChunk *lastpatch = NULL;
-
- /* This routine applys the patch */
-
- LONG AddPatch(rom,lst,tag)
- ULONG rom;
- struct patch *lst;
- struct systag *tag;
- {
- UWORD *kickver = (UWORD *)(0x100000C - ( * (ULONG *) 0xFFFFEC ));
- UWORD *addr, *base;
- struct pitem *item;
- struct MemChunk *chunk;
- LONG any = FALSE;
-
- while (lst) {
- if (lst->Version == kickver[0] && lst->Revision == kickver[1]) {
- for (item = &lst->list[0]; item->Type != PT_END; ++item) {
- any = TRUE;
- switch (item->Type) {
- case PT_IGNORE :
- break;
- case PT_STRING :
- MemCopy(item->Code,(char *)(rom+item->Offset),item->Length);
- ++tag->patches;
- break;
- case PT_JSR :
- chunk = (struct MemChunk *)AllocMem(item->Length+14L,0L);
- chunk->mc_Next = lastpatch;
- lastpatch = chunk;
- chunk->mc_Bytes = item->Length+14L;
- addr = (UWORD *)(((ULONG)chunk)+8L);
- base = (UWORD *)(rom+item->Offset);
- MemCopy(base,addr,6L);
- base[0] = (UWORD)JSR_OPCODE;
- base[1] = (UWORD)(((ULONG)addr)>>16L);
- base[2] = (UWORD)(((ULONG)addr)&0x0ffff);
- MemCopy(item->Code,&addr[3],item->Length);
- ++tag->patches;
- break;
- }
- }
- }
- lst = lst->next;
- }
- return any;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-