[net.sources.mac] IMLib Source

shebanow@ernie.BERKELEY.EDU (Mike Shebanow) (11/28/85)

(beware the line eater)


The next three postings contain the actual source files for IMLib,
a library of routines which provide emulation for a large number
of the [Pascal Only] routines described in Inside Mac. This posting
contains IMLib.Job, the job file for MDSMake, and IMLib.link, the
link file for the Consulair Linker. These files are only useable with
Consulair C version 4.00 or higher, but users of other compilers may find
some of the code educational (especially the code to read and create
Finder arguments).

A special note: IMLib REQUIRES the file PrLink.REL in order to link
correctly. PrLink.REL was distributed by Apple with the Software
Supplement, and is available for downloading on CompuServe &
Delphi (and probably other boards as well). I am not posting
PrLink.REL because it is Apple software and requires special permission
to distribute. If you cannot get it from a friend, a bbs, or a users group,
then you can safely delete all references to PrLink.REL and PrLinkage.*
from the JOB and Link files and use the library without the printer code.

The code has been copyrighted by its various authors. However, all the code
has been published freely in one form or another, and you the authors have
given their permission for the code to be distributed for non-commercial
purposes.

Correspondence can be sent to:

Andrew Shebanow
HyperSoft
2124 Kittredge Street #174
Berkeley CA 94704

or:
	CompuServe: 75046,677
	Delphi: SHEBANOW
	WELL: shebanow

or:
	send questions to net.micro.mac

Have fun!

======================= IMLib.Job ============================
FileMgr.asm
PrLinkage.asm
TECalls.c
Packages.asm
ToolUtils.c
FinderParms.c
MemoryMgr.asm
EventMgr.asm
OSUtils.asm
StringLib.c
IMLib.link -> IMLib.rel : PrLink.REL
======================= IMLib.Link ============================
/Library IMLib
/Create
FileMgr
PrLinkage
PrLink
TECalls
Packages
ToolUtils
FinderParms
MemoryMgr
StringLib
EventMgr
OSUtils
/End
============================= end =============================

shebanow@ernie.BERKELEY.EDU (Mike Shebanow) (11/28/85)

(beware the line eater)

=========================Packages.Asm==============================
;
; Packages.ASM		Andrew G. Shebanow		8/31/85
;
; Portions of this code Copyright 1984,1985 Consulair Corp.
;
; This file contains routines to emulate the high level calls
; for all of the Macintosh packages (with the exception of the SANE
; related ones). These interface routines have the same names
; and calling conventions as the routines in Inside Mac. The routines
; are intended for use with Consulair's MacC compiler, but could
; be converted to any other compiler as well.
;
; The Standard File package routines are based on code written
; by Bill Duvall of Consulair Corp.
;
; Copyright 1985 HyperSoft	All Rights Reserved
;
; Modifications:
;	10/18/85	Fixed StringToNum routine selector (AGS)
;

	INCLUDE MacTraps.D
	INCLUDE ToolEqu.D
	INCLUDE SysEqu.D

	; International Utilities
	XDEF IUDateString
	XDEF IUDatePString
	XDEF IUTimeString
	XDEF IUTimePString
	XDEF IUMetric
	XDEF IUGetIntl
	XDEF IUSetIntl
	XDEF IUCompString
	XDEF IUMagString
	XDEF IUEqualString
	XDEF IUMagIDString
	; Binary Decimal Conversion
	XDEF NumToString
	XDEF StringToNum
	; Standard File
	XDEF SFPutFile
	XDEF SFPPutFile
	XDEF SFGetFile
	XDEF SFPGetFile
	; Disk Initialization
	XDEF DILoad
	XDEF DIUnload
	XDEF DIBadMount
	XDEF DIFormat
	XDEF DIVerify
	XDEF DIZero

	Module 'IntlTime'

; IUDateString(dateTime,form,theString)
; long dateTime;	(D0)
; DateForm form;	(D1)
; Str255 *theString;	(D2)

IUDateString
	MOVE.L	D0,-(SP)	; dateTime
	MOVE.W	D1,-(SP)	; form
	MOVE.L	D2,-(SP)	; theString
	MOVE	#0,-(SP)	; routine selector
	_Pack6
	RTS

; IUDatePString(dateTime,form,theString,intlParam)
; long dateTime;	(D0)
; DateForm form;	(D1)
; Str255 *theString;	(D2)
; Handle intlParam;	(D3)

IUDatePString
	MOVE.L	D0,-(SP)	; dateTime
	MOVE.W	D1,-(SP)	; form
	MOVE.L	D2,-(SP)	; theString
	MOVE.L	D3,-(SP)	; intlParam
	MOVE	#14,-(SP)	; routine selector
	_Pack6
	RTS

; IUTimeString(dateTime,wantSeconds,theString)
; long dateTime;	(D0)
; short wantSeconds;	(D1)	(actually boolean)
; Str255 *theString	(D2)

IUTimeString
	MOVE.L	D0,-(SP)	; dateTime
	MOVE.B	D1,-(SP)	; wantSeconds (BOOLEAN)
	MOVE.L	D2,-(SP)	; theString
	MOVE	#2,-(SP)	; routine selector
	_Pack6
	RTS

; IUTimePString(dateTime,wantSeconds,theString,intlParam)
; long dateTime;	(D0)
; short wantSeconds;	(D1)	(actually boolean)
; Str255 *theString	(D2)
; Handle intlParam;	(D3)

