home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Emulation / BasiliskII / src / rsrc_patches.cpp < prev    next >
C/C++ Source or Header  |  1999-10-31  |  20KB  |  603 lines

  1. /*
  2.  *  rsrc_patches.cpp - Resource patches
  3.  *
  4.  *  Basilisk II (C) 1997-1999 Christian Bauer
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public License as published by
  8.  *  the Free Software Foundation; either version 2 of the License, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  */
  20.  
  21. #include <string.h>
  22.  
  23. #include "sysdeps.h"
  24. #include "cpu_emulation.h"
  25. #include "main.h"
  26. #include "emul_op.h"
  27. #include "audio.h"
  28. #include "audio_defs.h"
  29. #include "rsrc_patches.h"
  30.  
  31. #if ENABLE_MON
  32. #include "mon.h"
  33. #endif
  34.  
  35. #define DEBUG 0
  36. #include "debug.h"
  37.  
  38.  
  39. #if !EMULATED_68K
  40. // Assembly functions
  41. extern "C" void Scod060Patch1(void);
  42. extern "C" void Scod060Patch2(void);
  43. extern "C" void ThInitFPUPatch(void);
  44. #endif
  45.  
  46.  
  47. /*
  48.  *  Search resource for byte string, return offset (or 0)
  49.  */
  50.  
  51. static uint32 find_rsrc_data(const uint8 *rsrc, uint32 max, const uint8 *search, uint32 search_len, uint32 ofs = 0)
  52. {
  53.     while (ofs < max - search_len) {
  54.         if (!memcmp(rsrc + ofs, search, search_len))
  55.             return ofs;
  56.         ofs++;
  57.     }
  58.     return 0;
  59. }
  60.  
  61.  
  62. /*
  63.  *  Resource patches via vCheckLoad
  64.  */
  65.  
  66. void CheckLoad(uint32 type, int16 id, uint8 *p, uint32 size)
  67. {
  68.     uint16 *p16;
  69.     uint32 base;
  70.     D(bug("vCheckLoad %c%c%c%c (%08lx) ID %d, data %08lx, size %ld\n", (char)(type >> 24), (char)((type >> 16) & 0xff), (char )((type >> 8) & 0xff), (char )(type & 0xff), type, id, p, size));
  71.  
  72.     if (type == 'boot' && id == 3) {
  73.         D(bug(" boot 3 found\n"));
  74.  
  75.         // Set boot stack pointer (7.5, 7.6, 7.6.1, 8.0)
  76.         static const uint8 dat[] = {0x22, 0x00, 0xe4, 0x89, 0x90, 0x81, 0x22, 0x40};
  77.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  78.         if (base) {
  79.             p16 = (uint16 *)(p + base + 6);
  80.             *p16 = htons(M68K_EMUL_OP_FIX_BOOTSTACK);
  81.             FlushCodeCache(p + base + 6, 2);
  82.             D(bug("  patch 1 applied\n"));
  83.         }
  84.  
  85. #if !ROM_IS_WRITE_PROTECTED
  86.         // Set fake handle at 0x0000 to some safe place (so broken Mac programs won't write into Mac ROM) (7.5, 8.0)
  87.         static const uint8 dat2[] = {0x20, 0x78, 0x02, 0xae, 0xd1, 0xfc, 0x00, 0x01, 0x00, 0x00, 0x21, 0xc8, 0x00, 0x00};
  88.         base = find_rsrc_data(p, size, dat2, sizeof(dat2));
  89.         if (base) {
  90.             p16 = (uint16 *)(p + base);
  91.  
  92. #if defined(AMIGA)
  93.             // Set 0x0000 to scratch memory area
  94.             extern uint32 ScratchMem;
  95.             *p16++ = htons(0x207c);            // move.l    #ScratchMem,a0
  96.             *p16++ = htons(ScratchMem >> 16);
  97.             *p16++ = htons(ScratchMem);
  98.             *p16++ = htons(M68K_NOP);
  99.             *p16 = htons(M68K_NOP);
  100. #else
  101. #error System specific handling for writable ROM is required here
  102. #endif
  103.             FlushCodeCache(p + base, 14);
  104.             D(bug("  patch 2 applied\n"));
  105.         }
  106.  
  107.     } else if (type == 'boot' && id == 2) {
  108.         D(bug(" boot 2 found\n"));
  109.  
  110.         // Set fake handle at 0x0000 to some safe place (so broken Mac programs won't write into Mac ROM) (7.5, 8.0)
  111.         static const uint8 dat[] = {0x20, 0x78, 0x02, 0xae, 0xd1, 0xfc, 0x00, 0x01, 0x00, 0x00, 0x21, 0xc8, 0x00, 0x00};
  112.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  113.         if (base) {
  114.             p16 = (uint16 *)(p + base);
  115.  
  116. #if defined(AMIGA)
  117.             // Set 0x0000 to scratch memory area
  118.             extern uint32 ScratchMem;
  119.             *p16++ = htons(0x207c);            // move.l    #ScratchMem,a0
  120.             *p16++ = htons(ScratchMem >> 16);
  121.             *p16++ = htons(ScratchMem);
  122.             *p16++ = htons(M68K_NOP);
  123.             *p16 = htons(M68K_NOP);
  124. #else
  125. #error System specific handling for writable ROM is required here
  126. #endif
  127.             FlushCodeCache(p + base, 14);
  128.             D(bug("  patch 1 applied\n"));
  129.         }
  130. #endif
  131.  
  132.     } else if (type == 'PTCH' && id == 630) {
  133.         D(bug("PTCH 630 found\n"));
  134.  
  135.         // Don't replace Time Manager (Classic ROM, 6.0.3)
  136.         static const uint8 dat[] = {0x30, 0x3c, 0x00, 0x58, 0xa2, 0x47};
  137.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  138.         if (base) {
  139.             p16 = (uint16 *)(p + base);
  140.             p16[2] = htons(M68K_NOP);
  141.             p16[7] = htons(M68K_NOP);
  142.             p16[12] = htons(M68K_NOP);
  143.             FlushCodeCache(p + base, 26);
  144.             D(bug("  patch 1 applied\n"));
  145.         }
  146.  
  147.         // Don't replace Time Manager (Classic ROM, 6.0.8)
  148.         static const uint8 dat2[] = {0x70, 0x58, 0xa2, 0x47};
  149.         base = find_rsrc_data(p, size, dat2, sizeof(dat2));
  150.         if (base) {
  151.             p16 = (uint16 *)(p + base);
  152.             p16[1] = htons(M68K_NOP);
  153.             p16[5] = htons(M68K_NOP);
  154.             p16[9] = htons(M68K_NOP);
  155.             FlushCodeCache(p + base, 20);
  156.             D(bug("  patch 1 applied\n"));
  157.         }
  158.  
  159.     } else if (type == 'ptch' && id == 26) {
  160.         D(bug(" ptch 26 found\n"));
  161.  
  162.         // Trap ABC4 is initialized with absolute ROM address (7.5, 7.6, 7.6.1, 8.0)
  163.         static const uint8 dat[] = {0x40, 0x83, 0x36, 0x10};
  164.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  165.         if (base) {
  166.             p16 = (uint16 *)(p + base);
  167.             *p16++ = htons((ROMBaseMac + 0x33610) >> 16);
  168.             *p16 = htons((ROMBaseMac + 0x33610) & 0xffff);
  169.             FlushCodeCache(p + base, 4);
  170.             D(bug("  patch 1 applied\n"));
  171.         }
  172.  
  173.     } else if (type == 'ptch' && id == 34) {
  174.         D(bug(" ptch 34 found\n"));
  175.  
  176.         // Don't wait for VIA (Classic ROM, 6.0.8)
  177.         static const uint8 dat[] = {0x22, 0x78, 0x01, 0xd4, 0x10, 0x11, 0x02, 0x00, 0x00, 0x30};
  178.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  179.         if (base) {
  180.             p16 = (uint16 *)(p + base + 14);
  181.             *p16 = htons(M68K_NOP);
  182.             FlushCodeCache(p + base + 14, 2);
  183.             D(bug("  patch 1 applied\n"));
  184.         }
  185.  
  186.         // Don't replace ADBOp() (Classic ROM, 6.0.8)
  187.         static const uint8 dat2[] = {0x21, 0xc0, 0x05, 0xf0};
  188.         base = find_rsrc_data(p, size, dat2, sizeof(dat2));
  189.         if (base) {
  190.             p16 = (uint16 *)(p + base);
  191.             *p16++ = htons(M68K_NOP);
  192.             *p16 = htons(M68K_NOP);
  193.             FlushCodeCache(p + base, 4);
  194.             D(bug("  patch 2 applied\n"));
  195.         }
  196.  
  197. #if !EMULATED_68K
  198.     } else if (CPUIs68060 && (type == 'gpch' && id == 669 || type == 'lpch' && id == 63)) {
  199.         D(bug(" gpch 669/lpch 63 found\n"));
  200.  
  201.         static uint16 ThPatchSpace[1024];    // Replacement routines are constructed here
  202.         uint16 *q = ThPatchSpace;
  203.         uint32 start;
  204.         int i;
  205.  
  206.         // Patch Thread Manager thread switcher for 68060 FPU (7.5, 8.0)
  207.         static const uint8 dat[] = {0x22, 0x6f, 0x00, 0x08, 0x20, 0x2f, 0x00, 0x04, 0x67, 0x18};
  208.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  209.         if (base) {    // Skip first routine (no FPU -> no FPU)
  210.  
  211.             base = find_rsrc_data(p, size - base - 2, dat, sizeof(dat), base + 2);
  212.             if (base) {    // no FPU -> FPU
  213.  
  214.                 p16 = (uint16 *)(p + base);
  215.                 start = (uint32)q;
  216.                 for (i=0; i<28; i++) *q++ = *p16++;
  217.                 *q++ = htons(0x4a2f);        // tst.b 2(sp)                (null FPU state or "FPU state saved" flag set?)
  218.                 *q++ = htons(2);
  219.                 *q++ = htons(0x6712);        // beq
  220.                 *q++ = htons(0x588f);        // addq.l #2,sp                (flag set, skip it)
  221.                 *q++ = htons(0xf21f);        // fmove.l (sp)+,fpcr        (restore FPU registers)
  222.                 *q++ = htons(0x9000);
  223.                 *q++ = htons(0xf21f);        // fmove.l (sp)+,fpsr
  224.                 *q++ = htons(0x8800);
  225.                 *q++ = htons(0xf21f);        // fmove.l (sp)+,fpiar
  226.                 *q++ = htons(0x8400);
  227.                 *q++ = htons(0xf21f);        // fmovem.x (sp)+,fp0-fp7
  228.                 *q++ = htons(0xd0ff);
  229.                 *q++ = htons(0xf35f);        // frestore (sp)+
  230.                 *q++ = htons(0x4e75);        // rts
  231.  
  232.                 p16 = (uint16 *)(p + base);
  233.                 *p16++ = htons(M68K_JMP);
  234.                 *p16++ = htons(start >> 16);
  235.                 *p16 = htons(start & 0xffff);
  236.                 FlushCodeCache(p + base, 6);
  237.                 D(bug("  patch 1 applied\n"));
  238.  
  239.                 static const uint8 dat2[] = {0x22, 0x6f, 0x00, 0x08, 0x20, 0x2f, 0x00, 0x04, 0x67, 0x28};
  240.                 base = find_rsrc_data(p, size, dat2, sizeof(dat2));
  241.                 if (base) {    // FPU -> FPU
  242.  
  243.                     p16 = (uint16 *)(p + base);
  244.                     start = (uint32)q;
  245.                     for (i=0; i<4; i++) *q++ = *p16++;
  246.                     *q++ = htons(0x6736);        // beq
  247.                     *q++ = htons(0xf327);        // fsave -(sp)                (save FPU state frame)
  248.                     *q++ = htons(0x4a2f);        // tst.b 2(sp)                (null FPU state?)
  249.                     *q++ = htons(2);
  250.                     *q++ = htons(0x6716);        // beq
  251.                     *q++ = htons(0xf227);        // fmovem.x fp0-fp7,-(sp)    (no, save FPU registers)
  252.                     *q++ = htons(0xe0ff);
  253.                     *q++ = htons(0xf227);        // fmove.l fpiar,-(sp)
  254.                     *q++ = htons(0xa400);
  255.                     *q++ = htons(0xf227);        // fmove.l fpsr,-(sp)
  256.                     *q++ = htons(0xa800);
  257.                     *q++ = htons(0xf227);        // fmove.l fpcr,-(sp)
  258.                     *q++ = htons(0xb000);
  259.                     *q++ = htons(0x4879);        // pea -1                    (push "FPU state saved" flag)
  260.                     *q++ = htons(0xffff);
  261.                     *q++ = htons(0xffff);
  262.                     p16 += 9;
  263.                     for (i=0; i<23; i++) *q++ = *p16++;
  264.                     *q++ = htons(0x4a2f);        // tst.b 2(sp)                (null FPU state or "FPU state saved" flag set?)
  265.                     *q++ = htons(2);
  266.                     *q++ = htons(0x6712);        // beq
  267.                     *q++ = htons(0x588f);        // addq.l #2,sp                (flag set, skip it)
  268.                     *q++ = htons(0xf21f);        // fmove.l (sp)+,fpcr        (restore FPU registers)
  269.                     *q++ = htons(0x9000);
  270.                     *q++ = htons(0xf21f);        // fmove.l (sp)+,fpsr
  271.                     *q++ = htons(0x8800);
  272.                     *q++ = htons(0xf21f);        // fmove.l (sp)+,fpiar
  273.                     *q++ = htons(0x8400);
  274.                     *q++ = htons(0xf21f);        // fmovem.x (sp)+,fp0-fp7
  275.                     *q++ = htons(0xd0ff);
  276.                     *q++ = htons(0xf35f);        // frestore (sp)+
  277.                     *q++ = htons(0x4e75);        // rts
  278.  
  279.                     p16 = (uint16 *)(p + base);
  280.                     *p16++ = htons(M68K_JMP);
  281.                     *p16++ = htons(start >> 16);
  282.                     *p16 = htons(start & 0xffff);
  283.                     FlushCodeCache(p + base, 6);
  284.                     D(bug("  patch 2 applied\n"));
  285.  
  286.                     base = find_rsrc_data(p, size - base - 2, dat2, sizeof(dat2), base + 2);
  287.                     if (base) {    // FPU -> no FPU
  288.     
  289.                         p16 = (uint16 *)(p + base);
  290.                         start = (uint32)q;
  291.                         for (i=0; i<4; i++) *q++ = *p16++;
  292.                         *q++ = htons(0x6736);        // beq
  293.                         *q++ = htons(0xf327);        // fsave -(sp)                (save FPU state frame)
  294.                         *q++ = htons(0x4a2f);        // tst.b 2(sp)                (null FPU state?)
  295.                         *q++ = htons(2);
  296.                         *q++ = htons(0x6716);        // beq
  297.                         *q++ = htons(0xf227);        // fmovem.x fp0-fp7,-(sp)    (no, save FPU registers)
  298.                         *q++ = htons(0xe0ff);
  299.                         *q++ = htons(0xf227);        // fmove.l fpiar,-(sp)
  300.                         *q++ = htons(0xa400);
  301.                         *q++ = htons(0xf227);        // fmove.l fpsr,-(sp)
  302.                         *q++ = htons(0xa800);
  303.                         *q++ = htons(0xf227);        // fmove.l fpcr,-(sp)
  304.                         *q++ = htons(0xb000);
  305.                         *q++ = htons(0x4879);        // pea -1                    (push "FPU state saved" flag)
  306.                         *q++ = htons(0xffff);
  307.                         *q++ = htons(0xffff);
  308.                         p16 += 9;
  309.                         for (i=0; i<24; i++) *q++ = *p16++;
  310.  
  311.                         p16 = (uint16 *)(p + base);
  312.                         *p16++ = htons(M68K_JMP);
  313.                         *p16++ = htons(start >> 16);
  314.                         *p16 = htons(start & 0xffff);
  315.                         FlushCodeCache(p + base, 6);
  316.                         D(bug("  patch 3 applied\n"));
  317.                     }
  318.                 }
  319.             }
  320.         }
  321.  
  322.         // Patch Thread Manager thread switcher for 68060 FPU (additional routines under 8.0 for Mixed Mode Manager)
  323.         static const uint8 dat3[] = {0x22, 0x6f, 0x00, 0x08, 0x20, 0x2f, 0x00, 0x04, 0x67, 0x40};
  324.         base = find_rsrc_data(p, size, dat3, sizeof(dat3));
  325.         if (base) {    // Skip first routine (no FPU -> no FPU)
  326.  
  327.             base = find_rsrc_data(p, size - base - 2, dat3, sizeof(dat3), base + 2);
  328.             if (base) {    // no FPU -> FPU
  329.  
  330.                 p16 = (uint16 *)(p + base);
  331.                 start = (uint32)q;
  332.                 for (i=0; i<48; i++) *q++ = *p16++;
  333.                 *q++ = htons(0x4a2f);        // tst.b 2(sp)                (null FPU state or "FPU state saved" flag set?)
  334.                 *q++ = htons(2);
  335.                 *q++ = htons(0x6712);        // beq
  336.                 *q++ = htons(0x588f);        // addq.l #2,sp                (flag set, skip it)
  337.                 *q++ = htons(0xf21f);        // fmove.l (sp)+,fpcr        (restore FPU registers)
  338.                 *q++ = htons(0x9000);
  339.                 *q++ = htons(0xf21f);        // fmove.l (sp)+,fpsr
  340.                 *q++ = htons(0x8800);
  341.                 *q++ = htons(0xf21f);        // fmove.l (sp)+,fpiar
  342.                 *q++ = htons(0x8400);
  343.                 *q++ = htons(0xf21f);        // fmovem.x (sp)+,fp0-fp7
  344.                 *q++ = htons(0xd0ff);
  345.                 p16 += 7;
  346.                 for (i=0; i<20; i++) *q++ = *p16++;
  347.  
  348.                 p16 = (uint16 *)(p + base);
  349.                 *p16++ = htons(M68K_JMP);
  350.                 *p16++ = htons(start >> 16);
  351.                 *p16 = htons(start & 0xffff);
  352.                 FlushCodeCache(p + base, 6);
  353.                 D(bug("  patch 4 applied\n"));
  354.  
  355.                 static const uint8 dat4[] = {0x22, 0x6f, 0x00, 0x08, 0x20, 0x2f, 0x00, 0x04, 0x67, 0x50};
  356.                 base = find_rsrc_data(p, size, dat4, sizeof(dat4));
  357.                 if (base) {    // FPU -> FPU
  358.  
  359.                     p16 = (uint16 *)(p + base);
  360.                     start = (uint32)q;
  361.                     for (i=0; i<4; i++) *q++ = *p16++;
  362.                     *q++ = htons(0x675e);        // beq
  363.                     p16++;
  364.                     for (i=0; i<21; i++) *q++ = *p16++;
  365.                     *q++ = htons(0x4a2f);        // tst.b 2(sp)                (null FPU state?)
  366.                     *q++ = htons(2);
  367.                     *q++ = htons(0x6716);        // beq
  368.                     *q++ = htons(0xf227);        // fmovem.x fp0-fp7,-(sp)    (no, save FPU registers)
  369.                     *q++ = htons(0xe0ff);
  370.                     *q++ = htons(0xf227);        // fmove.l fpiar,-(sp)
  371.                     *q++ = htons(0xa400);
  372.                     *q++ = htons(0xf227);        // fmove.l fpsr,-(sp)
  373.                     *q++ = htons(0xa800);
  374.                     *q++ = htons(0xf227);        // fmove.l fpcr,-(sp)
  375.                     *q++ = htons(0xb000);
  376.                     *q++ = htons(0x4879);        // pea -1                    (push "FPU state saved" flag)
  377.                     *q++ = htons(0xffff);
  378.                     *q++ = htons(0xffff);
  379.                     p16 += 7;
  380.                     for (i=0; i<23; i++) *q++ = *p16++;
  381.                     *q++ = htons(0x4a2f);        // tst.b 2(sp)                (null FPU state or "FPU state saved" flag set?)
  382.                     *q++ = htons(2);
  383.                     *q++ = htons(0x6712);        // beq
  384.                     *q++ = htons(0x588f);        // addq.l #2,sp                (flag set, skip it)
  385.                     *q++ = htons(0xf21f);        // fmove.l (sp)+,fpcr        (restore FPU registers)
  386.                     *q++ = htons(0x9000);
  387.                     *q++ = htons(0xf21f);        // fmove.l (sp)+,fpsr
  388.                     *q++ = htons(0x8800);
  389.                     *q++ = htons(0xf21f);        // fmove.l (sp)+,fpiar
  390.                     *q++ = htons(0x8400);
  391.                     *q++ = htons(0xf21f);        // fmovem.x (sp)+,fp0-fp7
  392.                     *q++ = htons(0xd0ff);
  393.                     p16 += 7;
  394.                     for (i=0; i<20; i++) *q++ = *p16++;
  395.  
  396.                     p16 = (uint16 *)(p + base);
  397.                     *p16++ = htons(M68K_JMP);
  398.                     *p16++ = htons(start >> 16);
  399.                     *p16 = htons(start & 0xffff);
  400.                     FlushCodeCache(p + base, 6);
  401.                     D(bug("  patch 5 applied\n"));
  402.  
  403.                     base = find_rsrc_data(p, size - base - 2, dat4, sizeof(dat4), base + 2);
  404.                     if (base) {    // FPU -> no FPU
  405.  
  406.                         p16 = (uint16 *)(p + base);
  407.                         start = (uint32)q;
  408.                         for (i=0; i<4; i++) *q++ = *p16++;
  409.                         *q++ = htons(0x675e);        // beq
  410.                         p16++;
  411.                         for (i=0; i<21; i++) *q++ = *p16++;
  412.                         *q++ = htons(0x4a2f);        // tst.b 2(sp)                (null FPU state?)
  413.                         *q++ = htons(2);
  414.                         *q++ = htons(0x6716);        // beq
  415.                         *q++ = htons(0xf227);        // fmovem.x fp0-fp7,-(sp)    (no, save FPU registers)
  416.                         *q++ = htons(0xe0ff);
  417.                         *q++ = htons(0xf227);        // fmove.l fpiar,-(sp)
  418.                         *q++ = htons(0xa400);
  419.                         *q++ = htons(0xf227);        // fmove.l fpsr,-(sp)
  420.                         *q++ = htons(0xa800);
  421.                         *q++ = htons(0xf227);        // fmove.l fpcr,-(sp)
  422.                         *q++ = htons(0xb000);
  423.                         *q++ = htons(0x4879);        // pea -1                    (push "FPU state saved" flag)
  424.                         *q++ = htons(0xffff);
  425.                         *q++ = htons(0xffff);
  426.                         p16 += 7;
  427.                         for (i=0; i<42; i++) *q++ = *p16++;
  428.  
  429.                         p16 = (uint16 *)(p + base);
  430.                         *p16++ = htons(M68K_JMP);
  431.                         *p16++ = htons(start >> 16);
  432.                         *p16 = htons(start & 0xffff);
  433.                         FlushCodeCache(p + base, 6);
  434.                         D(bug("  patch 6 applied\n"));
  435.                     }
  436.                 }
  437.             }
  438.         }
  439.  
  440.         FlushCodeCache(ThPatchSpace, 1024);
  441.  
  442.         // Patch Thread Manager FPU init for 68060 FPU (7.5, 8.0)
  443.         static const uint8 dat5[] = {0x4a, 0x28, 0x00, 0xa4, 0x67, 0x0a, 0x4a, 0x2c, 0x00, 0x40};
  444.         base = find_rsrc_data(p, size, dat5, sizeof(dat5));
  445.         if (base) {
  446.             p16 = (uint16 *)(p + base + 6);
  447.             *p16++ = htons(M68K_JSR);
  448.             *p16++ = htons((uint32)ThInitFPUPatch >> 16);
  449.             *p16++ = htons((uint32)ThInitFPUPatch & 0xffff);
  450.             *p16++ = htons(M68K_NOP);
  451.             *p16 = htons(M68K_NOP);
  452.             FlushCodeCache(p + base + 6, 10);
  453.             D(bug("  patch 7 applied\n"));
  454.         }
  455. #endif
  456.  
  457.     } else if (type == 'gpch' && id == 750) {
  458.         D(bug(" gpch 750 found\n"));
  459.  
  460.         // Don't use PTEST instruction in BlockMove() (7.5, 7.6, 7.6.1, 8.0)
  461.         static const uint8 dat[] = {0xa0, 0x8d, 0x0c, 0x81, 0x00, 0x00, 0x0c, 0x00, 0x65, 0x06, 0x4e, 0x71, 0xf4, 0xf8};
  462.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  463.         if (base) {
  464.             p16 = (uint16 *)(p + base + 8);
  465.             *p16 = htons(M68K_NOP);
  466.             FlushCodeCache(p + base + 8, 2);
  467.             D(bug("  patch 1 applied\n"));
  468.         }
  469.  
  470.     } else if (type == 'lpch' && id == 24) {
  471.         D(bug(" lpch 24 found\n"));
  472.  
  473.         // Don't replace Time Manager (7.0.1, 7.1, 7.5, 7.6, 7.6.1, 8.0)
  474.         static const uint8 dat[] = {0x70, 0x59, 0xa2, 0x47};
  475.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  476.         if (base) {
  477.             p16 = (uint16 *)(p + base + 2);
  478.             *p16++ = htons(M68K_NOP);
  479.             p16 += 3;
  480.             *p16++ = htons(M68K_NOP);
  481.             p16 += 7;
  482.             *p16 = htons(M68K_NOP);
  483.             FlushCodeCache(p + base + 2, 28);
  484.             D(bug("  patch 1 applied\n"));
  485.         }
  486.  
  487.     } else if (type == 'lpch' && id == 31) {
  488.         D(bug(" lpch 31 found\n"));
  489.  
  490.         // Don't write to VIA in vSoundDead() (7.0.1, 7.1, 7.5, 7.6, 7.6.1, 8.0)
  491.         static const uint8 dat[] = {0x20, 0x78, 0x01, 0xd4, 0x08, 0xd0, 0x00, 0x07, 0x4e, 0x75};
  492.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  493.         if (base) {
  494.             p16 = (uint16 *)(p + base);
  495.             *p16 = htons(M68K_RTS);
  496.             FlushCodeCache(p + base, 2);
  497.             D(bug("  patch 1 applied\n"));
  498.         }
  499.  
  500.         // Don't replace SCSI manager (7.1, 7.5, 7.6.1, 8.0)
  501.         static const uint8 dat2[] = {0x0c, 0x6f, 0x00, 0x0e, 0x00, 0x04, 0x66, 0x0c};
  502.         base = find_rsrc_data(p, size, dat2, sizeof(dat2));
  503.         if (base) {
  504.             p16 = (uint16 *)(p + base);
  505.             *p16++ = htons(M68K_EMUL_OP_SCSI_DISPATCH);
  506.             *p16++ = htons(0x2e49);        // move.l    a1,a7
  507.             *p16 = htons(M68K_JMP_A0);
  508.             FlushCodeCache(p + base, 6);
  509.             D(bug("  patch 2 applied\n"));
  510.         }
  511.  
  512. #if !EMULATED_68K
  513.     } else if (CPUIs68060 && type == 'scod' && (id == -16463 || id == -16464)) {
  514.         D(bug(" scod -16463/-16464 found\n"));
  515.  
  516.         // Correct 68060 FP frame handling in Process Manager task switches (7.1, 7.5, 8.0)
  517.         static const uint8 dat[] = {0xf3, 0x27, 0x4a, 0x17};
  518.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  519.         if (base) {
  520.             p16 = (uint16 *)(p + base);
  521.             *p16++ = htons(M68K_JMP);
  522.             *p16++ = htons((uint32)Scod060Patch1 >> 16);
  523.             *p16 = htons((uint32)Scod060Patch1 & 0xffff);
  524.             FlushCodeCache(p + base, 6);
  525.             D(bug("  patch 1 applied\n"));
  526.         }
  527.  
  528.         // Even a null FP frame is 3 longwords on the 68060 (7.1, 7.5, 8.0)
  529.         static const uint8 dat2[] = {0xf3, 0x5f, 0x4e, 0x75};
  530.         base = find_rsrc_data(p, size, dat2, sizeof(dat2));
  531.         if (base) {
  532.             p16 = (uint16 *)(p + base - 2);
  533.             *p16++ = htons(M68K_JMP);
  534.             *p16++ = htons((uint32)Scod060Patch2 >> 16);
  535.             *p16 = htons((uint32)Scod060Patch2 & 0xffff);
  536.             FlushCodeCache(p + base - 2, 6);
  537.             D(bug("  patch 2 applied\n"));
  538.         }
  539. #endif
  540.  
  541.     } else if (type == 'thng' && id == -16563) {
  542.         D(bug(" thng -16563 found\n"));
  543.  
  544.         // Set audio component flags (7.5, 7.6, 7.6.1, 8.0)
  545.         *(uint32 *)(p + componentFlags) = htonl(audio_component_flags);
  546.         D(bug("  patch 1 applied\n"));
  547.  
  548.     } else if (type == 'sift' && id == -16563) {
  549.         D(bug(" sift -16563 found\n"));
  550.  
  551.         // Replace audio component (7.5, 7.6, 7.6.1, 8.0)
  552.         p16 = (uint16 *)p;
  553.         *p16++ = htons(0x4e56); *p16++ = htons(0x0000);    // link        a6,#0
  554.         *p16++ = htons(0x48e7); *p16++ = htons(0x8018);    // movem.l    d0/a3-a4,-(sp)
  555.         *p16++ = htons(0x266e); *p16++ = htons(0x000c);    // movea.l    12(a6),a3
  556.         *p16++ = htons(0x286e); *p16++ = htons(0x0008);    // movea.l    8(a6),a4
  557.         *p16++ = htons(M68K_EMUL_OP_AUDIO);
  558.         *p16++ = htons(0x2d40); *p16++ = htons(0x0010);    // move.l    d0,16(a6)
  559.         *p16++ = htons(0x4cdf); *p16++ = htons(0x1801);    // movem.l    (sp)+,d0/a3-a4
  560.         *p16++ = htons(0x4e5e);                            // unlk        a6
  561.         *p16++ = htons(0x4e74); *p16++ = htons(0x0008);    // rtd        #8
  562.         FlushCodeCache(p, 32);
  563.         D(bug("  patch 1 applied\n"));
  564.  
  565.     } else if (type == 'inst' && id == -19069) {
  566.         D(bug(" inst -19069 found\n"));
  567.  
  568.         // Don't replace Microseconds (QuickTime 2.0)
  569.         static const uint8 dat[] = {0x30, 0x3c, 0xa1, 0x93, 0xa2, 0x47};
  570.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  571.         if (base) {
  572.             p16 = (uint16 *)(p + base + 4);
  573.             *p16 = htons(M68K_NOP);
  574.             FlushCodeCache(p + base + 4, 2);
  575.             D(bug("  patch 1 applied\n"));
  576.         }
  577.  
  578.     } else if (type == 'DRVR' && id == -20066) {
  579.         D(bug("DRVR -20066 found\n"));
  580.  
  581.         // Don't access SCC in .Infra driver
  582.         static const uint8 dat[] = {0x28, 0x78, 0x01, 0xd8, 0x48, 0xc7, 0x20, 0x0c, 0xd0, 0x87, 0x20, 0x40, 0x1c, 0x10};
  583.         base = find_rsrc_data(p, size, dat, sizeof(dat));
  584.         if (base) {
  585.             p16 = (uint16 *)(p + base + 12);
  586.             *p16 = htons(0x7a00);    // moveq #0,d6
  587.             FlushCodeCache(p + base + 12, 2);
  588.             D(bug("  patch 1 applied\n"));
  589.         }
  590.  
  591.     } else if (type == 'ltlk' && id == 0) {
  592.         D(bug(" ltlk 0 found\n"));
  593.  
  594.         // Disable LocalTalk (7.0.1, 7.5, 7.6, 7.6.1, 8.0)
  595.         p16 = (uint16 *)p;
  596.         *p16++ = htons(M68K_JMP_A0);
  597.         *p16++ = htons(0x7000);
  598.         *p16 = htons(M68K_RTS);
  599.         FlushCodeCache(p, 6);
  600.         D(bug("  patch 1 applied\n"));
  601.     }
  602. }
  603.