mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-12-19 09:31:26 +00:00
- fixed compilation problems under AmigaOS
- fsave/frestore on AmigaOS and NetBSD/m68k always use a 68882/68040-style FPU frame, eliminating the need for 68060 FPU patches
This commit is contained in:
parent
738fa25344
commit
f17b9006d6
@ -1,3 +1,8 @@
|
||||
V1.0 (snapshot) - <date>
|
||||
- added support for on-the-fly video resolution and depth seitching
|
||||
- fsave/frestore emulation under AmigaOS and NetBSD/m68k always behave
|
||||
like a 68882/68040 FPU, eliminating the need for 68060 FPU patches
|
||||
|
||||
V0.9 (release 0.9-1) - 31.May 2001
|
||||
- final adjustments for 0.9 release
|
||||
|
||||
|
@ -33,9 +33,6 @@
|
||||
XDEF _Execute68kTrap
|
||||
XDEF _TrapHandlerAsm
|
||||
XDEF _ExceptionHandlerAsm
|
||||
XDEF _Scod060Patch1
|
||||
XDEF _Scod060Patch2
|
||||
XDEF _ThInitFPUPatch
|
||||
XDEF _AsmTriggerNMI
|
||||
|
||||
XREF _OldTrapHandler
|
||||
@ -243,63 +240,6 @@ _ExceptionHandlerAsm
|
||||
4$ move.l (sp)+,d0
|
||||
rts
|
||||
|
||||
*
|
||||
* Process Manager 68060 FPU patches
|
||||
*
|
||||
|
||||
_Scod060Patch1 fsave -(sp) ;Save FPU state
|
||||
tst.b 2(sp) ;Null?
|
||||
beq.s 1$
|
||||
fmovem.x fp0-fp7,-(sp) ;No, save FPU registers
|
||||
fmove.l fpiar,-(sp)
|
||||
fmove.l fpsr,-(sp)
|
||||
fmove.l fpcr,-(sp)
|
||||
pea -1 ;Push "FPU state saved" flag
|
||||
1$ move.l d1,-(sp)
|
||||
move.l d0,-(sp)
|
||||
bsr.s 3$ ;Switch integer registers and stack
|
||||
addq.l #8,sp
|
||||
tst.b 2(sp) ;New FPU state null or "FPU state saved" flag set?
|
||||
beq.s 2$
|
||||
addq.l #4,sp ;Flag set, skip it
|
||||
fmove.l (sp)+,fpcr ;Restore FPU registers and state
|
||||
fmove.l (sp)+,fpsr
|
||||
fmove.l (sp)+,fpiar
|
||||
fmovem.x (sp)+,fp0-fp7
|
||||
2$ frestore (sp)+
|
||||
movem.l (sp)+,d0-d1
|
||||
rts
|
||||
|
||||
3$ move.l 4(sp),a0 ;Switch integer registers and stack
|
||||
move sr,-(sp)
|
||||
movem.l d2-d7/a2-a6,-(sp)
|
||||
cmp.w #0,a0
|
||||
beq.s 4$
|
||||
move.l sp,(a0)
|
||||
4$ move.l $36(sp),a0
|
||||
movem.l (a0)+,d2-d7/a2-a6
|
||||
move (a0)+,sr
|
||||
move.l a0,sp
|
||||
rts
|
||||
|
||||
_Scod060Patch2 move.l d0,-(sp) ;Create 68060 null frame on stack
|
||||
move.l d0,-(sp)
|
||||
move.l d0,-(sp)
|
||||
frestore (sp)+ ;and load it
|
||||
rts
|
||||
|
||||
*
|
||||
* Thread Manager 68060 FPU patches
|
||||
*
|
||||
|
||||
_ThInitFPUPatch tst.b $40(a4)
|
||||
bne.s 1$
|
||||
moveq #0,d0 ;Create 68060 null frame on stack
|
||||
move.l d0,-(a3)
|
||||
move.l d0,-(a3)
|
||||
move.l d0,-(a3)
|
||||
1$ rts
|
||||
|
||||
*
|
||||
* Trap handler of main task
|
||||
*
|
||||
@ -695,38 +635,35 @@ movefromsrsp move.l a0,-(sp) ;Save a0
|
||||
fsavepush move.l (sp),d0 ;Restore d0
|
||||
move.l a0,(sp) ;Save a0
|
||||
move.l usp,a0 ;Get user stack pointer
|
||||
fsave -(a0) ;Push FP state
|
||||
move.l #$41000000,-(a0) ;Push idle frame
|
||||
move.l a0,usp ;Update USP
|
||||
move.l (sp)+,a0 ;Restore a0
|
||||
addq.l #2,2(sp) ;Skip instruction
|
||||
rte
|
||||
|
||||
; fsave xxx(a5)
|
||||
fsavea5 move.l (sp),d0 ;Restore d0
|
||||
move.l a0,(sp) ;Save a0
|
||||
move.l a5,a0 ;Get base register
|
||||
add.w ([6,sp],2),a0 ;Add offset to base register
|
||||
move.l #$41000000,(a0) ;Push idle frame
|
||||
move.l (sp)+,a0 ;Restore a0
|
||||
addq.l #4,2(sp) ;Skip instruction
|
||||
rte
|
||||
|
||||
; frestore (sp)+
|
||||
frestorepop move.l (sp),d0 ;Restore d0
|
||||
move.l a0,(sp) ;Save a0
|
||||
move.l usp,a0 ;Get user stack pointer
|
||||
frestore (a0)+ ;Restore FP state
|
||||
addq.l #4,a0 ;Nothing to do...
|
||||
move.l a0,usp ;Update USP
|
||||
move.l (sp)+,a0 ;Restore a0
|
||||
addq.l #2,2(sp) ;Skip instruction
|
||||
rte
|
||||
|
||||
; frestore xxx(a5) +jl+
|
||||
; frestore xxx(a5)
|
||||
frestorea5 move.l (sp),d0 ;Restore d0
|
||||
move.l a0,(sp) ;Save a0
|
||||
move.l a5,a0 ;Get base register
|
||||
add.w ([6,sp],2),a0 ;Add offset to base register
|
||||
frestore (a0) ;Restore FP state from (a0)
|
||||
move.l (sp)+,a0 ;Restore a0
|
||||
addq.l #4,2(sp) ;Skip instruction
|
||||
rte
|
||||
|
||||
; fsave xxx(a5) +jl+
|
||||
fsavea5 move.l (sp),d0 ;Restore d0
|
||||
move.l a0,(sp) ;Save a0
|
||||
move.l a5,a0 ;Get base register
|
||||
add.w ([6,sp],2),a0 ;Add offset to base register
|
||||
fsave (a0) ;Push FP state to (a0)
|
||||
move.l (sp)+,a0 ;Restore a0
|
||||
addq.l #4,2(sp) ;Skip instruction
|
||||
rte
|
||||
|
@ -276,7 +276,7 @@ int main(int argc, char **argv)
|
||||
|
||||
// Load Mac ROM
|
||||
BPTR rom_fh = Open(rom_path ? (char *)rom_path : (char *)ROM_FILE_NAME, MODE_OLDFILE);
|
||||
if (rom_fh == NULL) {
|
||||
if (rom_fh == 0) {
|
||||
ErrorAlert(GetString(STR_NO_ROM_FILE_ERR));
|
||||
QuitEmulator();
|
||||
}
|
||||
|
@ -119,8 +119,6 @@ static void set_video_monitor(uint32 width, uint32 height, uint32 bytes_per_row,
|
||||
mode.depth = VDEPTH_8BIT;
|
||||
break;
|
||||
case 15:
|
||||
mode.depth = VDEPTH_16BIT;
|
||||
break;
|
||||
case 16:
|
||||
mode.depth = VDEPTH_16BIT;
|
||||
break;
|
||||
@ -216,8 +214,8 @@ static bool init_pip(int width, int height)
|
||||
p96PIP_GetTags(the_win, P96PIP_SourceBitMap, (ULONG)&the_bitmap, TAG_END);
|
||||
|
||||
// Add resolution and set VideoMonitor
|
||||
set_video_monitor(width, height, p96GetBitMapAttr(the_bitmap, P96BMA_BYTESPERROW), 16);
|
||||
VideoMonitor.mac_frame_base = p96GetBitMapAttr(the_bitmap, P96BMA_MEMORY);
|
||||
set_video_monitor(width, height, p96GetBitMapAttr(the_bitmap, P96BMA_BYTESPERROW), 16);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -540,7 +538,8 @@ void VideoExit(void)
|
||||
|
||||
void video_set_palette(uint8 *pal)
|
||||
{
|
||||
if (display_type == DISPLAY_SCREEN_P96 || display_type == DISPLAY_SCREEN_CGFX) {
|
||||
if ((display_type == DISPLAY_SCREEN_P96 || display_type == DISPLAY_SCREEN_CGFX)
|
||||
&& !IsDirectMode(VideoMonitor.mode)) {
|
||||
|
||||
// Convert palette to 32 bits
|
||||
ULONG table[2 + 256 * 3];
|
||||
|
@ -27,9 +27,6 @@
|
||||
.globl _ClearInterruptFlag__FUi
|
||||
.globl _Execute68k
|
||||
.globl _Execute68kTrap
|
||||
.globl _Scod060Patch1
|
||||
.globl _Scod060Patch2
|
||||
.globl _ThInitFPUPatch
|
||||
.globl _EmulOpTrampoline
|
||||
|
||||
.globl _RAMBaseHost
|
||||
@ -181,66 +178,3 @@ _EmulOpTrampoline:
|
||||
eot1: moveml sp@+,d0-d7/a0-a6 |Restore registers
|
||||
addql #4,sp |Skip saved SP
|
||||
rtr
|
||||
|
||||
|
||||
/*
|
||||
* Process Manager 68060 FPU patches
|
||||
*/
|
||||
|
||||
.type _Scod060Patch1,@function
|
||||
_Scod060Patch1: fsave sp@- |Save FPU state
|
||||
tstb sp@(2) |Null?
|
||||
beqs sc1
|
||||
fmovemx fp0-fp7,sp@- |No, save FPU registers
|
||||
fmovel fpi,sp@-
|
||||
fmovel fpsr,sp@-
|
||||
fmovel fpcr,sp@-
|
||||
pea -1 |Push "FPU state saved" flag
|
||||
sc1: movl d1,sp@-
|
||||
movl d0,sp@-
|
||||
bsrs sc3 |Switch integer registers and stack
|
||||
addql #8,sp
|
||||
tstb sp@(2) |New FPU state null or "FPU state saved" flag set?
|
||||
beqs sc2
|
||||
addql #4,sp |Flag set, skip it
|
||||
fmovel sp@+,fpcr |Restore FPU registers and state
|
||||
fmovel sp@+,fpsr
|
||||
fmovel sp@+,fpi
|
||||
fmovemx sp@+,fp0-fp7
|
||||
sc2: frestore sp@+
|
||||
movml sp@+,d0-d1
|
||||
rts
|
||||
|
||||
sc3: movl sp@(4),a0 |Switch integer registers and stack
|
||||
movw sr,sp@-
|
||||
movml d2-d7/a2-a6,sp@-
|
||||
cmpw #0,a0
|
||||
beqs sc4
|
||||
movl sp,a0@
|
||||
sc4: movl sp@(0x36),a0
|
||||
movml a0@+,d2-d7/a2-a6
|
||||
movw a0@+,sr
|
||||
movl a0,sp
|
||||
rts
|
||||
|
||||
.type _Scod060Patch2,@function
|
||||
_Scod060Patch2: movl d0,sp@- |Create 68060 null frame on stack
|
||||
movl d0,sp@-
|
||||
movl d0,sp@-
|
||||
frestore sp@+ |and load it
|
||||
rts
|
||||
|
||||
|
||||
/*
|
||||
* Thread Manager 68060 FPU patches
|
||||
*/
|
||||
|
||||
.type _ThInitFPUPatch,@function
|
||||
_ThInitFPUPatch:
|
||||
tstb a4@(0x40)
|
||||
bnes th1
|
||||
moveq #0,d0 |Create 68060 null frame on stack
|
||||
movl d0,a3@-
|
||||
movl d0,a3@-
|
||||
movl d0,a3@-
|
||||
th1: rts
|
||||
|
@ -1094,26 +1094,14 @@ static void sigill_handler(int sig, int code, struct sigcontext *scp)
|
||||
}
|
||||
|
||||
case 0xf327: // fsave -(sp)
|
||||
if (CPUIs68060) {
|
||||
regs->a[7] -= 4;
|
||||
WriteMacInt32(regs->a[7], 0x60000000); // Idle frame
|
||||
regs->a[7] -= 4;
|
||||
WriteMacInt32(regs->a[7], 0);
|
||||
regs->a[7] -= 4;
|
||||
WriteMacInt32(regs->a[7], 0);
|
||||
} else {
|
||||
regs->a[7] -= 4;
|
||||
WriteMacInt32(regs->a[7], 0x41000000); // Idle frame
|
||||
}
|
||||
regs->a[7] -= 4;
|
||||
WriteMacInt32(regs->a[7], 0x41000000); // Idle frame
|
||||
scp->sc_sp = regs->a[7];
|
||||
INC_PC(2);
|
||||
break;
|
||||
|
||||
case 0xf35f: // frestore (sp)+
|
||||
if (CPUIs68060)
|
||||
regs->a[7] += 12;
|
||||
else
|
||||
regs->a[7] += 4;
|
||||
regs->a[7] += 4;
|
||||
scp->sc_sp = regs->a[7];
|
||||
INC_PC(2);
|
||||
break;
|
||||
|
@ -37,14 +37,6 @@
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
#if !EMULATED_68K
|
||||
// Assembly functions
|
||||
extern "C" void Scod060Patch1(void);
|
||||
extern "C" void Scod060Patch2(void);
|
||||
extern "C" void ThInitFPUPatch(void);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Search resource for byte string, return offset (or 0)
|
||||
*/
|
||||
@ -90,7 +82,7 @@ void CheckLoad(uint32 type, int16 id, uint8 *p, uint32 size)
|
||||
if (base) {
|
||||
p16 = (uint16 *)(p + base);
|
||||
|
||||
#if defined(AMIGA) || defined(__NetBSD__) || defined(USE_SCRATCHMEM_SUBTERFUGE)
|
||||
#if defined(USE_SCRATCHMEM_SUBTERFUGE)
|
||||
// Set 0x0000 to scratch memory area
|
||||
extern uint8 *ScratchMem;
|
||||
const uint32 ScratchMemBase = Host2MacAddr(ScratchMem);
|
||||
@ -197,266 +189,6 @@ void CheckLoad(uint32 type, int16 id, uint8 *p, uint32 size)
|
||||
D(bug(" patch 2 applied\n"));
|
||||
}
|
||||
|
||||
#if !EMULATED_68K
|
||||
} else if (CPUIs68060 && (type == FOURCC('g','p','c','h') && id == 669 || type == FOURCC('l','p','c','h') && id == 63)) {
|
||||
D(bug(" gpch 669/lpch 63 found\n"));
|
||||
|
||||
static uint16 ThPatchSpace[1024]; // Replacement routines are constructed here
|
||||
uint16 *q = ThPatchSpace;
|
||||
uint32 start;
|
||||
int i;
|
||||
|
||||
// Patch Thread Manager thread switcher for 68060 FPU (7.5, 8.0)
|
||||
static const uint8 dat[] = {0x22, 0x6f, 0x00, 0x08, 0x20, 0x2f, 0x00, 0x04, 0x67, 0x18};
|
||||
base = find_rsrc_data(p, size, dat, sizeof(dat));
|
||||
if (base) { // Skip first routine (no FPU -> no FPU)
|
||||
|
||||
base = find_rsrc_data(p, size - base - 2, dat, sizeof(dat), base + 2);
|
||||
if (base) { // no FPU -> FPU
|
||||
|
||||
p16 = (uint16 *)(p + base);
|
||||
start = (uint32)q;
|
||||
for (i=0; i<28; i++) *q++ = *p16++;
|
||||
*q++ = htons(0x4a2f); // tst.b 2(sp) (null FPU state or "FPU state saved" flag set?)
|
||||
*q++ = htons(2);
|
||||
*q++ = htons(0x6712); // beq
|
||||
*q++ = htons(0x588f); // addq.l #2,sp (flag set, skip it)
|
||||
*q++ = htons(0xf21f); // fmove.l (sp)+,fpcr (restore FPU registers)
|
||||
*q++ = htons(0x9000);
|
||||
*q++ = htons(0xf21f); // fmove.l (sp)+,fpsr
|
||||
*q++ = htons(0x8800);
|
||||
*q++ = htons(0xf21f); // fmove.l (sp)+,fpiar
|
||||
*q++ = htons(0x8400);
|
||||
*q++ = htons(0xf21f); // fmovem.x (sp)+,fp0-fp7
|
||||
*q++ = htons(0xd0ff);
|
||||
*q++ = htons(0xf35f); // frestore (sp)+
|
||||
*q++ = htons(0x4e75); // rts
|
||||
|
||||
p16 = (uint16 *)(p + base);
|
||||
*p16++ = htons(M68K_JMP);
|
||||
*p16++ = htons(start >> 16);
|
||||
*p16 = htons(start & 0xffff);
|
||||
FlushCodeCache(p + base, 6);
|
||||
D(bug(" patch 1 applied\n"));
|
||||
|
||||
static const uint8 dat2[] = {0x22, 0x6f, 0x00, 0x08, 0x20, 0x2f, 0x00, 0x04, 0x67, 0x28};
|
||||
base = find_rsrc_data(p, size, dat2, sizeof(dat2));
|
||||
if (base) { // FPU -> FPU
|
||||
|
||||
p16 = (uint16 *)(p + base);
|
||||
start = (uint32)q;
|
||||
for (i=0; i<4; i++) *q++ = *p16++;
|
||||
*q++ = htons(0x6736); // beq
|
||||
*q++ = htons(0xf327); // fsave -(sp) (save FPU state frame)
|
||||
*q++ = htons(0x4a2f); // tst.b 2(sp) (null FPU state?)
|
||||
*q++ = htons(2);
|
||||
*q++ = htons(0x6716); // beq
|
||||
*q++ = htons(0xf227); // fmovem.x fp0-fp7,-(sp) (no, save FPU registers)
|
||||
*q++ = htons(0xe0ff);
|
||||
*q++ = htons(0xf227); // fmove.l fpiar,-(sp)
|
||||
*q++ = htons(0xa400);
|
||||
*q++ = htons(0xf227); // fmove.l fpsr,-(sp)
|
||||
*q++ = htons(0xa800);
|
||||
*q++ = htons(0xf227); // fmove.l fpcr,-(sp)
|
||||
*q++ = htons(0xb000);
|
||||
*q++ = htons(0x4879); // pea -1 (push "FPU state saved" flag)
|
||||
*q++ = htons(0xffff);
|
||||
*q++ = htons(0xffff);
|
||||
p16 += 9;
|
||||
for (i=0; i<23; i++) *q++ = *p16++;
|
||||
*q++ = htons(0x4a2f); // tst.b 2(sp) (null FPU state or "FPU state saved" flag set?)
|
||||
*q++ = htons(2);
|
||||
*q++ = htons(0x6712); // beq
|
||||
*q++ = htons(0x588f); // addq.l #2,sp (flag set, skip it)
|
||||
*q++ = htons(0xf21f); // fmove.l (sp)+,fpcr (restore FPU registers)
|
||||
*q++ = htons(0x9000);
|
||||
*q++ = htons(0xf21f); // fmove.l (sp)+,fpsr
|
||||
*q++ = htons(0x8800);
|
||||
*q++ = htons(0xf21f); // fmove.l (sp)+,fpiar
|
||||
*q++ = htons(0x8400);
|
||||
*q++ = htons(0xf21f); // fmovem.x (sp)+,fp0-fp7
|
||||
*q++ = htons(0xd0ff);
|
||||
*q++ = htons(0xf35f); // frestore (sp)+
|
||||
*q++ = htons(0x4e75); // rts
|
||||
|
||||
p16 = (uint16 *)(p + base);
|
||||
*p16++ = htons(M68K_JMP);
|
||||
*p16++ = htons(start >> 16);
|
||||
*p16 = htons(start & 0xffff);
|
||||
FlushCodeCache(p + base, 6);
|
||||
D(bug(" patch 2 applied\n"));
|
||||
|
||||
base = find_rsrc_data(p, size - base - 2, dat2, sizeof(dat2), base + 2);
|
||||
if (base) { // FPU -> no FPU
|
||||
|
||||
p16 = (uint16 *)(p + base);
|
||||
start = (uint32)q;
|
||||
for (i=0; i<4; i++) *q++ = *p16++;
|
||||
*q++ = htons(0x6736); // beq
|
||||
*q++ = htons(0xf327); // fsave -(sp) (save FPU state frame)
|
||||
*q++ = htons(0x4a2f); // tst.b 2(sp) (null FPU state?)
|
||||
*q++ = htons(2);
|
||||
*q++ = htons(0x6716); // beq
|
||||
*q++ = htons(0xf227); // fmovem.x fp0-fp7,-(sp) (no, save FPU registers)
|
||||
*q++ = htons(0xe0ff);
|
||||
*q++ = htons(0xf227); // fmove.l fpiar,-(sp)
|
||||
*q++ = htons(0xa400);
|
||||
*q++ = htons(0xf227); // fmove.l fpsr,-(sp)
|
||||
*q++ = htons(0xa800);
|
||||
*q++ = htons(0xf227); // fmove.l fpcr,-(sp)
|
||||
*q++ = htons(0xb000);
|
||||
*q++ = htons(0x4879); // pea -1 (push "FPU state saved" flag)
|
||||
*q++ = htons(0xffff);
|
||||
*q++ = htons(0xffff);
|
||||
p16 += 9;
|
||||
for (i=0; i<24; i++) *q++ = *p16++;
|
||||
|
||||
p16 = (uint16 *)(p + base);
|
||||
*p16++ = htons(M68K_JMP);
|
||||
*p16++ = htons(start >> 16);
|
||||
*p16 = htons(start & 0xffff);
|
||||
FlushCodeCache(p + base, 6);
|
||||
D(bug(" patch 3 applied\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Patch Thread Manager thread switcher for 68060 FPU (additional routines under 8.0 for Mixed Mode Manager)
|
||||
static const uint8 dat3[] = {0x22, 0x6f, 0x00, 0x08, 0x20, 0x2f, 0x00, 0x04, 0x67, 0x40};
|
||||
base = find_rsrc_data(p, size, dat3, sizeof(dat3));
|
||||
if (base) { // Skip first routine (no FPU -> no FPU)
|
||||
|
||||
base = find_rsrc_data(p, size - base - 2, dat3, sizeof(dat3), base + 2);
|
||||
if (base) { // no FPU -> FPU
|
||||
|
||||
p16 = (uint16 *)(p + base);
|
||||
start = (uint32)q;
|
||||
for (i=0; i<48; i++) *q++ = *p16++;
|
||||
*q++ = htons(0x4a2f); // tst.b 2(sp) (null FPU state or "FPU state saved" flag set?)
|
||||
*q++ = htons(2);
|
||||
*q++ = htons(0x6712); // beq
|
||||
*q++ = htons(0x588f); // addq.l #2,sp (flag set, skip it)
|
||||
*q++ = htons(0xf21f); // fmove.l (sp)+,fpcr (restore FPU registers)
|
||||
*q++ = htons(0x9000);
|
||||
*q++ = htons(0xf21f); // fmove.l (sp)+,fpsr
|
||||
*q++ = htons(0x8800);
|
||||
*q++ = htons(0xf21f); // fmove.l (sp)+,fpiar
|
||||
*q++ = htons(0x8400);
|
||||
*q++ = htons(0xf21f); // fmovem.x (sp)+,fp0-fp7
|
||||
*q++ = htons(0xd0ff);
|
||||
p16 += 7;
|
||||
for (i=0; i<20; i++) *q++ = *p16++;
|
||||
|
||||
p16 = (uint16 *)(p + base);
|
||||
*p16++ = htons(M68K_JMP);
|
||||
*p16++ = htons(start >> 16);
|
||||
*p16 = htons(start & 0xffff);
|
||||
FlushCodeCache(p + base, 6);
|
||||
D(bug(" patch 4 applied\n"));
|
||||
|
||||
static const uint8 dat4[] = {0x22, 0x6f, 0x00, 0x08, 0x20, 0x2f, 0x00, 0x04, 0x67, 0x50};
|
||||
base = find_rsrc_data(p, size, dat4, sizeof(dat4));
|
||||
if (base) { // FPU -> FPU
|
||||
|
||||
p16 = (uint16 *)(p + base);
|
||||
start = (uint32)q;
|
||||
for (i=0; i<4; i++) *q++ = *p16++;
|
||||
*q++ = htons(0x675e); // beq
|
||||
p16++;
|
||||
for (i=0; i<21; i++) *q++ = *p16++;
|
||||
*q++ = htons(0x4a2f); // tst.b 2(sp) (null FPU state?)
|
||||
*q++ = htons(2);
|
||||
*q++ = htons(0x6716); // beq
|
||||
*q++ = htons(0xf227); // fmovem.x fp0-fp7,-(sp) (no, save FPU registers)
|
||||
*q++ = htons(0xe0ff);
|
||||
*q++ = htons(0xf227); // fmove.l fpiar,-(sp)
|
||||
*q++ = htons(0xa400);
|
||||
*q++ = htons(0xf227); // fmove.l fpsr,-(sp)
|
||||
*q++ = htons(0xa800);
|
||||
*q++ = htons(0xf227); // fmove.l fpcr,-(sp)
|
||||
*q++ = htons(0xb000);
|
||||
*q++ = htons(0x4879); // pea -1 (push "FPU state saved" flag)
|
||||
*q++ = htons(0xffff);
|
||||
*q++ = htons(0xffff);
|
||||
p16 += 7;
|
||||
for (i=0; i<23; i++) *q++ = *p16++;
|
||||
*q++ = htons(0x4a2f); // tst.b 2(sp) (null FPU state or "FPU state saved" flag set?)
|
||||
*q++ = htons(2);
|
||||
*q++ = htons(0x6712); // beq
|
||||
*q++ = htons(0x588f); // addq.l #2,sp (flag set, skip it)
|
||||
*q++ = htons(0xf21f); // fmove.l (sp)+,fpcr (restore FPU registers)
|
||||
*q++ = htons(0x9000);
|
||||
*q++ = htons(0xf21f); // fmove.l (sp)+,fpsr
|
||||
*q++ = htons(0x8800);
|
||||
*q++ = htons(0xf21f); // fmove.l (sp)+,fpiar
|
||||
*q++ = htons(0x8400);
|
||||
*q++ = htons(0xf21f); // fmovem.x (sp)+,fp0-fp7
|
||||
*q++ = htons(0xd0ff);
|
||||
p16 += 7;
|
||||
for (i=0; i<20; i++) *q++ = *p16++;
|
||||
|
||||
p16 = (uint16 *)(p + base);
|
||||
*p16++ = htons(M68K_JMP);
|
||||
*p16++ = htons(start >> 16);
|
||||
*p16 = htons(start & 0xffff);
|
||||
FlushCodeCache(p + base, 6);
|
||||
D(bug(" patch 5 applied\n"));
|
||||
|
||||
base = find_rsrc_data(p, size - base - 2, dat4, sizeof(dat4), base + 2);
|
||||
if (base) { // FPU -> no FPU
|
||||
|
||||
p16 = (uint16 *)(p + base);
|
||||
start = (uint32)q;
|
||||
for (i=0; i<4; i++) *q++ = *p16++;
|
||||
*q++ = htons(0x675e); // beq
|
||||
p16++;
|
||||
for (i=0; i<21; i++) *q++ = *p16++;
|
||||
*q++ = htons(0x4a2f); // tst.b 2(sp) (null FPU state?)
|
||||
*q++ = htons(2);
|
||||
*q++ = htons(0x6716); // beq
|
||||
*q++ = htons(0xf227); // fmovem.x fp0-fp7,-(sp) (no, save FPU registers)
|
||||
*q++ = htons(0xe0ff);
|
||||
*q++ = htons(0xf227); // fmove.l fpiar,-(sp)
|
||||
*q++ = htons(0xa400);
|
||||
*q++ = htons(0xf227); // fmove.l fpsr,-(sp)
|
||||
*q++ = htons(0xa800);
|
||||
*q++ = htons(0xf227); // fmove.l fpcr,-(sp)
|
||||
*q++ = htons(0xb000);
|
||||
*q++ = htons(0x4879); // pea -1 (push "FPU state saved" flag)
|
||||
*q++ = htons(0xffff);
|
||||
*q++ = htons(0xffff);
|
||||
p16 += 7;
|
||||
for (i=0; i<42; i++) *q++ = *p16++;
|
||||
|
||||
p16 = (uint16 *)(p + base);
|
||||
*p16++ = htons(M68K_JMP);
|
||||
*p16++ = htons(start >> 16);
|
||||
*p16 = htons(start & 0xffff);
|
||||
FlushCodeCache(p + base, 6);
|
||||
D(bug(" patch 6 applied\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FlushCodeCache(ThPatchSpace, 1024);
|
||||
|
||||
// Patch Thread Manager FPU init for 68060 FPU (7.5, 8.0)
|
||||
static const uint8 dat5[] = {0x4a, 0x28, 0x00, 0xa4, 0x67, 0x0a, 0x4a, 0x2c, 0x00, 0x40};
|
||||
base = find_rsrc_data(p, size, dat5, sizeof(dat5));
|
||||
if (base) {
|
||||
p16 = (uint16 *)(p + base + 6);
|
||||
*p16++ = htons(M68K_JSR);
|
||||
*p16++ = htons((uint32)ThInitFPUPatch >> 16);
|
||||
*p16++ = htons((uint32)ThInitFPUPatch & 0xffff);
|
||||
*p16++ = htons(M68K_NOP);
|
||||
*p16 = htons(M68K_NOP);
|
||||
FlushCodeCache(p + base + 6, 10);
|
||||
D(bug(" patch 7 applied\n"));
|
||||
}
|
||||
#endif
|
||||
|
||||
} else if (type == FOURCC('g','p','c','h') && id == 750) {
|
||||
D(bug(" gpch 750 found\n"));
|
||||
|
||||
@ -514,35 +246,6 @@ void CheckLoad(uint32 type, int16 id, uint8 *p, uint32 size)
|
||||
D(bug(" patch 2 applied\n"));
|
||||
}
|
||||
|
||||
#if !EMULATED_68K
|
||||
} else if (CPUIs68060 && type == FOURCC('s','c','o','d') && (id == -16463 || id == -16464)) {
|
||||
D(bug(" scod -16463/-16464 found\n"));
|
||||
|
||||
// Correct 68060 FP frame handling in Process Manager task switches (7.1, 7.5, 8.0)
|
||||
static const uint8 dat[] = {0xf3, 0x27, 0x4a, 0x17};
|
||||
base = find_rsrc_data(p, size, dat, sizeof(dat));
|
||||
if (base) {
|
||||
p16 = (uint16 *)(p + base);
|
||||
*p16++ = htons(M68K_JMP);
|
||||
*p16++ = htons((uint32)Scod060Patch1 >> 16);
|
||||
*p16 = htons((uint32)Scod060Patch1 & 0xffff);
|
||||
FlushCodeCache(p + base, 6);
|
||||
D(bug(" patch 1 applied\n"));
|
||||
}
|
||||
|
||||
// Even a null FP frame is 3 longwords on the 68060 (7.1, 7.5, 8.0)
|
||||
static const uint8 dat2[] = {0xf3, 0x5f, 0x4e, 0x75};
|
||||
base = find_rsrc_data(p, size, dat2, sizeof(dat2));
|
||||
if (base) {
|
||||
p16 = (uint16 *)(p + base - 2);
|
||||
*p16++ = htons(M68K_JMP);
|
||||
*p16++ = htons((uint32)Scod060Patch2 >> 16);
|
||||
*p16 = htons((uint32)Scod060Patch2 & 0xffff);
|
||||
FlushCodeCache(p + base - 2, 6);
|
||||
D(bug(" patch 2 applied\n"));
|
||||
}
|
||||
#endif
|
||||
|
||||
} else if (type == FOURCC('t','h','n','g') && id == -16563) {
|
||||
D(bug(" thng -16563 found\n"));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user