home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 2: PC
/
frozenfish_august_1995.bin
/
bbs
/
d04xx
/
d0400.lha
/
SetCPU
/
misc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-11-03
|
5KB
|
218 lines
/*
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;
}