Source to jet/start.c


Enter a symbol's name here to quickly find it.

#include <Dialogs.h>
#include <Errors.h>
#include <Events.h>
#include <Fonts.h>
#include <Memory.h>
#include <Menus.h>
#include <OSUtils.h>
#include <Resources.h>
#include <SegLoad.h>
#include <SysEqu.h>
#include <TextEdit.h>
#include <ToolUtils.h>
#define StackBase (*(Ptr *)CurStackBase)
#define CurA5 (*(Ptr *)CurrentA5)
#include <Folders.h>
#include <GestaltEqu.h>
#include <Traps.h>
#ifndef _GestaltDispatch
#define _GestaltDispatch _Gestalt
#endif

#include "jet.h"
#define gestaltSysArchitecture 0x73797361  /* gestalt selector to find ppc */

/* #define DEBUG */

#define MAC_HEAP (300*1024L)
#define MAC_STACK (50*1024L)
#define JET_STACK (50*1024L)

#define PREFS_VERS 3
#define PREFS_ID 1

static void startup(void);
#ifdef DEBUG
static void debug(void);
#endif
static short NumToolboxTraps(void);
static TrapType GetTrapType(short theTrap);

static void readprefs(void);
static int openprefres(int create);

#ifdef __GNUC__
long saveda5 asm("saveda5");
long savedsp asm("savedsp");
struct qd qd;
#else
long saveda5;
long savedsp;
#endif

long jet_stack;
long *holdstart;
long *next_hold;
Prefs pref;

BASEPAGE *curbp;

#ifndef XXX
typedef long UniversalProcPtr;
#endif

static UniversalProcPtr old_es;
UniversalProcPtr old_md;

void entry_point(void)
{
	THz zone;
	EventRecord event;
	long response;
	
	savedsp = 0;
	saveda5 = (long)CurA5;
	next_hold = 0;
	InitGraf(&qd.thePort);
	InitFonts();
	InitWindows();
	InitMenus();
	TEInit();
	InitDialogs(0L);
	InitCursor();
	EventAvail(0, &event);
	if (event.modifiers & controlKey)
		Debugger();
	if (!TrapAvailable(_GestaltDispatch))
		fatal(EGESTALT);
		
	vm = (Gestalt(gestaltVMAttr, &response) == noErr && (response & 1) != 0)
	  || (Gestalt(gestaltMachineType, &response) == noErr && response == 406);
	if (vm) {
		holdstart = next_hold =(long *) StripAddress(NewPtrClear(4000L)); /* room for 500 processes */
		old_md = (UniversalProcPtr)NGetTrapAddress(_MemoryDispatch, OSTrap);
		NSetTrapAddress((UniversalProcPtr) Mem_Dispatch, _MemoryDispatch, OSTrap);
	}
	sysvar.alias = ((Gestalt(gestaltAliasMgrAttr, &response) == 0) &&
	    ((response & 1) != 0));
	sysvar.powerpc = ((Gestalt(gestaltSysArchitecture, &response) == 0) &&
	    ((response & 1) == 0));

	old_es = (UniversalProcPtr)NGetTrapAddress(_ExitToShell, ToolTrap);
	NSetTrapAddress((UniversalProcPtr)pES, _ExitToShell, ToolTrap);
	zone = ApplicZone();
	if (zone->bkLim+MAC_HEAP+MAC_STACK+JET_STACK > StackBase)
		fatal(EMEMORY);
	SetApplLimit(zone->bkLim + MAC_HEAP);
	MaxApplZone();
	savedsp = (long)zone->bkLim + MAC_STACK;
	jet_stack = savedsp + JET_STACK;
	setsp(jet_stack);
	startup();
}

void startup(void)
{
	long size;

	readprefs();
	init_console();
	init_events();
#ifdef DEBUG
	debug();
#endif
	init_memory((char *)jet_stack, (char *)StackBase);
	init_filesys();
	init_vector();
	size = (long)m_alloc(-1L);
	curbp = (BASEPAGE *)m_alloc(size);
	curbp->p_lowtpa = (char *)curbp;
	curbp->p_hitpa = (char *)curbp + size;
	curbp->p_parent = curbp;
	c_conws(
		"\r\n"
		"Just Enough TOS (" __DATE__ ")\r\n"
		"The JET library may have bugs.  Use it at your own risk!\r\n"
		);
	if (vm)
		c_conws("Wow: you're running with virtual memory!\r\n");
	if (sysvar.powerpc)
		c_conws("Hmmm, it seems we're running on a PowerPC\r\n");
	b_constat(2);

	{
		extern int main(void);
		main();
	}
}

void fatal(int code)
{
	/* this should put up an informational dialog if possible */
	SysBeep(5);
	SysBeep(5);
	SysBeep(5);
	ExitToShell();
}

#ifdef DEBUG
static void debug(void)
{
	long c;

	while (1) {
		while (b_constat(2) == 0)
			;
		c = b_conin(2);
		b_conout(2, c);
	}
}
#endif

static short NumToolboxTraps(void)
{
	if (NGetTrapAddress(_InitGraf, ToolTrap) ==
	    NGetTrapAddress(0xAA6E, ToolTrap))
		return(0x0200);
	else
		return(0x0400);
}

