]> asedeno.scripts.mit.edu Git - peal.git/blob - example/m68k.c
Greg Parker's Palm Elf Arm Loader (PEAL)
[peal.git] / example / m68k.c
1 /**********
2  * Copyright (c) 2004 Greg Parker.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  **********/
24
25 #include <PalmOS.h>
26 #include <stdint.h>
27 #include <stdarg.h>
28 #include "peal.h"
29
30 #define swap32(n) ( ((((unsigned long) (n)) << 24) & 0xFF000000) | \
31                     ((((unsigned long) (n)) <<  8) & 0x00FF0000) | \
32                     ((((unsigned long) (n)) >>  8) & 0x0000FF00) | \
33                     ((((unsigned long) (n)) >> 24) & 0x000000FF) )
34
35
36 void print(char *format, ...)
37 {
38     RectangleType r, empty;
39     char buf[200];
40
41     va_list args;
42     va_start(args, format);
43     StrVPrintF(buf, format, args);
44     va_end(args);
45
46     r.topLeft.x = 0;
47     r.topLeft.y = 0;
48     r.extent.x = 160;
49     r.extent.y = 160;
50     WinScrollRectangle(&r, winDown, 12, &empty);
51     WinEraseRectangle(&empty, 0);
52
53     WinDrawChars(buf, StrLen(buf), 1, 1);
54 }
55
56 static MemHandle armH = NULL;
57
58 PealModule *load(void)
59 {
60     /*
61     armH = DmGetResource('armc', 1000);
62     if (!armH) {
63         return 0;
64     }
65     return PealLoad(MemHandleLock(armH));
66     */
67     return PealLoadFromResources('armc', 1000);
68 }
69
70
71 void unload(PealModule *m)
72 {
73     PealUnload(m);
74     /*
75     MemHandleUnlock(armH);
76     DmReleaseResource(armH);
77     */
78 }
79
80
81 uint32_t callback(void)
82 {
83     return 42;
84 }
85
86
87 void test(PealModule *m)
88 {
89     void *GetCallCount_arm;
90     void *SetFunctionPointer_arm;
91     void *CallFunctionPointer_arm;
92     void *Call68K_arm;
93     
94     uint32_t *CallCount_arm;
95     void **Callback_arm;
96     uint32_t result;
97     char *str;
98
99     // Call an ARM function that uses global data
100     GetCallCount_arm = PealLookupSymbol(m, "GetCallCount");
101
102     result = PealCall(m, GetCallCount_arm, NULL);
103     print("CallCount(): %lu", result);
104     result = PealCall(m, GetCallCount_arm, NULL);
105     print("CallCount(): %lu", result);
106     result = PealCall(m, GetCallCount_arm, NULL);
107     print("CallCount(): %lu", result);
108
109     // Read an ARM variable directly
110     CallCount_arm = (uint32_t *)PealLookupSymbol(m, "CallCount");
111     print("CallCount variable is %lu", swap32(*CallCount_arm));
112
113     // Call an ARM function that uses function pointers and global data
114     SetFunctionPointer_arm = PealLookupSymbol(m, "SetFunctionPointer");
115     CallFunctionPointer_arm = PealLookupSymbol(m, "CallFunctionPointer");
116     
117     PealCall(m, SetFunctionPointer_arm, (void *)1);
118
119     str = (char *)PealCall(m, CallFunctionPointer_arm, NULL);
120     print("CallFunctionPointer (fn 1): '%s'", str);
121
122     PealCall(m, SetFunctionPointer_arm, (void *)0);
123     
124     str = (char *)PealCall(m, CallFunctionPointer_arm, NULL);
125     print("CallFunctionPointer (fn 0): '%s'", str);
126     str = (char *)PealCall(m, CallFunctionPointer_arm, NULL);
127     print("CallFunctionPointer (fn 0): '%s'", str);
128
129     // Set an ARM variable
130     Callback_arm = (void **)PealLookupSymbol(m, "Callback_m68k");
131     *Callback_arm = (void *)swap32(&callback);
132
133     // Call an ARM function that calls back into m68k
134     Call68K_arm = PealLookupSymbol(m, "Call68K");
135     result = PealCall(m, Call68K_arm, NULL);
136     print("m68k callback return %lu", result);
137
138     // Read an ARM variable directly
139     CallCount_arm = PealLookupSymbol(m, "CallCount");
140     print("CallCount variable is %lu", swap32(*CallCount_arm));
141 }
142
143
144 UInt32 PilotMain(UInt16 cmd, void *cmdPBP, UInt16 launchFlags)
145 {
146     PealModule *m;
147
148     // we don't handle search et al.
149     if (cmd != sysAppLaunchCmdNormalLaunch) return 0;
150     
151     m = load();
152     test(m);
153     unload(m);
154
155     print("Quitting in 10 seconds.");
156     SysTaskDelay(10*SysTicksPerSecond());
157     return 0;
158 }