IUTimePString
	MOVE.L	D0,-(SP)	; dateTime
	MOVE.B	D1,-(SP)	; wantSeconds
	MOVE.L	D2,-(SP)	; theString
	MOVE.L	D3,-(SP)	; intlParam
	MOVE	#16,-(SP)	; routine selector
	_Pack6
	RTS

	Module 'IntlMisc'

; char IUMetric()	(actually boolean)

IUMetric
	MOVE.B	#0,-(SP)	; save space for result
	MOVE	#4,-(SP)	; routine selector
	_Pack6
	MOVE.B	(SP)+,D0	; get result
	RTS			; result in D0???

; Handle IUGetIntl(theID)
; short theID;		(D0)

IUGetIntl
	MOVE.L	#0,-(SP)	; save space for result
	MOVE.W	D0,-(SP)	; theID
	MOVE	#6,-(SP)	; routine selector
	_Pack6
	MOVE.L	(SP)+,A0	; save result in A0
	RTS

; IUSetIntl(refNum,theID,intlParam)
; short refNum;		(D0)
; short theID;		(D1)
; Handle intlParam;	(D2)

IUSetIntl
	MOVE.W	D0,-(SP)	; refnum
	MOVE.W	D1,-(SP)	; theID
	MOVE.L	D2,-(SP)	; intlParam
	MOVE	#8,-(SP)	; routine selector
	_Pack6
	RTS

	Module 'IntlString'

; short IUCompString(aStr,bStr)
; Str255 *aStr;		(D0)
; Str255 *bStr;		(D1)

IUCompString
	MOVE.L	D0,A0		; get pointer to string
	MOVE.B	(A0)+,D2	; D2 = aLen
	MOVE.L	A0,D0		; D0 = first char of aStr
	MOVE.L	D1,A0
	MOVE.B	(A0)+,D3	; D3 = bLen
	MOVE.L	A0,D1		; D1 = first char of bStr
	BSR	IUMagString
	RTS			; result in D0

; short IUMagString(aStr,bStr,aLen,bLen)
; char *aStr;		(D0)
; char *bStr;		(D1)
; short aLen;		(D2)
; short bLen;		(D3)

IUMagString
	MOVE.W	#0,-(SP)	; save space for result
	MOVE.L	D0,-(SP)	; aStr
	MOVE.L	D1,-(SP)	; bStr
	MOVE.W	D2,-(SP)	; aLen
	MOVE.W	D3,-(SP)	; bLen
	MOVE	#10,-(SP)	; routine selector
	_Pack6
	MOVE.W	(SP)+,D0
	RTS			; result in D0

; short IUEqualString(aStr,bStr)
; Str255 *aStr;		(D0)
; Str255 *bStr;		(D1)

IUEqualString
	MOVE.L	D0,A0		; get pointer to string
	MOVE.B	(A0)+,D2	; D2 = aLen
	AND.L	#$0FF,D2
	MOVE.L	A0,D0		; D0 = first char of aStr
	MOVE.L	D1,A0
	MOVE.B	(A0)+,D3	; D3 = bLen
	AND.L	#$0FF,D3
	MOVE.L	A0,D1		; D1 = first char of bStr
	BSR	IUMagIDString
	RTS			; result in D0

; short IUMagIDString(aStr,bStr,aLen,bLen)
; char *aStr;		(D0)
; char *bStr;		(D1)
; short aLen;		(D2)
; short bLen;		(D3)

IUMagIDString
	MOVE.W	#0,-(SP)	; save space for result
	MOVE.L	D0,-(SP)	; aStr
	MOVE.L	D1,-(SP)	; bStr
	MOVE.W	D2,-(SP)	; aLen
	MOVE.W	D3,-(SP)	; bLen
	MOVE	#12,-(SP)	; routine selector
	_Pack6
	MOVE.W	(SP)+,D0
	RTS			; result in D0

	Module 'Binary2Decimal'

; NumToString(theNum,theString)
; long theNum;		(D0)
; Str255 *theString	(D1)

NumToString
	MOVE.L	A0,-(SP)	; save A0
	MOVE.L	D1,A0		; theString
	MOVE	#0,-(SP)	; routine selector
	_Pack7
	MOVE.L	(SP)+,A0	; restore A0
	RTS

; StringToNum(theString,theNum)
; Str255 *theString;	(D0)
; long *theNum;		(D1)

StringToNum
	MOVE.L	D1,-(SP)	; save D1
	MOVE.L	D0,A0		; A0 -> theString
	MOVE	#1,-(SP)	; routine selector
	_Pack7
	MOVE.L	(SP)+,A0	; move old D1 into A0
	MOVE.L	D0,(A0)		; save result
	RTS

	Module 'StdPutFile'

; SFPutFile(where, prompt, origName, dlgHook, reply)
; Point *where;			(D0)
; struct PStr *prompt;		(D1)
; struct PStr *origName;	(D2)
; int (*dlgHook)();		(D3)
; SFReply *reply;		(D4)

SFPutFile
	MOVE.L	D0,A0
	MOVE.L	(A0),-(SP)		; WHERE
	MOVE.L	D1,-(SP)		; PROMPT
	MOVE.L	D2,-(SP)		; origName
	MOVE.L	D3,-(SP)		; dlgHook
	MOVE.L	D4,-(SP)		; reply
	MOVE	#1,-(SP)		; routine selector
	_Pack3
	RTS

; SFPPutFile(where,prompt,origName,dlgHook,reply,dlgID,filterProc)
; Point *where;			(D0)
; struct PStr *prompt;		(D1)
; struct PStr *origName;	(D2)
; int (*dlgHook)();		(D3)
; SFReply *reply;		(D4)
; short dlgID;			(D5)
; int (*dlgHook)()		(D6)

