[net.sources.mac] MacC library code

info-mac@uw-beaver (09/16/85)

From: shebanow%ucbernie@Berkeley (Mike Shebanow)


A Modest proposal:

This is the list of functions that are not implemented as traps
in the current Mac ROMs. Apple provides most of these routines in
the Lisa Pascal environment only. I have implemented quite a few
of these routines for my own purposes. Many of them are extremely
useful. Some of them simply return the contents of global variables.

I am submitting this with the hope that somebody (or somebodies) out
there will implement the remaining functions and post them. I will probably
implement the routines from the 'OS Event Manager' and Text Edit' sections
sometime soon. I have no plans to do the driver level calls. If I can't
figure out a way to use Apple's Print Manager routines for MDS effectively,
I will rewrite those as well.

All of the code is written for Consulair C, and take register based
arguments. All the code was written by me, with the exception of the
File Manager code, which was written by Russ Whetmore. I am reposting
these, since I have added some routines and made some unnecessary changes.
I don't have the author's mail address, so I hope he doesn't object to
the reposting. I greatly appreciated his code, since it cut the size of my
application by about 1.5K (I had implemented the calls in C). I hope more
people will submit general purpose library code for MacC and other compilers.
A few of these routines have been posted to info-mac previously. These
versions supersede the previous versions.

Most of the routines have been very well tested by a make program I am in
the final phases of. The only exception to this is the code in Packages.asm,
of which I have used only the string comparison functions of the International
Utils package, and the SFGetFile routine from the Standard File package. The
other routines should work, since the code is pretty straightforward, but bugs
are a distinct possibility.

A special note: the routines in FinderParms.c contain not only the listed
routines from the Segment Loader, but also some routines for creating NEW
argument lists, which can be used to open documents when launching. The first
step is to call ZeroAppFiles(), which wipes the slate clean. The second step
is to call SetAppMessage(appPrint) if you want to set the message to appPrint.
Finally, call AddAppFile() once for each filename you wish to add, in order.
AddAppFile() accepts a pointer to a structure of type AppFile as its argument.
This is the same structure filled in by GetAppFiles(), as described in the
Segment loader docs.

Hope this stuff is useful...

Andrew Shebanow
c/o shebanow@ucbernie.ARPA

----------------------------- CUT HERE -------------------------------


