1 /*****************************************************************************
2  *
3  * Copyright (c) 2008-2010, CoreCodec, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *     * Redistributions of source code must retain the above copyright
9  *       notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above copyright
11  *       notice, this list of conditions and the following disclaimer in the
12  *       documentation and/or other materials provided with the distribution.
13  *     * Neither the name of CoreCodec, Inc. nor the
14  *       names of its contributors may be used to endorse or promote products
15  *       derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY CoreCodec, Inc. ``AS IS'' AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL CoreCodec, Inc. BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  ****************************************************************************/
29 
30 #include <PalmOS.h>
31 #include <MemGlue.h>
32 #include "m68k/peal.h"
33 #include <stdio.h>
34 #include <PceNativeCall.h>
35 
36 #define PALMOS_IX86_DLL(name)           #name
37 #define PALMOS_IX86_FUNC(name,func)     (NativeFuncType*)(PALMOS_IX86_DLL(name) ".dll\0" #func)
38 
39 #define SWAP16(a) ((((UInt16)(a) >> 8) & 0x00FF) | (((UInt16)(a) << 8) & 0xFF00))
40 
41 #define SWAP32(a) ((((UInt32)(a) >> 24) & 0x000000FF) | (((UInt32)(a) >> 8)  & 0x0000FF00) |\
42 	 	(((UInt32)(a) << 8)  & 0x00FF0000) | (((UInt32)(a) << 24) & 0xFF000000))
43 
44 typedef struct vfspath
45 {
46 	UInt16 volRefNum;
47 	Char path[256];
48 } vfspath;
49 
50 typedef struct launch
51 {
52 	MemPtr PealCall;
53 	PealModule* Module;
54 	void* LoadModule;
55 	void* FreeModule;
56 	void* GetSymbol;
57 
58 	MemPtr launchParameters;
59 	UInt16 launchCode;
60 	UInt16 launchFlags;
61 
62 } launch;
63 
RomVersionCheck(UInt16 launchFlags)64 static Err RomVersionCheck(UInt16 launchFlags)
65 {
66 	UInt32 Version;
67 	FtrGet(sysFtrCreator, sysFtrNumROMVersion, &Version);
68 
69 	if (Version < sysMakeROMVersion(5,0,0,sysROMStageDevelopment,0))
70 	{
71 		if ((launchFlags & sysAppLaunchFlagNewGlobals) != 0 &&
72 			(launchFlags & sysAppLaunchFlagUIApp) != 0)
73 		{
74 			FrmCustomAlert(WarningOKAlert, "System version 5.0 or greater is required to run this application!", " ", " ");
75 
76 			// Palm OS 1.0 requires you to explicitly launch another app
77 			if (Version < sysMakeROMVersion(1,0,0,sysROMStageRelease,0))
78 			{
79 				AppLaunchWithCommand(sysFileCDefaultApp,
80 						sysAppLaunchCmdNormalLaunch, NULL);
81 			}
82 		}
83 
84 		return sysErrRomIncompatible;
85 	}
86 	return errNone;
87 }
88 
89 static PealModule* Module = NULL;
90 static void* PaceMain = NULL;
91 
LookupSymbol86(void * Module,const char * Name)92 static void* LookupSymbol86(void* Module,const char* Name)
93 {
94 	return NULL;
95 }
96 
LoadModule(UInt16 ftrId,Boolean mem,Boolean onlyftr,Boolean memsema)97 static void* LoadModule(UInt16 ftrId,Boolean mem,Boolean onlyftr,Boolean memsema)
98 {
99 	return PealLoadFromResources('armc',1000,Module,PROJECT_FOURCC,ftrId,mem,onlyftr,memsema);
100 }
101 
PealCall86(void * Module,void * Func,void * Param)102 static UInt32 PealCall86(void* Module,void* Func,void* Param)
103 {
104 	return PceNativeCall((NativeFuncType*)Func,Param);
105 }
106 
GetHeapId()107 static UInt16 GetHeapId()
108 {
109 	MemPtr p=MemPtrNew(8);
110 	UInt16 Id=MemPtrHeapID(p);
111 	MemPtrFree(p);
112 	return Id;
113 }
114 
PilotMain(UInt16 launchCode,MemPtr launchParameters,UInt16 launchFlags)115 UInt32 PilotMain(UInt16 launchCode, MemPtr launchParameters, UInt16 launchFlags)
116 {
117 	UInt32 Value;
118 	UInt32 Result = errNone;
119 	UInt32 CPU;
120 	launch Launch;
121 	Launch.launchParameters = launchParameters;
122 	Launch.launchCode = launchCode;
123 	Launch.launchFlags = launchFlags;
124 
125 	if ((launchCode == sysAppLaunchCmdNormalLaunch ||
126 		launchCode == sysAppLaunchCmdOpenDB ||
127 		launchCode == sysAppLaunchCmdCustomBase) && !RomVersionCheck(launchFlags))
128 	{
129 		FtrGet(sysFileCSystem, sysFtrNumProcessorID, &CPU);
130 		if (CPU == sysFtrNumProcessorx86)
131 		{
132 			Module = PealLoadFromResources('armc', 1000, NULL, PROJECT_FOURCC,32,0,0,0); // just for testing
133 
134 			Launch.FreeModule = PealUnload;
135 			Launch.LoadModule = LoadModule;
136 			Launch.GetSymbol = LookupSymbol86;
137 			Launch.PealCall = PealCall86;
138 			Launch.Module = Module;
139 			PceNativeCall(PALMOS_IX86_FUNC(PROJECT_OUTPUT,PaceMain86),&Launch);
140 
141 			if (Module)
142 				PealUnload(Module);
143 		}
144 		else
145 		if (sysFtrNumProcessorIsARM(CPU))
146 		{
147 			UInt32 Version;
148 			Boolean MemSema;
149 
150 			FtrGet(sysFtrCreator, sysFtrNumROMVersion, &Version);
151 			MemSema = Version < sysMakeROMVersion(6,0,0,sysROMStageDevelopment,0);
152 
153 			Module = PealLoadFromResources('armc', 1000, NULL, PROJECT_FOURCC,32,0,0,MemSema);
154 			if (Module)
155 			{
156 				PaceMain = PealLookupSymbol(Module, "PaceMain");
157 				if (PaceMain)
158 				{
159 					Launch.FreeModule = PealUnload;
160 					Launch.LoadModule = LoadModule;
161 					Launch.GetSymbol = PealLookupSymbol;
162 					Launch.PealCall = PealCall;
163 					Launch.Module = Module;
164 
165 					Result = PealCall(Module,PaceMain,&Launch);
166 				}
167 				PealUnload(Module);
168 				MemHeapCompact(GetHeapId());
169 			}
170 		}
171 		else
172 			FrmCustomAlert(WarningOKAlert, "ARM processor is required to run this application!", " ", " ");
173 
174 		if (FtrGet(PROJECT_FOURCC,20,&Value)==errNone)
175 			FtrPtrFree(PROJECT_FOURCC,20);
176 	}
177 	else
178 	if (launchCode == sysAppLaunchCmdNotify && (launchFlags & sysAppLaunchFlagSubCall)!=0)
179 	{
180 		FtrGet(sysFileCSystem, sysFtrNumProcessorID, &CPU);
181 		if (CPU == sysFtrNumProcessorx86)
182 			Result = PceNativeCall(PALMOS_IX86_FUNC(PROJECT_OUTPUT,PaceMain86),&Launch);
183 		else
184 		if (sysFtrNumProcessorIsARM(CPU) && Module && PaceMain)
185 			Result = PealCall(Module,PaceMain,&Launch);
186 	}
187 	return Result;
188 }
189