SFPPutFile
	MOVE.L	D0,A0
	MOVE.L	(A0),-(SP)		; WHERE
	MOVE.L	D1,-(SP)		; PROMPT
	MOVE.L	D2,-(SP)		; origName
	MOVE.L	D3,-(SP)		; dlgHook
	MOVE.L	D4,-(SP)		; reply
	MOVE.W	D5,-(SP)		; dlgID
	MOVE.L	D6,-(SP)		; dlgHook
	MOVE	#3,-(SP)		; routine selector
	_Pack3
	RTS

	Module 'StdGetFile'

; SFGetFile(where, prompt, fileFilter, numTypes, typeList, dlgHook, reply)
; Point *where;			(D0)
; struct PStr *prompt;		(D1)
; int (*fileFilter)();		(D2)
; short numTypes;		(D3)
; SFTypeList *typeList;		(D4)
; int (*dlgHook)();		(D5)
; SFReply *reply;		(D6)

SFGetFile
	MOVE.L	D0,A0
	MOVE.L	(A0),-(SP)		; WHERE
	MOVE.L	D1,-(SP)		; PROMPT
	MOVE.L	D2,-(SP)		; FILTER PROC
	MOVE.W	D3,-(SP)		; numTypes
	MOVE.L	D4,-(SP)		; typeList
	MOVE.L	D5,-(SP)		; dlgHook
	MOVE.L	D6,-(SP)		; reply
	MOVE	#2,-(SP)		; routine selector
	_Pack3
	RTS
      
; SFPGetFile(where, prompt, fileFilter, numTypes, typeList,
;			dlgHook, reply, dlgID, filterProc)
; Point *where;			(D0)
; struct PStr *prompt;		(D1)
; int (*fileFilter)();		(D2)
; short numTypes;		(D3)
; SFTypeList *typeList;		(D4)
; int (*dlgHook)();		(D5)
; SFReply *reply;		(D6)
; short dlgID;			8(A6)
; int (*filterProc)()		12(A6)

SFPGetFile
	LINK	A6,#0
	MOVE.L	D0,A0
	MOVE.L	(A0),-(SP)		; WHERE
	MOVE.L	D1,-(SP)		; PROMPT
	MOVE.L	D2,-(SP)		; FILTER PROC
	MOVE.W	D3,-(SP)		; numTypes
	MOVE.L	D4,-(SP)		; typeList
	MOVE.L	D5,-(SP)		; dlgHook
	MOVE.L	D6,-(SP)		; reply
	MOVE.W	10(A6),-(SP)		; dlgID
	MOVE.L	12(A6),-(SP)		; filterProc
	MOVE	#4,-(SP)		; routine selector
	_Pack3
	UNLK	A6
	RTS

	Module 'DiskInit'

; DILoad()

DILoad
	MOVE	#2,-(SP)		; routine selector
	_Pack2
	RTS

; DIUnload()

DIUnload
	MOVE	#4,-(SP)		; routine selector
	_Pack2
	RTS

; short DIBadMount(where,evtMessage)
; Point *where;		(D0)
; long evtMessage;	(D1)

DIBadMount
	MOVE.W	#0,-(SP)		; save space for result
	MOVE.L	D0,A0			; convert point to long
	MOVE.L	(A0),-(SP)		; where
	MOVE.L	D1,-(SP)		; evtMessage
	MOVE	#0,-(SP)		; routine selector
	_Pack2
	MOVE.W	(SP)+,D0
	RTS				; D0 contains error

; short DIFormat(drvNum)
; short drvNum;		(D0)

DIFormat
	MOVE.W	#0,-(SP)		; save space for result
	MOVE.W	D0,-(SP)		; drvNum
	MOVE	#6,-(SP)		; routine selector
	_Pack2
	MOVE.W	(SP)+,D0
	RTS				; D0 contains error

; short DIVerify(drvNum)
; short drvNum;		(D0)

DIVerify
	MOVE.W	#0,-(SP)		; save space for result
	MOVE.W	D0,-(SP)		; drvNum
	MOVE	#8,-(SP)		; routine selector
	_Pack2
	MOVE.W	(SP)+,D0
	RTS				; D0 contains error

; short DIZero(drvNum,volName)
; short drvNum;		(D0)
; Str255 *volName;	(D1)

DIZero
	MOVE.W	#0,-(SP)		; save space for result
	MOVE.W	D0,-(SP)		; drvNum
	MOVE.L	D1,-(SP)		; volName
	MOVE	#10,-(SP)		; routine selector
	_Pack2
	MOVE.W	(SP)+,D0
	RTS				; D0 contains error

	END

=========================StringLib.c==============================
/*
 * StringLib.C		Andrew G. Shebanow		8/2/85
 *
 * Routines for doing operations on Pascal strings in Mac C.
 *
 * Copyright 1985	HyperSoft	All Rights Reserved
 */

#include <Memory.h>
#include <Resource.h>

/* this is a library of routines */
#Options M

/* some handy definitions */
/* miscellaneous definitions */
#define VOID	void
#define BYTE	char
#define WORD	short
#define LONG	int
#define UBYTE	unsigned char
#define UWORD	unsigned short
#define ULONG	unsigned int

#define REG	register
#define LOCAL	static
#define GLOBAL	/* */
#define EXTERN	extern

#define TYPEDEF	typedef
#define STRUCT	struct
#define UNION	union

/* pascal boolean definitions */
#define TRUE		1
#define FALSE		0
#define NULL		0

