2004-09-17 09:11:33 +02:00
|
|
|
/* -*-mode: C; fill-column: 77; c-basic-offset: 4; -*- */
|
2004-09-19 04:38:13 +02:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2004-09-17 09:11:33 +02:00
|
|
|
|
|
|
|
#include <PalmTypes.h>
|
|
|
|
#include <SystemMgr.h>
|
|
|
|
#include <PceNativeCall.h>
|
|
|
|
#include <FeatureMgr.h>
|
|
|
|
#include <StringMgr.h>
|
|
|
|
#include <Form.h>
|
|
|
|
#include <DataMgr.h>
|
|
|
|
#include "pnostate.h"
|
2004-09-24 03:27:41 +02:00
|
|
|
#include "palmmain.h" /* for Ftr enum */
|
2004-09-17 09:11:33 +02:00
|
|
|
|
|
|
|
static void
|
|
|
|
write_byte32( void* dest, UInt32 val )
|
|
|
|
{
|
|
|
|
MemMove( dest, &val, sizeof(val) );
|
|
|
|
}
|
|
|
|
|
|
|
|
static UInt32
|
|
|
|
byte_swap32( UInt32 in )
|
|
|
|
{
|
|
|
|
UInt32 tmp = 0L;
|
|
|
|
tmp |= (in & 0x000000FF) << 24;
|
|
|
|
tmp |= (in & 0x0000FF00) << 8;
|
|
|
|
tmp |= (in & 0x00FF0000) >> 8;
|
|
|
|
tmp |= (in & 0xFF000000) >> 24;
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
alertUser( char* str )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2004-09-19 04:38:13 +02:00
|
|
|
typedef struct PNOFtrHeader {
|
|
|
|
UInt32* gotTable;
|
|
|
|
} PNOFtrHeader;
|
|
|
|
|
2004-09-17 09:11:33 +02:00
|
|
|
void
|
2004-09-19 04:38:13 +02:00
|
|
|
storageCallback( void/*PnoletUserData*/* _dataP )
|
2004-09-17 09:11:33 +02:00
|
|
|
{
|
2004-09-19 04:38:13 +02:00
|
|
|
PnoletUserData* dataP = (PnoletUserData*)_dataP;
|
2004-09-17 09:11:33 +02:00
|
|
|
char buf[48];
|
|
|
|
UInt32 offset;
|
2004-09-19 04:38:13 +02:00
|
|
|
PNOFtrHeader* ftrBase;
|
2004-09-17 09:11:33 +02:00
|
|
|
|
|
|
|
StrPrintF( buf, "storageCallback(%lx)", dataP );
|
2004-09-19 04:38:13 +02:00
|
|
|
WinDrawChars( buf, StrLen(buf), 5, 40 );
|
2004-09-17 09:11:33 +02:00
|
|
|
|
|
|
|
StrPrintF( buf, "src=%lx; dest=%lx", dataP->stateSrc, dataP->stateDest );
|
|
|
|
WinDrawChars( buf, StrLen(buf), 5, 50 );
|
|
|
|
|
2004-09-19 04:38:13 +02:00
|
|
|
ftrBase = (PNOFtrHeader*)dataP->pnoletEntry;
|
|
|
|
--ftrBase; /* back up over header */
|
|
|
|
offset = (char*)dataP->stateDest - (char*)ftrBase;
|
|
|
|
DmWrite( ftrBase, offset, dataP->stateSrc, sizeof(PNOState) );
|
|
|
|
WinDrawChars( "callback done", 13, 5, 60 );
|
2004-09-17 09:11:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2004-09-19 04:38:13 +02:00
|
|
|
countOrLoadPNOCs( UInt32* pnoSizeP, UInt8* base, UInt32 offset )
|
2004-09-17 09:11:33 +02:00
|
|
|
{
|
|
|
|
DmResID id;
|
|
|
|
|
|
|
|
for ( id = 0; ; ++id ) {
|
|
|
|
UInt32 size;
|
|
|
|
MemHandle h = DmGetResource( 'PNOC', id );
|
|
|
|
|
|
|
|
if ( !h ) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
size = MemHandleSize( h );
|
2004-09-19 04:38:13 +02:00
|
|
|
if ( !!base ) {
|
|
|
|
Err err = DmWrite( base, offset, MemHandleLock(h), size );
|
2004-09-17 09:11:33 +02:00
|
|
|
if ( err != errNone ) {
|
|
|
|
alertUser( "error from DmWrite" );
|
|
|
|
}
|
|
|
|
MemHandleUnlock(h);
|
|
|
|
}
|
|
|
|
DmReleaseResource(h);
|
2004-09-19 04:38:13 +02:00
|
|
|
offset += size;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !!pnoSizeP ) {
|
|
|
|
*pnoSizeP = offset;
|
2004-09-17 09:11:33 +02:00
|
|
|
}
|
|
|
|
} /* countOrLoadPNOCs */
|
|
|
|
|
2004-09-19 04:38:13 +02:00
|
|
|
static void
|
|
|
|
setupPnolet( UInt32** entryP, UInt32** gotTableP )
|
2004-09-17 09:11:33 +02:00
|
|
|
{
|
2004-09-19 04:38:13 +02:00
|
|
|
char buf[64];
|
|
|
|
PNOFtrHeader* ftrBase;
|
2004-09-24 03:27:41 +02:00
|
|
|
Err err = FtrGet( APPID, PNOLET_STORE_FEATURE, (UInt32*)&ftrBase );
|
2004-09-19 04:38:13 +02:00
|
|
|
|
|
|
|
if ( err != errNone ) {
|
2004-09-17 09:11:33 +02:00
|
|
|
UInt32* gotTable;
|
|
|
|
UInt32 pnoSize, gotSize, pad;
|
2004-09-19 04:38:13 +02:00
|
|
|
UInt32 ftrSize = sizeof( PNOFtrHeader );
|
|
|
|
UInt32* pnoCode;
|
|
|
|
PNOFtrHeader header;
|
2004-09-17 09:11:33 +02:00
|
|
|
|
|
|
|
// LOAD: GOT table
|
|
|
|
MemHandle h = DmGetResource( 'PNOG', 0 );
|
|
|
|
if ( !h ) {
|
|
|
|
gotSize = 0;
|
|
|
|
gotTable = NULL;
|
|
|
|
} else {
|
|
|
|
gotSize = MemHandleSize( h );
|
|
|
|
gotTable = (UInt32*)MemPtrNew( gotSize );
|
|
|
|
MemMove( gotTable, MemHandleLock(h), gotSize );
|
|
|
|
MemHandleUnlock( h );
|
|
|
|
DmReleaseResource( h );
|
|
|
|
}
|
2004-09-19 04:38:13 +02:00
|
|
|
ftrSize += gotSize;
|
2004-09-17 09:11:33 +02:00
|
|
|
|
2004-09-19 04:38:13 +02:00
|
|
|
countOrLoadPNOCs( &pnoSize, NULL, 0 );
|
|
|
|
ftrSize += pnoSize;
|
2004-09-17 09:11:33 +02:00
|
|
|
pad = (4 - (pnoSize & 3)) & 3;
|
2004-09-19 04:38:13 +02:00
|
|
|
ftrSize += pad;
|
|
|
|
|
2004-09-24 03:27:41 +02:00
|
|
|
FtrPtrNew( APPID, PNOLET_STORE_FEATURE, ftrSize, (void**)&ftrBase );
|
2004-09-19 04:38:13 +02:00
|
|
|
pnoCode = (UInt32*)&ftrBase[1];
|
2004-09-17 09:11:33 +02:00
|
|
|
|
2004-09-19 04:38:13 +02:00
|
|
|
StrPrintF( buf, "code ends at 0x%lx",
|
|
|
|
((char*)ftrBase) + ftrSize );
|
|
|
|
WinDrawChars( buf, StrLen(buf), 5, 10 );
|
|
|
|
|
|
|
|
countOrLoadPNOCs( NULL, (UInt8*)ftrBase, sizeof(PNOFtrHeader) );
|
2004-09-17 09:11:33 +02:00
|
|
|
|
|
|
|
if ( gotSize > 0 ) {
|
|
|
|
UInt32 cnt = gotSize >> 2;
|
|
|
|
UInt32 i;
|
|
|
|
for ( i = 0; i < cnt; ++i ) {
|
|
|
|
write_byte32(&gotTable[i],
|
|
|
|
byte_swap32(byte_swap32(gotTable[i])
|
|
|
|
+ (UInt32)pnoCode));
|
|
|
|
}
|
|
|
|
|
2004-09-19 04:38:13 +02:00
|
|
|
DmWrite( ftrBase, sizeof(PNOFtrHeader) + pnoSize + pad,
|
|
|
|
gotTable, gotSize );
|
2004-09-17 09:11:33 +02:00
|
|
|
MemPtrFree( gotTable );
|
2004-09-19 04:38:13 +02:00
|
|
|
|
|
|
|
header.gotTable = (UInt32*)(((char*)pnoCode) + pnoSize + pad);
|
|
|
|
DmWrite( ftrBase, 0, &header, sizeof(header) );
|
2004-09-17 09:11:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-09-19 04:38:13 +02:00
|
|
|
*gotTableP = ftrBase->gotTable;
|
|
|
|
*entryP = (UInt32*)&ftrBase[1];
|
|
|
|
|
|
|
|
StrPrintF( buf, "got at 0x%lx", *gotTableP );
|
|
|
|
WinDrawChars( buf, StrLen(buf), 5, 20 );
|
|
|
|
} /* setupPnolet */
|
2004-09-17 09:11:33 +02:00
|
|
|
|
|
|
|
static Boolean
|
2004-09-24 03:27:41 +02:00
|
|
|
shouldRunPnolet()
|
2004-09-17 09:11:33 +02:00
|
|
|
{
|
2004-09-24 03:27:41 +02:00
|
|
|
UInt32 value;
|
|
|
|
Boolean result = false;
|
|
|
|
Err err = FtrGet( sysFtrCreator, sysFtrNumProcessorID, &value );
|
|
|
|
|
|
|
|
if ( ( err == errNone ) && sysFtrNumProcessorIsARM( value ) ) {
|
|
|
|
result = true;
|
|
|
|
}
|
|
|
|
if ( result ) {
|
|
|
|
err = FtrGet( APPID, WANTS_ARM_FEATURE, &value );
|
|
|
|
if ( (err != errNone) || (value != WANTS_ARM) ) {
|
|
|
|
result = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
} /* shouldRunPnolet */
|
2004-09-17 09:11:33 +02:00
|
|
|
|
|
|
|
UInt32
|
|
|
|
PilotMain( UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags)
|
|
|
|
{
|
2004-09-24 03:27:41 +02:00
|
|
|
UInt32 result = 0;
|
|
|
|
if ( ( cmd == sysAppLaunchCmdNormalLaunch )
|
|
|
|
#ifdef IR_EXCHMGR
|
|
|
|
|| ( cmd == sysAppLaunchCmdExgAskUser )
|
|
|
|
|| ( cmd == sysAppLaunchCmdSyncNotify )
|
|
|
|
|| ( cmd == sysAppLaunchCmdExgReceiveData )
|
|
|
|
#endif
|
|
|
|
) {
|
|
|
|
|
|
|
|
/* This is the entry point for both an ARM-only app and one capable
|
|
|
|
of doing both. If the latter, and ARM's an option, we want to use
|
|
|
|
it unless the user's said not to. */
|
|
|
|
|
|
|
|
if ( shouldRunPnolet() ) {
|
2004-09-19 04:38:13 +02:00
|
|
|
char buf[64];
|
2004-09-17 09:11:33 +02:00
|
|
|
UInt32* gotTable;
|
|
|
|
PnoletUserData* dataP;
|
2004-09-19 04:38:13 +02:00
|
|
|
UInt32* pnoCode;
|
2004-09-17 09:11:33 +02:00
|
|
|
UInt32 result;
|
|
|
|
|
2004-09-19 04:38:13 +02:00
|
|
|
setupPnolet( &pnoCode, &gotTable );
|
|
|
|
|
2004-09-17 09:11:33 +02:00
|
|
|
dataP = (PnoletUserData*)MemPtrNew( sizeof(PnoletUserData) );
|
|
|
|
dataP->pnoletEntry = pnoCode;
|
|
|
|
dataP->gotTable = gotTable;
|
|
|
|
dataP->storageCallback = storageCallback;
|
|
|
|
|
2004-09-19 04:38:13 +02:00
|
|
|
dataP->cmdPBP = cmdPBP;
|
|
|
|
dataP->cmd = cmd;
|
|
|
|
dataP->launchFlags = launchFlags;
|
|
|
|
|
|
|
|
StrPrintF( buf, "armlet starts at 0x%lx", pnoCode );
|
|
|
|
WinDrawChars( buf, StrLen(buf), 5, 30 );
|
|
|
|
|
2004-09-17 09:11:33 +02:00
|
|
|
result = PceNativeCall((NativeFuncType*)pnoCode, (void*)dataP );
|
|
|
|
MemPtrFree( dataP );
|
|
|
|
|
2004-09-19 04:38:13 +02:00
|
|
|
/* Might want to hang onto this, though it's a bit selfish.... */
|
2004-09-24 03:27:41 +02:00
|
|
|
FtrPtrFree( APPID, PNOLET_STORE_FEATURE );
|
2004-09-17 09:11:33 +02:00
|
|
|
} else {
|
2004-09-24 03:27:41 +02:00
|
|
|
#ifdef FEATURE_PNOAND68K
|
|
|
|
result = PM2(PilotMain)( cmd, cmdPBP, launchFlags);
|
|
|
|
#else
|
|
|
|
(void)FrmCustomAlert( XW_ERROR_ALERT_ID,
|
|
|
|
"Arm-only Crosswords won't run on this device",
|
|
|
|
" ", " " );
|
|
|
|
#endif
|
2004-09-17 09:11:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-09-24 03:27:41 +02:00
|
|
|
return result;
|
2004-09-17 09:11:33 +02:00
|
|
|
} /* PilotMain */
|