/* ** ** wbstart.library emulation v44 ** © 1999 by Stephan Rupprecht ** All Rights reserved ** */ #include #include #include #include #include #include #include #include #include #include #include #include #include "library.h" #define SysBase WBStartBase->wbsb_SysBase #define WorkbenchBase WBStartBase->wbsb_WorkbenchBase #define UtilityBase WBStartBase->wbsb_UtilityBase #define DOSBase WBStartBase->wbsb_DOSBase #ifndef BPTR #define BPTR ULONG #endif #define REG(r) __asm( #r ) #define VERSION 2 #define REVISION 2 /****************************************************************************/ struct Library *LibInit(ULONG Segment REG(a0), struct WBStartBase *WBStartBase REG(d0), struct Library * REG(a6)); struct Library *LibOpen(struct WBStartBase *WBStartBase REG(a6)); ULONG LibExpunge(struct WBStartBase *WBStartBase REG(a6)); ULONG LibClose(struct WBStartBase *WBStartBase REG(a6)); LONG LibExtFunc(void); BOOL L_OpenLibs( struct WBStartBase *WBStartBase ); VOID L_CloseLibs( struct WBStartBase *WBStartBase ); LONG WBStartTagList( struct TagItem *tlist REG(a0), struct WBStartBase *WBStartBase REG(a6) ); /****************************************************************************/ ULONG LibVectors[] = { (ULONG)LibOpen, (ULONG)LibClose, (ULONG)LibExpunge, (ULONG)LibExtFunc, (ULONG)LibExtFunc, (ULONG)WBStartTagList, (ULONG)-1L }; UBYTE LibName[] = "wbstart.library", LibID[] = "wbstart.library 44.1 (22.10.99) emulation (C) 1999 by Stephan Rupprecht"; ULONG LibInitTab[] = { (ULONG) sizeof(struct WBStartBase), (ULONG) LibVectors, (ULONG) NULL, (ULONG) LibInit }; struct Resident ROMTag = /* do not change */ { RTC_MATCHWORD, &ROMTag, &ROMTag + 1, RTF_AUTOINIT, VERSION, NT_LIBRARY, 0, LibName, LibID, (APTR)&LibInitTab }; /****************************************************************************/ LONG nop(void) { return(-1L); } /****************************************************************************/ LONG LibExtFunc(void) { return(0L); } /****************************************************************************/ #if 0 void kprintf( STRPTR FormatStr, ... ) { #undef SysBase struct Library *SysBase = (*(struct Library **)4L); TEXT PutChData[64]; STRPTR p = PutChData; RawDoFmt(FormatStr, ((STRPTR)(&FormatStr))+4, (void (*)())"\x16\xc0\x4e\x75", PutChData); do RawPutChar( *p ); while( *p++ ); #define SysBase WBStartBase->wbsb_SysBase } #else #define kprintf(...) #endif /****************************************************************************/ struct Library * LibInit(ULONG Segment REG(a0), struct WBStartBase *WBStartBase REG(d0), struct Library *ExecBase REG(a6)) { kprintf( "LibInit()\n" ); SysBase = ExecBase; WBStartBase->LibSegment = Segment; WBStartBase->LibNode.lib_Revision = REVISION; InitSemaphore( &WBStartBase->wbsb_LibLock ); ObtainSemaphore( &WBStartBase->wbsb_LibLock ); if( ((struct ExecBase *)ExecBase)->AttnFlags & AFF_68020 ) { if( L_OpenLibs( WBStartBase ) ) { kprintf( "LibInit()- ok\n" ); ReleaseSemaphore( &WBStartBase->wbsb_LibLock ); return((struct Library *)WBStartBase); } L_CloseLibs( WBStartBase ); } ReleaseSemaphore( &WBStartBase->wbsb_LibLock ); FreeMem((BYTE *)WBStartBase-WBStartBase->LibNode.lib_NegSize, WBStartBase->LibNode.lib_NegSize + WBStartBase->LibNode.lib_PosSize); kprintf( "LibInit() - error\n" ); return(NULL); } /****************************************************************************/ struct Library * LibOpen(struct WBStartBase *WBStartBase REG(a6)) { kprintf( "LibOpen()\n" ); ObtainSemaphore( &WBStartBase->wbsb_LibLock ); WBStartBase->LibNode.lib_Flags &= ~LIBF_DELEXP; WBStartBase->LibNode.lib_OpenCnt++; ReleaseSemaphore( &WBStartBase->wbsb_LibLock ); kprintf( "LibOpen() - okay\n" ); return((struct Library *)WBStartBase); } /****************************************************************************/ ULONG LibExpunge(struct WBStartBase *WBStartBase REG(a6)) { ULONG retval = NULL; kprintf( "LibExpunge()\n" ); ObtainSemaphore( &WBStartBase->wbsb_LibLock ); if( WBStartBase->LibNode.lib_OpenCnt ) { WBStartBase->LibNode.lib_Flags |= LIBF_DELEXP; kprintf( "LibExpunge() - still in use\n" ); } else { L_CloseLibs( WBStartBase ); Remove((struct Node *)WBStartBase); FreeMem((BYTE *)WBStartBase-WBStartBase->LibNode.lib_NegSize, WBStartBase->LibNode.lib_NegSize + WBStartBase->LibNode.lib_PosSize); retval = (ULONG) WBStartBase->LibSegment; kprintf( "LibExpunge() - okay\n" ); } ReleaseSemaphore( &WBStartBase->wbsb_LibLock ); return retval; } /****************************************************************************/ ULONG LibClose(struct WBStartBase *WBStartBase REG(a6)) { ULONG retval = NULL; ObtainSemaphore( &WBStartBase->wbsb_LibLock ); kprintf( "LibClose()\n" ); if( ! ( WBStartBase->LibNode.lib_OpenCnt ) || ! ( --WBStartBase->LibNode.lib_OpenCnt ) ) { if( WBStartBase->LibNode.lib_Flags & LIBF_DELEXP ) { retval = LibExpunge( WBStartBase ); } } ReleaseSemaphore( &WBStartBase->wbsb_LibLock ); kprintf( "LibClose - retval %08lx\n", retval ); return retval; } /****************************************************************************/ BOOL L_OpenLibs( struct WBStartBase *WBStartBase ) { if( ( WorkbenchBase = OpenLibrary( "workbench.library", 44L ) ) && ( DOSBase = OpenLibrary( "dos.library", 40L ) ) && ( UtilityBase = OpenLibrary( "utility.library", 40L ) ) ) { return TRUE; } return FALSE; } /****************************************************************************/ VOID L_CloseLibs( struct WBStartBase *WBStartBase ) { CloseLibrary( WorkbenchBase ); CloseLibrary( DOSBase ); CloseLibrary( UtilityBase ); } /****************************************************************************/ LONG WBStartTagList( struct TagItem *tlist REG(a0), struct WBStartBase *WBStartBase REG(a6) ) { struct TagItem *ti; struct WBArg *args = NULL; STRPTR name = NULL; BPTR dirlock = NULL; ULONG argc = 0UL, ret = 20UL; kprintf( "WBStartTagList() - taglist at %08lx\n", tlist ); while( ti = NextTagItem( &tlist ) ) { ULONG data = ti->ti_Data; switch( ti->ti_Tag ) { case WBStart_Name: name = (STRPTR) data; kprintf( "Name: %s\n", name ); break; case WBStart_DirectoryName: if( data ) { UnLock( dirlock ); dirlock = Lock( (STRPTR) data, SHARED_LOCK ); kprintf( "DirName: %s\n", data ); } break; case WBStart_DirectoryLock: UnLock( dirlock ); dirlock = DupLock( (BPTR) data ); kprintf( "DirLock: %08lx\n", dirlock ); break; case WBStart_ArgumentCount: argc = data; break; case WBStart_ArgumentList: args = (struct WBArg *) data; break; } } if( name ) { if( argc && args ) { kprintf( "Args: %ld\n", argc ); if( ti = tlist = AllocVec( 2 * (argc+1) * sizeof( struct TagItem ), MEMF_ANY ) ) { kprintf( "Alloced %ld bytes at: %08lx\n", 2 * (argc+1) * sizeof( struct TagItem ), tlist ); while( argc-- ) { kprintf( "LOCK: %08lx, NAME: %s\n", args->wa_Lock, args->wa_Name ); ti->ti_Tag = WBOPENA_ArgLock; ti->ti_Data = (ULONG) args->wa_Lock; ti++; ti->ti_Tag = WBOPENA_ArgName; ti->ti_Data = (ULONG) args->wa_Name; ti++; args++; } ti->ti_Tag = TAG_DONE; } else tlist = (struct TagItem *) -1L; } else tlist = NULL; if( tlist != (struct TagItem *) -1L ) { BPTR olddir; if( dirlock ) olddir = CurrentDir( dirlock ); kprintf( "Calling OpenWorkbenchObjectA()\n" ); if( OpenWorkbenchObjectA( name, tlist ) ) ret = 0UL; kprintf( "Returned from OpenWorkbenchObjectA()\n" ); if( dirlock ) CurrentDir( olddir ); kprintf( "Free: %08lx\n", tlist ); FreeVec( tlist ); } } UnLock( dirlock ); kprintf( "Functions returns %ld\n", ret ); return ret; } /****************************************************************************/