--- SheepShaver/src/include/thunks.h 2004/04/18 23:03:52 1.6 +++ SheepShaver/src/include/thunks.h 2006/05/03 21:45:14 1.14 @@ -32,6 +32,10 @@ enum { NATIVE_VIDEO_INSTALL_ACCEL, NATIVE_VIDEO_VBL, NATIVE_VIDEO_DO_DRIVER_IO, + NATIVE_ETHER_AO_GET_HWADDR, + NATIVE_ETHER_AO_ADD_MULTI, + NATIVE_ETHER_AO_DEL_MULTI, + NATIVE_ETHER_AO_SEND_PACKET, NATIVE_ETHER_IRQ, NATIVE_ETHER_INIT, NATIVE_ETHER_TERM, @@ -51,8 +55,6 @@ enum { NATIVE_GET_IND_RESOURCE, NATIVE_GET_1_IND_RESOURCE, NATIVE_R_GET_RESOURCE, - NATIVE_DISABLE_INTERRUPT, - NATIVE_ENABLE_INTERRUPT, NATIVE_MAKE_EXECUTABLE, NATIVE_CHECK_LOAD_INVOC, NATIVE_SYNC_HOOK, @@ -60,8 +62,10 @@ enum { NATIVE_FILLRECT_HOOK, NATIVE_BITBLT, NATIVE_INVRECT, - NATIVE_FILLRECT_8, - NATIVE_FILLRECT_32, + NATIVE_FILLRECT, + NATIVE_NAMED_CHECK_LOAD_INVOC, + NATIVE_GET_NAMED_RESOURCE, + NATIVE_GET_1_NAMED_RESOURCE, NATIVE_OP_MAX }; @@ -88,6 +92,22 @@ extern uint32 NativeRoutineDescriptor(in /* * Helpers to share 32-bit addressable data with MacOS + * + * There are two distinct allocatable regions: + * + * - The Data region is used to share data between MacOS and + * SheepShaver. This is stack-like allocation since it is + * meant to only hold temporary data which dies at the end + * of the current function scope. + * + * - The Procedure region is used to hold permanent M68K or + * PowerPC code to assist native routine implementations. + * + * - The Procedure region grows up whereas the Data region + * grows down. They may intersect into the ZeroPage, which + * is a read-only page with all bits set to zero. In practise, + * the intersection is unlikely since the Procedure region is + * static and the Data region is meant to be small (< 256 KB). */ class SheepMem { @@ -96,15 +116,17 @@ protected: static uint32 page_size; static uintptr zero_page; static uintptr base; - static uintptr top; - static const uint32 size = 0x40000; // 256 KB + static uintptr data; + static uintptr proc; + static const uint32 size = 0x80000; // 512 KB public: static bool Init(void); static void Exit(void); static uint32 PageSize(); - static uintptr ZeroPage(); - static uintptr Reserve(uint32 size); + static uint32 ZeroPage(); + static uint32 Reserve(uint32 size); static void Release(uint32 size); + static uint32 ReserveProc(uint32 size); friend class SheepVar; }; @@ -119,32 +141,51 @@ inline uint32 SheepMem::PageSize() return page_size; } -inline uintptr SheepMem::ZeroPage() +inline uint32 SheepMem::ZeroPage() { return zero_page; } -inline uintptr SheepMem::Reserve(uint32 size) +inline uint32 SheepMem::Reserve(uint32 size) { - top -= align(size); - assert(top >= base); - return top; + data -= align(size); + assert(data >= proc); + return data; } inline void SheepMem::Release(uint32 size) { - top += align(size); + data += align(size); } +inline uint32 SheepMem::ReserveProc(uint32 size) +{ + uint32 mproc = proc; + proc += align(size); + assert(proc < data); + return mproc; +} + +static inline uint32 SheepProc(const uint8 *proc, uint32 proc_size) +{ + uint32 mac_proc = SheepMem::ReserveProc(proc_size); + Host2Mac_memcpy(mac_proc, proc, proc_size); + return mac_proc; +} + +#define BUILD_SHEEPSHAVER_PROCEDURE(PROC) \ + static uint32 PROC = 0; \ + if (PROC == 0) \ + PROC = SheepProc(PROC##_template, sizeof(PROC##_template)) + class SheepVar { - uintptr m_base; - uint32 m_size; + uint32 m_base; + uint32 m_size; public: SheepVar(uint32 requested_size); ~SheepVar() { SheepMem::Release(m_size); } - uintptr addr() const { return m_base; } - void *ptr() const { return (void *)addr(); } + uint32 addr() const { return m_base; } }; inline SheepVar::SheepVar(uint32 requested_size) @@ -155,11 +196,10 @@ inline SheepVar::SheepVar(uint32 request // TODO: optimize for 32-bit platforms -template< int size > +template< int requested_size > struct SheepArray : public SheepVar { - SheepArray() : SheepVar(size) { } - uint8 *ptr() const { return (uint8 *)addr(); } + SheepArray() : SheepVar(requested_size) { } }; struct SheepVar32 : public SheepVar @@ -168,17 +208,14 @@ struct SheepVar32 : public SheepVar SheepVar32(uint32 value) : SheepVar(4) { set_value(value); } uint32 value() const { return ReadMacInt32(addr()); } void set_value(uint32 v) { WriteMacInt32(addr(), v); } - uint32 *ptr() const { return (uint32 *)addr(); } }; struct SheepString : public SheepVar { SheepString(const char *str) : SheepVar(strlen(str) + 1) - { if (str) strcpy((char *)addr(), str); else WriteMacInt8(addr(), 0); } + { if (str) strcpy(value(), str); else WriteMacInt8(addr(), 0); } char *value() const - { return (char *)addr(); } - char *ptr() const - { return (char *)addr(); } + { return (char *)Mac2HostAddr(addr()); } }; #endif