/*
 * StrUpper:
 *
 *	Converts a strings contents to uppercase. No checking for
 * international characters is done.
 */

GLOBAL
VOID StrUpper(str)
     StringPtr str;
     {
	UBYTE cntr, lim;
	UBYTE ch;

	lim = str->count;
	for (cntr = 0; cntr < lim; cntr++)
	  {
	    ch = str->s[cntr];
	    if ((ch >= 'a') && (ch <= 'z'))
	      str->s[cntr] = (ch - 'a' + 'A');
	  }
     }

/*
 * AppendStr:
 *
 *	Append str2 to str1. It is assumed that str1 has all 255 bytes
 * of data allocated to it.
 */

GLOBAL
VOID AppendStr(str1,str2)
     StringPtr str1;
     StringPtr str2;
     {
	UBYTE cntr;
	UBYTE lim;
	UBYTE offst;

	if ((str2 == NULL) || (str2->count == 0))
	  return;
	if ((str1->count + str2->count) > 255)
	  lim = 255 - str1->count;
	else lim = str2->count;
	offst = str1->count;
	for (cntr = 0; cntr < lim; cntr++)
	  str1->s[offst + cntr] = str2->s[cntr];
	str1->count += lim;
     }

/*
 * CopyStr:
 *
 *	copies source string to destination string.
 */

GLOBAL
VOID CopyStr(srcStr,dstStr)
     REG StringPtr srcStr;
     REG StringPtr dstStr;
     {
	REG UBYTE cntr;
	REG UBYTE lim;
	
	lim = srcStr->count;
	dstStr->count = lim;
	for (cntr = 0; cntr < lim; cntr++)
	  dstStr->s[cntr] = srcStr->s[cntr];
     }

/*
 * GetSuffix:
 *
 *	searches a filename for a suffix (eg, ".c"), and copies the suffix
 * into another string. Note that it searches BACKWARDS into the string, so
 * the file 'Crazy Name.file.c' has a suffix string of '.c'!
 */

GLOBAL
LONG GetSuffix(fileName,suffix)
     StringPtr fileName;
     StringPtr suffix;
     {
	WORD cntr;
	WORD lim;
	WORD found = FALSE;
	UBYTE dcntr = 0;

	lim = (WORD) (fileName->count & 0x0ff);
	suffix->count = 0;
	if (lim == 0)
	  return(FALSE);
	for (cntr = lim - 1; cntr >= 0; cntr--)
	  if (fileName->s[cntr] == '.')
	    {
	      found = TRUE;
	      break;
	    }
	if (found == FALSE)
	  return(FALSE);
	while (cntr < lim)
	  {
	    suffix->s[dcntr++] = fileName->s[cntr++];
	    suffix->count += 1;
	  }
	return(TRUE);
     }

/*
 * ChangeSuffix:
 *
 *	searches a string for a suffix (eg, ".c"), and copies the string
 * to a destintaion string, using the new suffix passed to it.
 */

GLOBAL
VOID ChangeSuffix(srcStr,dstStr,suffix)
     StringPtr srcStr;
     StringPtr dstStr;
     StringPtr suffix;
     {
	UBYTE cntr, lim;
	WORD found = FALSE;
	UBYTE dcntr = 0;

	lim = srcStr->count;
	dstStr->count = 0;
	if (lim == 0)
	  {
	    /* copy suffix string to dest string */
	    CopyStr(suffix,dstStr);
	    return;
	  }
	/* copy entire string */
	CopyStr(srcStr,dstStr);
	/* search for start of suffix, moving backwards */
	for (cntr = lim - 1; cntr >= 0; cntr--)
	  if (dstStr->s[cntr] == '.')
	    {
	      found = TRUE;
	      break;
	    }
	if (found == TRUE)
	  dstStr->count = cntr;		/* truncate the string */
	/* append new suffix */
	AppendStr(dstStr,suffix);
	return;
     }

/**************************** end of StringLib.C *********************/
=========================TECalls.c==============================
/*
 * TECalls.c	Dave Burnard		7/6/85
 *
 * TEScrap ToolBox Extension Routines. Desribed in the TextEdit section
 * of Inside Mac.
 *
 * Copyright 1985 Dave Burnard
 *
 * Modifications:
 *
 *	10/18/85 Cosmetic modifications to match rest of library (AGS)
 */

#Options +Z

#include "MacDefs.h"
#include "Memory.h"

#define OSErr short

/* ToolBox Global access */
#define TEScrpLength *((short *)0x0AB0)
#define TEScrpHandle *((Handle *)0x0AB4)

/*
 * TEScrapHandle:
 *
 *	returns a handle to the text edit scrap.
 */

Handle TEScrapHandle()
       {
	return(TEScrpHandle);
       }

/*
 * TEGetScrapLen:
 *
 *	returns the length of the TextEdit scrap.
 */

long TEGetScrapLen()
     {
	return(TEScrpLength);
     }

/*
 * TESetScrapLen:
 *
 *	sets the length of the text edit scrap. Presumably called after
 * you put something in the scrap.
 */

void TESetScrapLen(length)
     long length;
     {
	TEScrpLength = (short) length;
     }

/*
 * TEFromScrap:
 *
 *	Sets the TE scrap to have a copy of the real scrap data.
 * Note that the function actually returns the scrap length, not the
 * OSErr as it should. Maybe a call to MemError() would result in
 * the desired result?
 */

OSErr TEFromScrap()
      {
	long offset,length;

	length = GetScrap(TEScrapHandle(), 'TEXT', &offset);
	if (length > 0)
	  {
	    TESetScrapLen(length);
	  }
	return((OSErr) length);
      }

