/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */ /* * Copyright 2004 by Eric House (xwords@eehouse.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 #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 XWFEATURE_IR 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 XWFEATURE_IR /* 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 XWFEATURE_IR if ( mustRevert ) { convertParamFromArm( cmd, oldVal, &ptrStorage ); } #endif asm( "mov r10, %0" : : "r" (oldR10) ); return result; } /* realArmletEntryPoint( */ PNOState* getStorageLoc( void ) { 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. */ }