Function	IM Section	Done?	By Whom?
GetDblTime	Event Manager	NO
GetCaretTime	Event Manager	NO
TEFromScrap	TextEdit	NO
TEToScrap	TextEdit	NO
TEScrapHandle	TextEdit	NO
TEGetScrapLen	TextEdit	NO
TESetScrapLen	TextEdit	NO
GetIndString	ToolUtil	YES	AGS
GetIndPattern	ToolUtil	YES	AGS
IUDateString	Package Mgr	YES	AGS
IUDatePString	Package Mgr	YES	AGS
IUTimeString	Package Mgr	YES	AGS
IUTimePString	Package Mgr	YES	AGS
IUMetric	Package Mgr	YES	AGS
IUGetIntl	Package Mgr	YES	AGS
IUSetIntl	Package Mgr	YES	AGS
IUCompString	Package Mgr	YES	AGS
IUMagString	Package Mgr	YES	AGS
IUEqualString	Package Mgr	YES	AGS
IUMagIDString	Package Mgr	YES	AGS
NumToString	Package Mgr	YES	AGS
StringToNum	Package Mgr	YES	AGS
SFPutFile	Package Mgr	YES	Consulair/AGS
SFPPutFile	Package Mgr	YES	AGS
SFGetFile	Package Mgr	YES	Consulair/AGS
SFPGetFile	Package Mgr	YES	AGS
DILoad		Package Mgr	YES	AGS
DIUnLoad	Package Mgr	YES	AGS
DIBadMount	Package Mgr	YES	AGS
DIFormat	Package Mgr	YES	AGS
DIVerify	Package Mgr	YES	AGS
DIZero		Package Mgr	YES	AGS
MaxApplZone	Memory Mgr	YES	MacTutor
SystemZone	Memory Mgr	YES	AGS
ApplicZone	Memory Mgr	YES	AGS
GZCritical	Memory Mgr	YES	AGS
GZSaveHnd	Memory Mgr	YES	AGS
TopMem		Memory Mgr	YES	AGS
MemError	Memory Mgr	YES	AGS
CountAppFiles	Segment Ldr	YES	AGS
GetAppFiles	Segment Ldr	YES	AGS
ClrAppFiles	Segment Ldr	YES	AGS
SetEventMask	OS Event Mgr	NO
GetEVQHdr	OS Event Mgr	NO
GetVInfo	File Mgr	YES	RW
GetVol		File Mgr	YES	RW
SetVol		File Mgr	YES	RW
FlushVol	File Mgr	YES	RW
UnmountVol	File Mgr	YES	RW
Eject		File Mgr	YES	RW
Create		File Mgr	YES	RW
FSOpen		File Mgr	YES	RW
FSRead		File Mgr	YES	RW
FSWrite		File Mgr	YES	RW
GetFPos		File Mgr	YES	RW
SetFPos		File Mgr	YES	RW
GetEOF		File Mgr	YES	RW
SetEOF		File Mgr	YES	RW
Allocate	File Mgr	YES	RW
FSClose		File Mgr	YES	RW
GetFInfo	File Mgr	YES	RW
SetFInfo	File Mgr	YES	RW
SetFLock	File Mgr	YES	RW
RstFLock	File Mgr	YES	RW
Rename		File Mgr	YES	RW
FSDelete	File Mgr	YES	RW
GetFSQHdr	File Mgr	YES	AGS
GetVCBQHdr	File Mgr	YES	AGS
GetDrvQHdr	File Mgr	YES	AGS
OpenDriver	Device Mgr	NO
CloseDriver	Device Mgr	NO
Control		Device Mgr	NO
Status		Device Mgr	NO
KillIO		Device Mgr	NO
GetDCtlQHdr	Device Mgr	NO
DiskEject	Disk Driver	NO
SetTagBuffer	Disk Driver	NO
DriveStatus	Disk Driver	NO
StartSound	Sound Driver	NO
StopSound	Sound Driver	NO
SoundDone	Sound Driver	NO
GetSoundVol	Sound Driver	NO
SetSoundVol	Sound Driver	NO
SerReset	Serial Driver	NO
SerSetBuf	Serial Driver	NO
SerHShake	Serial Driver	NO
SerSetBrk	Serial Driver	NO
SerClrBrk	Serial Driver	NO
SerGetBuf	Serial Driver	NO
SerErrFlag	Serial Driver	NO
GetVBLQHdr	Task Mgr	NO
GetDateTime	OS Utils	NO
GetTime		OS Utils	NO
SetTime		OS Utils	NO
GetSysPPtr	OS Utils	NO

Print Manager?	Print Mgr	YES	Apple (for MDS, stack based)
RAMSDOpen	Serial Driver	YES	Apple (for MDS, stack based)
RAMSDClose	Serial Driver	YES	Apple (for MDS, stack based)
AppleTalk?	AppleTalk Mgr	NO

----------------------------- CUT HERE -------------------------------

/*
 * 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"

/* 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

; 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

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

GetAppFiles:
	MOVEM.L	A0-A2/D0-D1,-(SP)	; save regs
	MOVE.L	AppParmHandle,A0
	MOVE.L	(A0),A0			; A0 points to AppParms
	MOVE.L	D1,A2			; A2 points to appFile
	JSR	FindIndex		; 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/D0-D1	; restore regs
	RTS

; 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	FindIndex		; 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

; 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

; 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

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

GetAppName
	MOVEM.L	A0-A1/D0,-(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/D0
	RTS

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

GetFndrName
	MOVEM.L	A0-A1/D0,-(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/D0
	RTS

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

SetFndrName
	MOVEM.L	A0-A1/D0,-(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/D0
	RTS

; FindIndex
;
;	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

FindIndex
	MOVEM.L	A2-A4/D1-D2,-(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/D1-D2	; restore regs
	RTS

#endasm
}

/********************* end of FinderParms.asm *********************/;