/*
 * TEToScrap:
 *
 * copy TE scrap to real scrap. MUST be preceded by a call to ZeroScrap!
 * Note that the function actually returns the scrap length, not the
 * OSErr as it should. Maybe a call to MemError() would result in
 * the desired result?
 */

OSErr TEToScrap()
      {
	Ptr *TEScrapH;
	long length;  
   
	HLock(TEScrapH = TEScrapHandle());
	length = PutScrap(TEGetScrapLen(), 'TEXT', *TEScrapH);
	HUnlock(TEScrapH);
	/* if length is <0, it is an error code */
	if (length >= 0)
	  {
	    length = 0;
	  }
	return((OSErr) length);
      }

/****************************** end of TECalls.c *************************/
=========================ToolUtils.c==============================
/*
 * ToolUtils.c		Andrew G. Shebanow		9/3/85
 *
 *	Implementation of ToolBox utility routines for MacC. These
 * routines emulate the [ No Trap Macro ] routines documented in the
 * ToolBox Utilities section of Inside Mac.
 */

#include <QuickDraw.h>
#include <Memory.h>
#include <Resource.h>

/* pascal boolean definitions */
#define TRUE		1
#define FALSE		0
#define NULL		0

/* this is a library of routines */
#Options M

/*
 * GetIndString:
 *
 *	This function attempts to read a 'STR#' resource into memory
 * and extract an individual string from that resource.
 */

GetIndString(theString,strListID,index)
StringPtr theString;		/* set to the string */
unsigned short strListID;	/* the id of the STR# resource */
unsigned short index;		/* index (range 1-n) of desired Str255 */
{
	StringHandle strHandle;
	register unsigned char *strPtr;
	register unsigned char idx;
	unsigned char lcntr, total;
	unsigned short *cntPtr, cnt;

	strHandle = (StringHandle) GetResource('STR#',strListID);
	if (strHandle == NULL)
	  {
	    theString->count = 0;
	    return;
	  }
	HLock(strHandle);
	cntPtr = (unsigned short *) *strHandle;
	cnt = *cntPtr;
	if (index > cnt)
	  {
	    theString->count = 0;
	    return;
	  }
	strPtr = (unsigned char *) ++cntPtr;
	index -= 1;
	for (idx = 0; idx < index; idx++)
	  {
	    /* get the strings before the desired string */
	    total = *strPtr;
	    strPtr += (total + 1);
	  }
	theString->count = *strPtr;
	strPtr++;
	total = theString->count;
	for (lcntr = 0; lcntr < total; lcntr++)
	  {
	    theString->s[lcntr] = *strPtr;
	    strPtr++;
	  }
	HUnlock(strHandle);
}

typedef struct {
	short count;
	Pattern thePats[100];
} PatList;

GetIndPattern(thePattern,patListID,index)
Pattern *thePattern;
short patListID;
short index;
{
	PatList **patHandle;
	PatList *patPtr;

	patHandle = (PatList **) GetResource('PAT#',patListID);
	if (patHandle == NULL)
	  return;
	HLock(patHandle);
	patPtr = *patHandle;
	if (index > patPtr->count)
	  {
	    HUnlock(patHandle);
	    return;
	  }
	BlockMove(&(patPtr->thePats[index]),thePattern,8);
	HUnlock(patHandle);
}

void ScreenRes(scrVRes,scrHRes)
     short *scrVRes;		/* D0.L */
     short *scrHRes;		/* D1.L */
     {
#asm
; These constants are defined in
;	Macintosh Technical Note 16: MacWorks XL Owners Manual
ScrVRes	EQU	$102
ScrHres	EQU	$104

	MOVEM.L	A0-A1,-(SP)	; save registers
	MOVE.L	D0,A0		; put variables in address registers
	MOVE.L	D1,A1
	MOVE.W	ScrVRes,(A0)	; store into variable
	MOVE.W	ScrHRes,(A1)	; ditto
	MOVEM.L	(SP)+,A0-A1	; restore registers
#endasm
     }

/**************************** end of ToolUtils.c *********************/

shebanow@ernie.BERKELEY.EDU (Mike Shebanow) (11/28/85)

(beware the line eater)


=========================EventMgr.Asm==============================
*
* EventMgr.asm		Andrew G. Shebanow		11/27/85
*
*	Glue code for the Event Manager (both Toolbox and OS level).
* Implements the [Pascal Only] calls defined in Inside Mac.
*
*	For the IMLib library, using Mac C calling conventions.
*
* Copyright 1985 HyperSoft			All Rights Reserved
*

* Standard includes
	INCLUDE SysEquX.D

* Defined here:
	XDEF GetCaretTime
	XDEF GetDblTime
	XDEF GetEvQHdr
	XDEF SetEventMask

*
* long GetCaretTime()
*

	Module 'GetCaretTime'
GetCaretTime
	MOVE.L	CaretTime,D0		; just get it
	RTS

*
* long GetDblTime()
*

	Module 'GetDblTime'
GetDblTime
	MOVE.L	DoubleTime,D0		; just get it
	RTS

*
* QHdrPtr GetEvQHdr()
*

	Module 'GetEvQHdr'
GetEvQHdr
	MOVE.L	EventQueue,A0		; This is defined as a 10 byte
					; area. Assuming that the first
					; longword is the QHdrPtr value.
					; Hopefully this is actually
					; the correct pointer to return.
	RTS

*
* SetEventMask(theMask)
* short theMask;	(D0.W)
*

	Module 'SetEventMask'
