|
|
|
|
|
|
|
||
|
||
|
|
||
July 1998 |
Revision 1.01 |
|
Persistor Instruments Inc. |
© 1998 All rights reserved. |
|
After the constants and typedefs in <cf1bios.h> comes the table of functions that your Persistor application uses to access driver system services. The table is constructed at compile time using several macros that precede the table. Most users will never need to know how this actually works, but since we force you to see this construct every time you scan through <cf1bios.h>, we thought some of the more curious programmers would like to know what's going on. If this is your first introduction to the CF1, we strongly recommend that you skip over the following complex discussion, and perhaps revisit this section after you've discovered that the rest of the operating system software is much more simple.
At compile time, the table becomes an enumerated list of driver function names. Later in <cf1bios.h>, the various driver functions become defined as inline functions (a feature of Metrowerks and many 68K compilers)which vector to specific flash addresses contained in a separate but synchronized address table in RAM which is automatically initialized at startup. This synchronization is maintained by compiling the drivers with using the same <cf1bios.h>, but redefining the macros to build the actual address table. An abbreviated example will help explain...
This is effectively the same as the real <cf1bios.h>, but scaled way back, and stripped of everything except the components that describe the mechanics of the vector table. The macro DRVRLIST translates the sequence of names to an enumerated list of names, each prefaced with an underscore character. The macro DRVR_CALL translates one of these enumerations to the sequence of machine instructions that fetch the vector and jump to the appropriate location.
#define RAM_BASE_ADDR 0x00000000
#define OS_DRVR_BASE (RAM_BASE_ADDR + 0x000800) // shared driver vectors
#define DRVR_DEF_BEGIN enum {
#define DRVR_DEF_END DRVR_ENUM_END};
#define DRVRLIST(n) _##n,
#define DRVR_CALL(f) = { 0x2078, _##f*4+OS_DRVR_BASE, 0x4E90 }
DRVR_DEF_BEGIN
DRVRLIST( OSFunctFoo )
DRVRLIST( OSFunctBar )
//...
DRVRLIST( OSFunctLast )
DRVR_DEF_END
void OSFunctFoo(long parm) DRVR_CALL(OSFunctFoo);
char *OSFunctBar(short count) DRVR_CALL(OSFunctBar);
//...
short OSFunctLast(void) DRVR_CALL(OSFunctLast);
#include <cf1bios.h>
main()
{
char *p = OSFunctBar(9);
if (OSFunctLast())
OSFunctFoo(7);
}
enum {
_OSFunctFoo,
_OSFunctBar,
_OSFunctLast,
DRVR_ENUM_END};
void OSFunctFoo(long parm) = { 0x2078, _OSFunctFoo*4+(0x00000000 + 0x000800), 0x4E90 };
char *OSFunctBar(short count) = { 0x2078, _OSFunctBar*4+(0x00000000 + 0x000800), 0x4E90 };
short OSFunctLast(void) = { 0x2078, _OSFunctLast*4+(0x00000000 + 0x000800), 0x4E90 };
main()
{
char *p = OSFunctBar(9);
if (OSFunctLast())
OSFunctFoo(7);
}
Hunk: Kind=HUNK_GLOBAL_CODE Name="main"(1) Size=54
main()
{
00000000: 4E56 FFFC link a6,#-4
char *p = OSFunctBar(9);
00000004: 3F3C 0009 move.w #9,-(a7)
00000008: 2078 0804 movea.l 0x00000804,a0
0000000C: 4E90 jsr (a0)
0000000E: 2D48 FFFC move.l a0,-4(a6)
if (OSFunctLast())
00000012: 2078 0808 movea.l 0x00000808,a0
00000016: 4E90 jsr (a0)
00000018: 4A40 tst.w d0
0000001A: 544F addq.w #2,a7
0000001C: 670C beq.s *+14 ; 0x0000002a
OSFunctFoo(7);
0000001E: 4878 0007 pea 0x00000007
00000022: 2078 0800 movea.l 0x00000800,a0
00000026: 4E90 jsr (a0)
00000028: 584F addq.w #4,a7
0000002A: 4E5E unlk a6
0000002C: 4E75 rts
0000002E: 846D 6169 6E00 dc.b 0x84,'main',0x00
00000034: 0000
}
|
|
|
|
|
|
Tel: 508-759-6434 |
|
Fax: 508-759-6436 |
|
|
||