home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / emulate / fast_a_m.lha / Fast_A-Max_2.5 / Fast_A-Max.c < prev    next >
C/C++ Source or Header  |  1993-04-05  |  8KB  |  228 lines

  1. /*============================================================================*/
  2.  
  3. /* Fast A-Max.c version 2.5,  written by John O'Leary,  93.3.29 */
  4. /* Upgrade (and rename) of FastMax version 3,  written  90.5.28 */
  5.  
  6. /* Must be compiled so that parameters are passed on the stack */
  7. /* and function return values are passed back in D0 */
  8. /* and size of  char == byte,  short == word,  long == longword */
  9.  
  10. /*============================================================================*/
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14.  
  15. FILE  * F;
  16. char  * InFile1 = "A-Max Startup";
  17. char  * InFile2 = "A-MaxStartup";
  18. char  * InFile;
  19. char  * BackupFile = "Original A-Max Startup";
  20. char  * OutFile = "A-Max Fast Startup";
  21. char  * ROMsFile = "Mac ROMs";
  22. unsigned char  * Buffer, far ROMs [1 << 17];
  23. extern far ReadFile;
  24. unsigned long  (* ReadROM) (unsigned char *, long);
  25.   /* ReadROM is a pointer to a function returning an unsigned long value */
  26. unsigned long  ROM_ID, ROMSize, FileSize, Start, Finish, I;
  27.  
  28. void  main (int, char * []);
  29. void  CleanUp (unsigned short int, char *, char *, char *);
  30.  
  31. /*============================================================================*/
  32.  
  33. void main (argc, argv)
  34.  
  35. int  argc;
  36. char  * argv [];
  37.  
  38.    {
  39.    if (argc > 1 & argv [1] [0] == '?' | argc > 3)
  40.       CleanUp (0, "A-Max program patch\nUSAGE: ", argv [0],
  41.        " [Original_filename [Backup_filename]]\n");
  42.    if (argc > 1)  InFile = argv [1];  else  InFile = InFile1;
  43.    if (argc > 2)  BackupFile = argv [2];
  44.  
  45. /*------------------------------------------------------------------------------
  46.     Read original program file
  47. ------------------------------------------------------------------------------*/
  48.  
  49.    if ((F = fopen (InFile, "r")) == 0)
  50.       if (argc > 1)
  51.          goto NO_INPUT;
  52.       else
  53.          {
  54.          InFile = InFile2;
  55.          if ((F = fopen (InFile, "r")) == 0)
  56. NO_INPUT:
  57.             CleanUp (0, "Couldn't open file '", InFile, "' for input\n");
  58.          }
  59.    fseek (F, 0L, 2);
  60.    if ((FileSize = ftell (F)) <= 0)
  61.       CleanUp (1, "Input file '", InFile, "' is empty.\n");
  62.    if ((Buffer = malloc (FileSize)) == NULL)
  63.       CleanUp (1, "Unable to allocate memory for buffer.\n", "", "");
  64.    printf ("Reading original program file '%s'... ", InFile);
  65.    rewind (F);
  66.    FileSize = fread (Buffer, 1, FileSize, F);
  67.    fclose (F);
  68.    printf ("%ld bytes.\n", FileSize);
  69.  
  70. /*------------------------------------------------------------------------------
  71.    Search for beginning and end of ReadROM routine
  72. ------------------------------------------------------------------------------*/
  73.  
  74.    printf ("Searching program for ReadROM routine... ");
  75.    for (Start = 0;
  76.     Buffer [Start]   != 0x48 |
  77.     Buffer [Start+1] != 0xE7 |
  78.     Buffer [Start+2] != 0x7F |
  79.     Buffer [Start+3] != 0xFE |
  80.     Buffer [Start+4] != 0x78 |
  81.     Buffer [Start+5] != 0x04 |
  82.     Buffer [Start+6] != 0x20 |
  83.     Buffer [Start+7] != 0x6F;
  84.     Start ++)
  85.       if (Start >= FileSize-100)
  86.          CleanUp (2, "not found.\n", "", "");
  87.    /* Start is index of first byte of ReadROM routine */
  88.  
  89.    for (Finish = Start+10;
  90.     Buffer [Finish-7] != 0xE3 |
  91.     Buffer [Finish-6] != 0xEB |
  92.     Buffer [Finish-5] != 0xE7 |
  93.     Buffer [Finish-4] != 0xEF |
  94.     Buffer [Finish-3] != 0xF3 |
  95.     Buffer [Finish-2] != 0xFB |
  96.     Buffer [Finish-1] != 0xF7 |
  97.     Buffer [Finish]   != 0xFF;
  98.     Finish ++)
  99.       if (Finish >= FileSize-1)
  100.          CleanUp (2, "not found.\n", "", "");
  101.    /* Finish is index of byte immediately following ReadROM routine */
  102.  
  103. /*------------------------------------------------------------------------------
  104.    Patch (DiskResource -> dr_Flags) handling in ReadROM routine
  105.    of A-Max version 1 for compatibility with SetPatch
  106. ------------------------------------------------------------------------------*/
  107.  
  108.    for (I = Start;  I < Finish;  I ++)
  109.       if (Buffer [I]   == 0x08 &&
  110.           Buffer [I+1] == 0xE9 &&
  111.           Buffer [I+2] == 0x00 &&
  112.           Buffer [I+3] == 0x07)
  113.          {
  114.          Buffer [I] = 0x08;  Buffer [I+1] = 0x29;  /* replace BSET with BTST */
  115.          }
  116.    printf ("found.\n");
  117.  
  118. /*------------------------------------------------------------------------------
  119.    Call original ReadROM routine with pointer to ROMs buffer and
  120.    zero longword (needed by ReadROM of A-Max version > 2.0) on the stack
  121.    Amigas with MMUs may not like this!
  122. ------------------------------------------------------------------------------*/
  123.  
  124.    printf ("WARNING:  Interrupts will be disabled for up to 30 seconds... Press RETURN");
  125.    getchar ();
  126.    printf ("Looking for Macintosh ROMs... ");
  127.    ReadROM = (unsigned long (*) ()) & Buffer [Start];
  128.    ROM_ID = ReadROM (ROMs, 0L);
  129.  
  130. /*------------------------------------------------------------------------------
  131.    The ROM ID is returned in D0
  132.    High word == 0x69 for 64K ROMs, 0x75 for 128K ROMs
  133.    Low word == bit number for drive SEL
  134. ------------------------------------------------------------------------------*/
  135.  
  136.    if (ROM_ID >> 16 == 0x69)
  137.       ROMSize = 1 << 16  /* 64K */;
  138.    else if (ROM_ID >> 16 == 0x75)
  139.       ROMSize = 1 << 17  /* 128K */;
  140.    else
  141.          CleanUp (2, "not found.\n", "", "");
  142.    printf ("%dK ROMs found in drive number %d\n",
  143.     (short) (ROMSize >> 10), (short) ROM_ID - 3);
  144.  
  145. /*------------------------------------------------------------------------------
  146.    Write ROM ID and contents of ROMs to file
  147. ------------------------------------------------------------------------------*/
  148.  
  149.    if ((F = fopen (ROMsFile, "w")) == 0)
  150.       CleanUp (2, "couldn't open file '", ROMsFile, "' for output\n");
  151.    printf ("Writing contents of ROMs to file '%s'... ", ROMsFile);
  152.    if (fwrite ((unsigned char *) & ROM_ID, 4, 1, F) != 1)
  153.       CleanUp (3, "error.\n", "", "");
  154.    if (fwrite ((unsigned char *) ROMs, 1, ROMSize, F) != ROMSize)
  155.       CleanUp (3, "error.\n", "", "");
  156.    fclose (F);
  157.    printf ("done.\n");
  158.  
  159. /*------------------------------------------------------------------------------
  160.    Write new program file, with ReadROM replaced by ReadFile routine
  161. ------------------------------------------------------------------------------*/
  162.  
  163.    if ((F = fopen (OutFile, "w")) == 0)
  164.       CleanUp (2, "couldn't open file '", OutFile, "' for output\n");
  165.    printf ("Writing patched program file '%s'... ", OutFile);
  166.    if (fwrite ((unsigned char *) Buffer, 1, Start, F) != Start)
  167.       CleanUp (4, "error.\n", "", "");
  168.    if (fwrite ((unsigned char *) & ReadFile, 1, Finish - Start, F) != Finish - Start)
  169.       CleanUp (4, "error.\n", "", "");
  170.    if (fwrite ((unsigned char *) & Buffer [Finish], 1, FileSize - Finish, F) != FileSize - Finish)
  171.       CleanUp (4, "error.\n", "", "");
  172.    printf ("done.\n");
  173.    fclose (F);
  174.    free (Buffer);
  175.  
  176. /*------------------------------------------------------------------------------
  177.    Backup original program file
  178. ------------------------------------------------------------------------------*/
  179.  
  180.    printf ("Backing up original '%s' to '%s'... ", InFile, BackupFile);
  181.    remove (BackupFile);
  182.    if (rename (InFile, BackupFile) != 0)
  183.       CleanUp (0, "couldn't rename file.\n", "", "");
  184.    printf ("done.\n");
  185.  
  186. /*------------------------------------------------------------------------------
  187.    Rename patched program file
  188. ------------------------------------------------------------------------------*/
  189.  
  190.    printf ("Renaming new file '%s' as '%s'... ", OutFile, InFile);
  191.    if (rename (OutFile, InFile) != 0)
  192.       CleanUp (0, "couldn't rename file.\n", "", "");
  193.    printf ("done.\n");
  194.    }
  195.  
  196. /*============================================================================*/
  197.  
  198. void CleanUp (Level, Message1, Message2, Message3)
  199.  
  200.    unsigned short int  Level;
  201.    char  * Message1, * Message2, * Message3;
  202.  
  203.    {
  204.    printf (Message1);
  205.    printf (Message2);
  206.    printf (Message3);
  207.    switch (Level)
  208.       {
  209.       case (4):
  210.          fclose (F);
  211.          remove (OutFile);
  212.          printf ("%s deleted.\n", OutFile);
  213.          free (Buffer);
  214.          break;
  215.       case (3):
  216.          fclose (F);
  217.          remove (ROMsFile);
  218.          printf ("%s deleted.\n", ROMsFile);
  219.       case (2):
  220.          free (Buffer);
  221.          break;
  222.       case (1):
  223.          fclose (F);
  224.          break;
  225.       }
  226.    exit (20 + Level);
  227.    }
  228.