SetEventMask
	MOVE.L	A0,-(SP)		; save A0
	MOVE.L	#SysEvtMask,A0		; A0 -> the os global variable
	MOVE.W	D0,(A0)			; store mask
	MOVE.L	(SP)+,A0		; restore A0
	RTS

	END

************************* end of EventMgr.asm *************************
=========================FinderParms.c==============================
/*
 * FinderParms.c	Andrew G. Shebanow	8/31/85
 *
 * Routines to emulate the Pascal calls which return finder information
 * (e.g., file arguments, open or print, etc). Written to
 * interface to Consulair's MacC compiler.
 *
 * In addition, several additional calls have been added to the library.
 * These routines let applications manipulate the application parms for
 * another application prior to a Launch call.
 *
 * Copyright 1985	HyperSoft	All Rights Reserved
 *
 * Modification History
 *
 *	9/9/85	Moved to C version			(AGS)
 *	9/9/85	Added code to set finder parms		(AGS)
 */

#include "memory.h"

/* this is a library of routines */
#Options M

/* finder message open files or print files */
#define appOpen		0
#define appPrint	1

/* finder application parameter info */
typedef struct {
	short		vRefNum;
	unsigned long	fType;
	short		versNum;
	Str255		fName;
} AppFile;

#define APPPARMHANDLE	0x0aec

typedef struct {
	short message;
	short count;
	AppFile files[4];	/* actually open ended */
} AppParms;

short AddAppFile(appFile)
      AppFile *appFile;
      {
	Handle appParmH;
	AppParms *appParmPtr;
	AppFile *newAppFile;
	unsigned long appHsize, appFsize;
	unsigned long newSize;

	appParmH = (Handle) APPPARMHANDLE;
	appParmH = (Handle) *appParmH;
	appHsize = GetHandleSize(appParmH);
	appFsize = (unsigned long) appFile->fName.count;
	appFsize++;
	if ((appFsize & 0x01) != 0)
	  appFsize++;
	appFsize += 8;
	newSize = appFsize + appHsize;
	if (SetHandleSize(appParmH,newSize) != 0)
	  return(1);
	appParmPtr = (AppParms *) *appParmH;
	newAppFile = &(appParmPtr->files[appParmPtr->count]);
	BlockMove(appFile,newAppFile,appFsize);
	appParmPtr->count += 1;
	return(0);
      }

