home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 397.lha / SetCPU_V1.60 / misc.c < prev    next >
C/C++ Source or Header  |  1990-07-01  |  5KB  |  218 lines

  1. /*
  2.     SetCPU V1.60
  3.     by Dave Haynie, April 13, 1990
  4.     Released to the Public Domain
  5.  
  6.     MISC.C MODULE
  7.     
  8.     This module is responsible for managing ROM image patchs.
  9. */
  10.  
  11. #include "setcpu.h"
  12.  
  13.  
  14. /* ====================================================================== */
  15.  
  16. /* This replaces the Lattice "stricmp()" function, plus it's a better form
  17.    for my needs here. */
  18.    
  19. LONG striequ(s1,s2)
  20. char *s1,*s2;
  21. {
  22.    LONG aok = FALSE;
  23.    
  24.    while (*s1 && *s2 && (aok = (*s1++ & 0xdf) == (*s2++ & 0xdf)));
  25.    return (LONG) (!*s1 && !*s2 && aok);
  26. }
  27.  
  28. LONG strniequ(s1,s2,n)
  29. char *s1,*s2;
  30. unsigned n;
  31. {
  32.    LONG aok = FALSE;
  33.    
  34.    while (n-- && *s1 && *s2 && (aok = (*s1++ & 0xdf) == (*s2++ & 0xdf)));
  35.    return aok;
  36. }
  37.  
  38. /* ====================================================================== */
  39.  
  40. /* The device I/O functions. */
  41.  
  42. /* This routine turns off the motor. */
  43.  
  44. void MotorOff(req)
  45. struct IOStdReq *req;
  46. {
  47.    req->io_Length = 0L;
  48.    req->io_Command = TD_MOTOR;
  49.    (void)DoIO((struct IORequest *)req);
  50. }
  51.  
  52. /* This function fills the buffer "buf" with the contents of the given
  53.    sector number.  Returns 0 if there's no error.  */
  54.  
  55. BYTE ReadBuf(buf,sect,req)
  56. char *buf;
  57. LONG sect;
  58. struct IOStdReq *req;
  59. {
  60.    req->io_Length = 512L;
  61.    req->io_Data = (APTR) buf;
  62.    req->io_Command = CMD_READ;
  63.    req->io_Offset = (512L * sect);
  64.    (void)DoIO((struct IORequest *)req);
  65.    return req->io_Error;
  66. }
  67.  
  68. /* This function takes in a DOS name, and returns either the 
  69.    trackdisk.device unit that it corresponds to, or -1L. */
  70.    
  71. LONG CheckTDDev(name)
  72. char *name;
  73. {
  74.    char *devname;
  75.    struct DosLibrary *dl;
  76.    struct RootNode *dr;
  77.    struct DosInfo *di;
  78.    struct DeviceNode *dev;
  79.    struct FileSysStartupMsg *start;
  80.    struct DosEnvec *env;
  81.  
  82.    dl = (struct DosLibrary *)OpenLibrary("dos.library",0L);
  83.    dr = (struct RootNode *)dl->dl_Root;
  84.    di = (struct DosInfo *)BADDR(dr->rn_Info);
  85.    dev = (struct DeviceNode *)BADDR(di->di_DevInfo);
  86.    CloseLibrary((struct Library *)dl);
  87.  
  88.   /* Next we find the device */
  89.    if (name[strlen(name)-1] == ':') name[strlen(name)-1] = '\0';
  90.  
  91.    for (; dev != NULL; dev = (struct DeviceNode *)BADDR(dev->dn_Next)) {
  92.       if (dev->dn_Type != DLT_DEVICE) continue;
  93.       devname = (char *)BADDR(dev->dn_Name);
  94.       if (strniequ(name,devname+1,(unsigned)devname[0])) break;
  95.    }
  96.  
  97.   /* Is it a valid trackdisk.device? */
  98.    if (!dev) return -1L;
  99.    if (!(start = (struct FileSysStartupMsg *)BADDR(dev->dn_Startup))) return -1L;
  100.    env = (struct DosEnvec *)BADDR(start->fssm_Environ);
  101.    if (env->de_BlocksPerTrack != 11L || env->de_LowCyl != 0L) return -1L;
  102.    devname = (char *)BADDR(start->fssm_Device);
  103.    if (!strniequ(devname+1,"trackdisk.device",16)) return -1L;
  104.  
  105.    return start->fssm_Unit;
  106. }
  107.  
  108. /* ====================================================================== */
  109.  
  110. /* The patch manager stuff. */
  111.  
  112. /* The "JSR address" opcode used for my patches. */
  113.  
  114. #define JSR_OPCODE    0x4eb9
  115.  
  116. /* These are for some string patches */
  117.  
  118. static char DiskS[] = "SALV to recover it! ";
  119.  
  120. /* These are the V1.3 patches */
  121.  
  122. struct pitem PL_345[] = {
  123.    { PT_KEYBOARD,0,0x2528a,  0L, NULL },        /* Keyboard... */
  124.    { PT_STRING,  0,0x3fe19, 20L, (UWORD *)DiskS },    /* "DiskDoctor" name */
  125.    { PT_END,     0,      0,  0L, NULL }
  126. };
  127.  
  128. struct pitem PL_33180[] = {
  129.    { PT_KEYBOARD,0,0x2572a,  0L, NULL },        /* Keyboard... */
  130.    { PT_STRING,  0,0x3fe11, 20L, (UWORD *)DiskS },    /* "DiskDoctor" name */
  131.    { PT_END,     0,      0,  0L, NULL }
  132. };
  133.  
  134. /* This is main system patch list. */
  135.  
  136. struct patch SystemPatch[] = {
  137.    { &SystemPatch[1], &PL_345[0],34,5 },
  138.    { NULL, &PL_33180[0],33,180 }
  139. };
  140.  
  141. /* This is a pointer to the base of the last applied patch, for making
  142.    patch links.  The structure of any applied allocated patch, such as
  143.    a JSR patch, is a link pointer, the actual patch size, and then the
  144.    patch code.  This lets any version of SetCPU remove allocated patches
  145.    from any other version, providing it can locate the tag. */
  146.  
  147. struct MemChunk *lastpatch = NULL;
  148.  
  149. /* This routine applys the patch */
  150.  
  151. LONG AddPatch(rom,lst,tag)
  152. ULONG rom;
  153. struct patch *lst;
  154. struct systag *tag;
  155. {
  156.    UWORD *kickver = (UWORD *)(0x100000C - ( * (ULONG *) 0xFFFFEC ));
  157.    UWORD *addr, *base;
  158.    struct pitem *item;
  159.    struct MemChunk *chunk;
  160.    LONG any = FALSE;
  161.  
  162.    while (lst) {
  163.       if (lst->Version == kickver[0] && lst->Revision == kickver[1]) {
  164.          for (item = &lst->list[0]; item->Type != PT_END; ++item) {
  165.             any = TRUE;
  166.             switch (item->Type) {
  167.                case PT_IGNORE :
  168.                   break;
  169.                case PT_STRING :
  170.                   MemCopy(item->Code,(char *)(rom+item->Offset),item->Length);
  171.                   ++tag->patches;
  172.                   break;
  173.                case PT_JSR    :
  174.                   chunk = (struct MemChunk *)AllocMem(item->Length+14L,0L);
  175.                   chunk->mc_Next = lastpatch;
  176.                   lastpatch = chunk;
  177.                   chunk->mc_Bytes = item->Length+14L;
  178.                   addr = (UWORD *)(((ULONG)chunk)+8L);
  179.                   base = (UWORD *)(rom+item->Offset);
  180.                   MemCopy(base,addr,6L);
  181.                   base[0] = (UWORD)JSR_OPCODE;
  182.                   base[1] = (UWORD)(((ULONG)addr)>>16L);
  183.                   base[2] = (UWORD)(((ULONG)addr)&0x0ffff);
  184.                   MemCopy(item->Code,&addr[3],item->Length);
  185.                   ++tag->patches;
  186.                   break;
  187.             }
  188.          }
  189.       }
  190.       lst = lst->next;
  191.    }
  192.    return any;
  193. }
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207.  
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.