----------------------------- CUT HERE -------------------------------

; 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
;

	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/D0-D1,-(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/D0-D1 ; 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	D1,-(SP)	; save D1
	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	MOVE.L	(SP)+,D1
	RTS

; Handle GZSaveHnd()

GZSaveHnd
	MOVE.L	GZRootHnd,A0
	RTS

; Ptr TopMem()

TopMem
	MOVE.L	MemTop,A0
	RTS

; OSErr MemError()
; this routine always returns 0, since all MacC mem traps return the error
; immediately!

MemError
	MOVE.W	#0,D0		; always NoErr!!!
	RTS

	END

----------------------------- CUT HERE -------------------------------

;
; 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
;

	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

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

IUDateString
	MOVE.L	D0,-(SP)	; dateTime
	MOVE.L	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.L	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

; 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

; 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

; 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
	MOVEM.L	A0/D0-D1,-(SP)	; save regs
	MOVE.L	D0,A0		; A0 -> theString
	MOVE	#0,-(SP)	; routine selector
	_Pack7
	MOVE.L	D1,A0
	MOVE.L	D0,(A0)		; save result
	MOVEM.L	(SP)+,A0/D0-D1	; restore regs
	RTS

; 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

; 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

; 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


----------------------------- CUT HERE -------------------------------

/*
 * 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

/*
 * 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;
	unsigned char *strPtr;
	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;
	    for (lcntr = 0; lcntr <= total; lcntr++)
	      strPtr++;
	  }
	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);
}

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

----------------------------- CUT HERE -------------------------------

;------------------------------------------------------------------------------
; FileManager.ASM
;
; Emulation of Lisa Pascal interface for high-level file manager routines
; (Written to interface with Consulair Mac C)
;
; Russ Wetmore	for Star Systems Software, Inc.
;
; Version 2.1			24 June 1985
;
; Added the three Queue related [ Pascal Only ] calls from Inside
; Mac &  removed the signal exit possibilities. Mercilessy removed comments,
; because I was running out of disk space! My apologies to the author.
;
; 	Andrew Shebanow
;------------------------------------------------------------------------------
; UPDATE HISTORY:
;   9 Sep 1985 - Removed Signal call error handling
;   4 Sep 1985 - Added File Mgr Queue routines for completeness
;------------------------------------------------------------------------------
; This module was created for a number of reasons, mainly to resolve
;	ideological inconsistencies between Consulair's C-flavored
;	library routines and file management as described in
;	Inside Macintosh.
; One caveat:  These routines use one common parameter block, which as
;	a convenience is cleared before _any_ routine is executed.
;	For most functions, the loss of efficiency with regards to
;	speed is offset by the compactness of these routines.  For
;	those instances where separately maintained parameter blocks
;	will result in better performance, you're probably better off
;	doing the low-level diddling yourself.
; This module can be used as well by assembly language programmers, with
;	one exception:
;	1) "GetVInfo" uses a Consulair C macro called MULS.L which is
;	a signed multiply of two 32-bit values.  You'd have to emulate
;	this with your own subroutine.  I was just too lazy to write it
;	out myself and too honest to copy Bill Duvall's copyrighted
;	routines and imply that they were my own.
;------------------------------------------------------------------------------


;------------------------------------------------------------------------------
;	Include support files:
;------------------------------------------------------------------------------

		Include	SysEqu.D		; I need system equates
		Include	MacTraps.D		; I need (want) trap macros
		Include FSEqu.D			; Need File Manager Equates
		Include M68KLIB.D		; (Consulair C file - for macro)

;------------------------------------------------------------------------------
;	Global variables
;------------------------------------------------------------------------------

		XDEF	paramBlock
		.ALIGN	2
paramBlock:	ds.L	20,0			;Globally accessable parameter block (80 bytes max)



;------------------------------------------------------------------------------
;	Support subroutines
;------------------------------------------------------------------------------

; Clear parameter block to zeroes
clearPB:	move	#20-1,D6		;max size of ioParam/FileParam/VolumeParam (in longs)
		lea	paramBlock(A5),A0	;Fetch => to start of block
	@1:	clr.L	(A0)+
		dbra	D6,@1
globret:	rts

; Common subroutine to plug ioNamePtr and ioVRefNum fields
;	(and sets up parameter block for trap call to boot)
NameAndVref:	move.L	D0,paramBlock+ioFileName(A5)
		move	D1,paramBlock+ioVRefNum(A5)
		lea	paramBlock(A5),A0
		rts

; Common subroutine to return volume name to user from parameter block
;	Assumes A1 points to user supplied Str255 struct
retvolName:	move.L	paramBlock+ioFileName(A5),A0
		; A1 already equals target address (volName)
		clr.L	D0
		move.B	(A0),D0		;fetch Pascal string length
		addq.L	#1,D0		;Plus 1 to offset for length byte
		_BlockMove
		rts
	

;------------------------------------------------------------------------------
;	OSErr GetVInfo(drvNum, volName, vRefNum, freeBytes)
;	short drvNum;		(D0.W)
;	char *volName;		(D1.L)
;	short *vRefNum;		(D2.L)
;	long *freeBytes;	(D3.L)
;------------------------------------------------------------------------------

		XDEF	GetVInfo
GetVInfo:	jsr	clearPB			;clear out parameter block

		movem.L	D1-D3,-(SP)		;save volName, vRefNum, freeBytes

		tst	D0			;drvNum given?
		bne.S	@1			;Yes

		; drvNum = 0, so we use vRefNum to determine volume
		move.L	D2,A2			;Gotta go indirect
		move	(A2),paramBlock+ioVRefNum(A5)
		bra.S	@2

	@1:	; if drvNum is negative, only use volName to determine volume
		bmi.S	@2			;Go if drvNum is negative

		; drvNum is positive, so use it to determine volume
		move	D0,paramBlock+ioVolIndex(A5)

	@2:	; In any case, stuff volName into parameter block
		move.L	D1,paramBlock+ioFileName(A5)

		lea	paramBlock(A5),A0	;Set up trap call
		_GetVolInfo

		movem.L	(SP)+,A1-A3		;fetch saved params

		move	D0,D4			;Save returned error

		move.L	A1,D0			;Was volName supplied?
		beq.S	@4			;Nope, go on

		jsr	retvolName

	@4:	move	paramBlock+ioVRefNum(A5),(A2)	;return volume reference number

		move.L	paramBlock+ioVAlBlkSiz(A5),D0	;freeBytes = size of alloc block
		move	paramBlock+ioVFrBlk(A5),D1	;...times number of free blocks
		ext.L	D1
		MULS.L	D0,D1	;(CONSULAIR MACRO)

		move.L	D1,(A3)

	@3:	move	D4,D0			;Fetch saved error code
		rts				;We always return OSErr, regardless of signalflag


;------------------------------------------------------------------------------
;	OSErr GetVol(volName, vRefNum)
;	char *volName;		(D0.L)
;	short *vRefNum;		(D1.L)
;------------------------------------------------------------------------------

		XDEF	GetVol
GetVol:		jsr	clearPB

		movem.L	D0-D1,-(SP)		;Save params

		lea	paramBlock(A5),A0	;Set up trap call
		_GetVol

		movem.L	(SP)+,A1-A2		;Fetch saved params

		move	D0,D4			;Save returned error

		move.L	A1,D0			;volName supplied?
		beq.S	@1			;Nope, go on

		jsr	retvolName

	@1:	move	paramBlock+ioVRefNum(A5),(A2)	;return VRefNum

		move	D4,D0
		rts


;------------------------------------------------------------------------------
;	OSErr SetVol(volName, vRefNum)
;	char *volName;		(D0.L)
;	short vRefNum;		(D1.W)
;------------------------------------------------------------------------------
;	OSErr FlushVol(volName, vRefNum)
;	char *volName;		(D0.L)
;	short vRefNum;		(D1.W)
;------------------------------------------------------------------------------
;	OSErr UnmountVol(volName, vRefNum)
;	char *volName;		(D0.L)
;	short vRefNum;		(D1.W)
;------------------------------------------------------------------------------
;	OSErr Eject(volName, vRefNum)
;	char *volName;		(D0.L)
;	short vRefNum;		(D1.W)
;------------------------------------------------------------------------------

		XDEF	SetVol
SetVol:		move	#$A015,D2		; (_SetVol)
		bra.S	VolCommon

		XDEF	FlushVol
FlushVol:	move	#$A013,D2		; (_FlshVol)
		bra.S	VolCommon

		XDEF	UnmountVol
UnmountVol:	move	#$A00E,D2		; (_UnmountVol)
		bra.S	VolCommon

		XDEF	Eject
Eject:		move	#$A017,D2		; (_Eject)


VolCommon:	jsr	clearPB

		tst	D1			;vRefNum supplied?
		beq.S	@1			;Nope, go on

		; if vRefNum is non-zero, use it to determine volume
		move	D1,paramBlock+ioVRefNum(A5)
		bra.S	@2

	@1:	; else, use volName to determine volume
		move.L	D0,paramBlock+ioFileName(A5)

	@2:	lea	paramBlock(A5),A0
		lea	@3,A1
		move	D2,(A1)
		; We have to initialize this to a trap value, else, the 68000 may
		;   get confused first time through trying to determine how many
		;   bytes make up the next command
	@3:	_SetVol				;Gets replaced by proper trap value

		rts


;------------------------------------------------------------------------------
;	OSErr Create(fileName, vRefNum, creator, fileType)
;	Str255 *fileName;	(D0.L)
;	short vRefNum;		(D1.W)
;	OSType creator;		(D2.L)
;	OSType fileType;	(D3.L)
;------------------------------------------------------------------------------

		XDEF	Create
Create:		jsr	clearPB

		movem.L	D2-D3,-(SP)		;Save OSTypes

		jsr	NameAndVref
		_Create

		movem.L	(SP)+,D2-D3		;Fetch saved OSTypes

		tst	D0			;Error occurred?
		bne.S	@1			;Yes, make like a tree and leaf

		move.L	D2,D0			;Test to see if either creator
		or.L	D3,D0			;...or fileType supplied
		beq.S	@1			;Nope, just exit quietly

		move.L	D3,paramBlock+ioFlUsrWds(A5)	;Set creator
		move.L	D2,paramBlock+ioFlUsrWds+4(A5)	;Set type
		lea	paramBlock(A5),A0
		_SetFileInfo

	@1:	rts


;------------------------------------------------------------------------------
;	OSErr FSOpen(fileName, vRefNum, refNum)
;	Str255 *fileName;	(D0.L)
;	short vRefNum;		(D1.W)
;	short *refNum;		(D2.L)
;------------------------------------------------------------------------------
;	OSErr OpenRF(fileName, vRefNum, refNum)
;	Str255 *fileName;	(D0.L)
;	short vRefNum;		(D1.W)
;	short *refNum;		(D2.L)
;------------------------------------------------------------------------------
;	NOTE:	An additional non-Pascal-ish entry point is supplied which has the format:
;	OpenFork(fileName, vRefNum, refNum, fork)
;	where fork = 0 if data fork, 1 if resource fork
;------------------------------------------------------------------------------

opentable:	_Open
		_OpenRF

		XDEF	OpenRF
OpenRF:		move	#1,D3
		bra.S	OpenFork

		XDEF	FSOpen
FSOpen:		clr	D3

		XDEF	OpenFork
OpenFork:	jsr	clearPB

		move.L	D2,A3			;Save => to refNum
		lsr	#1,D3			;Account for word offset

		jsr	NameAndVref

		lea	opentable,A1		;Point to table
		add	D3,A1			;A1 points to proper trap value
		lea	@1,A2
		move	(A1),(A2)
	@1:	_Open				;Replaced by proper trap value

		move	paramBlock+ioRefNum(A5),(A3)	;Pass back refNum

	@2:	rts


;------------------------------------------------------------------------------
;	OSErr FSRead(refNum, count, buffPtr)
;	short refNum;		(D0.W)
;	long *count;		(D1.L)
;	char *buffPtr;		(D2.L)
;------------------------------------------------------------------------------
;	OSErr FSWrite(refNum, count, buffPtr)
;	short refNum;		(D0.W)
;	long *count;		(D1.L)
;	char *buffPtr;		(D2.L)
;------------------------------------------------------------------------------

		XDEF	FSRead
FSRead:		move	#$A002,D3		; (_Read)
		bra.S	RWcommon

		XDEF	FSWrite
FSWrite:	move	#$A003,D3		; (_Write)

RWcommon:	jsr	clearPB

		move.L	D1,A3			;Gotta go indirect to get to count

		move	D0,paramBlock+ioRefNum(A5)	;Set up refNum
		move.L	(A3),paramBlock+ioReqCount(A5)	;Set up count
		move.L	D2,paramBlock+ioBuffer(A5)	;Set up buffPtr

		lea	paramBlock(A5),A0	;Set up trap call
		lea	@1,A1
		move	D3,(A1)
	@1:	_Read				;Gets replaced by proper trap value

		move.L	paramBlock+ioActCount(A5),(A3)	;Return count

	@2:	rts


;------------------------------------------------------------------------------
;	OSErr GetFPos(refNum, filePos)
;	short refNum;		(D0.W)
;	long *filePos;		(D1.L)
;------------------------------------------------------------------------------

		XDEF	GetFPos
GetFPos:	jsr	clearPB

		move.L	D1,A3

		move	D0,paramBlock+ioRefNum(A5)	;Set up refNum

		lea	paramBlock(A5),A0
		_GetFPos

		move.L	paramBlock+ioPosOffset(A5),(A3)	;Return filePos

		rts


;------------------------------------------------------------------------------
;	OSErr SetFPos(refNum, posMode, posOff)
;	short refNum;		(D0.W)
;	short posMode;		(D1.W)
;	long posOff;		(D2.L)
;------------------------------------------------------------------------------

		XDEF	SetFPos
SetFPos:	jsr	clearPB

		move	D0,paramBlock+ioRefNum(A5)
		move	D1,paramBlock+ioPosMode(A5)
		move.L	D2,paramBlock+ioPosOffset(A5)

		lea	paramBlock(A5),A0
		_SetFPos

		rts


;------------------------------------------------------------------------------
;	OSErr GetEOF(refNum, logEOF)
;	short refNum;		(D0.W)
;	long *logEOF;		(D1.L)
;------------------------------------------------------------------------------

		XDEF	GetEOF
GetEOF:		jsr	clearPB

		move.L	D1,A3

		move	D0,paramBlock+ioRefNum(A5)

		lea	paramBlock(A5),A0
		_GetEOF

		move.L	paramBlock+ioLEOF(A5),(A3)	;Return logEOF

		rts


;------------------------------------------------------------------------------
;	OSErr SetEOF(refNum, filePos)
;	short refNum;		(D0.W)
;	long logEOF;		(D1.L)
;------------------------------------------------------------------------------

		XDEF	SetEOF
SetEOF:		jsr	clearPB

		move	D0,paramBlock+ioRefNum(A5)
		move.L	D1,paramBlock+ioLEOF(A5)

		lea	paramBlock(A5),A0
		_SetEOF

		rts


;------------------------------------------------------------------------------
;	OSErr Allocate(refNum, count)
;	short refNum;		(D0.W)
;	long count;		(D1.L)
;------------------------------------------------------------------------------

		XDEF	Allocate
Allocate:	jsr	clearPB

		move	D0,paramBlock+ioRefNum(A5)
		move.L	D1,paramBlock+ioReqCount(A5)

		lea	paramBlock(A5),A0
		_Allocate

		rts


;------------------------------------------------------------------------------
;	OSErr FSClose(refNum)
;	short refNum;		(D0.W)
;------------------------------------------------------------------------------

		XDEF	FSClose
FSClose:	jsr	clearPB

		move	D0,paramBlock+ioRefNum(A5)

		lea	paramBlock(A5),A0
		_Close

		rts


;------------------------------------------------------------------------------
;	OSErr GetFInfo(fileName, vRefNum, fndrInfo)
;	Str255 *fileName;	(D0.L)
;	short vRefNum;		(D1.W)
;	FInfo *fndrInfo;	(D2.L)
;------------------------------------------------------------------------------

		XDEF	GetFInfo
GetFInfo:	jsr	clearPB

		move.L	D2,A3

		jsr	NameAndVref

		_GetFileInfo

		lea	paramBlock+ioFlUsrWds(A5),A2
		move.L	(A2)+,(A3)+		; (faster than _BlockMove)
		move.L	(A2)+,(A3)+
		move.L	(A2)+,(A3)+
		move.L	(A2),(A3)

		rts				;We always return OSErr, regardless of signalflag


;------------------------------------------------------------------------------
;	OSErr SetFInfo(fileName, vRefNum, fndrInfo)
;	Str255 *fileName;	(D0.L)
;	short vRefNum;		(D1.W)
;	FInfo *fndrInfo;	(D2.L)
;------------------------------------------------------------------------------

		XDEF	SetFInfo
SetFInfo:	jsr	clearPB

		jsr	NameAndVref

		move.L	D2,A1
		lea	paramBlock+ioFlUsrWds(A5),A2
		move.L	(A1)+,(A2)+		; (faster than _BlockMove)
		move.L	(A1)+,(A2)+
		move.L	(A1)+,(A2)+
		move.L	(A1),(A2)

		_SetFileInfo

		rts


;------------------------------------------------------------------------------
;	OSErr SetFLock(fileName, vRefNum)
;	Str255 *fileName;	(D0.L)
;	short vRefNum;		(D1.W)
;------------------------------------------------------------------------------
;	OSErr RstFLock(fileName, vRefNum)
;	Str255 *fileName;	(D0.L)
;	short vRefNum;		(D1.W)
;------------------------------------------------------------------------------
;	OSErr FSDelete(fileName, vRefNum)
;	Str255 *fileName;	(D0.L)
;	short vRefNum;		(D1.W)
;------------------------------------------------------------------------------

		XDEF	SetFLock
SetFLock:	move	#$A041,D2		; (_SetFLock)
		bra.S	LkDlcommon

		XDEF	RstFLock
RstFLock:	move	#$A042,D2		; (_RstFLock)
		bra.S	LkDlcommon

		XDEF	FSDelete
FSDelete:	move	#$A009,D2		; (_Delete)

LkDlcommon:	jsr	clearPB

		jsr	NameAndVref

		lea	@1,A1
		move	D2,(A1)
	@1:	_RstFilLock			;Gets replaced by proper trap value

		rts


;------------------------------------------------------------------------------
;	OSErr Rename(oldName, vRefNum, newName)
;	Str255 *oldName;	(D0.L)
;	short vRefNum;		(D1.W)
;	Str255 *newName;	(D2.L)
;------------------------------------------------------------------------------

		XDEF	Rename
Rename:		jsr	clearPB

		jsr	NameAndVref
		move.L	D2,paramBlock+ioNewName(A5)

		_Rename

		rts

;------------------------------------------------------------------------------
;	QHdrPtr GetFSQHdr()
;------------------------------------------------------------------------------

		XDEF	GetFSQHdr
GetFSQHdr
		move.l	fsQHdr,A0
		rts

;------------------------------------------------------------------------------
;	QHdrPtr GetVCBQHdr()
;------------------------------------------------------------------------------

		XDEF	GetVCBQHdr
GetVCBQHdr
		move.l	vcbQHdr,A0
		rts

;------------------------------------------------------------------------------
;	QHdrPtr GetDrvQHdr()
;------------------------------------------------------------------------------

		XDEF	GetDrvQHdr
GetDrvQHdr
		move.l	drvQHdr,A0
		rts

		END

--------------------------- end of posting ------------------------------------