static asmprocs()
{
#asm

	INCLUDE MACTRAPS.D
	INCLUDE SYSEQU.D
	INCLUDE TOOLEQU.D

; Routines declared here:
	XDEF CountAppFiles
	XDEF GetAppFiles
	XDEF ClrAppFiles
	XDEF ZeroAppFiles
	XDEF SetAppMessage
	XDEF GetAppName
	XDEF GetFndrName
	XDEF SetFndrName
	XDEF LOCFindIndex

	SModule 'FindIndex'

; LOCFindIndex
;
;	finds the nth AppFile record.
;
; INPUT:
;	A0.L	pointer to AppParms
;	D0.W	index (1..count)
; OUTPUT:
;	A1.L	pointer to AppFile data or 0 if not found

LOCFindIndex
	MOVEM.L	A2-A4,-(SP)	; save regs
	MOVE.L	0,A1			; set result to 0
	TST	D0			; test for legal index
	BLE	FindXit
	CMP	2(A0),D0
	BGT	FindXit

	LEA	4(A0),A2		; start of first AppFile
	MOVE	D0,D1			; D1 is loop counter
@1	SUBQ	#1,D1			; index from 0
	BEQ	@2			; if 0 we are done

	ADD.L	#8,A2			; start of filename string
	MOVE.B	(A2),D2			; D2 gets filename size
	AND.L	#$0FF,D2		; mask off high bits
	ADDQ.L	#1,D2			; plus one more for size byte
	BTST	#0,D2			; test for pad byte
	BEQ	@3			; if odd count, we must pad
	ADDQ.L	#1,D2			; add one for pad byte

@3	ADD.L	D2,A2			; add string size to address
	BRA	@1

@2	MOVE.L	A2,A1			; store in result

FindXit	MOVEM.L	(SP)+,A2-A4		; restore regs
	RTS

	SModule 'CountAppFiles'

; void CountAppFiles(message,count)
; short *message;	(D0)
; short *count;		(D1)

CountAppFiles:
	MOVEM.L	A0-A2,-(SP)	; save regs
	MOVE.L	AppParmHandle,A0
	MOVE.L	(A0),A0		; A0 points to AppParms
	MOVE.L	D0,A1		; A1 points to message
	MOVE.L	D1,A2		; A2 points to count
	MOVE	(A0),(A1)	; save into message
	MOVE	2(A0),(A2)	; save into count
	MOVEM.L	(SP)+,A0-A2	; restore regs
	RTS

	SModule 'GetAppFiles'

; void GetAppFiles(index,appFile)
; short index;		(D0)
; AppFile *appFile;	(D1)

GetAppFiles:
	MOVEM.L	A0-A2,-(SP)	; save regs
	MOVE.L	AppParmHandle,A0
	MOVE.L	(A0),A0			; A0 points to AppParms
	MOVE.L	D1,A2			; A2 points to appFile
	JSR	LOCFindIndex		; find index
	CMP.L	#0,A1
	BEQ	@1			; if couldn't find, handle error
	; copy AppFile data from A1 to appFile
	MOVE.L	A1,A0			; source ptr
	MOVE.L	A2,A1			; dest ptr
	MOVE.L	8(A0),D0		; put str len in D0
	AND.L	#$0FF,D0		; mask hight bytes
	ADDQ.L	#1,D0
	BTST	#0,D0
	BEQ	@2			; if odd number of bytes...
	ADDQ.L	#1,D0			; pad with additional byte

@2	ADD.L	#8,D0			; add space for other data
	_BlockMove

@1	MOVEM.L	(SP)+,A0-A2		; restore regs
	RTS

	SModule 'ClrAppFiles'

; void ClrAppFiles(index)
; short index;		(D0)

ClrAppFiles:
	MOVEM.L	A0-A1,-(SP)		; save regs
	MOVE.L	AppParmHandle,A0
	MOVE.L	(A0),A0			; A0 points to AppParms
	JSR	LOCFindIndex		; find index
	CMP.L	#0,A1
	BEQ	@1
	MOVE.L	#0,2(A1)		; clear out fType field
@1	MOVEM.L	(SP)+,A0-A1		; restore regs
	RTS

	SModule 'ZeroAppFiles'

; void ZeroAppFiles()

ZeroAppFiles
	MOVEM.L	A0-A1,-(SP)		; save regs
	MOVE.L	AppParmHandle,A0
	MOVE.L	(A0),A1			; A1 points to AppParms
	CLR.L	(A1)			; set message & count to 0
	MOVEQ.L	#4,D0			; set handle size to 4
	_SetHandleSize
	MOVEM.L	(SP)+,A0-A1		; restore regs
	RTS

	SModule 'SetAppMessage'

; void SetAppMessage(message)
; short message;	(D0)

SetAppMessage
	MOVE.L	A0,-(SP)		; save regs
	MOVE.L	AppParmHandle,A0
	MOVE.L	(A0),A1			; A1 points to AppParms
	MOVE.W	D0,(A0)			; move message into app parm area
	MOVE.L	(SP)+,A0		; restore regs
	RTS

	SModule 'GetAppName'

; void GetAppName(appName)
; StringPtr appName;		(D0)
;
;	return name of current application

GetAppName
	MOVEM.L	A0-A1,-(SP)
	TST.L	D0
	BEQ	@1		; if string pointer is null, return

	LEA	CurApName,A0	; src <- CurApName global
	MOVE.L	D0,A1		; dst <- appName
	MOVE.B	(A0),D0		; get string size
	AND.L	#$0FF,D0
	ADDQ.L	#1,D0		; add 1 for size byte

	_BlockMove		; copy the string

@1	MOVEM.L	(SP)+,A0-A1
	RTS

	SModule 'GetFndrName'

; GetFndrName(fndrName)
; StringPtr fndrName;		(D0)
;
;	return name of current finder.
;

GetFndrName
	MOVEM.L	A0-A1,-(SP)
	TST.L	D0
	BEQ	@1		; if string pointer is null, return

	LEA	FinderName,A0	; src <- FinderName
	MOVE.L	D0,A1		; dst <- fndrName
	MOVE.B	(A0),D0		; get string size
	AND.L	#$0FF,D0
	ADDQ.L	#1,D0		; add 1 for size byte
	
	_BlockMove		; copy the string

@1	MOVEM.L	(SP)+,A0-A1
	RTS

	SModule 'SetFndrName'

; SetFndrName(fndrName)
; StringPtr fndrName;		(D0)
;
;	set current finder.
;

SetFndrName
	MOVEM.L	A0-A1,-(SP)
	TST.L	D0
	BEQ	@1		; if string pointer is null, return

	MOVE.L	D0,A0		; src <- fndrName
	LEA	FinderName,A1	; dst <- FinderName global
	MOVE.B	(A0),D0		; get string size

	CMP.B	#15,D0
	BGT	@1		; if string to big, do nothing

	AND.L	#$0FF,D0
	ADDQ.L	#1,D0		; add 1 for size byte

	_BlockMove		; copy the string

@1	MOVEM.L	(SP)+,A0-A1
	RTS

#endasm
}

/********************* end of FinderParms.c *********************/
=========================MemoryMgr.Asm==============================
;
; MemoryMgr.Asm		Andrew G. Shebanow	9/1/85
;
;	Routines to emulate the [NO TRAP MACRO] routines documented in
; the Memory Manager section of Inside Mac.
;
; The routine MaxApplZone was taken from the 8/85 issue of MacTutor Magazine
; and is copyrighted by MacTutor Magazine.
;
; Copyright 1985	HyperSoft	All Rights Reserved
;
; Modifications:
;
; 10/18/85	Made MemError return value of variable in
;		Low Memory
;

	INCLUDE MacTraps.D
	INCLUDE SysEquX.D

	; Declared here:
	XDEF MaxApplZone
	XDEF SystemZone
	XDEF ApplicZone
	XDEF GZCritical
	XDEF GZSaveHnd
	XDEF TopMem
	XDEF MemError

; MaxApplZone()
;
; This routine from 8/85 issue of MacTutor magazine
;
; "MaxApplZone expands the application heap zone to the application heap
; limit without purging any blocks currently in the zone. If the zone
; already extends to the limit, it won't be changed"
;	Inside Macintosh spec of MaxApplZone

MinBlkSize	EQU	12	; minimum physical size of block