static TrapType GetTrapType(short theTrap)
{
	if ((theTrap & 0x0800) > 0)
		return(ToolTrap);
	else
		return(OSTrap);
}

Boolean TrapAvailable(short theTrap)
{
	TrapType	tType;
	
	tType = GetTrapType(theTrap);
	if (tType == ToolTrap)
		theTrap = theTrap & 0x07FF;
	if (theTrap >= NumToolboxTraps())
		theTrap = _Unimplemented;
	return (NGetTrapAddress(theTrap, tType) !=
		NGetTrapAddress(_Unimplemented, ToolTrap));
}

/*
 * readprefs
 */
static void readprefs(void)
{
	short rf = -1;
	Handle h = 0;
	
	if ((rf = openprefres(true)) == -1)
		goto defaults;
	
	if ((h = Get1Resource(PREFS, PREFS_ID)) == 0)
		goto defaults;
	
	HLock(h);
	pref = **(Prefs **)h;
	
	if (pref.version != PREFS_VERS)
		goto defaults;
	
 xit:
	if (h)
		ReleaseResource(h);
	if (rf != -1)
		CloseResFile(rf);
	return;
	
 defaults:
	pref.version = PREFS_VERS;
	SetRect(&pref.wrect, 5, 40, 100, 100);
	pref.swap_delete = false;
	pref.swap_control = false;
	pref.curs_flash = false;
	pref.fwrap = true;
	pref.maxx = 80 - 1;
	pref.maxy = 24 - 1;
	goto xit;
}


/*
 * writeprefs
 */
void writeprefs(void)
{
	OSErr s;
	short rf = -1;
	Handle h = 0;
	
	if ((rf = openprefres(true)) == -1) {
		return;
	}
	
	if ((h = Get1Resource(PREFS, PREFS_ID)) == 0) {
		if (!(h = NewHandle(sizeof(pref)))) {
			goto xit;
		}
		AddResource(h, PREFS, PREFS_ID, "\pPrefs");
	} else {
		SetHandleSize(h, sizeof(pref));
		if ((s = MemError())) {
			goto xit;
		}
	}		

	pref.wrect = (*((WindowPeek)myWindow)->contRgn)->rgnBBox;
	pref.maxx = maxx;
	pref.maxy = maxy;
	
	HLock(h);
	*((Prefs *)*h) = pref;
	ChangedResource(h);
	
 xit:
	if (rf != -1)
		CloseResFile(rf);
}

/*
 * openprefres
 * Open MacMiNT Preferences resource file
 * return rf or -1 if error
 */
static int openprefres(int create)
{
	int s;
	int rf;
	short vref;
	long dirid = 0, fold;
	SysEnvRec theWorld;
	HParamBlockRec pb;
	StringPtr name = "\pMacMiNT Preferences";
	
	/*
	 * Try to find the Preferences folder, else use the system folder.
	 */
	if (Gestalt(gestaltFindFolderAttr, &fold) || ((fold & 1) != 1) ||
	    FindFolder(kOnSystemDisk, kPreferencesFolderType,
		       false, &vref, &dirid)) {
		if (SysEnvirons(1, &theWorld) == 0)
			vref = theWorld.sysVRefNum;
		else
			vref = 0;
	}
	
	if ((rf = HOpenResFile(vref, dirid, name, fsRdWrPerm)) == -1) {
		s = ResError();
		if (((s == fnfErr) || (s == eofErr)) && create) {
			HCreateResFile(vref, dirid, name); /* create the file */
			if ((s = ResError())) {
				return -1;
			}
			/*
			 * set finder info for new file, ignore errors.
			 */
			pb.fileParam.ioNamePtr = name;
			pb.fileParam.ioVRefNum = vref;
			pb.fileParam.ioFVersNum = 0;
			pb.fileParam.ioFDirIndex = 0;
			pb.fileParam.ioDirID = dirid;
			if (!(rf = PBHGetFInfoSync(&pb))) {
				pb.fileParam.ioFlFndrInfo.fdType = PREFS;
				pb.fileParam.ioFlFndrInfo.fdCreator = MINT;
				pb.fileParam.ioNamePtr = name;
				pb.fileParam.ioVRefNum = vref;
				pb.fileParam.ioDirID = dirid;
				(void) PBHSetFInfoSync(&pb);
			}
			/*
			 * retry open
			 */
			if ((rf = HOpenResFile(vref, dirid, name, fsRdWrPerm)) == -1) {
				s = ResError();
				return -1;
			}
		} else {
			return -1;
		}
	}
	return rf;
}

void ES(void)
{
	long *holdlen;
	
	if (vm) {
		asm("
			.word	0x7008,0xa08d	/* enter supervisor mode */
			tstl	_macssp
			beq nomacssp
			movel	_macssp,sp
	nomacssp:
			andiw #0xdfff,sr
			movel _jet_stack,sp ");
		holdlen = holdstart;
		holdlen++;
		while (*holdstart)
				if (UnholdMemory((long *) *holdstart,*holdlen))
			 	  c_conws("Damn, can't unhold memory for quitting\n");
	}
	clean_vector();
	NSetTrapAddress(old_es, _ExitToShell, ToolTrap);
	ExitToShell();
}