xwords/xwords4/palm/pnolet.c
ehouse 44b836717f Don't call startup code when PilotMain is called reentrantly; flip
ExgSocketType when passed into PilotMain; stop warning from
getStorageLoc; remove old screen drawing for debugging.
2004-10-02 03:57:36 +00:00

161 lines
4.9 KiB
C

/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
/*
* Copyright 2004 by Eric House (fixin@peak.org). All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <PceNativeCall.h>
#include "pnostate.h"
#include "pace_gen.h"
#include "pace_man.h" /* for the ExgSocketType flippers */
#include "palmmain.h"
typedef union ParamStub {
ExgAskParamType exgAskParamType;
ExgSocketType exgSocketType;
} ParamStub;
unsigned long
realArmletEntryPoint( const void *emulStateP,
void *userData68KP,
Call68KFuncType* call68KFuncP );
/* With arm-palmos-gcc, there can't be any .GOT references in the entry point
(since those values get put inline BEFORE the function rather than
after.) */
unsigned long
ArmletEntryPoint( const void *emulStateP,
void *userData68KP,
Call68KFuncType* call68KFuncP )
{
return realArmletEntryPoint( emulStateP,
userData68KP,
call68KFuncP );
}
#ifdef IR_EXCHMGR
static XP_Bool
convertParamToArm( UInt16 cmd, ParamStub* armParam, MemPtr parm68K )
{
XP_Bool revert;
if ( cmd == sysAppLaunchCmdExgAskUser ) {
/* We don't read the data, but we do write to one field. */
revert = XP_TRUE;
} else if ( cmd == sysAppLaunchCmdExgReceiveData ) {
flipEngSocketToArm( &armParam->exgSocketType,
(const unsigned char*)parm68K );
revert = XP_TRUE; /* just to be safe */
} else {
revert = XP_FALSE;
}
return revert;
} /* convertParamToArm */
static void
convertParamFromArm( UInt16 cmd, MemPtr parm68K, ParamStub* armParam )
{
if ( cmd == sysAppLaunchCmdExgAskUser ) {
write_unaligned8( &((unsigned char*)parm68K)[4],
armParam->exgAskParamType.result );
} else if ( cmd == sysAppLaunchCmdExgReceiveData ) {
flipEngSocketFromArm( parm68K, &armParam->exgSocketType );
} else {
XP_ASSERT(0);
}
}
#endif
unsigned long
realArmletEntryPoint( const void *emulStateP,
void *userData68KP,
Call68KFuncType* call68KFuncP )
{
PNOState* loc;
PNOState state;
PnoletUserData* dataP;
unsigned long result;
unsigned long oldR10;
UInt16 cmd;
MemPtr cmdPBP;
MemPtr oldVal;
ParamStub ptrStorage;
XP_Bool mustRevert;
loc = getStorageLoc();
dataP = (PnoletUserData*)userData68KP;
dataP->stateSrc = (PNOState*)Byte_Swap32((unsigned long)&state);
dataP->stateDest = (PNOState*)Byte_Swap32((unsigned long)loc);
state.gotTable = (unsigned long*)
Byte_Swap32((unsigned long)dataP->gotTable);
if ( !dataP->recursive ) {
STACK_START(unsigned char, stack, 4 );
ADD_TO_STACK4(stack, userData68KP, 0);
STACK_END(stack);
state.emulStateP = emulStateP;
state.call68KFuncP = call68KFuncP;
(*call68KFuncP)( emulStateP,
Byte_Swap32((unsigned long)dataP->storageCallback),
stack, 4 );
}
asm( "mov %0, r10" : "=r" (oldR10) );
asm( "mov r10, %0" : : "r" (state.gotTable) );
cmd = Byte_Swap16( dataP->cmd );
cmdPBP = (MemPtr)Byte_Swap32((unsigned long)dataP->cmdPBP);
#ifdef IR_EXCHMGR
/* if the cmd is sysAppLaunchCmdExgAskUser or
sysAppLaunchCmdExgReceiveData then we're going to be making use of the
cmdPBP value in PilotMain. Need to convert it here. */
mustRevert = convertParamToArm( cmd, &ptrStorage, cmdPBP );
#endif
oldVal = cmdPBP;
cmdPBP = &ptrStorage;
result = PM2(PilotMain)( cmd, cmdPBP, Byte_Swap16(dataP->launchFlags) );
#ifdef IR_EXCHMGR
if ( mustRevert ) {
convertParamFromArm( cmd, oldVal, &ptrStorage );
}
#endif
asm( "mov r10, %0" : : "r" (oldR10) );
return result;
}
PNOState*
getStorageLoc()
{
asm( "adr r0,data" );
asm( "mov pc,lr" );
asm( "data:" );
/* we need sizeof(PNOState) worth of bytes after the data label. */
asm( "nop" );
asm( "nop" );
return (PNOState*)0L; /* shut up compiler; overwrite me!!!! */
/* The compiler's adding a "mov pc,lr" here too that we can overwrite. */
}