MaxApplZone
	MOVEM.L	A0-A1,-(SP)	; save regs
	MOVE.L	ApplLimit,A0	; A0 = application heap limit (ptr)
	MOVE.L	HeapEnd,A1	; A1 = addr of cur zone trailer
	MOVE.L	A0,D0
	SUB.L	A1,D0		; D0 = size of unused space (incl trailer)
	MOVEQ	#MinBlkSize,D1	; D1 = min phys size of a block
	CMP.L	D1,D0		; unused space < min block size?
	BLO.S	@0		; if so, can't expand zone, bye-bye
	MOVE.L	A0,HeapEnd	; update HeapEnd to heap limit
	MOVE.L	D0,(A1)		; unused space = free block (header = size)
	MOVE.L	ApplZone,A1	; A1 points to zone header
	MOVE.L	A0,(A1)		; ApplicZone->bkLim = heap limit
	MOVE.L	D1,(A0)		; make new zone trailer (free, size = min)
	ADD.L	D0,zcbFree(A1)	; update count of free bytes in zone
	MOVEM.L	(SP)+,A0-A1	; restore regs
@0	RTS

; THz SystemZone()

SystemZone
	MOVE.L	SysZone,A0	; SysZone is a pointer to system zone
	RTS

; THz ApplicZone()

ApplicZone
	MOVE.L	ApplZone,A0	; ApplZone is a pointer to applic zone
	RTS

; char GZCritical()

GZCritical
	MOVE.L	#1,D0		; default return is TRUE
	MOVE.L	GZMoveHnd,D1
	BEQ.S	@0
	MOVE.L	GZRootHnd,D1
	BEQ.S	@0
	MOVE.B	#0,D0		; return false
@0	RTS

; Handle GZSaveHnd()

GZSaveHnd
	MOVE.L	GZRootHnd,A0
	RTS

; Ptr TopMem()

TopMem
	MOVE.L	MemTop,A0
	RTS

; OSErr MemError()
;
; Apple's document LoAlpha.TXT (from the Software Supplement)
; specifies address $220 as the location of the last memory manager
; error. However, this location is NOT part of SysEqu.TXT, and it may be
; used by Apple's memory manager glue routine to STORE the error instead
; of simply reading from it. No guarantee of valid results.

MemError
	MOVE.W	$220,D0
	RTS

	END
=========================OSUtils.Asm==============================
*
* OSUtils.asm		Andrew G. Shebanow	11/27/85
*
*	Routines to emulate the [Pascal Only] calls defined
* in the OS Utilities section of Inside Macintosh for Consulair C.
* Also includes one routine for Vertical Retrace Manager.
*
* Copyright 1985 HyperSoft	All Rights Reserved
*

* Standard Includes:
	INCLUDE SysEquX.D
	INCLUDE MacTraps.D

* Defined here:
	XDEF Environs
	XDEF Restart
	XDEF SetUpA5
	XDEF RestoreA5
	XDEF GetTime
	XDEF SetTime
	XDEF GetDateTime
	XDEF GetSysPPtr
	XDEF GetVBLQHdr

*
* Environs(rom,machine)
* short *rom;		(D0.L)
* short *machine;	(D1.L)
*

; these constants are defined by Macintsoh Tech Note #16: MacWorks XL
RomVers	EQU	$400008
Machine EQU	$400009

	Module	'Environs'
Environs
	MOVEM.L	A0-A1,-(SP)	; save regs
	MOVE.L	D0,A0
	MOVE.L	D1,A0
	CLR.W	(A0)
	CLR.W	(A1)
	MOVE.B	RomVers,1(A0)	; save version into lsb of var
	MOVE.B	Machine,1(A1)	; save machine into lsb of var
	MOVEM.L	(SP)+,A0-A1	; restore regs
	RTS

*
* Restart()
*

	Module	'Restart'
Restart
	RTS

*
* SetUpA5()
*

	Module	'A5SetupRestore'

SavedA5	DS.L	1

SetUpA5
	MOVE.L	A4,-(SP)		; save regs
	MOVE.L	A5,A4			; save old (and possibly wrong) A5
	MOVE.L	CurrentA5,A5		; get real A5 FIRST
	MOVE.L	A4,SavedA5(A5)		; NOW use as index to global
	MOVE.L	(SP)+,A4		; restore regs
	RTS

*
* RestoreA5()
*

RestoreA5
	MOVE.L	CurrentA5,A5		; make sure we are valid FIRST
	MOVE.L	SavedA5(A5),A5		; set to old value
	RTS

*
* GetTime(date)
* DateTimeRec *date;		(D0.L)
*

	Module	'GetTime'
GetTime
	MOVEM.L	D0/A0,-(SP)		; save regs
	MOVE.L	D0,A0
	MOVE.L	Time,D0
	_Secs2Date			; call trap
	MOVEM.L	(SP)+,D0/A0		; restore regs
	RTS

*
* SetTime(date)
* DateTimeRec *date;		(D0.L)
*

	Module	'SetTime'
SetTime
	MOVEM.L	D0/A0,-(SP)		; save regs
	MOVE.L	D0,A0
	_Date2Secs			; call trap
	_SetDateTime			; store that time
	MOVEM.L	(SP)+,D0/A0		; restore regs
	RTS

*
* GetDateTime(secs)
* long *secs;		(D0.L)
*

	Module	'GetDateTime'
GetDateTime
	MOVE.L	A0,-(SP)		; save A0
	MOVE.L	D0,A0
	MOVE.L	Time,(A0)		; get value of variable
	MOVE.L	(SP)+,A0		; restore A0
	RTS

*
* SysPPtr GetSysPPtr()
*

	Module	'GetSysPPtr'
GetSysPPtr
	MOVE.L	#SysParam,A0		; store pointer in A0
	RTS

*
* QHdrPtr GetVBLQHdr()
*

	Module 'GetVBLQhdr'
GetVBLQHdr
	MOVE.L	vblQueue,A0		; get address of queue ptr
	RTS

	END

*********************** end of OSUtils.ASM **************************