annotate _posts/2025-10-19-oms-part-1.html @ 119:3d2803ed2c6a default tip

CI: alpine/edge is broken
author Paper <paper@tflc.us>
date Mon, 20 Oct 2025 00:14:33 -0400
parents 503e22dd6cf5
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
118
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
1 ---
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
2 layout: post
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
3 author: Paper
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
4 title: 'The Open Music System, part 1 - initialization'
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
5 nowplaying: 'The Radio Dept. - Brobygatan'
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
6 ---
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
7 <span>
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
8 Applications wanting to interact with OMS must first call into
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
9 <code>Gestalt</code> with the first parameter being the magic
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
10 bytes <code>" OMS"</code> (<code>0x204F3D53</code>) and the
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
11 second parameter being a pointer to a 32-bit variable that
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
12 receives the magic pointer.
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
13 </span>
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
14 {% comment %}
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
15 is there was a way to do this with newlines? this is ugly
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
16 {% endcomment %}
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
17 <figure><pre class="code-block"><code>UniversalProcPtr OMS_GetGestaltPtr(void)
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
18 {
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
19 OSErr err;
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
20 uint32_t x;
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
21
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
22 err = Gestalt(0x204F3D53 /* " OMS" */, &x);
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
23 if (err != noErr)
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
24 return NULL;
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
25
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
26 return (UniversalProcPtr)x;
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
27 }</code></pre></figure>
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
28 <span>
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
29 From here, applications must retrieve an array of functions
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
30 through calling that magic pointer. Note that users cannot
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
31 simply call this pointer directly, unless they are specifically
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
32 only targeting 68k. You must use the <code>CallUniversalProc</code>
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
33 function to safely call into 68k code.
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
34 </span>
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
35 <figure><pre class="code-block"><code>UniversalProcPtr oms_table[0x5e];
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
36
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
37 #define OMS_GESTALT_PROC_TYPE \
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
38 (kThinkCStackBased \
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
39 | RESULT_SIZE(kFourByteCode) \
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
40 | STACK_ROUTINE_PARAMETER(1, kTwoByteCode) \
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
41 | STACK_ROUTINE_PARAMETER(2, kFourByteCode))
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
42
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
43 int32_t OMS_Init(void)
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
44 {
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
45 uint32_t functable;
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
46 UniversalProcPtr omsptr;
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
47
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
48 omsptr = OMS_GetGestaltPtr();
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
49 if (!omsptr)
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
50 return -1;
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
51
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
52 functable = CallUniversalProc(omsptr, OMS_GESTALT_PROC_TYPE, 4, 0);
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
53 if (functable != (uint32_t)-1) {
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
54 memcpy(oms_table, (const void *)functable, sizeof(oms_table));
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
55 } else {
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
56 /* very old OMS */
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
57 uint32_t i;
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
58
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
59 functable = CallUniversalProc(omsptr, OMS_GESTALT_PROC_TYPE, 1, 0);
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
60 if (!functable)
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
61 return -1;
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
62
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
63 for (i = 0; i < ARRAY_SIZE(oms_table); i++, functable += 4)
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
64 oms_table[i] = (UniversalProcPtr)functable;
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
65 }
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
66
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
67 return 0;
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
68 }</code></pre></figure>
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
69 <span>
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
70 At this point, you can now call into any of the pointers in
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
71 <code>oms_table</code>, provided that you know what the parameters
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
72 are. The easiest way I've found to find the parameters is to open an
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
73 OMS-capable program in a reverse-engineering tool, search for uses of
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
74 <code>CallUniversalProc</code> that look roughly like the initialization
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
75 code above, and mark the offset they are copied to as the OMS table with
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
76 the correct size and type. You can then find other uses of
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
77 <code>CallUniversalProc</code> that use the pointers in the OMS table,
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
78 and mark down the procedure type (the second parameter to
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
79 <code>CallUniversalProc</code>). To decode the procedure type, I've
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
80 written a simple utility to do the heavy lifting
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
81 <a class="prettylink" href="https://hg.tflc.us/codedump/file/tip/decode-mixed-mode.c">here</a>.
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
82 Do take note that it does not support register-based calling yet.
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
83 Feel free to send me any patches if you add support for it ;)
503e22dd6cf5 blog: add (unfinished) series on OMS
Paper <paper@tflc.us>
parents:
diff changeset
84 </span>