[net.sources.mac] Source code for TMON Extended User Area

darin@ut-dillo.UUCP (Darin Adler) (12/08/85)

<>

Here is the source code for the Extended User Area (which was going to be
part 1 of 3 in a previous posting).  It is in the form of 7 separate shell
archives.

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
-----cut here-----cut here-----cut here-----cut here-----
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	EUA.Asm.1
# This archive created: Sun Dec  8 13:27:51 1985
# By:	Darin Adler ()
echo shar: extracting EUA.Asm.1 '(29950 characters)'
cat << \SHAR_EOF > EUA.Asm.1
;Extended Monitor User Area  (Public Domain - Not For Sale)
;
;Written by Darin Adler
;
;Based upon the original user area by Waldemar Horwat
;
;Portions of this code are Copyright (c) 1985 ICOM Simulations
;The rest of the code is Copyright (c) 1985 Darin Adler
;
;Created:	August 14, 1984
;Last modified:	December 1, 1985
;
;This is for use with Monitor version 2.585, Macintosh ROM version $69.
;
;This is an MDS (Consulair) assembler source file.
;It may have to be modified in order to be used with other assemblers.
;
;If you have difficulties with any portion of this code (particularly
;the "discipline"), send comments or a description of your problem to:
;
;	Darin Adler
;	2765 Marl Oak Dr.
;	Highland Park, IL  60035
;
;Questions, comments or orders for TMON should be directed to:
;
;	ICOM Simulations
;	626 Wheeling Rd.
;	Wheeling, IL  60090
;	(312) 520-4440
;
;I give many thanks to Waldemar Horwat for writing TMON; to Todd Squires,
;Jay Zipnick, Craig Erickson, Terry Schulenburg for using and testing the
;early versions; to Andrew Donoho and the others from Austin who continue
;to test and make wonderful suggestions; to Steve Capps for the great idea
;(and code) for "discipline"; and to all the owners of TMON, who know a
;good thing when they see it!
;


AreaSize	EQU	$5500
Version		EQU	652


;These are the trap files, etc. for MDS.

		INCLUDE	MacTraps.D

		INCLUDE	SysEquX.D
JHideCursor	EQU	$800			;vectors for Hide and Show Cursor (from old SysEqu)
JShowCursor	EQU	$804

		INCLUDE FSEqu.D
FSFCBLen	EQU	$3F6			;length of the FCBs

		INCLUDE	ToolEquX.D
nextMap		EQU	16			;offset from one resource map to the next
resFileID	EQU	20			;offset to the resource file ID

		INCLUDE	QuickEqu.D

		INCLUDE	PackMacs.Txt


;The following macro is for word aligned, long word values.

		MACRO	LONG	value	=
		DC	{value}>>16,{value}&$FFFF
		|

;The next macro is for user area relative word addresses

		MACRO	ADDR	address	=
		IF	'{address}'='0'
		DC	0
		ELSE
		IF	'{address}'='.0'
		DC	0
		ELSE
		DC	{address}-A
		ENDIF
		ENDIF
		|

;The following macro is for traps into the monitor.

		MACRO	TRAPMon	string	=
		TRAP	#$F
TRAPMon.	SET	*
		DC.B	{string}
		IF	*-TRAPMon. <> 16
		DC.B	0
		ENDIF
		.ALIGN	2
		|

;The next 3 macros are for user area functions.

		MACRO	UAFunc	name,next	=
.{name}
		ADDR	.{next}
		ADDR	{name}
		DC.B	.{name}.1-*-1
		|
		MACRO	UAParam	name,parms	=
.{name}.1
		.ALIGN	2
		DC.B	{parms}
		DC.B	.{name}.2-*-1
		|
		MACRO	UACode	name		=
.{name}.2
		.ALIGN	2
{name}
		|


;These are the equates for the extended ASCII used in names.

End.If		EQU	$00
If.Else		EQU	$01
If.Pos		EQU	$02
If.Neg		EQU	$03
Colon		EQU	$04
Skip		EQU	$04 ;+1 to +10
PrHex		EQU	$0E ;+1 to +8
PrASCII		EQU	$16 ;+1 to +8
NoOp		EQU	$1F
DisAsm0		EQU	$80
DisAsm1		EQU	$81
Recognize	EQU	$82


;These are some useful Monitor routines.

_Print1		EQU	 -8(A5)
_ExiTMON	EQU	-12(A5)
_Print2		EQU	-20(A5)
_PutASCII	EQU	-24(A5)
_Put1Dig	EQU	-28(A5)
_Put2Dig	EQU	-32(A5)
_Put4Dig	EQU	-36(A5)
_Put6Dig	EQU	-40(A5)
_Put8Dig	EQU	-44(A5)
_NextCResFile	EQU	-48(A5)
_FindRes	EQU	-52(A5)
_Recognize	EQU	-56(A5)


;These are some of the monitor's variables

MonExecuting.A5	EQU	$15(A5)
PC.A5		EQU	$4E(A5)
D0.A5		EQU	$60(A5)
A0.A5		EQU	$80(A5)
SP.A5		EQU	$94(A5)
N.A5		EQU	$98(A5)
V.A5		EQU	$9C(A5)
V.A2		EQU	$9C(A2)

A5.TMON		EQU	*-$500			;Monitor globals relative to the user area.
MonExecuting	EQU	$15+A5.TMON		;This is the monitor status byte.
UserInform	EQU	$207+A5.TMON
TMONStart	EQU	$FC			;The contents of this point to the bottom of TMON.


		;#################
		;##             ##
		;##  User Area  ##
		;##             ##
		;#################


A

;This is the start of the user area.  See the TMON manual for details on the first 32 bytes.


_AreaSize	DC	AreaSize		;The size of the user area.
_Version	DC	Version			;The current version number.
_FlagWord	DC.B	%10010000		;Refresh and screen size. (Auto-Quit and no Vector Refresh)
_Inhibits	DC.B	%00000000		;Heap, label, and screen inhibit flags.
_PortConfig	DC	%0000000000000010	;Printer port, DTR handshake.
_PortRate	DC	%1100110000001010	;9600 baud, 8 data bits, 2 stop, no parity.
_A000Hook	ADDR	A000Hook		;The A000 hook.
_PrintError	ADDR	PrintError		;The error location.
_FirstUAFunc	ADDR	.Toggle			;The first user routine.
_HeapHook	ADDR	HeapHook		;The heap window hook.
_InitHook	ADDR	InitHook		;User initialization routine.
_EnterHook	ADDR	EnterHook		;User enter routine.
_ExitHook	ADDR	ExitHook		;User exit routine.
_LabelScan	ADDR	LabelScan		;User label table scanning routine.
_CodeLabelScan	ADDR	CodeLabelScan		;User label-in-code scanning routine.
_LabelFind	ADDR	LabelFind		;User routine to find label in table.
_CodeLabelFind	ADDR	CodeLabelFind		;User routine to find label in code.
_Reserved	DC	0,0,0,0,0,0,0,0		;Reserved for future use.


nasty0		LONG	'NIL!'			;Something nasty for location 0.
val10000	LONG	$10000			;A useful constant.
updating	LONG	0			;A record of the last window that called BeginUpdate.


InitHook
		TST.L	D0			;Is this the first call to InitHook?
		BNE.S	EveryInit
FirstInit
		BSR	GetTrapAddressPatch	;Patch fo fix incompatibility with HyperDrive 20
		BSR	AppleTalkPatch		;Patch to fix incompatibility with AppleTalk interface code.
		BSR	DebuggerInit		;Redefine the _Debugger trap.
		BSR	DebuggerPatch		;Fix up TMON's detection of the _Debugger opcode.
		BSR	SeeThroughPatch		;Fix up the fancy screen.
EveryInit
		BSR	A000OnOff		;Check if we need to wire in A000 traps.
		BSR	ChecksumInit		;Calculate an initial value for the checksum.
		BSR	FreeFormPatch		;Patch to fix a bug in Free Form sound.
		BSR	SaveMemTop		;Get the "real" MemTop.
		BSR	DisciplineInit		;Initialize the discipline code.
		MOVE.L	nasty0,0		;Trash location zero.
		RTS


EnterHook
		BSR	CursorEnter		;Play games with the cursor.
		BSR	RecordEnter		;Make 'Trap Record' seem continuous.
		RTS


ExitHook
		BSR	CursorExit		;Play games with the cursor.
		BSR	RecordExit		;Make 'Trap Record' seem continuous.
		MOVE.L	nasty0,0		;Trash location zero.
		RTS


HeapHook
		BSR	HeapIdentify
		RTS


		;#################################
		;##                             ##
		;##  User Area Built-In Labels  ##
		;##                             ##
		;#################################


;
;This is the label table built into the user area.
;

UALabelTable

		MACRO	Label	first,last,name	=
		LONG	{first}
		LONG	{last}
Label.		SET	*
		DC.B	'{name|0:8}'
		DCB.B	Label.+8-*,$20
		|

		;To add labels to this table simply add blocks of 16 bytes
		;(labels as described in the manual) between the UALabelTable
		;label and the UALabelTableEnd label.

		Label	  $8,  $C,BusError
		Label	  $C, $10,AddrErr
		Label	 $10, $14,Illegal
		Label	 $14, $18,ZeroDiv
		Label	 $18, $1C,ChkError
		Label	 $1C, $20,TrapVErr
		Label	 $20, $24,Privileg
		Label	 $24, $28,Trace
		Label	 $28, $2C,Line1010
		Label	 $2C, $30,Line1111
		Label	 $34, $38,Coproces
		Label	 $38, $3C,FormatEr
		Label	 $3C, $40,Uninited
		Label	 $60, $64,Spurious
		Label	 $64, $68,AutoInt1
		Label	 $68, $6C,AutoInt2
		Label	 $6C, $70,AutoInt3
		Label	 $70, $74,AutoInt4
		Label	 $74, $78,AutoInt5
		Label	 $78, $7C,AutoInt6
		Label	 $7C, $80,AutoInt7
		Label	 $80, $C0,TRAPtble
		Label	$100,$102,MonkeyLives
		Label	$102,$104,ScrVRes
		Label	$104,$106,ScrHRes
		Label	$106,$108,ScreenRow
		Label	$108,$10C,MemTop
		Label	$10C,$110,BufPtr
		Label	$110,$114,StkLowPt
		Label	$114,$118,HeapEnd
		Label	$118,$11C,TheZone
		Label	$11C,$120,UTableBase
		Label	$120,$124,MacJmp
		Label	$124,$128,DskRtnAdr
		Label	$128,$12C,PollRtnAddr
		Label	$12C,$12D,DskVerify
		Label	$12D,$12E,LoadTrap
		Label	$12E,$12F,MmInOK
		Label	$12F,$130,DiskWr11
		Label	$130,$134,ApplLimit
		Label	$134,$138,SonyVars
		Label	$138,$13A,PWMValue
		Label	$13A,$13E,PollStack
		Label	$13E,$142,PollProc
		Label	$142,$144,DskErr
		Label	$144,$146,SysEvtMask
		Label	$146,$14A,SysEvtBuf
		Label	$14A,$154,EventQueue
		Label	$154,$156,EvtBufCnt
		Label	$156,$15A,RndSeed
		Label	$15A,$15C,SysVersion
		Label	$15C,$15D,SEvtEnb
		Label	$15D,$15E,DSWndUpdate
		Label	$15E,$15F,FontFlag
		Label	$15F,$160,IntFlag
		Label	$160,$16A,VBLQueue
		Label	$16A,$16E,Ticks
		Label	$16E,$172,MBTicks
		Label	$172,$173,MBState
		Label	$173,$174,Tocks
		Label	$174,$17C,KeyMap
		Label	$17C,$184,KeypadMap
		Label	$184,$186,KeyLast
		Label	$186,$18A,KeyTime
		Label	$18A,$18E,KeyRepTime
		Label	$18E,$190,KeyThresh
		Label	$190,$192,KeyRepThresh
		Label	$192,$1B2,Lvl1DT
		Label	$1B2,$1D2,Lvl2DT
		Label	$1D2,$1D4,UnitNtryCnt
		Label	$1D4,$1D8,VIA
		Label	$1D8,$1DC,SCCRd
		Label	$1DC,$1E0,SCCWr
		Label	$1E0,$1E4,IWM
		Label	$1E4,$1F8,scratch20
		Label	$1F8,$1F9,SPValid
		Label	$1F9,$1FA,SPATalkA
		Label	$1FA,$1FB,SPATalkB
		Label	$1FB,$200,SPConfig
		Label	$200,$204,SPAlarm
		Label	$204,$206,SPFont
		Label	$206,$207,SPKbd
		Label	$207,$208,SPPrint
		Label	$208,$209,SPVolCtl
		Label	$209,$20A,SPClikCaret
		Label	$20A,$20B,SPMisc1
		Label	$20B,$20C,SPMisc2
		Label	$1F8,$20C,SysParam
		Label	$20C,$210,Time
		Label	$210,$212,BootDrive
		Label	$212,$214,JShell
		Label	$214,$216,SFSaveDisk
		Label	$216,$21A,KbdVars
		Label	$21A,$21E,JKybdTask
		Label	$21E,$21F,KbdType
		Label	$21F,$220,AlarmState
		Label	$220,$222,MemError
		Label	$222,$226,JFlgTrkSpd
		Label	$226,$22A,JDiskPrime
		Label	$22A,$22E,JRdAddr
		Label	$22E,$232,JRdData
		Label	$232,$236,JWrData
		Label	$236,$23A,JSeek
		Label	$23A,$23E,JSetUpPoll
		Label	$23E,$242,JRecal
		Label	$242,$246,JControl
		Label	$246,$24A,JWakeUp
		Label	$24A,$24E,JReSeek
		Label	$24E,$252,JMakeSpdTbl
		Label	$252,$256,JAdrDisk
		Label	$256,$25A,JSetSpeed
		Label	$25A,$25E,NiblTbl
		Label	$222,$260,DiskVars
		Label	$260,$261,SdVolume
		Label	$261,$262,Finder
		Label	$262,$266,SoundPtr
		Label	$266,$26A,SoundBase
		Label	$26A,$27A,SoundVBL
		Label	$27A,$27E,SoundDCE
		Label	$27E,$27F,SoundActive
		Label	$27F,$280,SoundLevel
		Label	$280,$282,CurPitch
		Label	$282,$28A,Switcher
		Label	$28A,$28E,RSDHndl
		Label	$28E,$290,ROM85
		Label	$290,$291,PortAUse
		Label	$291,$292,PortBUse
		Label	$292,$29A,ScreenVars
		Label	$29A,$29E,JGNEFilter
		Label	$29E,$2A2,Key1Trans
		Label	$2A2,$2A6,Key2Trans
		Label	$2A6,$2AA,SysZone
		Label	$2AA,$2AE,ApplZone
		Label	$2AE,$2B2,ROMBase
		Label	$2B2,$2B6,RAMBase
		Label	$2B6,$2BA,BasicGlob
		Label	$2BA,$2BE,DSAlertTab
		Label	$2BE,$2CE,ExtStsDT
		Label	$2CE,$2CF,SCCASts
		Label	$2CF,$2D0,SCCBSts
		Label	$2D0,$2D8,SerialVars
		Label	$2DC,$2E0,ABusDCE
		Label	$2D8,$2E0,ABusVars
		Label	$2E0,$2F0,FinderName
		Label	$2F0,$2F4,DoubleTime
		Label	$2F4,$2F8,CaretTime
		Label	$2F8,$2F9,ScrDmpEnb
		Label	$2F9,$2FA,ScrDmpType
		Label	$2FA,$2FC,TagData
		Label	$2FC,$300,BufTgFNum
		Label	$300,$302,BufTgFFlg
		Label	$302,$304,BufTgFBkNum
		Label	$304,$308,BufTgDate
		Label	$308,$312,DrvQHdr
		Label	$312,$316,PWMBuf2
		Label	$316,$31A,MacPgm
		Label	$31A,$31E,Lo3Bytes
		Label	$31E,$322,MinStack
		Label	$322,$326,DefltStack
		Label	$326,$328,MMDefFlags
		Label	$328,$32C,GZRootHnd
		Label	$32C,$330,GZRootPtr
		Label	$330,$334,GZMoveHnd
		Label	$334,$338,DSDrawProc
		Label	$338,$33C,EjectNotify
		Label	$33C,$340,IAZNotify
		Label	$340,$342,CkdDB
		Label	$342,$344,NxtDB
		Label	$344,$346,MaxDB
		Label	$346,$347,FlushOnly
		Label	$347,$348,RegRsrc
		Label	$348,$349,FLckUnlck
		Label	$349,$34A,FrcSync
		Label	$34A,$34C,NewMount
		Label	$34C,$34E,DrMstrBlk
		Label	$34E,$352,FCBSPtr
		Label	$352,$356,DefVCBPtr
		Label	$356,$360,VCBQHdr
		Label	$360,$362,FSBusy
		Label	$362,$366,FSQHead
		Label	$366,$36A,FSQTail
		Label	$360,$36A,FSQHdr
		Label	$36A,$3A2,RgSvArea
		Label	$3A2,$3A4,ErCode
		Label	$3A4,$3D6,Params
		Label	$3D6,$3DE,FSTemp8
		Label	$3DE,$3E2,FSTemp4
		Label	$3E2,$3E6,FSQueueHook
		Label	$3E6,$3EA,ExtFSHook
		Label	$3EA,$3EE,DskSwtchHook
		Label	$3EE,$3F2,ReqstVol
		Label	$3F2,$3F6,ToExtFS
		Label	$3F6,$3F8,FSFCBLen
		Label	$3F8,$400,DSAlertRect
		Label	$400,$800,DispatchTab
		Label	$800,$804,JHideCursor
		Label	$804,$808,JShowCursor
		Label	$808,$80C,JShieldCursor
		Label	$80C,$810,JScrnAddr
		Label	$810,$814,JScrnSize
		Label	$814,$818,JInitCrsr
		Label	$818,$81C,JSetCrsr
		Label	$81C,$820,JCrsrObscure
		Label	$820,$824,JUpdateProc
		Label	$824,$828,ScrnBase
		Label	$828,$82C,MTemp
		Label	$82C,$830,RawMouse
		Label	$830,$834,Mouse
		Label	$834,$83C,CrsrPin
		Label	$83C,$844,CrsrRect
		Label	$844,$888,TheCrsr
		Label	$888,$88C,CrsrAddr
		Label	$88C,$8CC,CrsrSave
		Label	$8CC,$8CD,CrsrVis
		Label	$8CD,$8CE,CrsrBusy
		Label	$8CE,$8CF,CrsrNew
		Label	$8CF,$8D0,CrsrCouple
		Label	$8D0,$8D2,CrsrState
		Label	$8D2,$8D3,CrsrObscure
		Label	$8D3,$8D4,CrsrScale
		Label	$8D6,$8DA,MouseMask
		Label	$8DA,$8DE,MouseOffset
		Label	$8DE,$8E0,JournalFlag
		Label	$8E0,$8E4,JSwapFont
		Label	$8E4,$8E8,JFontInfo
		Label	$8E8,$8EC,JournalRef
		Label	$8EC,$8EE,CrsrThresh
		Label	$8EE,$8F2,JCrsrTask
		Label	$8F2,$8F3,WWExist
		Label	$8F3,$8F4,QDExist
		Label	$8F4,$8F8,JFetch
		Label	$8F8,$8FC,JStash
		Label	$8FC,$900,JIODone
		Label	$900,$902,CurApRefnum
		Label	$902,$903,LaunchFlag
		Label	$904,$908,CurrentA5
		Label	$908,$90C,CurStack
		Label	$910,$930,CurApName
		Label	$930,$934,SaveSegHandle
		Label	$934,$936,CurJTOffset
		Label	$936,$938,CurPageOption
		Label	$93A,$944,LoaderPBlock
		Label	$900,$944,LoadVars
		Label	$944,$946,PrintErr
		Label	$946,$947,ChooserBits
		Label	$944,$954,PrintVars
		Label	$954,$960,CoreEdit
		Label	$960,$964,scrapSize
		Label	$964,$968,scrapHandle
		Label	$968,$96A,scrapCount
		Label	$96A,$96C,scrapState
		Label	$96C,$970,scrapName
		Label	$970,$980,ScrapTag
		Label	$960,$980,ScrapVars
		Label	$980,$984,RomFont0
		Label	$984,$986,ApFontID
		Label	$986,$987,GotStrike
		Label	$987,$988,FMDefaultSize
		Label	$988,$98A,CurFMFamily
		Label	$98A,$98C,CurFMSize
		Label	$98C,$98D,CurFMFace
		Label	$98D,$98E,CurFMNeedBits
		Label	$98E,$990,CurFMDevice
		Label	$990,$994,CurFMNumer
		Label	$994,$998,CurFMDenom
		Label	$988,$998,CurFMInput
		Label	$998,$99A,FOutError
		Label	$99A,$99E,FOutFontHandle
		Label	$99E,$99F,FOutBold
		Label	$99F,$9A0,FOutItalic
		Label	$9A0,$9A1,FOutULOffset
		Label	$9A1,$9A2,FOutULShadow
		Label	$9A2,$9A3,FOutULThick
		Label	$9A3,$9A4,FOutShadow
		Label	$9A4,$9A5,FOutExtra
		Label	$9A5,$9A6,FOutAscent
		Label	$9A6,$9A7,FOutDescent
		Label	$9A7,$9A8,FOutWidMax
		Label	$9A8,$9A9,FOutLeading
		Label	$9A9,$9AA,FOutUnused
		Label	$9AA,$9AE,FOutNumeer
		Label	$9AE,$9B2,FOutDenom
		Label	$998,$9B2,FOutRec
		Label	$9B2,$9B6,FMDotsPerInch
		Label	$9B6,$9CE,FMStyleTab
		Label	$9CE,$9D6,ToolScratch
		Label	$9D6,$9DA,WindowList
		Label	$9DA,$9DC,SaveUpdate
		Label	$9DC,$9DE,PaintWhite
		Label	$9DE,$9E2,WMgrPort
		Label	$9E2,$9E6,DeskPort
		Label	$9E6,$9EA,OldStructure
		Label	$9EA,$9EE,OldContent
		Label	$9EE,$9F2,GrayRgn
		Label	$9F2,$9F6,SaveVisRgn
		Label	$9F6,$9FA,DragHook
		Label	$9FA,$A02,scratch8
		Label	$A02,$A06,OneOne
		Label	$A06,$A0A,MinusOne
		Label	$A0E,$A1C,IconBitmap
		Label	$A1C,$A20,MenuList
		Label	$A20,$A22,MBarEnable
		Label	$A22,$A24,CurDeKind
		Label	$A24,$A26,MenuFlash
		Label	$A26,$A28,TheMenu
		Label	$A28,$A2C,SavedHandle
		Label	$A2C,$A30,MBarHook
		Label	$A30,$A34,MenuHook
		Label	$A34,$A3C,DragPattern
		Label	$A3C,$A44,DeskPattern
		Label	$A44,$A46,DragFlag
		Label	$A46,$A4A,CurDragAction
		Label	$A4A,$A50,FPState
		Label	$A50,$A54,TopMapHndl
		Label	$A54,$A58,SysMapHndl
		Label	$A58,$A5A,SysMap
		Label	$A5A,$A5C,CurMap
		Label	$A5C,$A5E,ResReadOnly
		Label	$A5E,$A60,ResLoad
		Label	$A60,$A62,ResErr
		Label	$A62,$A63,TaskLock
		Label	$A63,$A64,FScaleDisable
		Label	$A64,$A68,CurActivate
		Label	$A68,$A6C,CurDeactive
		Label	$A6C,$A70,DeskHook
		Label	$A70,$A74,TEDoText
		Label	$A74,$A78,TERecal
		Label	$A78,$A84,ApplScratch
		Label	$A84,$A88,GhostWindow
		Label	$A88,$A8C,CloseOrnHook
		Label	$A8C,$A90,ResumeProc
		Label	$A90,$A94,SaveProc
		Label	$A94,$A98,SaveSP
		Label	$A98,$A9A,ANumber
		Label	$A9A,$A9C,ACount
		Label	$A9C,$AA0,DABeeper
		Label	$AA0,$AB0,DAStrings
		Label	$AB0,$AB2,TEScrpLength
		Label	$AB4,$AB8,TEScrpHandle
		Label	$AB8,$AD8,AppPacks
		Label	$AD8,$AE8,SysResName
		Label	$AEC,$AF0,AppParmHandle
		Label	$AF0,$AF2,DSErrCode
		Label	$AF2,$AF6,ResErrProc
		Label	$AF6,$AFA,TEWdBreak
		Label	$AFA,$AFC,DlgFont

UALabelTableEnd

NumUALabels	EQU	(UALabelTableEnd-UALabelTable)/16


		;###########################
		;##                       ##
		;##  User Area functions  ##
		;##                       ##
		;###########################


;
;The following is the first function in the user area.
;It is used to link between two different sets of UA functions.
;

	UAFunc	Toggle,BlockMove
		DC.B	'Toggle screens {'
		DC.B	If.Pos
		DC.B	  'generic'
		DC.B	If.Else
		DC.B	  'heap, label and A000 trap'
		DC.B	End.If
		DC.B	' functions}'
	UAParam	Toggle,%00001
		DC.B	0
	UACode	Toggle
		NOT.B	(A0)
		BEQ.S	@1
		MOVE.W	#.LabelTableSet-A,.Toggle-A(A2)
		RTS
@1		MOVE.W	#.BlockMove-A,.Toggle-A(A2)
		RTS


;The 1st user area screen starts here


	UAFunc	BlockMove,BlockCompare
		DC.B	'Block move (src dst len)'
	UAParam	BlockMove,%01000
	UACode	BlockMove
		MOVE.L	D0,A0			;Call the ROM _BlockMove routine.
		MOVE.L	D1,A1
		MOVE.L	D2,D0
		_BlockMove
		RTS


	UAFunc	BlockCompare,BlockFill
		DC.B	'Block compare {'
		DC.B	If.Neg
		DC.B	  Skip+9
		DC.B	If.Else
		DC.B	  If.Neg
		DC.B	    'Match',Skip+8
		DC.B	  If.Else
		DC.B	    'Mismatch at ',Skip+1,PrHex+6,'/',Skip+1,PrHex+6
		DC.B	  End.If
		DC.B	End.If
		DC.B	'} (adr1 adr2 len)',Colon
		DC.B	If.Pos
		DC.B	  PrHex+6,' ',Skip+1,PrHex+6,' ',Skip+1,PrHex+6
	UAParam	BlockCompare,%01001
		DC	$FF00
		LONG	-1
		LONG	-1
		LONG	-1
		LONG	-1
		LONG	-1
	UACode	BlockCompare
		TST.B	D7			;No parameters?
		BEQ.S	@2			;It's a "match"
		TST.L	D2			;Is the length zero or negative?
		BLE.S	@2			;YES.  All zero-length areas "match".
		BSR	AddressCheck
		MOVEM.L	D0/D1/D2,10(A0)		;Save the current values.
		MOVE.L	D0,A1
		MOVE.L	D1,A2
		SUBQ.L	#1,D2
@1		CMPM.B	(A1)+,(A2)+		;Compare one byte.
		DBNE	D2,@1
		BNE.S	Mismatch		;A mismatch.
		SUB.L	val10000,D2		;This is the compare outer loop.
		BCC.S	@1
@2		SCC	10(A0)			;Flag whether a comparison is going.
		SCC	(A0)+
		ST	(A0)			;The blocks match.
		RTS

Mismatch
		CLR.W	(A0)+			;Flag a mismatch.
		SUBQ.W	#1,A1			;Pass back the address of the mismatch.
		MOVE.L	A1,(A0)+
		BSR	StoreV
		SUBQ.W	#1,A2
		MOVE.L	A2,(A0)+
@1		CMPM.B	(A1)+,(A2)+		;Now search for another match.
		DBEQ	D2,@1
		BEQ.S	@2			;A match.
		SUB.L	val10000,D2		;This is the compare outer loop.
		BCC.S	@1
		BRA.S	@3
@2		SUBQ.W	#1,A1			;Move the pointers back one byte.
		SUBQ.W	#1,A2
@3		ADDQ.L	#1,D2
		MOVE.L	A1,(A0)+		;Save the pointers and the new count for the user's
		MOVE.L	A2,(A0)+		;convenience.
		MOVE.L	D2,(A0)
		RTS


	UAFunc	BlockFill,Search
		DC.B	'Fill (bgn end val [vLen])'
	UAParam	BlockFill,%11000
	UACode	BlockFill
		LSR.B	#1,D7
		BCC.S	@1
		BSR.S	Measure			;Find the size of the item.
@1		MOVEQ	#%10110,D6
		BSR.S	MeasureCheck
		MOVE.L	D2,D4
		SUBQ.B	#2,D3
		BEQ.S	@2			;Do a word fill.
		BCC.S	@3			;Do a longword fill.
		LSL.W	#8,D4			;Do a byte fill.  Copy the byte into both the low
		MOVE.B	D2,D4			;and high order bytes of the low word in D2.
		MOVE.W	D4,D2
@2		SWAP	D2			;Copy the word into both the low and high order
		MOVE.W	D4,D2			;words in D2.
@3		SUB.L	D0,D1			;If the ending address is lower than the beginning
		BLT.S	@5			;address, exit.
		MOVE.L	D0,A0
@4		ROL.L	#8,D2			;Shift the next byte into position, and put it into
		MOVE.B	D2,(A0)+		;the destination.
		DBRA	D1,@4
		SUB.L	val10000,D1		;This is a continuation of the loop.
		BCC.S	@4
@5		RTS


Measure
		MOVEQ	#1,D4
		MOVEQ	#0,D3
@1		ADDQ.W	#1,D3			;Compare the value against $100, $10000, and
		ROL.L	#8,D4			;$1000000.  Estimate the length based on the
		CMP.L	D4,D2			;results.
		BCS.S	@2
		CMP.W	#4,D3
		BCS.S	@1
@2		RTS


MeasureCheck
		MOVEQ	#4,D4			;D4 contains the constant 4.
		CMP.L	D4,D3			;The length can't be greater than four.
		BLS.S	@1
		MOVE.L	D5,D3
@1		BTST	D3,D6			;The length has to be within the requested range.
		BNE.S	AddressCheck
		ADDQ.B	#1,D3
		BRA.S	@1


AddressCheck
		AND.L	Lo3Bytes,D0		;Strip the high bytes from the addresses.
		AND.L	Lo3Bytes,D1
		RTS


	UAFunc	Search,RegisterBuffer
		DC.B	'Find {'
		DC.B	If.Neg
		DC.B	  'byte'
		DC.B	If.Else
		DC.B	  'word'
		DC.B	End.If
		DC.B	' aligned} {'
		DC.B	If.Neg
		DC.B	  Skip+4
		DC.B	If.Else
		DC.B	  Skip+1,PrHex+6
		DC.B	End.If
		DC.B	'} (val [vLen [bgn [end]]])',Colon
		DC.B	If.Pos
		DC.B	  Skip+1,PrHex+8,' '
		DC.B	  If.Pos
		DC.B	    PrHex+1,' '
		DC.B	    If.Pos
		DC.B	      PrHex+6,' ',Skip+1,PrHex+6
	UAParam	Search,%11111
		DC	$FFFF
		LONG	0
		DC	$FF00
		LONG	0
		DC	$FF00
		LONG	-1
		LONG	-1
	UACode	Search
		TST.B	D7			;If just a RETURN was pressed, toggle between byte
		BNE.S	@1			;and word aligned search.
		NOT.B	(A0)
		RTS
@1		EXG	D0,D2
		EXG	D1,D3
		SUBQ.B	#1,D7			;If vLen wasn't given, calculate it.
		BNE.S	@2
		BSR	Measure
@2		MOVEQ	#%11110,D6		;vLen can be 1..4 for byte-aligned searches and 2
		TST.B	(A0)+			;or 4 for word-aligned searches.
		BNE.S	@3
		MOVEQ	#%10100,D6
@3		BSR	MeasureCheck
		SUBQ.B	#3,D7			;If the ending address wasn't given, set it to the
		BEQ.S	@4			;end of memory.
		MOVE.L	RealMemTop,D1		;Use the "real" MemTop.
		SUBQ.L	#1,D1
@4		ST	(A0)+			;Assume that nothing was found.
		CLR.L	(A0)+			;Clear the "found" address.
		CLR.W	(A0)+			;Make everything appear.
		CLR.L	(A0)+			;Prevent the value itself from being found.
		MOVE.W	D3,(A0)+		;Save the search size.
		MOVE.L	D0,(A0)+		;Save the beginning address.
		MOVE.L	D1,(A0)			;Save the ending address.
		MOVE.L	D2,D6			;Save the value that is being searched, but not in
		SUBQ.W	#1,D3			;memory, because it would be found there.
		MOVE.W	D3,D4
		ASL.W	#3,D4			;Shift the high-order byte of the value into the
		ROR.L	D4,D2			;least significant byte of D2.
		TST.B	-18(A0)
		BMI.S	@5
		BCLR	D5,D0			;Align addresses to word boundaries for word-aligned
		BSET	D5,D1			;search.  D5 should be zero.
@5		MOVE.L	D0,A1
		SUB.L	D3,D1			;Subtract the length from the ending address.
		SUB.L	D0,D1			;Get the length of the area to be searched.
		BLT.S	@50			;It is less than zero.
		TST.B	-18(A0)
		BPL.S	@30

@10		CMP.B	(A1)+,D2		;Does this byte match?
@11		DBEQ	D1,@10
		BEQ.S	@12			;YES.
		SUB.L	val10000,D1		;NO.  This is a high-order loop.
		BCC.S	@10
@50		MOVE.L	D6,-10(A0)
		RTS				;Pass back failure code.

@12		MOVE.W	D3,D4			;Create private copies of the address, value, and
		MOVE.L	D2,D5			;length of value.
		MOVE.L	A1,A3
		BRA.S	@21
@20		ROL.L	#8,D5			;Compare the next byte in the value.
		CMP.B	(A3)+,D5
		BNE.S	@11
@21		DBRA	D4,@20			;Were all bytes present in the value compared?
		CMP.L	A5,A1			;YES.  Don't report a match if it is in the
		BCS.S	@40			;Monitor's variables area to prevent spurious finds.
		CMP.L	A2,A1
		BCS.S	@11
@40		MOVEQ	#1,D0
		BRA.S	@42			;Go report a find.

@30		ROL.L	#8,D2			;D1 contains the number of words, not bytes, for
		LSR.L	#1,D1			;word-aligned search.
@31		CMP.W	(A1)+,D2
@32		DBEQ	D1,@31
		BEQ.S	@33
		SUB.L	val10000,D1
		BCC.S	@31
		BRA.S	@50
@33		CMP.W	#1,D3
		BEQ.S	@34
		MOVE.L	D2,D5
		SWAP	D5
		CMP.W	(A1),D5
		BNE.S	@32
@34		CMP.L	A5,A1			;YES.  Don't report a match if it is in the
		BCS.S	@41			;Monitor's variables area to prevent spurious finds.
		CMP.L	A2,A1
		BCS.S	@32
@41		MOVEQ	#2,D0
@42		MOVE.L	A1,-(A0)		;Save the address of the match plus one.
		SUBQ.W	#2,A0
		MOVE.L	D6,-(A0)		;Save the value being searched.
		SUBQ.W	#2,A0
		SUB.W	D0,A1
		MOVE.L	A1,-(A0)		;Pass back the address of the match.
		CLR.B	-(A0)			;Indicate that the search was successful.
StoreV		MOVE.L	A1,V.A5			;Store this value in the V variable.
		RTS


	UAFunc	RegisterBuffer,Print
		DC.B	'Registers {'
		DC.B	If.Pos
		DC.B	  Skip+1,'PC=',PrHex+8,'} (0=save, 1=load, 2=swap)'
		DC.B	If.Else
		DC.B	  '} (0=save)'
	UAParam	RegisterBuffer,%00011
		DC	$FF00
		DCB.W	37,0			;37 words for the registers
	UACode	RegisterBuffer
		TST.W	D7
		BNE.S	BufferFunctions
		ST	(A0)
		RTS
BufferFunctions	TST.B	(A0)			;Are there stored registers?
		BEQ.S	@10
		TST.L	D0
		BEQ.S	@10
		RTS
@10		CLR.W	(A0)+
		LEA	PC.A5,A5		;Get the PC.
		MOVEQ	#37-1,D1		;Use 37 words.
		TST.L	D0			;Get the function code.
		BEQ.S	@1			;SaveRegs.
		SUBQ.L	#2,D0
		BEQ.S	@2			;SwapRegs.
		BCC.S	@3			;Exit if the number wasn't between 0 and 2.
		EXG	A0,A5			;LoadRegs. Do a reverse SaveRegs.
@1		MOVE.W	(A5)+,(A0)+
		DBRA	D1,@1
		RTS
@2		MOVE.W	(A5),D2			;Exchange the register sets.
		MOVE.W	(A0),(A5)+
		MOVE.W	D2,(A0)+
		DBRA	D1,@2
@3		RTS


		;Pick one of three routines to follow this one.

	UAFunc	Print,Template
		DC.B	'Print {'
		DC.B	If.Pos
		DC.B	  If.Pos,'dump'
		DC.B	  If.Else,'disassembly'
		DC.B	  End.If
		DC.B	If.Else
		DC.B	  If.Pos,'file'
		DC.B	  If.Else,'heap'
		DC.B	  End.If
		DC.B	End.If
		DC.B	'} {error=',PrHex+4,'} ('
		DC.B	If.Pos,'bgn end'
		DC.B	If.Else
		DC.B	  If.Pos,'file'
		DC.B	  If.Else,'zone'
		DC.B	  End.If
		DC.B	  '#'
		DC.B	End.If
		DC.B	')'
	UAParam	Print,%00101
		DC	0
PrintError	DC	0
		DC	0
	UACode	Print
		TST.W	D7			;Were any arguments supplied?
		BNE.S	@2			;YES.  Go to the printing section.
		NOT.B	1(A0)			;NO.  Go to the next state in the state machine.
		BNE.S	@1
		NOT.B	(A0)
		EOR.B	#%00110,-2(A0)		;Adjust the number of parameters allowed.
@1		MOVE.W	(A0),4(A0)
		RTS
@2		MOVE.B	1(A0),D5		;Prepare dump vs. disassembly or file vs. heap flag.
		SUBQ.W	#2,D7			;Is this a dump/disassembly print?
		BCS.S	@3			;NO.
		MOVE.L	D0,A1			;YES.
		MOVE.L	D1,A4			;Prepare the registers and go to the print routine.
		JMP	_Print1
@3		MOVE.W	D0,D6			;Prepare the file number.
		TST.B	D5
		BEQ.S	@4
		TST.L	D0			;If the heap number is requested instead, prepare
		SEQ	D6			;that.
		ASL.W	#8,D6
@4		JMP	_Print2			;Go to the print routine.


	UAFunc	Template,StackLook
		DC.B	'Template {'
		DC.B	If.Pos
		DC.B	  If.Pos,'WindowRecord'
		DC.B	  If.Else,'ControlRecord'
		DC.B	  End.If
		DC.B	If.Else
		DC.B	  If.Pos,'TERec'
		DC.B	  If.Else,'ParamBlock'
		DC.B	  End.If
		DC.B	End.If
		DC.B	If.Pos
		DC.B	  ' @'
		DC.B	  PrHex+6
		DC.B	End.If
		DC.B	'} (addr)',Colon
		DC.B	If.Pos
		DC.B	  PrHex+6
		DC.B	If.Else
		DC.B	  If.Pos
		DC.B	    'RA0'
	UAParam	Template,%00011
		DC	0
		LONG	-1
FutureTemplate	LONG	-1
	UACode	Template
		TST.B	D7
		BNE.S	ChoseTemplate
		TST.L	2(A0)
		BPL.S	CanceledTemplate
		NOT.B	1(A0)
		BNE.S	@1
		NOT.B	(A0)
@1		RTS

CanceledTemplate
		MOVE.W	#.StackLook-A,.Template-A(A2)
		MOVEQ	#-1,D0
		MOVE.L	D0,2(A0)
		MOVE.L	D0,6(A0)
Template.RTS	RTS

ChoseTemplate
		MOVE.L	A0,A5
		MOVE.L	D0,A0
		BSR	CheckA0			;If A0 is odd or NIL then don't accept it.
		BCS.S	Template.RTS

		MOVE.W	#.Template1-A,.Template-A(A2)
		MOVE.W	(A5)+,D0		;Get the signatures.
		MOVE.L	A0,(A5)			;Put the address in the template indicator.
		MOVE.L	A0,A5			;And into a handy register.

		LEA	Part1,A1		;Point the registers to the templates.
		LEA	Part2,A2
		LEA	Part3,A3
		LEA	Part4,A4

		MOVE.W	D0,(A1)+		;Inform each piece what kind it is.
		MOVE.W	D0,(A2)+
		MOVE.W	D0,(A3)+
		MOVE.W	D0,(A4)+

		PEA	FinishTemplate

		TST.W	D0
		BPL.S	@1
		TST.B	D0
		BMI	ParamTemplate
		BRA	TETemplate
@1		TST.B	D0
		BMI	ControlTemplate

WindowTemplate
		LEA	portBits(A5),A0
		MOVE.L	(A0)+,(A1)+	;baseAddr
		MOVE.W	(A0)+,(A1)+	;rowBytes
		MOVE.L	(A0)+,(A1)+	;bounds
		MOVE.L	(A0)+,(A1)+
		MOVE.L	(A0)+,(A1)+	;portRect
		MOVE.L	(A0)+,(A1)+
		MOVE.L	(A0)+,(A2)+	;visRgn
		MOVE.L	(A0)+,(A2)+	;clipRgn
		LEA	windowKind(A5),A0
		MOVE.W	(A0)+,(A2)+
		TST.B	(A0)+		;visible
		SNE	(A2)+
		TST.B	(A0)+		;hilited
		SNE	(A2)+
		TST.B	(A0)+		;goAway
		SNE	(A2)+
		ADDQ	#1,A0		;skip "spareFlag"
		MOVE.L	(A0)+,(A3)+	;strucRgn
		MOVE.L	(A0)+,(A3)+	;contRgn
		MOVE.L	(A0)+,(A3)+	;updateRgn
		MOVE.L	(A0)+,(A3)+	;defProc
		MOVE.L	(A0)+,(A3)+	;dataHandle
		MOVE.L	wControlList(A5),(A4)+
		MOVE.L	nextWindow(A5),D2
		MOVE.L	D2,(A4)+
		MOVE.L	wRefCon(A5),(A4)+

		MOVE.L	wTitleHandle(A5),A0
		BSR	IndirectA0
		BCC.S	@1
		MOVEQ	#0,D0
		MOVE.L	D0,A0
@1		ST	(A4)+
		RTS

ControlTemplate
		MOVE.L	(A0)+,D2	;nextControl
		MOVE.L	D2,(A1)+
		MOVE.L	(A0)+,(A1)+	;owner
		MOVE.L	(A0)+,(A1)+	;rect
		MOVE.L	(A0)+,(A1)+
		TST.B	(A0)+		;visible
		SNE	(A1)+
		MOVE.B	(A0)+,(A1)+	;hilited
		MOVE.W	(A0)+,(A2)+	;value
		MOVE.L	(A0)+,(A2)+	;min, max
		MOVE.L	(A0)+,(A2)+	;defProc
		MOVE.L	(A0)+,(A2)+	;dataHandle
		MOVE.L	(A0)+,(A2)+	;actionProc
		MOVE.L	(A0)+,(A3)+	;refCon

		ST	(A4)+

		AND.L	Lo3Bytes,D2
		BTST	#0,D2		;Check for odd address.
		BNE.S	D2.NIL
		TST.L	D2
		BEQ.S	D2.NIL
		EXG	D2,A1
		MOVE.L	(A1),D2
		RTS

D2.NIL		MOVEQ	#0,D2
		RTS

TETemplate
		MOVE.L	(A0)+,(A1)+	;destRect
		MOVE.L	(A0)+,(A1)+
		MOVE.L	(A0)+,(A1)+	;viewRect
		MOVE.L	(A0)+,(A1)+
		MOVE.W	teLineHite(A5),(A1)+
		MOVE.W	teNLines(A5),(A1)+
		LEA	teSelPoint(A5),A0
		MOVE.L	(A0)+,(A2)+
		MOVE.L	(A0)+,(A2)+	;selStart, selEnd
		ADDQ	#2,A0		;skip "active"
		MOVE.L	(A0)+,(A2)+	;wordBreak
		MOVE.L	(A0)+,(A2)+	;clikLoop
		MOVE.L	(A0)+,(A3)+	;clickTime
		MOVE.W	(A0)+,(A3)+	;clickLoc
		MOVE.L	(A0)+,(A3)+	;caretTime
		MOVE.W	(A0)+,(A3)+	;caretState

		MOVE.W	(A0)+,D0	;justification
		BEQ.S	@1		;left?
		CMP.W	MinusOne,D0
		BEQ.S	@1		;right?
		CMP.W	#1,D0
		BNE.S	@2		;center?
		MOVE.W	#$FF,D0		;center
		BRA.S	@1
@2		MOVE.W	#$FF00,D0	;INVALID
@1		MOVE.W	D0,(A3)+

		MOVE.W	(A0)+,(A4)+	;length
		MOVE.L	(A0)+,(A4)+	;textH
		MOVE.W	teFont(A5),(A4)+
		LEA	teSize(A5),A0
		MOVE.W	(A0)+,(A4)+
		MOVE.L	(A0)+,(A4)+	;port
		MOVE.L	(A0)+,(A4)+	;hiHook
		MOVE.L	(A0)+,(A4)+	;carHook

		MOVEQ	#-1,D2
		MOVE.L	D2,A0		;A0 is for the name.
		MOVE.L	A5,D2		;do the same one over again
		CLR.B	(A4)+
		RTS

ParamTemplate
		MOVE.L	(A0)+,(A1)+	;qLink
		ADDQ	#2,A0		;skip qType
		MOVE.W	(A0)+,(A1)+	;trap
		MOVE.L	(A0)+,(A1)+	;cmdAddr
		MOVE.L	(A0)+,(A1)+	;completion
		MOVE.W	(A0)+,(A1)+	;ioResult
		ADDQ	#4,A0		;skip namePtr
		MOVE.L	(A0)+,(A2)+	;vRefNum and refNum
		MOVE.W	(A0)+,(A2)+	;version and permission
		MOVE.L	(A0)+,(A2)+	;misc
		MOVE.L	(A0)+,(A2)+	;buffer
		MOVE.L	(A0)+,(A3)+	;reqCount
		MOVE.L	(A0)+,(A3)+	;actCount
		MOVE.W	(A0)+,(A3)+	;mode
		MOVE.L	(A0)+,(A3)+	;offset

		MOVE.L	ioFileName(A5),A0
		MOVE.L	#$FF000000,D2
		ST	(A4)+
		RTS

SHAR_EOF
if test 29950 -ne "`wc -c EUA.Asm.1`"
then
echo shar: error transmitting EUA.Asm.1 '(should have been 29950 characters)'
fi
#	End of shell archive
exit 0
-- 
Darin Adler
{gatech,harvard,ihnp4,seismo}!ut-sally!ut-dillo!darin

darin@ut-dillo.UUCP (Darin Adler) (12/08/85)

Part 2 of the source code for the Extended User Area.

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
-----cut here-----cut here-----cut here-----cut here-----
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	EUA.Asm.2
# This archive created: Sun Dec  8 13:28:04 1985
# By:	Darin Adler ()
echo shar: extracting EUA.Asm.2 '(30904 characters)'
cat << \SHAR_EOF > EUA.Asm.2
FinishTemplate
		CLR.B	(A4)
		MOVE.L	A0,D7		;Check for NIL
		BEQ.S	NameNIL		;go mark it NIL.
		ST	(A4)		;Mark valid, if so.
		MOVE.W	#63,D1		;D1 is max allowable chars-1.
		LEA	Name64,A1
		MOVEQ	#0,D0
		MOVE.B	(A0)+,D0	;Get string length into D0.
@1		SUBQ.W	#1,D0		;Decrement length.
		BMI.S	@2		;Don't stuff a char, stuff a NoOp.
		MOVE.B	(A0)+,(A1)+
		BRA.S	@3
@2		MOVE.B	#NoOp,(A1)+
@3		DBRA	D1,@1		;Do it 64 times
NameNIL
		MOVE.L	D2,A0		;Get the potential next address
		BSR	CheckA0
		BCC.S	@1
		MOVEQ	#-1,D0
		MOVE.L	D0,A0
@1		LEA	FutureTemplate,A1
		MOVE.L	A0,(A1)		;Set up for next time
		RTS

	UAFunc	Template1,Template2
		DC.B	If.Pos
		DC.B	  If.Pos
		DC.B	    ':address=',Skip+1,PrHex+6
		DC.B	    ':rowBytes=',Skip+1,PrHex+2
		DC.B	    ':bounds=',PrHex+4,' ',PrHex+4,' ',PrHex+4,' ',PrHex+4
		DC.B	    ':portRect=',PrHex+4,' ',PrHex+4,' ',PrHex+4,' ',PrHex+4
		DC.B	  If.Else
		DC.B	    ':nextControl=',Skip+1,PrHex+6
		DC.B	    ':owner=',Skip+1,PrHex+6
		DC.B	    ':rect=',PrHex+4,' ',PrHex+4,' ',PrHex+4,' ',PrHex+4
		DC.B	    ':',If.Pos,'in',End.If,'visible'
		DC.B	    ':hilite=',PrHex+2
		DC.B	  End.If
		DC.B	If.Else
		DC.B	  If.Pos
		DC.B	    ':destRect=',PrHex+4,' ',PrHex+4,' ',PrHex+4,' ',PrHex+4
		DC.B	    ':viewRect=',PrHex+4,' ',PrHex+4,' ',PrHex+4,' ',PrHex+4
		DC.B	    ':height=',PrHex+4
		DC.B	    ':lines=',PrHex+4
		DC.B	  If.Else
		DC.B	    ':qLink=',Skip+1,PrHex+6
		DC.B	    ':trap=',PrHex+4
		DC.B	    ':cmdAddr=',Skip+1,PrHex+6
		DC.B	    ':completion=',Skip+1,PrHex+6
		DC.B	    ':result=',PrHex+4
	UAParam	Template1,0
Part1		DC	0
		DCB.B	22,0
	UACode	Template1


	UAFunc	Template2,Template3
		DC.B	If.Pos
		DC.B	  If.Pos
		DC.B	    ':visRgn=',Skip+1,PrHex+6
		DC.B	    ':clipRgn=',Skip+1,PrHex+6
		DC.B	    ':windowKind=',PrHex+4
		DC.B	    ':',If.Pos,'in',End.If,'visible'
		DC.B	    ':',If.Pos,'not ',End.If,'hilited'
		DC.B	    ':',If.Pos,'noG',If.Else,'g',End.If,'oAway'
		DC.B	  If.Else
		DC.B	    ':value=',PrHex+4
		DC.B	    ':min=',PrHex+4
		DC.B	    ':max=',PrHex+4
		DC.B	    ':defProc=',Skip+1,PrHex+6
		DC.B	    ':dataHandle=',Skip+1,PrHex+6
		DC.B	    ':action=',Skip+1,PrHex+6
		DC.B	  End.If
		DC.B	If.Else
		DC.B	  If.Pos
		DC.B	    ':selPoint=',PrHex+4,' ',PrHex+4
		DC.B	    ':selStart=',PrHex+4
		DC.B	    ':selEnd=',PrHex+4
		DC.B	    ':wordBreak=',Skip+1,PrHex+6
		DC.B	    ':clikLoop=',Skip+1,PrHex+6
		DC.B	  If.Else
		DC.B	    ':vRefNum=',PrHex+4
		DC.B	    ':refNum=',PrHex+4
		DC.B	    ':versNum=',PrHex+2
		DC.B	    ':permission=',PrHex+2
		DC.B	    ':misc=',Skip+1,PrHex+6
		DC.B	    ':buffer=',Skip+1,PrHex+6
	UAParam	Template2,0
Part2		DC	0
		DCB.B	18,0
	UACode	Template2


	UAFunc	Template3,Template4
		DC.B	If.Pos
		DC.B	  If.Pos
		DC.B	    ':strucRgn=',Skip+1,PrHex+6
		DC.B	    ':contRgn=',Skip+1,PrHex+6
		DC.B	    ':updateRgn=',Skip+1,PrHex+6
		DC.B	    ':defProc=',Skip+1,PrHex+6
		DC.B	    ':dataHandle=',Skip+1,PrHex+6
		DC.B	  If.Else
		DC.B	    ':refCon=',PrHex+8
		DC.B	  End.If
		DC.B	If.Else
		DC.B	  If.Pos
		DC.B	    ':clickTime=',PrHex+8
		DC.B	    ':clickLoc=',PrHex+4
		DC.B	    ':caretTime=',PrHex+8
		DC.B	    ':caretState=',PrHex+4
		DC.B	    ':',If.Pos
		DC.B	      If.Pos,'left'
		DC.B	      If.Else,'center'
		DC.B	      End.If
		DC.B	    If.Else
		DC.B	      If.Pos,'???'
		DC.B	      If.Else,'right'
		DC.B	      End.If
		DC.B	    End.If,' justify'
		DC.B	  If.Else
		DC.B	    ':reqCount=',PrHex+8
		DC.B	    ':actCount=',PrHex+8
		DC.B	    ':newLineChar=',PrHex+2
		DC.B	    ':posMode=',PrHex+2
		DC.B	    ':offset=',PrHex+8
	UAParam	Template3,0
Part3		DC	0
		DCB.B	20,0
	UACode	Template3


	UAFunc	Template4,ResetMacintosh
		DC.B	If.Pos
		DC.B	  If.Pos
		DC.B	    ':controlList=',Skip+1,PrHex+6
		DC.B	    ':nextWindow=',Skip+1,PrHex+6
		DC.B	    ':refCon=',PrHex+8
		DC.B	    ':'
		DC.B	  If.Else
		DC.B	    ':Control '
		DC.B	  End.If,'title'
		DC.B	If.Else
		DC.B	  If.Pos
		DC.B	    ':length=',PrHex+4
		DC.B	    ':textH=',Skip+1,PrHex+6
		DC.B	    ':font=',PrHex+3
		DC.B	    ':size=',Skip+1,PrHex+2
		DC.B	    ':port=',Skip+1,PrHex+6
		DC.B	    ':hiHook=',Skip+1,PrHex+6
		DC.B	    ':carHook=',Skip+1,PrHex+6
		DC.B	  If.Else
		DC.B	    ':Volume/File name'
		DC.B	  End.If
		DC.B	End.If
		DC.B	If.Neg
		DC.B	  '='
		DC.B	  If.Neg
		DC.B	    '"'
Name64		DCB.B	    64,NoOp		;name can be up to 64 chars
		DC.B	    '"'
		DC.B	  If.Else
		DC.B	    'NIL'
	UAParam	Template4,0
Part4		DC	0
		DCB.B	22,0
		DC	0
	UACode	Template4


	UAFunc	StackLook,StackCrawl
		DC.B	'Stack addresses {'
		DC.B	If.Pos
		DC.B	  PrHex+6
		DC.B	  ' (',Recognize,Skip+1,')'	; ? Recognize bug
		DC.B	If.Else
		DC.B	  Skip+7
		DC.B	End.If
		DC.B	'} (addr)',Colon
		DC.B	If.Pos
		DC.B	  PrHex+6
		DC.B	If.Else
		DC.B	  If.Neg
		DC.B	    'SP'
	UAParam	StackLook,%00011
		LONG	-1
		LONG	-1
		LONG	-1
	UACode	StackLook
		MOVE.L	A0,A4
		TST.B	D7			;Check the number of parameters.
		BNE.S	Look
CancelLook
		MOVEQ	#-1,D0			;If none, cancel things (RA6).
		MOVE.L	D0,(A4)+
		MOVE.L	D0,(A4)+
		MOVE.L	D0,(A4)+
		RTS
Look
		MOVE.L	D0,D1			;Otherwise check validity.
		BSR.S	CheckStackD1.A0
		BCS.S	CancelLook		;Invalid also means cancel.
		ADDQ.L	#2,D0			;Advance D0.
		MOVE.L	(A0),D1
		BSR	CheckD1.A0
		BCS.S	Look			;Keep looking for a valid value.
		CMP.L	ROMBase,A0
		BHS.S	StopLooking
		CMP.L	RealMemTop,A0
		BHS.S	Look			;Keep looking for a valid value.
StopLooking
		MOVE.L	A0,V.A5			;Put the contents in the monitor's V.
		MOVE.L	A0,(A4)
		MOVE.L	A0,4(A4)

		MOVE.L	D0,D1
		BSR	CheckStackD1.A0
		BCS.S	@3

		MOVE.L	A0,8(A4)		;Next SP.
		RTS

@3		MOVE.W	#$FF00,8(A4)		;No SP.
		RTS


CheckStackD1.A0
		BSR.S	CheckD1.A0
		BCS.S	@1
		MOVE.L	CurStackBase,D7		;Get the stack base.
		NEG.L	D7
		ADD.L	A0,D7			;Set the carry if D1>CurStackBase
@1		RTS


CheckD1.A0	;A more thorough check based on CheckA0

		AND.L	Lo3Bytes,D1
		MOVE.L	D1,A0
		BSR	CheckA0
		BCS.S	@1
		ADD.L	#-$500000,D1		;Set the carry if D1>500000
@1		RTS


	UAFunc	StackCrawl,GetResource
		DC.B	'Stack crawl {'
		DC.B	If.Pos
		DC.B	  'PC=',PrHex+6
		DC.B	  ' (',Recognize,Skip+1,')'	; ? Recognize bug
		DC.B	If.Else
		DC.B	  Skip+7
		DC.B	End.If
		DC.B	'} (addr)',Colon
		DC.B	If.Pos
		DC.B	  PrHex+6
		DC.B	If.Else
		DC.B	  If.Neg
		DC.B	    'RA6'
	UAParam	StackCrawl,%00011
		LONG	-1
		LONG	-1
		LONG	-1
	UACode	StackCrawl
		MOVE.L	A0,A4
		TST.B	D7			;Check the number of parameters
		BNE.S	Crawl
CancelCrawl
		MOVEQ	#-1,D0			;If none, cancel things (RA6)
		MOVE.L	D0,(A4)+
		MOVE.L	D0,(A4)+
		MOVE.L	D0,(A4)+
		RTS
Crawl
		MOVE.L	D0,D1			;Otherwise check validity
		BSR.S	CheckD1.A0
		BCS.S	CancelCrawl		;Invalid also means cancel
		MOVE.L	A0,N.A5			;Put the A6 in the monitor's N
		MOVE.L	4(A0),D1
		BSR	CheckD1.A0
		BCC.S	@1
		ST	(A4)			;Invalid PC
		BRA.S	@2

@1		MOVE.L	A0,V.A5			;Put the PC in the monitor's V
		MOVE.L	A0,(A4)
		MOVE.L	A0,4(A4)

@2		MOVE.L	D0,A0			;De-ref that other thing.
		MOVE.L	(A0),D1
		BSR	CheckD1.A0
		BCS.S	@3

		MOVE.L	A0,8(A4)		;Next A6
		RTS

@3		MOVE.W	#$FF00,8(A4)		;No A6
		RTS


	UAFunc	GetResource,ShowScreen
		DC.B	'Load resource {'
		DC.B	If.Pos
		DC.B	  'at ',PrHex+6
		DC.B	If.Else
		DC.B	  Skip+3
		DC.B	End.If
		DC.B	'} (type ID)',Colon
		DC.B	If.Pos
		DC.B	  Skip+1,'''',PrASCII+4,'''',' ',PrHex+4
	UAParam	GetResource,%00101
		LONG	-1
		DC	$FF00
		LONG	0
		DC	0
	UACode	GetResource
		TST.B	D7
		BNE.S	@1
		MOVEQ	#-1,D0
		MOVE.L	D0,(A0)+
		MOVE.B	D0,(A0)+
		RTS
@1		CLR.B	4(A0)
		BSR	ExiTMON.
		LEA	A0.A5,A1		;Save Monitor's A0 through A2.
		MOVE.L	(A1),-(A2)
		MOVE.L	A5,(A1)			;Store A5 in Monitor's A2.
		MOVE.L	-(A1),-(A2)
		MOVE.L	A0,(A1)			;Store a pointer to GetResource's user data area in
		MOVE.L	-(A1),-(A2)		;Monitor's A1.
		LEA	D0.A5,A1
		MOVE.L	(A1),-(A2)		;Save Monitor's D0 through D2.
		MOVE.L	-(A1),-(A2)
		MOVE.L	D1,(A1)			;Store D1 in Monitor's D1.
		MOVE.L	-(A1),-(A2)
		MOVE.L	D0,(A1)			;Store D0 in Monitor's D0.
		LEA	LoadRes.,A0
		BRA	ExiTMON
LoadRes.
		MOVE.L	D0,6(A1)		;Save the data given to this routine.
		MOVE.W	D1,10(A1)
		CLR.L	-(SP)			;Prepare to call _GetResource.
		MOVE.L	D0,-(SP)
		MOVE.W	D1,-(SP)
		MOVE.W	ResErr,D2		;Save the current resource manager error.
		_GetResource			;Load the resource.
		MOVE.W	D2,ResErr
		ST	(A1)			;Assume that an error occurred.
		MOVE.L	(SP)+,A0
		MOVE.L	A0,D0			;If the handle is NIL, exit.
		BEQ.S	@1
		MOVE.L	(A0),D0			;If it isn't NIL, give the dereferenced handle.
		MOVE.L	D0,(A1)
		CLR.B	(A1)
		MOVE.L	(A1),V.A2		;Also store the position in V.
@1		MOVEM.L	(SP)+,D0/D1/D2/A0/A1/A2
		TRAPMon	'OK'


	UAFunc	ShowScreen,ResetMacintosh
		DC.B	'Click mouse outside TMON'
	UAParam	ShowScreen,%00001
	UACode	ShowScreen
		BSR.S	ExiTMON.		;Prepare to exit the Monitor.
		LEA	ShowScreen.,A0
		BRA.S	ExiTMON
ShowScreen.
		TST.B	MBState			;Wait until the mouse button is released.
		BPL.S	ShowScreen.
@1		TST.B	MBState			;Wait until it is pressed again.
		BMI.S	@1
		TRAPMon	'OK'			;Go back to the Monitor.


ExiTMON
		MOVE.L	A2,SP.A5
		MOVE.L	A0,-(A3)
		JMP	_ExiTMON

ExiTMON.
		MOVE.L	SP.A5,A2		;Prepare the PC and SR to exit the Monitor.
		LEA	PC.A5,A3
		MOVE.L	(A3)+,-(A2)
		MOVE.W	(A3),-(A2)
		MOVE.W	#$2000,(A3)
		RTS


	UAFunc	ResetMacintosh,0
		DC.B	If.Pos
		DC.B	  'Finder'
		DC.B	If.Else
		DC.B	  'Shut down'
		DC.B	End.If
		DC.B	' (confirm)'
	UAParam	ResetMacintosh,%00011
		DC.B	0
	UACode	ResetMacintosh
		TST.B	D7			;If just a RETURN was pressed, toggle
		BNE.S	@1
		NOT.B	(A0)
		RTS
@1		TST.B	(A0)
		BPL.S	Finder


ShutDown
		SUB.W	#ioQElSize,SP		;Eject disks in both drives and reset.
		MOVE.L	SP,A0
		CLR.L	ioVNPtr(A0)
		MOVE.L	VCBQHdr+qHead,A1	;Get the first Drive Queue entry
@2		MOVE.L	A1,D0
		BEQ.S	@1
		MOVE.W	VCBVRefNum(A1),ioVRefNum(A0)
		_Eject				;Eject a volume
		_UnmountVol
		MOVE.L	qLink(A1),A1		;Advance along queue
		BRA.S	@2
@1		MOVE.L	ROMBase,A0		;Get the restart address
		ADD	#10,A0			;from the ROM.
		JMP	(A0)


Finder
		BSR	ExiTMON.		;Prepare to exit the Monitor.
		LEA	Finder.,A0
		BRA	ExiTMON


Finder.
		MOVE.L	CurrentA5,A5		;Set up globals
		MOVE.L	CurStackBase,SP

CloseResFiles
		MOVE.L	TopMapHndl,A0		;Check if we are done yet
		CMP.L	SysMapHndl,A0
		BEQ.S	CloseOtherFiles

		MOVE.L	(A0),A0			;Deref the map pointer
		MOVE.W	resFileID(A0),-(SP)	;And get the file ID to close it
		_CloseResFile			;Close resource files
		BRA.S	CloseResFiles

CloseOtherFiles
		MOVE.W	FSFCBLen,D3		;Get the FCB length in D3
		BPL.S	NotMFS
		MOVE.W	#30,D3			;MFS FCB length is 30
NotMFS
		SUB.W	#ioQElSize,SP		;Close non-resource files
		MOVE.L	SP,A0
		MOVE.L	FCBSPtr,A1		;Point to FCBs
		MOVE.W	(A1),D2			;Get size of FCBs
		MOVEQ	#2,D1			;Start with the first file
CheckFile
		CMP.W	D2,D1
		BHS.S	DidAllFiles
		CMP.W	SysMap,D1		;Do NOT close the System resource file
		BEQ	NextFile
		TST.L	fcbFlNm(A1,D1.W)	;Check if the file is used
		BEQ.S	NextFile
		MOVE.W	D1,ioRefNum(A0)		;Close the file
		_Close
NextFile
		ADD.W	D3,D1			;Advance to another FCB
		BRA.S	CheckFile

DidAllFiles
		_ExitToShell


;The 2nd user area screen starts here (label, A000 trap and heap)


	UAFunc	LabelTableSet,LAddRemove
		DC.B	'Label table {'
		DC.B	If.Pos
		DC.B	  Skip+1,PrHex+3,' labels} (nLabels [loc])',Colon
		DC.B	  Skip+2,PrHex+3,' ',Skip+1,PrHex+6
		DC.B	If.Else
		DC.B	  '} (nLabels [loc])'
	UAParam	LabelTableSet,%00111
		DC	$FF00
NumLabels	DC	0
LabelEnabled	DC	$FF00
LabelCapacity	DC	0
LabelTable	LONG	0
		DC	0
	UACode	LabelTableSet
		MOVE.L	D1,D2			;Shift the parameters by one and fall into RecordTableSet.
		MOVE.L	D0,D1
		MOVEQ	#0,D0
		ADDQ.B	#1,D7
		BSR	RecordTableSet		;Use the RecordTableSet routine to do most of the work.
		LEA	LabelEnabled,A0
		MOVE.W	(A0),-4(A0)
		RTS


	UAFunc	LAddRemove,LabelLoad
		DC.B	'Label add/remove {'
		DC.B	If.Pos
		DC.B	  Skip+1,'"',PrASCII+8,'"',' '
		DC.B	  If.Neg
		DC.B	    'removed'
		DC.B	  If.Else
		DC.B	    'added '
		DC.B	    If.Neg
		DC.B	      'rel ''',PrASCII+4,''''
		DC.B	    End.If
		DC.B	  End.If
		DC.B	End.If
		DC.B	'} (lbl [adr [end]])'
	UAParam	LAddRemove,$80+%11101	;$80 means the first 2 are a label
		DC	$FF00
		LONG	0
		LONG	0
		DC	0
		LONG	0
	UACode	LAddRemove
		AND.L	Lo3Bytes,D2		;Clear the high bytes of the addresses.
		AND.L	Lo3Bytes,D3
LAddRemove.Map
		MOVE.L	D7,D6			;If bit 31 of D7 is set, no checks are made.
		MOVE.L	A0,A3			;Save A0.
		CLR.W	(A3)+			;Initialize results.
		MOVE.L	D0,(A3)+
		MOVE.L	D1,(A3)+
		TST.W	D6			;If no parameters, do nothing.
		BEQ.S	@10
		MOVE.B	LabelEnabled,D7		;If there is no table of labels, do nothing.
		BMI.S	@10
		MOVE.B	_Inhibits,D7		;Get the value of _Inhibits.
		SWAP	D7
		MOVE.L	D2,D4			;Save D2 and D3.
		MOVE.L	D3,D5
		MOVEQ	#-1,D2
		BSR	LabelFind.		;Is the label present in the table?
		TST.L	D0
		BNE.S	@2			;NO.
		MOVE.L	A0,D0			;YES.  Is it in the user area table?
		BEQ.S	@10			;YES.
		SUBQ.W	#2,D6			;NO.  Should it be removed?
		BNE.S	@3			;NO.  Change its value.
		LEA	NumLabels,A1		;YES.  Remove it.
		SUBQ.W	#1,(A1)
		MOVEQ	#0,D0			;Call _BlockMove to shift the remaining labels
		MOVE.W	(A1),D0			;forward.
		ASL.W	#4,D0
		MOVE.L	A0,A1
		ADD.W	#16,A0
		ADD.L	LabelTable,D0
		MOVE.L	D0,A2
		SUB.L	A1,D0
		BEQ.S	@1
		_BlockMove
@1		CLR.L	(A2)+			;Clear the last label.
		CLR.L	(A2)+
		CLR.L	(A2)+
		CLR.L	(A2)+
		ST	(A3)			;Tell the user that the label was removed.
		RTS
@10		ST	-10(A3)			;Return an error.
		RTS
@2		SUBQ.W	#2,D6			;If the label was not found, and no more parameters
		BEQ.S	@10			;were given, return an error.
		LEA	NumLabels,A0		;If can't insert another label because the table is
		MOVE.W	(A0),D2			;full, return an error.
		CMP.W	LabelCapacity,D2
		BCC.S	@10
		ADDQ.W	#1,(A0)
		MOVE.L	LabelTable,A0
		ASL.W	#4,D2
		ADD.W	D2,A0
@3		MOVE.L	A0,-(SP)		;Save the location to contain the next label.
		LEA	_Inhibits,A0
		MOVE.B	(A0),-(SP)		;Set all _Inhibits flags except searching resources
		ORI.B	#%00110100,(A0)		;and the master switch.
		SUB.W	#24,SP			;Allocate space for _Recognize's information.
		MOVE.L	SP,A2
		ADDQ.W	#1,A2			;Put the data on a word boundary for easier access.
		MOVEM.L	D4/A0,-(SP)
		MOVE.L	D4,D2
		MOVEQ	#-1,D0			;If there is a third parameter, assume that
		SUBQ.W	#1,D6			;_Recognize failed.
		BNE.S	@4
		JSR	_Recognize		;Check if the address given in D4 was in a resource.
@4		MOVEM.L	(SP)+,D4/A0
		CLR.W	(A3)
		TST.B	D0
		BNE.S	@11			;NO.
		ADDQ.W	#2,SP			;YES.  Extract the resource type, ID, and internal
		MOVE.L	(SP)+,D4		;offset.
		ST	1(A3)
		MOVE.L	D4,2(A3)
		BSR.S	@20
		MOVE.W	D0,D5
		SWAP	D5
		ADDQ.W	#6,SP
		BSR.S	@20
		SUB.W	#12,SP
		MOVE.W	D0,D5
		BRA.S	@13
@11		TST.L	D6			;If bit 31 of D6 was set, do no checks.
		BMI.S	@13
		TST.W	D6			;Calculate the ending address from the starting one
		BNE.S	@12			;unless the ending address is already given.
		MOVE.L	D4,D5
		ADD.L	#$800,D5		;Default is $800+starting address.
@12		CMP.L	D4,D5			;Ending address must be greater than the starting
		BHI.S	@13			;address.
		MOVE.L	D4,D5
		ADDQ.L	#1,D5
@13		ADD.W	#24,SP			;Deallocate the stack space.
		MOVE.B	(SP)+,(A0)		;Restore _Inhibits.
		MOVE.L	(SP)+,A0		;Get the address into which the label is to be
		MOVE.L	D4,(A0)+		;stored.
		MOVE.L	D5,(A0)+		;Store the label data.
		MOVE.L	-8(A3),(A0)+
		MOVE.L	-(A3),(A0)+
		RTS

@20		MOVEQ	#3,D2			;Extract a word from a four-digit hexadecimal
		LEA	4(SP),A1		;number on the stack.
@21		MOVE.B	(A1)+,D1
		SUB.B	#'0',D1
		CMP.B	#10,D1
		BCS.S	@22
		SUBQ.B	#7,D1
@22		ASL.W	#4,D0			;Store the result in D0.
		ADD.B	D1,D0
		DBRA	D2,@21
LabelLoadRTS	RTS


	UAFunc	LabelLoad,TrapRecord
		DC.B	'Label file load'
	UAParam	LabelLoad,%00001
	UACode	LabelLoad
		MOVE.B	LabelEnabled,D0		;If there is no table of labels, do nothing.
		BMI.S	LabelLoadRTS
		BSR	ExiTMON.		;Prepare to exit the Monitor.
		LEA	LabelLoad.,A0
		BRA	ExiTMON


;
;This subroutine is used to load label maps into memory.
;
LabelLoad.

A6TypeList	EQU	-4
A6Reply		EQU	A6TypeList-64-rName
A6IO		EQU	A6Reply-ioQElSize
A6Size		EQU	A6IO

typeList	EQU	A6TypeList(A6)		;Type list for _SFGetFile.
reply		EQU	A6Reply(A6)		;Reply record from _SFGetFile.
param		EQU	A6IO(A6)		;File I/O queue element.

sfGood		EQU	A6Reply+rGood(A6)
sfType		EQU	A6Reply+rType(A6)
sfVolume	EQU	A6Reply+rVolume(A6)
sfVersion	EQU	A6Reply+rVersion(A6)
sfName		EQU	A6Reply+rName(A6)

scratch64	EQU	reply			;At least 64 bytes will be here.

		MOVEM.L	D0-D7/A0-A5,-(SP)	;Save registers.
		MOVE.L	CurrentA5,A5		;Get A5 for QuickDraw.
		LINK	A6,#A6Size
		MOVE.L	#'TEXT',typeList
		MOVE.L	#$00440052,-(SP)	;where = (82,68).
		CLR.L	-(SP)			;Prompt parameter - not used.
		CLR.L	-(SP)			;No fileFilter.
		MOVE.W	#1,-(SP)		;One type.
		PEA	typeList		;Type list.
		CLR.L	-(SP)			;No dlgHook.
		PEA	reply			;reply record.
		_SFGetFile
		LEA	A5.TMON,A5		;Get the Monitor's A5.
		TST.B	sfGood			;Was cancel pressed?
		BEQ.S	@20			;YES.  Do nothing.
		LEA	param,A0
		LEA	sfName,A1		;Prepare the parameter block for _Open.
		MOVE.L	A1,ioFileName(A0)
		MOVE.W	sfVolume,ioVRefNum(A0)
		MOVE.W	#1,ioFileType(A0)	;Clear ioFileType and set ioPermssn to read.
		CLR.L	ioOwnBuf(A0)		;No special file buffer.
		_Open				;Open the text file.
		BNE.S	@20			;If errors, do nothing.
		MOVEQ	#0,D6			;Get the next identifier.
		BRA.S	@2
@1		ADDQ.W	#8,SP
@2		MOVE.L	#'    ',-(SP)		;Initially clear all eight characters to spaces.
		MOVE.L	(SP),-(SP)
		MOVEQ	#0,D3
@3		BSR	@40			;Get the next character.
		BEQ.S	@1			;If this is not a normal legal ASCII character,
		CMP.B	#'=',D0			;restart.
		BEQ.S	@4			;If this is the equal sign, proceed.
		CMP.B	#8,D3			;Put this character onto the string, but keep only
		BCC.S	@3			;the first eight characters found.
		MOVE.B	D0,0(SP,D3.W)
		ADDQ.W	#1,D3
		BRA.S	@3

@20		UNLK	A6
		MOVEM.L	(SP)+,D0-D7/A0-A5	;Exit with an error.
		TRAPMon	'Bad load'

@4		TST.W	D3			;If the identifier was null, try again.
		BEQ.S	@1
		MOVEM.L	(SP)+,D2/D3
		BSR.S	@60			;Get a decimal number (the segment number).
		BCS.S	@2			;If error, try again.
		CMP.B	#':',D0			;The next character must be a colon.
		BNE.S	@2
		MOVE.W	D1,D4			;Save the segment number in D4.
		BSR.S	@30			;Get the offset.
		BCS.S	@2
		AND.L	Lo3Bytes,D1		;Clear the high byte of the address.
		MOVEM.L	D5-D7/A2-A4/A6,-(SP)	;Save registers for LAddRemove.
		MOVE.L	D2,D0
		EXG	D1,D3
		TST.W	D4			;If the segment number was zero, create an absolute
		BNE.S	@10			;reference.
		MOVE.L	D3,D2
		ADD.L	#$800,D3		;Let the ending address equal the starting address
		BRA.S	@11			;plus $800.
@10		MOVE.L	#'CODE',D2		;If the segment number was not zero, create a
		SWAP	D3			;'CODE' resource-relative reference.
		MOVE.W	D4,D3
		SWAP	D3
		ADDQ.W	#4,D3			;Skip the four bytes at the segment beginning.
@11		MOVEQ	#9,D7			;Set bit 31 of D7.
		ROR.L	#1,D7
		LEA	scratch64,A3		;Provide a scratch area for LAddRemove.
		BSR	LAddRemove.Map		;Add the label.  There is no error checking.
		MOVEM.L	(SP)+,D5-D7/A2-A4/A6
		BRA	@2

@30		MOVEQ	#0,D5			;Attempt to get a hexadecimal number.  D5 is zero
		MOVEQ	#0,D1			;when there are no digits.  D1 has the number.
@31		BSR.S	@40			;Get the next character and make it into a number.
		MOVE.B	D0,D7			;D7 is destroyed.
		SUB.B	#'0',D7
		BCS.S	@32
		CMP.B	#10,D7
		BCS.S	@33
		CMP.B	#17,D7
		BCS.S	@32
		SUBQ.B	#7,D7
		CMP.B	#$10,D7
		BCC.S	@32
@33		LSL.L	#4,D1			;If successful, append it to the number.  There is
		ADD.B	D7,D1			;no overflow checking.
		MOVEQ	#1,D5
		BRA.S	@31
@32		SUBQ.B	#1,D5			;Set the carry if no digits were found.
		RTS

@60		MOVEQ	#0,D5			;Attempt to get a decimal number.  D5 is zero
		MOVEQ	#0,D1			;when there are no digits.  D1 has the number.
@61		BSR.S	@40			;Get the next character and make it into a number.
		MOVE.B	D0,D7			;D7 is destroyed.
		SUB.B	#'0',D7
		BCS.S	@62
		CMP.B	#10,D7
		BCC.S	@62
@63		MOVEQ	#0,D0			;Make a number in D0.
		MOVE.B	D7,D0
		LSL.L	#1,D1			;If successful, append it to the number.  There is
		ADD.L	D1,D0			;no overflow checking.
		LSL.L	#2,D1
		ADD.L	D0,D1
		MOVEQ	#1,D5
		BRA.S	@61
@62		SUBQ.B	#1,D5			;Set the carry if no digits were found.
		RTS

@40		TST.B	D6			;If the end of file was encountered, go exit now.
		BNE.S	@50
		LEA	param,A0
		LEA	-1(A6),A1
		MOVE.L	A1,ioBuffer(A0)
		MOVEQ	#1,D0
		MOVE.L	D0,ioReqCount(A0)	;Request a read of one byte.
		CLR.W	ioPosMode(A0)		;Read from the mark.
		_Read
		BMI.S	@41			;If error, pass back a zero and exit on the next
		MOVE.B	-1(A6),D0		;call to @40 (to finish a number if necessary).
		CMP.B	#' ',D0
		BEQ.S	@40			;Ignore spaces.
		BCS.S	@42
		CMP.B	#$7F,D0			;Convert characters below $20 and above $7E to 0.
		BCS.S	@43
		BRA.S	@42
@41		MOVEQ	#1,D6			;Set the end of file flag.
@42		MOVEQ	#0,D0
@43		TST.B	D0
		RTS

@50		_Close				;Close the file.
		UNLK	A6
		MOVEM.L	(SP)+,D0-D7/A0-A5	;Exit with no error.

		TRAPMon	'OK'


	UAFunc	TrapRecord,RecordTableSet
		DC.B	'Trap record (t0 [t1 [PC0 PC1]])',Colon
		DC.B	If.Pos
		DC.B	  Skip+1,DisAsm0,' ',DisAsm0
		DC.B	  If.Pos
		DC.B	    '  ',PrHex+6,' ',Skip+1,PrHex+6
	UAParam	TrapRecord,%10111
TrapRList	DC	$FF00
		DC	0,0
		LONG	-1
		LONG	-1
		ADDR	RecordHook
	UACode	TrapRecord
		BRA	A000


	UAFunc	RecordTableSet,TrapScramble
		DC.B	'Record {'
		DC.B	If.Neg
		DC.B	  Skip+1,PrHex+4,' new traps'
		DC.B	If.Else
		DC.B	  Skip+3
		DC.B	End.If
		DC.B	'} (fullStop nMsg [loc])',Colon
		DC.B	If.Pos
		DC.B	  PrHex+1,' ',PrHex+3,' ',Skip+1,PrHex+6
	UAParam	RecordTableSet,%01101
		DC	0
RecordData	DC	0
		DC	$FF00
		DC	0
		LONG	0
		DC	0
		DC	0
	UACode	RecordTableSet
		ADDQ	#2,A0
		MOVE.L	A0,A2
		CLR.W	(A2)+			;Always set the number of new traps to zero.
		TST.B	8(A2)			;If a block was previously allocated, deallocate it
		BEQ.S	@1			;now.
		MOVE.L	4(A2),A0
		MOVE.L	D0,-(SP)
		_DisposPtr
		MOVE.L	(SP)+,D0
		CLR.B	8(A2)			;Don't deallocate it again.
@1		MOVE.L	A2,A1
		CMP.B	#2,D7			;If not enough parameters present, exit.
		BCS.S	@10
		AND.W	#$7FF,D1		;Can't have a zero-message storage area.
		BEQ.S	@10
		CLR.B	(A1)+			;Set the recording master switch.
		TST.L	D0
		SNE	(A1)			;Initialize the overflow flag.
		NEG.B	(A1)+
		MOVE.W	D1,(A1)+		;If data given, store it.
		MOVEQ	#0,D0
		MOVE.W	D1,D0
		ASL.W	#4,D0
		SUBQ.W	#3,D7			;If address given, done.
		BEQ.S	@6			;Otherwise, allocate a block of the appropriate size
		_NewPtr,Sys+Clear		;in the system Heap.
		BNE.S	@10			;If error, turn off the master switch.
		ST	4(A1)			;Set the heap block allocated flag.
@9		MOVE.L	A0,(A1)			;Store the address of the block.
		MOVE.L	A0,V.A5			;Store it also in the V variable.
		RTS
@6		MOVE.L	D2,A0
		MOVE.L	A0,A3			;Clear the block if it was manually allocated.
		LSR.W	#2,D0
		BRA.S	@8
@7		CLR.L	(A3)+
@8		DBRA	D0,@7
		BRA.S	@9

@10		ST	(A2)			;Clear the master switch.
		RTS


RecordEnter
		LEA	RecordData+2,A0		;Prepare to use the swapping routine to move the
		MOVE.W	(A0)+,D0		;latest traps to the beginning.
		BMI.S	@1
		MOVEQ	#0,D1			;Otherwise use SlowScramble to shift the message table
		MOVE.W	(A0)+,D1		;so that the latest message is at the top.
		ASL.W	#4,D1			;D1 now contains the size of the table.
		MOVE.L	(A0)+,A5		;A5 contains its beginning.
		MOVEQ	#0,D4
		MOVE.W	2(A0),D4		;D4 contains the offset to the current storing
		BEQ.S	@1			;position in the table.
		ASL.W	#4,D4
		SUB.L	D4,D1			;D1 now contains the offset from D4 to the end.
		MOVE.L	A5,A4
		ADD.L	D4,A4			;A4 now points to the current storing position.
		BSR	SlowScramble		;Use the routine from ScrambleHeap to expedite shifting.
@1
		LEA	RecordData,A0		;Check if there were any?
		TST.W	(A0)
		SNE	-2(A0)
		RTS

RecordExit
		LEA	RecordData,A0		;Clear the number of messages every time exiting
		CLR.W	(A0)			;the Monitor.
		CLR.W	12(A0)
		RTS


	UAFunc	TrapScramble,HeapInfo
		DC.B	'Trap {heap check'
		DC.B	If.Neg
		DC.B	  ', scramble'
		DC.B	End.If
		DC.B	If.Neg
		DC.B	  ', purge'
		DC.B	End.If
		DC.B	'} (zone#)',Colon
		DC.B	If.Pos,PrHex+1
	UAParam	TrapScramble,%00011
CheckOnly	DC.B	$FF
PurgeAlso	DC.B	0
TrapSList	DC.B	$80
CurrentHeap	DC.B	0
		DC	$1E,$27			;_NewPtr _ReallocHandle
		LONG	-1
		LONG	-1
		ADDR	ScrambleHook
	UACode	TrapScramble
		TST.B	D7			;If no number was given, go to the second part.
		BEQ.S	@2
		TST.L	D0			;Choose the heap and enable the scramble.
		BEQ.S	@1
		MOVEQ	#1,D0
@1		MOVE.W	#.ScrambleNow-A,.TrapScramble-A(A2)
		CLR.B	ScrambleNowErr-A(A2)
		ST	HeapInfoDisp-A(A2)
		CLR.B	HeapInfoHeap-A(A2)
		MOVE.W	D0,2(A0)
		BRA.S	@3
@2		MOVE.W	#.HeapInfo-A,.TrapScramble-A(A2)
		BSET	#7,2(A0)		;If the ScrambleHeap is enabled, disable it.
		BEQ.S	@3			;Otherwise,
		NOT.B	1(A0)			;allow the user to pick a combination of two flags.
		BMI.S	@3
		NOT.B	(A0)			;Flip the heap flag.
@3		MOVE.W	(A0),CheckOnly.-A(A2)	;Notify the ScrambleNow function.
		BRA	A000OnOff		;Check the master A000 intercept switch.


	UAFunc	HeapInfo,TrapDiscipline
		DC.B	'Heap {'
		DC.B	If.Pos
		DC.B	  'free=',PrHex+6
		DC.B	  Skip+1,' max=',PrHex+6
		DC.B	  Skip+1,' grow=',PrHex+6
		DC.B	If.Else
		DC.B	  Skip+3,Skip+4,Skip+4
		DC.B	End.If
		DC.B	'} (zone#)',Colon
		DC.B	If.Neg
		DC.B	  PrHex+1
	UAParam	HeapInfo,%00011
HeapInfoDisp	LONG	-1
		LONG	-1
		LONG	-1
HeapInfoHeap	DC	0
	UACode	HeapInfo
		TST.B	D7
		BNE.S	@10
		ST	(A0)
		CLR.B	12(A0)
		RTS
@10		MOVE.L	A0,A4			;Save a pointer to the variables.
		ADD.W	#12,A0
		ST	(A0)+
		TST.L	D0
		SNE	(A0)			;Store the given heap zone.
		NEG.B	(A0)
		BSR	GetZone			;Get the appriopriate heap zone.
		BSR	PurgeHeap		;Get the maximum possible block size.
		MOVE.L	12(A6),(A4)+		;Get the theoretical number of free bytes.
		MOVE.L	D0,(A4)+		;Get the maximum allowable block size.
		MOVE.L	A0,D0
		BEQ.S	@2			;If this isn't the application heap zone, exit.
		MOVE.L	SP.A5,D0		;Get the SP.
		AND.L	Lo3Bytes,D0
		SUB.L	MinStack,D0		;Pick either the application limit or SP-minimum
		CMP.L	ApplLimit,D0		;stack size, whichever is less.
		BCS.S	@1
		MOVE.L	ApplLimit,D0
@1		SUB.L	HeapEnd,D0		;Subtract the end of heap from that.
@2		MOVE.L	D0,(A4)+		;Get the maximum grow area.
		RTS


	UAFunc	ScrambleNow,TrapDiscipline
		DC.B	'Check'
		DC.B	If.Neg
		DC.B	  ', scramble'
		DC.B	End.If
		DC.B	If.Neg
		DC.B	  ', purge'
		DC.B	End.If
		DC.B	' now {'
		DC.B	If.Neg
		DC.B	  'heap error'
		DC.B	End.If
		DC.B	'}'
	UAParam	ScrambleNow,%00001
CheckOnly.	DC.B	$FF
PurgeAlso.	DC.B	$00
ScrambleNowErr	DC.B	0			;Was there an error?
	UACode	ScrambleNow
		BSR	ScrambleHeap
		LEA	ScrambleNowErr,A0
		TST.L	D0
		SNE	(A0)			;Set if there is an error.
		RTS


	UAFunc	TrapDiscipline,TrapChecksum
		DC.B	'Trap discipline (t0 [t1 [PC0 PC1]])',Colon
		DC.B	If.Pos
		DC.B	  Skip+1,DisAsm0,' ',DisAsm0
		DC.B	  If.Pos
		DC.B	    '  ',PrHex+6,' ',Skip+1,PrHex+6
	UAParam	TrapDiscipline,%10111
TrapDList	DC	$FF00
		DC	0,0
		LONG	-1
		LONG	-1
		ADDR	DisciplineHook
	UACode	TrapDiscipline
		BRA	A000


	UAFunc	TrapChecksum,Checksum
		DC.B	'Trap checksum (t0 [t1 [PC0 PC1]])',Colon
		DC.B	If.Pos
		DC.B	  Skip+1,DisAsm0,' ',DisAsm0
		DC.B	  If.Pos
		DC.B	    '  ',PrHex+6,' ',Skip+1,PrHex+6
	UAParam	TrapChecksum,%10111
TrapCList	DC	$FF00
		DC	0,0
		LONG	-1
		LONG	-1
		ADDR	ChecksumHook
	UACode	TrapChecksum
		BRA	A000


	UAFunc	Checksum,TrapIntercept
		DC.B	'Checksum (bgn end) {',PrHex+4,'}',Colon
		DC.B	Skip+1,PrHex+6,' ',Skip+1,PrHex+6
	UAParam	Checksum,%00100
ChecksumValue	DC	0
		LONG	$400000
		LONG	$40FFFF
	UACode	Checksum
		AND.L	Lo3Bytes,D0
		AND.L	Lo3Bytes,D1
		MOVEM.L	D0/D1,2(A0)		;Save the addresses.
		BSR.S	Checker			;Calculate the checksum.
		MOVE.W	D2,(A0)			;Store the checksum.
		RTS

Checker
		SUB.L	D0,D1			;End must not be less than start.
		BLT.S	@2
		MOVE.L	D0,A1
@1		ADD.B	(A1)+,D2		;Add another byte and shift.
		ROR.W	#1,D2
		DBRA	D1,@1
		SUB.L	val10000,D1		;This is the outer checksum loop.
		BCC.S	@1
@2		RTS

ChecksumInit
		LEA	ChecksumValue,A0
		MOVEM.L	2(A0),D0/D1
		BSR.S	Checker
		MOVE.W	D2,(A0)
		RTS


	UAFunc	TrapIntercept,TrapSignal
		DC.B	'Trap intercept (t0 [t1 [PC0 PC1]])',Colon
		DC.B	If.Pos
		DC.B	  Skip+1,DisAsm0,' ',DisAsm0
		DC.B	  If.Pos
		DC.B	    '  ',PrHex+6,' ',Skip+1,PrHex+6
	UAParam	TrapIntercept,%10111
TrapIList	DC	$FF00
		DC	0,0
		LONG	-1
		LONG	-1
		ADDR	InterceptHook
	UACode	TrapIntercept
		BRA	A000


	UAFunc	TrapSignal,0
		DC.B	'Trap signal (t0 [t1 [PC0 PC1]])',Colon
		DC.B	If.Pos
		DC.B	  Skip+1,DisAsm0,' ',DisAsm0
		DC.B	  If.Pos
		DC.B	    '  ',PrHex+6,' ',Skip+1,PrHex+6
	UAParam	TrapSignal,%10111
TrapGList	DC	0
		DC	$170,$171		;_GetNextEvent,_EventAvail
		LONG	-1
		LONG	-1
		ADDR	SignalHook
	UACode	TrapSignal
		BRA	A000


		;####################################
		;##                                ##
		;##  A000 hook controller section  ##
		;##                                ##
		;####################################

;
;This routine is an "A000 hook controller" of the user area.  It examines the parameter lists TrapDList,
;TrapSList, TrapCList, TrapIList, TrapRList, and TrapGList and checks if they contain routines that
;should be executed.  If so, the routine is called (the routine's address is contained in the last
;word of its parameter list).  If the routine does not detect any errors, it should return 0 in
;D0.W; otherwise, it should return an offset into the user area, which will be called to display the
;error message while returning to the Monitor.
;
;The routines called must preserve all registers except D0, D1, A0, and A1.  They may use A000 traps
;without fear of reentrancy problems, as the Monitor's A000 hook is disabled for the duration of
;their execution.  The interrupt button is also disabled, and the interrupt level is set to 7.
;
;Upon entry D0.W contains the trap word stripped to the 9 least significant bits and A0 contains
;the address of the trap word.
;
;Beware:  Any 68000 exceptions like address errors or illegal instructions will have the same
;effect as pressing command-interrupt because the Monitor will think that the error occurred in
;its code.
;

A000Hook	MOVEM.L	D0/D1/A0/A1,-(SP)	;Save 4 registers.
		MOVE.L	10+4*4(SP),D0		;Get the A000 trap address.
		AND.L	Lo3Bytes,D0		;Clear the high PC byte.
		MOVE.L	D0,A0
		MOVE.W	(A0),D0
		AND.W	#$09FF,D0		;Get the trap number into D0.
		BCLR	#11,D0
		BNE.S	@1
		AND.W	#$00FF,D0		;Clear the eighth bit for OS traps.

@1		LEA	TrapRList,A1		;Check the five routines that have A000 hooks if
		BSR.S	@10			;they want to be executed.
		LEA	TrapSList,A1
		BSR.S	@10
		LEA	TrapDList,A1
		BSR.S	@10
		LEA	TrapCList,A1
		BSR.S	@10
		LEA	TrapIList,A1
		BSR.S	@10
		LEA	TrapGList,A1
		BSR.S	@10
		MOVEM.L	(SP)+,D0/D1/A0/A1	;If everything is fine, exit.
@2		RTS

@10		TST.W	(A1)+
		BMI.S	@2
		CMP.W	(A1)+,D0		;Is it in the specified range?
		BCS.S	@2
		CMP.W	(A1)+,D0
		BHI.S	@2
		TST.B	(A1)			;YES.  Was a PC range specified?
		BMI.S	@11			;If not, do the function.
		CMP.L	(A1),A0			;YES.  Is the PC in the specified range?
		BCS.S	@2
		CMP.L	4(A1),A0
		BHI.S	@2
@11		MOVEM.L	D0/A0,-(SP)		;If everything was successful, call the subroutine.
		BSR.S	FlipBit
		MOVE.W	8(A1),D1
		LEA	MonExecuting,A1		;Find the address of MonExecuting.
		MOVE.B	(A1),-(SP)		;To avoid re-entering make the Monitor think that
		MOVE.B	#$6B,(A1)		;it is executing.
		LEA	A,A1
		JSR	0(A1,D1.W)
		LEA	MonExecuting,A1		;Find the address of MonExecuting.
		MOVE.B	(SP)+,(A1)
		BSR.S	FlipBit
SHAR_EOF
if test 30904 -ne "`wc -c EUA.Asm.2`"
then
echo shar: error transmitting EUA.Asm.2 '(should have been 30904 characters)'
fi
#	End of shell archive
exit 0
-- 
Darin Adler
{gatech,harvard,ihnp4,seismo}!ut-sally!ut-dillo!darin

darin@ut-dillo.UUCP (Darin Adler) (12/08/85)

Part 3 of the source code for the Extended User Area.

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
-----cut here-----cut here-----cut here-----cut here-----
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	EUA.Asm.3
# This archive created: Sun Dec  8 13:28:11 1985
# By:	Darin Adler ()
echo shar: extracting EUA.Asm.3 '(29699 characters)'
cat << \SHAR_EOF > EUA.Asm.3
		TST.W	D0			;Check the return code.
		BNE.S	@12			;If nonzero, show an error.
		MOVE	#@13-A,D0
		MOVE.B	UserInform,D1		;Check UserInform.
		BMI.S	@12			;If an interrupt took place, fall into the Monitor.
		MOVEM.L	(SP)+,D0/A0		;Otherwise exit.
		MOVE.L	nasty0,0		;Trash location zero.
		RTS
@13		TRAPMon	'Interrupt'

@12		ADD.W	#12,SP			;Dispose the return address and D0, D1, and A1.
		MOVE.L	4+4*4(SP),4*4(SP)
		LEA	A,A0
		LEA	(A0,D0.W),A0		;Fall into the Monitor with the appropriate message.
		MOVE.L	A0,4+4*4(SP)
		MOVEM.L	(SP)+,D0/D1/A0/A1/A5
		RTS				;Jump to the appropriate TRAP #$F instruction.


;This routine flips a bit in the upper left corner.

FlipBit
		MOVE.B	#1,CrsrBusy		;Mark the cursor busy.

		CMP.W	#$A700,CrsrAddr+2	;Is the cursor in the upper left?
		BNE.S	NoCursorFlip
CursorFlip
		BCHG	#7,CrsrSave		;Flip the bit in the area under the cursor.
NoCursorFlip
		BCHG	#7,$3FA700		;Flip the bit on the screen.

		CLR.B	CrsrBusy		;The cursor isn't busy any more.
		RTS

;This routine turns the A000 subhooks on and off.

A000
		SUBQ.B	#1,D7
		BCS.S	@4			;No arguments given.  Delete the intercepting
		BNE.S	@1			;subroutine.
		MOVE.W	D0,D1			;If one argument is given, the second argument
@1		AND.W	#$1FF,D0		;is set to the first one.
		AND.W	#$1FF,D1
		CMP.W	D0,D1
		BCC.S	@2			;Make sure D0<=D1.
		EXG	D0,D1
@2		CLR.W	(A0)+			;The subroutine is installed.
		MOVE.W	D0,(A0)+		;Store the two arguments.
		MOVE.W	D1,(A0)+		;Install the subroutine.
		SUBQ.B	#3,D7
		BNE.S	@4			;If there is no PC range, indicate that fact.
		MOVE.L	Lo3Bytes,D4		;Clear the high bytes of the two addresses.
		AND.L	D4,D2
		AND.L	D4,D3
		CMP.L	D2,D3
		BCC.S	@3			;Make sure D2<=D3.
		EXG	D2,D3
@3		MOVE.L	D2,(A0)+		;Store the PC range.
		MOVE.L	D3,(A0)+
		BRA.S	A000OnOff
@4		ST	(A0)


;This routine turns the A000 dispatcher on or off depending on the situation

A000OnOff
		MOVE.W	#A000Hook-A,_A000Hook-A(A2)
		MOVE.B	TrapRList,D0		;The subroutine isn't installed.
		BEQ.S	@1
		MOVE.B	TrapSList,D0
		BEQ.S	@1
		MOVE.B	TrapDList,D0
		BEQ.S	@1
		MOVE.B	TrapCList,D0
		BEQ.S	@1
		MOVE.B	TrapIList,D0
		BEQ.S	@1
		MOVE.B	TrapGList,D0
		BEQ.S	@1
		CLR.W	_A000Hook-A(A2)		;Remove the subroutine.
@1		RTS


		;############################
		;##                        ##
		;##  A000 subhook section  ##
		;##                        ##
		;############################


;
;The following are the subhooks for A000 trap intercepts.
;


;
;The following is for heap check, scramble and/or purge.
;

ScrambleHook
		MOVEM.L	D2-D7/A2-A6,-(SP)
		SUB.W	#$1E,D0			;Is this a _NewPtr?
		BEQ.S	@22			;YES.
		SUBQ.W	#$22-$1E,D0		;NO.  Is this a _NewHandle?
		BEQ.S	@22			;YES.
		SUBQ.W	#$27-$22,D0		;NO.  Is this a _ReallocHandle?
		BEQ.S	@22			;YES.
		MOVEM.L	62(SP),D1/D2/A1		;NO.  Test for a _SetPtrSize or _SetHandleSize
		ADDQ.W	#$27-$20,D0
		BEQ.S	@21
		SUBQ.W	#$24-$20,D0
		BNE.S	@23			;None of these.  Don't do a heap scramble.
		MOVE.L	(A1),A1			;De-reference the handle in a _SetHandleSize
@21		SUBQ.W	#8,A1
		MOVE.L	(A1),D2			;Get the size of the memory manager block.
		AND.L	Lo3Bytes,D2
		SUBQ.L	#8,D2			;Subtract the size of the header.
		MOVEQ	#$0F,D3			;Also subtract the correction value.
		AND.B	(A1),D3
		SUB.L	D3,D2
		CMP.L	D1,D2			;Is the new size greater than the old size?
		BGE.S	@23			;If not, don't scramble.
@22		BSR	ScrambleHeap		;Call the ScrambleHeap routine.
		BRA.S	@24
@23		MOVEQ	#0,D0			;If not scrambled, return error code of zero.
@24		MOVEM.L	(SP)+,D2-D7/A2-A6
		RTS


;
;The following is for recording each trap.
;

RecordHook
		MOVEM.L	D2/A2,-(SP)
		LEA	RecordData+2,A1
		TST.B	(A1)+			;If master switch is off, do nothing.
		BMI.S	@4
		MOVE.B	(A1)+,D2		;Get the halting flag.
		MOVE.W	(A1)+,D1		;Get the number of messages.
		MOVE.L	(A1),A2			;Get the address of the table.
		TST.B	D2			;Is halting enabled?
		BEQ.S	@1
		MOVE	#@6-A,D0		;YES.  If the table is about to overflow, exit.
		CMP.W	-6(A1),D1
		BLS.S	@5
@1		ADDQ.W	#1,-6(A1)		;One more message is present.
		ADDQ.W	#6,A1
		MOVE.W	(A1),D2			;Decrement the pointer to the current message
		BNE.S	@2			;storing place.
		MOVE.W	D1,D2
@2		SUBQ.W	#1,D2
		MOVE.W	D2,(A1)
		ASL.W	#4,D2			;Copy the message.
		ADD.W	D2,A2
		MOVE.W	(A0),(A2)+		;Copy the opcode.
		MOVE.W	Ticks+2,(A2)+		;Copy the time.
		MOVE.L	A0,(A2)+		;Copy its PC.
		BTST	#3,(A0)
		BNE.S	@3
		MOVE.L	$1A(SP),(A2)+		;Also copy the values of D0 and A0.
		MOVE.L	$22(SP),(A2)
		BRA.S	@4
@3		MOVE.L	$38(SP),(A2)+		;Get the values of the top 8 stack bytes.
		MOVE.L	$3C(SP),(A2)+

;At this point the stack looks like this:
;  D2   A2   Ret  B  D0   A0   Ret  D0   D1   A0   A1   Ret  A5   SR PC   stk0 stk2
;  0000 0000 0000 00 0011 1111 1111 1111 1122 2222 2222 2222 2233 33 3333 3333 3333
;  0123 4567 89AB CD EF01 2345 6789 ABCD EF01 2345 6789 ABCD EF01 23 4567 89AB CDEF

@4		MOVEQ	#0,D0			;No errors.
@5		MOVEM.L	(SP)+,D2/A2
		RTS
@6		TRAPMon	'Record full'


;
;The following is for discipline.
;

DisciplineHook

;At this point the stack looks like this:
;  Ret  B  D0   A0   Ret  D0   D1   A0   A1   Ret  A5   SR PC   stack
;  0000 00 0000 1111 1111 1122 2222 2222 3333 3333 3344 44 4444 4455
;  0123 45 6789 0123 4567 8901 2345 6789 0123 4567 8901 23 4567 8901

		MOVEM.L	A2/A4/A6/D7,-(SP)
		LEA	4*4+18(SP),A4		;point A4 to the registers
		LEA	4*4+48(SP),A6		;point A6 to the stack

;At this point A6 points to the old stack and A4 points to this:
;  D0   D1   A0   A1   Ret  A5   SR PC
;  0000 0000 0011 1111 1111 2222 22 2222
;  0123 4567 8901 2345 6789 0123 45 6789

RegD0		EQU	0(A4)
RegD1		EQU	4(A4)

RegA0		EQU	8(A4)
RegA1		EQU	12(A4)
RegA5		EQU	20(A4)

RegSR		EQU	24(A4)
RegPC		EQU	26(A4)

Stack0		EQU	0(A6)
Stack2		EQU	2(A6)
Stack4		EQU	4(A6)
Stack6		EQU	6(A6)
Stack8		EQU	8(A6)
Stack10		EQU	10(A6)
Stack12		EQU	12(A6)
Stack14		EQU	14(A6)
Stack16		EQU	16(A6)
Stack18		EQU	18(A6)
Stack20		EQU	20(A6)
Stack22		EQU	22(A6)
Stack24		EQU	24(A6)
Stack26		EQU	26(A6)
Stack28		EQU	28(A6)

;The discipline code may trash D0, D1, A0, A1 and A2

		MOVE.W	(A0),D1			;Get the actual trap word.
		BTST	#11,D1			;Check what kind of trap.
		BNE.S	ToolboxTrap
OSTrap
		LEA	OSTraps,A0
		AND.W	#$FF,D1			;Get the trap number.
		BRA.S	DisciplineTrap
ToolboxTrap
		BTST	#10,D1			;Check if it is auto-pop.
		BEQ.S	@1
		ADDQ	#4,A6			;Skip over auto-pop return address.
@1		LEA	ToolTraps,A0
		AND.W	#$1FF,D1		;Get the trap number.
DisciplineTrap
		MOVEQ	#0,D7

		ADD.W	D1,D1
		MOVE.W	0(A0,D1.W),D1		;Find the discipline code.
		BEQ.S	NoDiscipline

		JSR	0(A0,D1.W)		;Call on discipline.
NoDiscipline
		MOVE.W	D7,D0			;Return the error code.

		MOVEM.L	(SP)+,A2/A4/A6/D7
		RTS


;
;The following is for checksumming on each trap.
;

ChecksumHook
		MOVE.L	D2,-(SP)
		MOVEQ	#0,D2			;Calculate the checksum.
		MOVEM.L	ChecksumValue+2,D0/D1
		BSR	Checker
		MOVEQ	#0,D0
		CMP.W	ChecksumValue,D2	;If the checksum matches, no error.
		BEQ.S	@1
		MOVE	#@2-A,D0		;Otherwise report the checksum error.
@1		MOVE.L	(SP)+,D2
		RTS
@2		TRAPMon	'Checksum failed'


;
;The following is for trap intercept.
;

InterceptHook
		MOVE	#@1-A,D0		;Always cause an error.
		RTS
@1		TRAPMon	'Trap intercepted'


;
;The following is for trap signalling.
;

SignalHook
		MOVEQ	#0,D0
		MOVE.B	UserInform,D1		;Cause an error if UserInform is nonzero.
		BEQ.S	@1
		MOVE	#@2-A,D0
@1		RTS
@2		TRAPMon	'Trap signal'


		;#########################################
		;##                                     ##
		;##  Heap check/scramble/purge section  ##
		;##                                     ##
		;#########################################

;+-----------------------------------------+
;| Check, scramble, and/or purge the Heap. |
;+-----------------------------------------+
;|
;|ENTRY: ScrambleHeap
;|
;|OUT:  D0.L'   Zero if scramble successful; HeapError-A otherwise.
;|
;|Destroys D1-D7,A0-A6.
;|

ScrambleHeap
		MOVE.L	SP,A2
		MOVE.B	CurrentHeap,D0
		BSR	GetZone			;Get the requested heap zone.
		BNE	ScrambleError
		MOVE.B	PurgeAlso,D0
		BEQ.S	@1
		BSR.S	PurgeHeap
@1		LEA	48(A6),A3
		CLR.L	(A3)+
ScrambleLoop
		MOVEQ	#0,D0			;(Give a return code of 0 if exiting.)
		CMP.L	(A6),A3			;Exit if done.
		BEQ	ScrambleEnd
		BSR	GetBlockInfo		;Get information about the first block.
		BMI.S	ScrambleLoop		;If it can't be moved, fetch the next block.
		MOVE.B	CheckOnly,D2		;If it isn't supposed to be moved, also fetch the
		BPL.S	ScrambleLoop		;next block.
		MOVE.B	D0,D3			;Save the information about the first block.
		MOVE.L	D1,D4
		MOVE.L	A4,A5			;A3 is the current address.
		CMP.L	(A6),A3			;D3 is the type of the first block.
		BEQ.S	ScrambleClr		;D4 is the length of the first block.
		BSR	GetBlockInfo		;A5 is the address of the first block.
		BMI.S	ScrambleClr		;D0 is the type of the second block.
		ADD.B	D3,D0			;D1 is the length of the second block.
		BEQ.S	Scramble2Blank		;A4 is the address of the second block.
		BMI	ScrambleSwap
		TST.B	D3
		BEQ.S	ScrambleAlter2nd
		MOVEQ	#0,D6
		BSR.S	AlterCount		;Get all the free areas after the block.
		BSR.S	AlterLen		;Find their total length.
		BSR.S	Alter1st		;Swap a block with a free area.  The block is first.
		EXG	D1,D4
		MOVE.L	A5,A0
		MOVE.L	A3,A1
		MOVE.L	D1,D0
		_BlockMove
ScrambleClr2
		MOVEQ	#4,D1			;Don't touch the next block.
		BSR.S	ScrambleClear
		BRA.S	ScrambleLoop

ScrambleAlter2nd
		BSR.S	Alter2nd		;Swap a free area with a block.  The block is
		MOVE.L	A4,A0			;second.
		MOVE.L	A5,A1
		MOVE.L	D1,D0
		MOVE.L	D0,D5
		_BlockMove
		MOVE.L	D4,(A3)			;Store the length of the free area.
		BRA.S	ScrambleLoop

Scramble2Blank
		MOVE.L	A4,A3			;Skip past one blank block.
ScrambleClr
		TST.B	D3			;Check if the first block is a free area.
		BNE.S	ScrambleLoop		;If not, don't clear it.
		CMP.B	#$C1,D0			;In the special case that the first block is a free
		BNE.S	ScrambleClr2		;block and the second one an immovable free block,
		MOVE.L	D1,-(SP)		;consolidate the two blocks.
		MOVEQ	#0,D1			;Erase the first long word of the second free block
		BSR.S	ScrambleClear		;as well.
		MOVE.L	(SP)+,D1
		ADD.L	D1,-(A5)
		BRA.S	ScrambleLoop

PurgeHeap
		MOVE.L	theZone,-(SP)		;Call MaxMem to do a purge.
		MOVE.L	A6,theZone
		_MaxMem
		MOVE.L	(SP)+,theZone
		RTS

Alter1st
		MOVE.L	4(A5),A0		;Adjust the handle to the first block.
		ADD.L	D1,0(A6,A0.L)
		RTS

AlterCount
		MOVEQ	#0,D7			;On exit, D7 will contain the number of blocks that
		MOVE.L	A4,A1			;were found.
@1		ADDQ.W	#1,D7
		CMP.L	(A6),A3			;Don't go past the end of the Heap.
		BEQ.S	@2
		BSR	GetBlockInfo		;Get a block.
		CMP.B	D0,D6			;Does it have the desired type?
		BEQ.S	@1			;YES.  Look at the next block.
		MOVE.L	A4,A3			;NO.  Go to the previous block.
@2		MOVE.L	A1,A4			;Restore A4.  A3 contains one byte past the end of
		RTS				;the last block found.

Alter2nd
		MOVEQ	#$40,D6			;Skip past any following relocatable blocks.
		BSR.S	AlterCount
		MOVE.L	A1,A3			;Do a second pass over these blocks.
@1		BSR	GetBlockInfo
		SUB.L	D4,(A0)			;Adjust the handles of all these blocks.
		SUBQ.W	#1,D7
		BNE.S	@1
		MOVE.L	A1,A4
AlterLen
		MOVE.L	A3,D1			;Find the total length of the blocks that were
		SUB.L	A4,D1			;found.
		SUBA.L	D4,A3			;ScrambleLoop will fetch the second block.
		RTS

ScrambleClear
		MOVE.L	D4,(A5)+		;Clear the first block.  (Assumes that it is a free
		SUB.L	D1,D4			;area).
		ADD.L	D4,A5
		MOVE.L	#'XYXY',D0
		LSR.L	#1,D4			;D4 is the number of words to clear.
		MOVE.L	D4,D1
		AND.W	#31,D1			;Use a slower loop to clear a number of words that
		BRA.S	@2			;is not a multiple of 32 words.
@1		MOVE.W	D0,-(A5)
@2		DBRA	D1,@1
		LSR.L	#5,D4
		BEQ.S	@5
		MOVE.L	D0,D1			;Now use a super-fast loop to clear the rest in
		MOVE.L	D0,D2			;multiples of 32 words.
		MOVE.L	D0,D3
		MOVE.L	D0,D7
		MOVE.L	D0,A0
		MOVE.L	D0,A1
		MOVE.L	D0,A4
		BRA.S	@4
@3		MOVEM.L	D0/D1/D2/D3/D7/A0/A1/A4,-(A5)
		MOVEM.L	D0/D1/D2/D3/D7/A0/A1/A4,-(A5)
@4		DBRA	D4,@3
@5		RTS

ScrambleSwap
		BSR.S	Alter2nd		;Swap two blocks.  This may not be a very fast
		BSR.S	Alter1st		;operation.
		MOVE.L	#160*5,D2
		CMP.L	D2,D1			;If both blocks are large, use the slow algorithm.
		BLS.S	@1
		CMP.L	D2,D4
		BHI.S	SlowSwap
@1		MOVE.W	#160,D2			;Use a lightning-fast algorithm if at least one
		SUB.L	D2,SP			;block is small enough.  Reserve 160 bytes on stack.
		ADD.L	D1,A4			;A4 now points to the end of the second block.
		CMP.L	D1,D4
		BHI.S	@10
		ADD.L	D4,D1			;D1 now contains the total length.
@2		MOVE.L	D2,D0			;The first block is the smaller one.
		SUB.L	D2,D4
		BCC.S	@3			;Put either 160 or the remaining length of the first
		ADD.L	D2,D4			;block into D0, whichever is smaller.
		MOVE.L	D4,D0
		MOVEQ	#0,D4
@3		MOVE.L	A5,A0			;Save D0 bytes from the beginning of the first
		MOVE.L	SP,A1			;block.
		BSR.S	FastPush
		MOVE.L	A5,A1			;Shift the remaining bytes to lower memory to cover
		NEG.L	D0			;the hole that was created.
		ADD.L	D1,D0
		_BlockMove
		MOVE.L	SP,A0			;Store the saved bytes at the end of the second
		MOVE.L	A4,A1			;block.
		SUB.W	D3,A1
		BSR.S	FastPull
		TST.L	D4
		BNE.S	@2			;If the swap isn't complete, shift again.
		BRA.S	@20

@10		ADD.L	D1,D4			;D4 now contains the total length.
@11		MOVE.L	D2,D0
		SUB.L	D2,D1
		BCC.S	@12			;Put either 160 or the remaining length of the
		ADD.L	D2,D1			;second block into D0, whichever is smaller.
		MOVE.L	D1,D0
		MOVEQ	#0,D1
@12		MOVE.L	A4,A0			;Save D0 bytes from the end of the second block.
		SUB.W	D0,A0
		MOVE.L	SP,A1
		BSR.S	FastPush
		MOVE.L	A5,A0			;Shift the remaining bytes to higher memory to cover
		MOVE.L	A5,A1			;the hole that was created.
		ADD.W	D0,A1
		NEG.L	D0
		ADD.L	D4,D0
		_BlockMove
		MOVE.L	SP,A0			;Store the saved bytes at the beginning of the
		MOVE.L	A5,A1			;first block.
		BSR.S	FastPull
		TST.L	D1
		BNE.S	@11			;If the swap isn't complete, shift again.
@20		ADD.L	D2,SP			;Release the memory reserved on the stack and exit.
toScrambleLoop	BRA	ScrambleLoop

FastPush
		MOVE.W	D0,D3
FastPull
		LSR.W	#2,D3			;This is a semi-efficient block move routine that
		BCC.S	@2			;doesn't have the overhead of calling _BlockMove.
		MOVE.W	(A0)+,(A1)+
		BRA.S	@2
@1		MOVE.L	(A0)+,(A1)+
@2		DBRA	D3,@1
		MOVE.W	D0,D3
		RTS

SlowSwap
		BSR.S	SlowScramble		;Call the subroutine and go back to the main loop.
		BRA.S	toScrambleLoop

SlowScramble
		MOVE.L	A4,A0			;This is a slower algorithm used for larger blocks.
		ADD.L	D1,A0			;A0 is one byte beyond the last byte to be moved.
		ADD.L	D4,D1
		MOVE.L	D1,D7			;D7 is now the total length.
		LSR.L	#1,D1			;D1 is now the total length/2.
		BRA.S	@4
@5		ADD.L	D7,A1			;In this loop, continue to swap the word in the
		CMP.L	A0,A1			;register with the next word in the memory until
		BNE.S	@2			;the two blocks are transposed.  Do not swap any
		MOVE.W	D2,(A1)			;of the words more than once; if that is about to
@4		MOVE.W	-(A0),D2		;happen, move the pointer to the preceeding word.
		MOVE.L	A0,A1
		BRA.S	@3
@1		SUB.L	D4,A1
		CMP.L	A5,A1
		BLT.S	@5
@2		MOVE.W	(A1),D3
		MOVE.W	D2,(A1)
		MOVE.W	D3,D2
@3		DBRA	D1,@1
		SUB.L	val10000,D1
		BCC.S	@1
		RTS

;+--------------------------+
;| Get either the system or |
;| application heap zone.   |
;| Avoid address errors.    |
;+--------------------------+
;|
;|ENTRY: GetZone
;|
;|IN:   Z: flag set for system zone, clear for application zone.
;|
;|OUT:  D0.L'   ^heap zone.
;|      A6'     ^heap zone (same as D0.L').
;|
;|Destroys A3.
;|

GetZone		BNE.S	@1			;Get the requested heap zone and put it into D0 and
		LEA	SysZone,A3		;A6, relying on the zero flag on entry:
		BRA.S	@2			;Z set for system zone, clear for application zone.
@1		LEA	ApplZone,A3
@2		MOVE.L	(A3),D0
		BCLR	#0,D0			;If the address is odd, make it even.
		MOVEA.L	D0,A6
		RTS


;+------------------------------------------------+
;| Examine one heap block.  If an error is found, |
;| MOVE.L A2,SP,  MOVE #HeapError-A,D0,  and RTS  |
;| are executed.                                  |
;+------------------------------------------------+
;|
;|ENTRY: GetBlockInfo
;|
;|IN:   A3:     ^block's header.
;|      A6:     ^heap zone that contains the block.
;|      A2:     SP to use in case an error is found.
;|
;|OUT:  If an error was found, the error routine is entered.  Otherwise,
;|      A3'     ^next block's header.
;|      A4'     A3:
;|      D1.L'   length of this block.
;|      CCR'    represents TST.B D0'.
;|      D0.B'   block type ($00,$40,$80,$C0,$C1).
;|         =$00'    free block.
;|         =$40'    relocatable block.
;|              D2.L'   handle value.
;|              A0'     handle address.
;|         =$80'    non-relocatable block.
;|         =$C0'    locked relocatable block.
;|         =$C1     a free block that shouldn't be moved.
;|
;|Destroys A0.
;|

GetBlockInfo
		MOVE.L	A3,A4			;Save A3.
		MOVE.B	(A3),D0			;Get the block type.
		MOVE.L	(A3)+,D1		;Get the block length.
		MOVE.L	(A3)+,A0		;Get the handle or heap zone address.
		AND.L	Lo3Bytes,D1
		AND.B	#$C0,D0
		BEQ.S	InfoEnd			;If this is a free block, leave.
		BMI.S	InfoRelocatable		;Do relocatable and illegal blocks.
		MOVEQ	#$FFFFFF80,D0		;This is a nonrelocatable block.  The indicated heap
		CMP.L	A0,A6			;zone address should match A6.
		BEQ.S	InfoEnd
ScrambleError
		MOVE.L	A2,SP			;Go to the error routine.
		MOVE	#HeapError-A,D0
		RTS
HeapError	TRAPMon	'Heap error'

InfoRelocatable
		SUB.B	#$40,D0			;If this is a $C0 type block, it is illegal.
		BMI.S	ScrambleError
		MOVE.L	A0,D2			;If the handle address is odd, the block is illegal.
		LSR.B	#1,D2
		BCS.S	ScrambleError
		ADD.L	A6,A0
		MOVE.L	(A0),D2			;If this relocatable block is locked, give it the
		BPL.S	@1			;$C0 type.
		MOVEQ	#$FFFFFFC0,D0
@1		AND.L	Lo3Bytes,D2
		CMP.L	D2,A3			;Make sure that this block's handle points back to
		BNE.S	ScrambleError		;the block.
InfoEnd		SUBQ.L	#8,D1			;Now add the length of the block to the address.
		BCS.S	ScrambleError		;If the block size is less than eight, give an
		BTST	#0,D1			;error.
		BNE.S	ScrambleError
		ADD.L	D1,A3
		CMP.L	(A6),A3
		BCS.S	@1
		BHI.S	ScrambleError		;Don't allow blocks beyond the end of the Heap.
		TST.B	D0			;If the last block is a free area, don't scramble it.
		BNE.S	@1
		MOVEQ	#$FFFFFFC1,D0
@1		ADDQ.L	#8,D1			;Correct for the two autoincrement instructions.
		TST.B	D0
ScrambleEnd
		RTS


		;######################
		;##                  ##
		;##  Label routines  ##
		;##                  ##
		;######################


;+--------------------------------------------------------+
;| Check if D2 is in a 'CODE' resource, and, if so,       |
;| attempt to find the name of the routine containing D2. |
;+--------------------------------------------------------+
;|
;|ENTRY: CodeLabelScan
;|
;|IN:   D2.L:   address to identify.
;|      D0.L:   0.
;|      D5.L:   if D2 is in a resource, offset from the resource beginning to D2.
;|      D6.L:   if D2 is in a resource, the resource type; otherwise, 0.
;|      D7.L:   Bits 0..15 contain the resource ID.  Bits 16..23 contain the value of _Inhibits.
;|      A4:     if D2 is in a resource, beginning address of the heap block.  (D2:-D5:)
;|      A3:     if D2 is in a resource, ending address of the heap block.  (D2:-D5:)
;|      A5:     ^Monitor's variables.
;|(D4 is initialized by the Monitor, but this routine does not use it.)
;|
;|OUT:  D0.L'=0   D2 could not be identified.
;|              D2.L'   D2.L:.
;|      D0.L'<>0  D2 was identified.
;|              D0.L'   first four letters of name.
;|              D1.L'   last four letters of name.
;|              A1'     address of the routine's beginning (the LINK instruction).
;|              D2.L'   D2.L:-A1'.
;|
;|Destroys D1,D3,A0,A1.
;|

CodeLabelScan
		MOVEM.L	D4/D6/D7,-(SP)		;Save registers.
		CMP.L	#'CODE',D6		;Don't search for code routine names unless this is
		BNE.S	@10			;a code segment.
		MOVE.L	D2,D7			;D7 will contain D2 truncated to an even value.
		BCLR	#0,D7
		MOVE.L	D7,A0
		MOVE.L	A3,D3			;D3 contains the number of words left to scan
		SUB.L	D7,D3			;before giving up at $800 or finishing at the end of
		CMP.W	#$800,D3		;the block.
		BCS.S	@1
		MOVE.W	#$800,D3
@1		LSR.W	#1,D3
		ADDQ.L	#2,D7			;Increment the starting position pointer by 2.
@19		MOVE.W	#$4E75,D1		;D1.W:  RTS
		MOVE.W	#$4ED0,D6		;D6.W:  JMP (A0)
		MOVE.W	#$4E56,D4		;D4.W:  LINK A6,#____
		BRA.S	@3
@2		MOVE.W	(A0)+,D0		;Get the next word.
		CMP.W	D1,D0			;Search for one of the above instructions.
		BEQ.S	@20			;If RTS or JMP (A0) is found, investigate further.
		CMP.W	D6,D0
		BEQ.S	@20
		CMP.W	D4,D0
@3		DBEQ	D3,@2			;If the LINK is found first, exit with no label.
		BNE.S	@10			;If the LINK is the first instruction encountered,
		CMPA.L	D7,A0			;leave it as it is because it may be the beginning
		BEQ.S	@19			;of the subroutine.
@10		MOVEQ	#0,D0			;Pass back no label code.
@11		MOVEM.L	(SP)+,D4/D6/D7		;Return.
		RTS

@20		CMP.W	#4,D3			;If there are less than eight bytes left to scan,
		BCS.S	@10			;it's not possible to have a full name here.
		BSR.S	CheckUNLK		;Check for an UNLK instruction before the RTS or
		BNE.S	@3			;JMP (A0).  If not found, continue searching.
		MOVEQ	#7,D6
@21		ROL.L	#8,D0			;Check the name to make sure that there are eight
		ROL.L	#8,D1			;letters of valid ASCII values present.
		MOVE.B	D1,D0
		MOVE.B	(A0)+,D1
		CMP.B	#6,D6
		BCS.S	@22
		AND.B	#$7F,D1			;Clear the high bit of the first and second bytes.
@22		CMP.B	#' ',D1			;Anything between $20 and $7E is valid.
		BCS.S	@10
		CMP.B	#$7F,D1
		BCC.S	@10
		DBRA	D6,@21
		MOVE.W	D5,D3			;A valid name has been found.  Now search backwards
		LSR.W	#1,D3			;for the LINK instruction.
		MOVE.L	D7,A1
@23		CMP.W	-(A1),D4
		DBEQ	D3,@23
		BNE.S	@10			;If run out of the block, exit.
		SUB.L	A1,D2			;Otherwise give the offset in D2 and return
		BRA.S	@11			;successfully.


;+-------------------------------------------------------+
;| Make sure that an UNLK A6 instruction exists no more  |
;| than ten words in front of A0.  Also make sure that   |
;| there is no LINK A6 between the UNLK A6 and A0.       |
;+-------------------------------------------------------+
;|
;|ENTRY: CheckUNLK
;|
;|IN:   A0:     Address from which to search.
;|
;|OUT:  Z flag' set if the conditions above satisfied, clear otherwise.
;|
;|Destroys nothing.
;|

CheckUNLK	MOVEM.L	D0/A0,-(SP)		;Save registers.
		MOVEQ	#9,D0			;Search ten words.
@1		CMP.W	#$4E5E,-(A0)		;UNLK A6
		BEQ.S	@2
		CMP.W	#$4E56,(A0)		;LINK A6,#____
		DBEQ	D0,@1
		MOVEQ	#-1,D0			;If not found or LINK found first, clear Z flag.
@2		MOVEM.L	(SP)+,D0/A0		;Return (MOVEM preserves flags).
		RTS


;+----------------------------------+
;| Find a given embedded routine    |
;| 8-character name in code blocks. |
;| See manual for details.          |
;+----------------------------------+
;|
;|ENTRY: CodeLabelFind
;|
;|IN:   D0.L:   first four characters of the name converted to upper case.
;|      D1.L:   last four characters of the name converted to upper case.
;|      D7.L:   bits 16..23 contain the value of _Inhibits.
;|      A5:     ^Monitor's variables.
;|
;|OUT:  D0.L'=0 the name has been found.
;|      D2.L'   the location of the routine that has the given name.
;|      D0.L'=D0.L: the name has not been found.
;|
;|Destroys D2,D3,A0,A1.
;|

CodeLabelFind
		MOVEM.L	D0/D1/D4-D7/A2-A4/A6,-(SP)
		BTST	#16+3,D7		;If can't scan resources, do nothing.
		BNE	@40
		MOVE.L	SP,A6
		MOVE.L	$A50,D1			;Start with the first resource file.
@1		JSR	_NextCResFile		;Check the next file.
		BEQ	@40			;If there is none, no data will be found.
		MOVE.L	A1,A0
		MOVE.W	(A0)+,D3		;D3 has the number of types+1.
		MOVE.L	#'CODE',D2
@11		CMP.L	(A0)+,D2
		ADDQ.W	#4,A0			;Look for blocks of type 'CODE'.
		DBEQ	D3,@11
		BNE.S	@1			;If not found, scan the next file.
		MOVE.W	-(A0),D0
		ADD.W	D0,A1			;Find the ID list and check for address errors.
		LSR.W	#1,D0
		BCS.S	@1
		MOVE.W	-(A0),D6		;D6 now has the number of 'CODE' IDs in the table.
@12		ADDQ.W	#8,A1
		MOVE.L	(A1)+,A0		;See if this 'CODE' segment is legally in memory.
		BSR	IndirectA0
		BCS.S	@50			;NO.
		TST.W	-12(A1)			;YES.  If its ID is zero, however, do not scan it.
		BEQ.S	@50
		MOVE.L	-8(A0),D0
		AND.L	Lo3Bytes,D0
		MOVEQ	#$0F,D2
		AND.B	-8(A0),D2		;Subtract the size correction from the size.
		SUB.L	D2,D0
		MOVEQ	#8,D2
		SUB.L	D2,D0
		BMI.S	@50			;If a negative number results, skip to the next
		LSR.L	#1,D0			;block.
		CMP.L	#$8000,D0
		BCS.S	@13
		MOVE.L	#$7FFF,D0
@13		MOVE.W	#$4E56,D2		;D2.W:  LINK A6,#____
		MOVE.W	#$4E75,D3		;D3.W:  RTS
		MOVE.W	#$4ED0,D4		;D4.W:  JMP (A0)
		BRA.S	@21
@20		CMP.W	(A0)+,D2		;Search for a LINK instruction.
@21		DBEQ	D0,@20
		BNE.S	@50			;Not found within the block.
@22		MOVEA.L	A0,A2			;Save the address and look for either RTS or
		BRA.S	@24			;JMP (A0).
@23		MOVE.W	(A0)+,D5
		CMP.W	D5,D3
		BEQ.S	@30
		CMP.W	D5,D4
		BEQ.S	@30
		CMP.W	D5,D2			;If another LINK is found first, restart this loop.
@24		DBEQ	D0,@23
		BNE.S	@50
		MOVEQ	#-1,D5			;Clear the Z flag and search again.
		BRA.S	@22
@30		BSR	CheckUNLK		;Check for an UNLK instruction before the RTS or
		BNE.S	@24			;JMP (A0).
		BSR.S	CheckName
		BNE.S	@21
		SUBQ.W	#2,A2
		MOVE.L	A2,D2
		CLR.L	(SP)			;Clear D0 on the stack image.
@40		MOVEM.L	(SP)+,D0/D1/D4-D7/A2-A4/A6
		RTS

@50		DBRA	D6,@12			;Examine the next block, or, if there are no more,
		BRA	@1			;the next file.


;+---------------------------------------------------------------------------------+
;| Compare the names at (A0)+ and (A6)+.  Convert the name at (A0)+ to upper case  |
;| and clear the 7th bit in its first 2 characters for the purpose of comparison.  |
;| The name at (A6)+ is assumed to be in upper case, as it will be if it was       |
;| generated by the Monitor.  Both names must be eight characters long.            |
;+---------------------------------------------------------------------------------+
;|
;|ENTRY: CheckName
;|
;|IN:   A0:     string1, upper or lower case, 7th bit clear or set on first character.
;|      A6:     string2, upper case only, 7th bit clear.
;|
;|OUT:  Z flag' set if uppercase(string1)=string2
;|              clear otherwise.
;|
;|Destroys nothing.
;|

CheckName
		MOVEM.L	D0/D1/A1/A2,-(SP)
		MOVEQ	#7,D0			;Compare eight characters.
		MOVE.L	A6,A1			;Use copies of A0 and A6.
		MOVE.L	A0,A2
@4		MOVEQ	#$7F,D1			;Clear the high bit of the first character.
		AND.B	(A2)+,D1
		BRA.S	@3
@1		CMP.B	#6,D0
		BHS.S	@4
		MOVE.B	(A2)+,D1
@3		CMP.B	#'a',D1			;Convert to upper case.
		BCS.S	@2
		CMP.B	#'z'+1,D1
		BCC.S	@2
		SUB.B	#$20,D1
@2		CMP.B	(A1)+,D1		;Compare and exit as soon as a mismatch is found or
		DBNE	D0,@1			;eight characters match.
		MOVEM.L	(SP)+,D0/D1/A1/A2
		RTS


;+---------------------------+
;| Find a given 8-character  |
;| label in the label table. |
;| See manual for details.   |
;+---------------------------+
;|
;|ENTRY: LabelFind
;|
;|IN:   D0.L:   first four characters of the name converted to upper case.
;|      D1.L:   last four characters of the name converted to upper case.
;|      D7:     bits 16..23 contain the value of _Inhibits.
;|      A5:     ^Monitor's variables.
;|
;|OUT:  D0.L'=0 the name has been found.
;|              D2.L'   the location of the routine that has the given name.
;|      D0.L'=D0.L: the name has not been found.
;|              D2.L'   unpredictable.
;|
;|Destroys D3,A0,A1.
;|
;|
;|ENTRY: LabelFind.
;|
;|Same as LabelFind except that if D2.B is nonzero, the subroutine will not check if the resource is in
;|memory for resource-relative labels.  Moreover, the address of the label will be passed back in
;|A0 if the label is found.  However the address of built-in labels is never returned.
;|

LabelFind
		MOVEQ	#0,D2
LabelFind.
		MOVE.B	LabelEnabled,D3		;If there is no table of labels, do nothing.
		MOVEM.L	D0/D1/D5/D6/A3/A4/A6,-(SP)
		MOVE.L	SP,A6			;A6 points to the saved name on the stack.
		BMI.S	@20
		MOVE.L	LabelTable,A0
		SUBQ.W	#8,A0
		MOVE.W	NumLabels,D3
		MOVEQ	#-1,D0			;Clear the Z flag.
		BRA.S	@2
@1		ADD.W	#16,A0			;Check the names in the label table.
		BSR.S	CheckName
@2		DBEQ	D3,@1
		BEQ.S	@21			;If found, continue
@20		LEA	UALabelTable+8,A0	;Point to built in label table.
		MOVE.W	#NumUALabels,D3
		MOVEQ	#-1,D0
		BRA.S	@22
@23		ADD.W	#16,A0
		BSR.S	CheckName
@22		DBEQ	D3,@23
@21		BNE.S	@10			;If no match, exit.
		MOVE.L	-(A0),D3		;Determine whether this is an absolute or
		MOVE.B	D2,D0			;resource-relative label.
		MOVE.L	-(A0),D2
		TST.B	(A0)
		BEQ.S	@3			;If absolute, exit successfully.
		TST.B	D0
		BNE.S	@3			;If supposed to pass back label address, exit now.
		BTST	#16+3,D7		;If resource-relative, resource scanning must not be
		BNE.S	@10			;inhibited!
		SWAP	D3
		JSR	_FindRes		;Find the desired resource, and, if all is well,
		TST.B	D0			;add the offset to its beginning.
		BNE.S	@10
		CLR.W	D3
		SWAP	D3
		ADD.L	D3,D2
@3
		LEA	UALabelTable,A1
		CMP.L	A1,A0
		BLO.S	@24
		LEA	UALabelTableEnd,A1
		CMP.L	A1,A0
		BHS.S	@24
		MOVEQ	#0,D0
		MOVE.L	D0,A0			;Do NOT return a pointer for built-ins
@24		CLR.L	(SP)			;Clear D0 on the stack image.
@10		MOVEM.L	(SP)+,D0/D1/D5/D6/A3/A4/A6
@11		RTS


;+------------------------------------+
;| Search the label table for a label |
;| that could be used to identify D2. |
;| The resource-relative labels will  |
;| be ignored if D6 is 0.             |
;+------------------------------------+
;|
;|ENTRY: LabelScan
;|
;|IN:   D2.L:   address to identify.
;|      D0.L:   0.
;|      D5.L:   if D2 is in a resource, offset from the resource beginning to D2.
;|      D6.L:   if D2 is in a resource, the resource type; otherwise, 0.
;|      D7.L:   Bits 0..15 contain the resource ID.  Bits 16..23 contain the value of _Inhibits.
;|      A4:     if D2 is in a resource, beginning address of the heap block.  (D2:-D5:)
;|      A3:     if D2 is in a resource, ending address of the heap block.  (D2:-D5:)
;|      A5:     ^Monitor's variables.
;|(D4 is initialized by the Monitor, but this routine does not use it.)
SHAR_EOF
if test 29699 -ne "`wc -c EUA.Asm.3`"
then
echo shar: error transmitting EUA.Asm.3 '(should have been 29699 characters)'
fi
#	End of shell archive
exit 0
-- 
Darin Adler
{gatech,harvard,ihnp4,seismo}!ut-sally!ut-dillo!darin

darin@ut-dillo.UUCP (Darin Adler) (12/08/85)

This is part 4 of the source code for the Extended User Area.


#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
-----cut here-----cut here-----cut here-----cut here-----
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	EUA.Asm.4
# This archive created: Sun Dec  8 13:28:18 1985
# By:	Darin Adler ()
echo shar: extracting EUA.Asm.4 '(29228 characters)'
cat << \SHAR_EOF > EUA.Asm.4
;|
;|OUT:  D0.L'=0   D2 could not be identified.
;|              D2.L'   D2.L:.
;|      D0.L'<>0  D2 was identified.
;|              D0.L'   first four letters of name.
;|              D1.L'   last four letters of name.
;|              D2.L'   offset from the label to D2.L.
;|
;|Destroys D1,D3,A0,A1.
;|

LabelScan
		MOVE.B	LabelEnabled,D3		;If there is no table of labels, do nothing.
		MOVEM.L	D4/D5,-(SP)		;Save registers.
		BMI.S	@20
		MOVE.L	LabelTable,A0
		MOVE.W	NumLabels,D3
		MOVEQ	#-1,D5			;Assume that the best fit was 4294967295 bytes off.
		BRA.S	@10
@1		MOVE.L	A0,A1			;Which type of a label is this?
		TST.B	(A1)
		BEQ.S	@2
		CMP.L	(A1)+,D6		;Resource-type.  The resource type and ID must
		BNE.S	@5			;match exactly.
		CMP.W	(A1)+,D7
		BNE.S	@5
		MOVEQ	#0,D4			;Get the address pointed by this label into D4.
		MOVE.W	(A1)+,D4
		ADD.L	A4,D4
		BRA.S	@3
@2		MOVE.L	(A1)+,D4		;Absolute-type.  The given location must be below
		CMP.L	(A1)+,D2		;the maximum address given.  If it is, get the
		BCC.S	@5			;address pointed by this label into D4.
@3		SUB.L	D4,D2
		BCS.S	@4			;Calculate the difference between D4 and the
		CMP.L	D5,D2			;location given, and check if this is a closest
		BCC.S	@4			;match.
		MOVE.L	D2,D5
		MOVE.L	(A1)+,D0		;If so, copy the name into D0 and D1 and the
		MOVE.L	(A1),D1			;difference into D5.
@4		ADD.L	D4,D2
@5		ADD.W	#16,A0
@10		DBRA	D3,@1
		LEA	UALabelTableEnd,A1	;Check if we were scanning the built in table.
		CMP.L	A0,A1
		BEQ.S	@21			;If so, we are done
@20		LEA	UALabelTable,A0
		MOVE.W	#NumUALabels,D3
		BRA.S	@10
@21		TST.L	D0			;If a good label has been found, put the difference
		BEQ.S	@11			;into D2.
		MOVE.L	D5,D2
@11		MOVEM.L	(SP)+,D4/D5		;Restore registers.
@12		RTS


		;####################################
		;##                                ##
		;##  Heap identification routines  ##
		;##                                ##
		;####################################


		STRING_FORMAT	2		;Precede strings with length byte.

Heap.V1
		DC	GrayRgn			;Locations of some low memory locations that
		DC	MenuList		;contain handles.
		DC	TEScrpHandle		;To add more, instert additional addresses here and
		DC	ScrapHandle		;put their names into Heap.L1.
		DC	SaveVisRgn
Heap.V1End

Heap.V2
		DC.B	visRgn,clipRgn,picSave,rgnSave,polySave
		DC.B	structRgn,contRgn,updateRgn
		DC.B	wDataHandle,wTitleHandle,windowPic
		DC.B	items,teHandle		;Only in dialog windows.

Heap.FInfo	DC.B	'FinderInfo'
Heap.Control	DC.B	'Control'
Heap.DI		DC.B	'Item #$'
Heap.DI2	DC.B	' Type $'
Heap.W2		DC.B	'(Window @$'
Heap.ParamText	DC.B	'ParamText'
Heap.Window	DC.B	'Window #$'
Heap.Kind	DC.B	', Kind $'
Heap.Map	DC.B	'Resource map $'
Heap.WMgrPort	DC.B	'WMgrPort'
Heap.RPSpace	DC.B	') '
Heap.RP8Spaces	DC.B	')        '

Heap..
Heap.L1
		DC.B	'GrayRgn'		;See Heap.V1 on how to add more names here.
		DC.B	'MenuList'
		DC.B	'TEScrap'
		DC.B	'Scrap'
		DC.B	'SaveVisRgn'
Heap.L2
		DC.B	'VisRgn','ClipRgn','PicSave','RgnSave','PolySave'
		DC.B	'StructRgn','ContRgn','UpdateRgn'
		DC.B	'WData','WTitle','WPic'
		DC.B	'Items','TEHandle'

		.ALIGN	2

		STRING_FORMAT 0			;Normal strings

;+--------------------------------+
;| Identify the heap block at A3. |
;+--------------------------------+
;|
;|ENTRY: HeapIdentify
;|
;|IN:   D3.W:   0 if nonrelocatable block, 1 if relocatable block, 2 if resource relocatable block.
;|      A1:     ^heap zone containing the block.
;|      A2:     ^text area for the information about the block.
;|      A3:     ^block.
;|      A4:     another pointer into the text area.  See the manual.
;|      A5:     ^Monitor's variables.
;|      A6:     ^handle if this is a relocatable block.
;|
;|OUT:  A2'     A2: moved past the text stored.
;|
;|Destroys D0-D7,A0,A1,A3,A4,A6.
;|

HeapIdentify
		SUBQ.W	#1,D3			;Look only at unidentified relocatable blocks and
		BEQ.S	Heap.Relocatable		;nonrelocatable blocks.
		BCC.S	Heap.RTS
		MOVEQ	#18,D1			;This is a nonrelocatable block.  Print 19 spaces.
		MOVEQ	#' ',D0
@1		MOVE.B	D0,(A2)+
		DBRA	D1,@1
		CMP.L	WMgrPort,A3		;Is this the Window Manager
		BNE.S	@2			;port?
		MOVEQ	#Heap.WMgrPort-Heap..,D7
		BRA.S	Heap.PString

@2		LEA	WindowList-nextWindow,A0;Scan the window list to check if this block is in
		MOVEQ	#-1,D0			;it.
@3		MOVE.L	nextWindow(A0),A0
		ADDQ.B	#1,D0
		BSR	CheckA0
		BCS.S	Heap.RTS		;The list is over; quit.
		CMP.L	A0,A3
		BNE.S	@3
		MOVEQ	#Heap.Window-Heap..,D7	;This block is in the list.
		BSR.S	Heap.PString
		JSR	_Put2Dig		;Display both the window number and kind.
		MOVEQ	#Heap.Kind-Heap..,D7
		MOVE.W	windowKind(A0),D0
Heap.S.D	BSR.S	Heap.PString		;Print a string and then a number.
		JMP	_Put4Dig


;+----------------------------------------------------+
;| Transfer a string from the string list onto (A2)+. |
;+----------------------------------------------------+
;|
;|ENTRY: Heap.IString
;|
;|IN:   A2:     ^destination text.
;|      D1.W:   string number (0=first, 1=second, etc.)
;|      D7.W:   offset to the first string from Heap..
;|
;|OUT:  A2'     A2: moved past the copied string.
;|
;|Destroys D1,D7.
;|
;|ENTRY: Heap.PString
;|
;|Same as above, except that D1.W: is set to zero.
;|

Heap.PString	MOVEQ	#0,D1			;Get the first string encountered in list.
Heap.IString	MOVE.L	A0,-(SP)		;Get the D1th string after the one at Heap..+D7.
		LEA	Heap..,A0		;A0 was saved.
		ADD.W	D7,A0
		MOVEQ	#0,D7
		BRA.S	@1
@2		ADD.W	D7,A0
@1		MOVE.B	(A0)+,D7		;Get the length of a string.
		DBRA	D1,@2			;If indexing, skip past that string.
		BRA.S	@3
@4		MOVE.B	(A0)+,(A2)+		;Copy the string into the destination.
@3		DBRA	D7,@4
		MOVE.L	(SP)+,A0		;Restore A0 and exit.
Heap.RTS	RTS

Heap.Relocatable
		MOVE.W	#'  ',(A2)+		;Print two spaces.
		MOVE.L	CurrentA5,A0
		BSR.S	@49			;Check if this block is the Finder information
		BCS.S	@1			;handle.
		MOVEQ	#Heap.FInfo-Heap..,D7
		CMP.L	16(A0),A6
		BEQ.S	Heap.PString		;Yes.  Print the appriopriate information.
@1		MOVEQ	#(Heap.V1End-Heap.V1)/2-1,D1
		LEA	Heap.V1End,A0
		MOVEQ	#0,D7			;Check if the low memory locations have
@2		MOVE.W	-(A0),A4		;handles to this block.
		CMP.L	(A4),A6
		BEQ.S	Heap.IString
		DBRA	D1,@2
		MOVEQ	#'0',D2			;Check the four ParamText locations.
		LEA	DAStrings,A0
@3		CMP.L	(A0)+,A6
		BNE.S	@4
		MOVEQ	#Heap.ParamText-Heap..,D7
		BSR.S	Heap.PString
		MOVE.B	D2,(A2)+
@9		RTS
@4		ADDQ.B	#1,D2
		CMP.B	#'4',D2
		BNE.S	@3
		LEA	TopMapHndl-nextMap,A0	;Scan the resource file list.
@10		MOVE.L	nextMap(A0),A0
		BSR	IndirectA0		;If there is a problem indirecting, abandon scan.
		BCS.S	@11
		CMP.L	A0,A3			;Is this the desired block?
		BNE.S	@10			;NO. Scan more.
		MOVEQ	#Heap.Map-Heap..,D7	;YES.  Give information.
		MOVE.W	resFileID(A0),D0
		BRA	Heap.S.D		;Exit.

@49		BRA	CheckA0

@30		BSR	Heap.WString		;Print the type of handle found.
		MOVEQ	#Heap.L2-Heap..,D7
		BRA	Heap.IString

@11		MOVEQ	#0,D3
		MOVE.L	WMgrPort,A0
		BRA.S	@50

@51		NOT.B	D3			;Switch from scanning WMgrPort to the window list.
		BEQ.S	@9
		LEA	WindowList-nextWindow,A4;Scan the window list.
@12		MOVE.L	nextWindow(A4),A0
@50		BSR.S	@49
		BCS.S	@51			;The list is over; quit.
		MOVE.L	A0,A4			;(A4 also points to the current window.)
		MOVEQ	#4,D2
		TST.B	D3			;If this is WMgrPort, check only the port variables.
		BEQ.S	@13
		MOVEQ	#10,D2
		CMP.W	#dialogKind,windowKind(A0)
						;Is this a dialog window?
		BNE.S	@13			;NO.
		MOVEQ	#12,D2			;YES.  There is one more handle to be checked.
@13		LEA	Heap.V2,A1		;Check each handle in turn.
		MOVEQ	#0,D0
		MOVEQ	#-1,D1
@14		ADDQ.W	#1,D1
		MOVE.B	(A1)+,D0
		CMP.L	0(A0,D0),A6
		BEQ.S	@30			;There is a match.
		DBRA	D2,@14
		TST.B	D3			;If this is WMgrPort, begin scanning the window
		BEQ.S	@51			;list.
		CMP.W	#dialogKind,windowKind(A4)
						;Is this a dialog window?
		BNE.S	@21			;NO.
		MOVE.L	items(A4),A0
		BSR	IndirectA0		;Get the item list.
		BCS.S	@21
		TST.B	(A0)			;Don't bother checking if there are more than 256
		BNE.S	@21			;items.
		MOVE.W	(A0)+,D0
		MOVEQ	#0,D2
@20		CMP.L	(A0)+,A6
		BEQ.S	@31			;There is a match.
		ADD.W	#9,A0			;Skip past the other items and the string to the
		MOVEQ	#0,D1			;next handle.
		MOVE.B	(A0),D1
		ADDQ.W	#1,D1
		BSET	#0,D1
		ADD.W	D1,A0
		ADDQ.W	#1,D2
		DBRA	D0,@20
@21		LEA	wControlList(A4),A0	;Prepare to scan the control list.
@22		MOVE.L	(A0),A0
		CMP.L	A0,A6			;Does this control match the handle?
		BEQ.S	@33
		BSR.S	IndirectA0		;NO.  Go check the next one.
		BCC.S	@22
		BRA.S	@12

@31		BSR.S	Heap.WString		;Identify the current window.
		MOVEQ	#Heap.DI-Heap..,D7
		BSR.S	Heap.toPString
		MOVE.W	D2,D0
		BSR.S	@32			;Print the item number.
		MOVEQ	#Heap.DI2-Heap..,D7
		BSR.S	Heap.toPString
		MOVE.B	8(A0),D0
@32		JMP	_Put2Dig

@33		BSR.S	Heap.WString		;Identify the current window and just print that
		MOVEQ	#Heap.Control-Heap..,D7	;this control belongs to that window.
Heap.toPString	BRA	Heap.PString

Heap.WString
		MOVE.W	D1,-(SP)		;Identify the current window.
		TST.B	D3
		BNE.S	@1
		MOVE.B	#'(',(A2)+		;This is the WMgrPort.
		MOVEQ	#Heap.WMgrPort-Heap..,D7
		BSR.S	Heap.toPString
		MOVEQ	#Heap.RP8Spaces-Heap..,D7
		BSR.S	Heap.toPString
		BRA.S	@2
@1		MOVEQ	#Heap.W2-Heap..,D7	;Print the address of the current window.
		BSR.S	Heap.toPString
		MOVE.L	A4,D0
		JSR	_Put6Dig		;Give the address of the window.
		MOVEQ	#Heap.RPSpace-Heap..,D7
		BSR.S	Heap.toPString
@2		MOVE.W	(SP)+,D1
		RTS


;+-----------------------------------------------------+
;| Dereference A0, checking it to make sure it is even |
;| and non-NIL both before and after dereferencing.    |
;+-----------------------------------------------------+
;|
;|ENTRY: IndirectA0
;|
;|IN:   A0:     pointer
;|
;|OUT:  Carry set   A0: or (A0:) was NIL or odd.
;|              A0'     unpredictable.
;|      Carry clear otherwise
;|              A0'     (A0:)
;|
;|Destroys D7.
;|
;|
;+----------------------------------------+
;| Make sure that A0 is even and non-NIL. |
;+----------------------------------------+
;|
;|ENTRY: CheckA0
;|
;|IN:   A0:     pointer
;|
;|OUT:  Carry set   A0: was NIL or odd.
;|      Carry clear otherwise
;|
;|Destroys D7.
;|

IndirectA0	BSR.S	CheckA0			;Check A0 before dereferencing.
		BCS.S	CheckA0.RTS		;If error do nothing.
		MOVE.L	(A0),A0			;Dereference it and check again.
CheckA0		MOVE.L	A0,D7			;Make sure that A0 is both non-NIL and even.
		BEQ.S	@1
		LSR.B	#1,D7
		RTS
@1		SUBQ.L	#1,D7			;Set the carry flag if it isn't.
CheckA0.RTS	RTS


		;##########################
		;##                      ##
		;##  Discipline section  ##
		;##                      ##
		;##########################


DisciplineInit
		LEA	updating,A0
		CLR.L	(A0)		;Initialize the Begin/EndUpdate.
		RTS

retOK
		MOVEQ	#0,D7
		RTS
retErr
		MOVE	#%01000,CCR	;Set the N bit to 1.
		RTS

		MACRO	ErrText	code,string	=
err{code}	TRAPMon	'? {string}'
retErr{code}	MOVE.W	#err{code}-A,D7
		BRA	retErr
		|


CheckRAM

;Given an address in D0, this checks to see if it is even.
;It also checks that it is between 0 and MemTop.
;It returns D0 with the high byte masked off.

		BTST	#0,D0		;odd address
		BNE.S	retErrOdd
CheckOddRAM
		AND.L	Lo3Bytes,D0	;mask off high byte
		BEQ.S	retErrZero
CheckRAM.
		CMP.L	RealMemTop,D0
		BHS.S	retErrAddress	;too high

		BRA.S	retOK

		ErrText	Zero,NIL address
		ErrText	Odd,odd address
		ErrText	Address,address

CheckROM

;Given an address in D0, this checks to see if it is even.
;It also checks that it is between $400000 and $40FFFF.
;It returns D0 with the high byte masked off.

		BTST	#0,D0		;odd address
		BNE.S	retErrOdd
CheckOddROM
		AND.L	Lo3Bytes,D0	;mask off high byte
		BEQ.S	retErrZero
CheckROM.
		CMP.L	#$400000,D0
		BLO.S	retErrAddress	;too low

		CMP.L	#$410000,D0
		BHS.S	retErrAddress	;too high

		BRA	retOK

CheckAddress
		BSR	CheckRAM
		BPL.S	@1
		BSR.S	CheckROM.
@1
		RTS

CheckOddAddress
		BSR	CheckOddRAM
		BPL.S	@1
		BSR	CheckROM.
@1
		RTS

CheckString
		BSR.S	CheckOddAddress
		BMI	retErrString
		MOVE.L	D0,A0
		ADD.B	(A0),D0
		BSR.S	CheckOddAddress
		BMI	retErrStringLength
		RTS

		ErrText	String,string
		ErrText	StringLength,string length

CheckJT
		BSR	CheckRAM
		BMI.S	retErrJT

		CMP.L	BufPtr,D0
		BHS.S	retErrJT
		SUB.L	CurrentA5,D0
		BLO.S	retErrJT
		MOVEQ	#0,D1
		MOVE.W	CurJTOffset,D1
		SUB.L	D1,D0
		BLO.S	retErrJT

		AND.B	#3,D0
		SUBQ.B	#2,D0
		BNE.S	retErrJT

		BRA	retOK

		ErrTExt	JT,jump table

CheckZone

;Given a heap zone address in D0, this checks to see that D0 is a valid
;heap zone pointer.
;It trashes register D0.  A1 is set to point to the zone header.

		BSR	CheckRAM
		BMI.S	retErrZonePtr

		MOVE.L	D0,A1		;check fields of this heap

		ADD.L	#heapData,D0	;point to the first byte of the heap

		CMP.L	bkLim(A1),D0	;get the top of the heap
		BHS.S	retErrZone	;if the header is too high, it is screwed up

		MOVE.L	bkLim(A1),D0
		BSR	CheckRAM
		BMI.S	retErrZone

		RTS

		ErrText	ZonePtr,THz
		ErrText	Zone,Zone

CheckBlock

;Given a heap zone address in D0 and a block pointer in A0, this checks
;to see that D0 is a valid heap zone pointer and that A0 falls within
;the zone.
;It trashes registers A1 and D0.

		CMP.L	D0,A0		;compare with the header
		BLO	retErr

		BSR.S	CheckZone
		BMI	retErr

		CMP.L	bkLim(A1),A0	;compare with the top of the heap
		BHS	retErr

		BRA	retOK

CheckPtr

;Given an address in D0, this checks to see if it is a valid pointer.
;It trashes registers D0, A0 and A1.

		BSR	CheckRAM
		BMI.S	retErrPtr	;check if pointer is good at all

		MOVE.L	D0,A0		;look at block more closely

		MOVE.B	tagBC-blkData(A0),D0
		AND.B	#tybkMask<<6,D0	;get the block type
		CMP.B	#tybkNRel<<6,D0	;is is a non-relocatable?
		BNE.S	retErrPtr

		MOVE.L	handle-blkData(A0),D0
		BSR.S	CheckBlock	;get a pointer to the heap zone
		BMI.S	retErrPtr

		RTS

		ErrText	Ptr,Ptr

CheckHandle

;Given an address in D0, this checks to see if it is a valid handle.
;It trashes registers D0, A0 and A1.

		BSR	CheckRAM
		BMI.S	retErrHandle

		MOVE.L	D0,A1		;save the master pointer address for later

		MOVE.L	D0,A0
		MOVE.L	(A0),D0		;deref handle
		BEQ	retOK		;purged handle is OK (master pointer=0)

		BSR	CheckRAM
		BMI.S	retErrHandle	;check if master pointer is valid

		MOVE.L	D0,A0		;look at block more closely

		MOVE.B	tagBC-blkData(A0),D0
		AND.B	#tybkMask<<6,D0	;get the block type
		CMP.B	#tybkRel<<6,D0	;is is a relocatable?
		BNE.S	retErrHandle

		MOVE.L	A1,D0		;get a pointer to the heap zone
		SUB.L	handle-blkData(A0),D0
		BSR.S	CheckBlock	;by subtracting the relative handle
		BMI.S	retErrHandle	;from the absolute handle and check it

		RTS

		ErrText	Handle,Handle

CheckFakeHandle

;This is just like CheckHandle except the handle can be a "fake" one.

		BSR	CheckAddress
		BMI.S	retErrHandle

		MOVE.L	D0,A0
		MOVE.L	(A0),D0
		BEQ	retOK
		BSR	CheckAddress
		BMI.S	retErrHandle

		RTS

CheckFullHandle

;This is just like CheckHandle except the handle cannot be empty.

		MOVE.L	D0,-(SP)
		BSR.S	CheckHandle
		MOVEA.L	(SP)+,A0
		BMI.S	retErrHandle

		MOVE.L	(A0),D0
		AND.L	Lo3Bytes,D0
		BEQ.S	retErrEmptyHandle

		BRA	retOK

		ErrText	EmptyHandle,empty Handle

CheckFakeFullHandle

;This is just like CheckFullHandle except the handle can be a "fake" one.

		BSR	CheckAddress
		BMI	retErrHandle

		MOVE.L	D0,A0
		MOVE.L	(A0),D0
		BSR	CheckAddress
		BMI	retErrHandle

		RTS

CheckRect

;Given a pointer to a rectangle in D0, it checks that it is sensible.
;It trashes A0 and returns the right-left value in D0 if it is successful.

		BSR	CheckAddress
		BMI.S	retErrRectPtr
CheckRect.
		MOVE.L	D0,A0

		MOVE.W	bottom(A0),D0
		SUB.W	top(A0),D0
		BLT.S	retErrRect

		MOVE.W	right(A0),D0
		SUB.W	left(A0),D0
		BLT.S	retErrRect

		BRA	retOK

		ErrText	RectPtr,^Rect
		ErrText	Rect,Rect

CheckBitMap

;Given a bit map pointer in D0, this checks that it is a valid bit map.

		BSR	CheckAddress
		BMI.S	retErrBitMapPtr
CheckBitMap.
		MOVE.L	D0,A1

		MOVE.L	baseAddr(A1),D0
		BSR	CheckAddress
		BMI.S	retErrBaseAddr

		MOVE.L	A1,D0
		ADD.L	#bounds,D0
		BSR	CheckRect.
		BMI.S	retErrBounds

		MOVE.W	rowBytes(A1),D1
		BTST	#0,D1
		BNE	retErrRowBytes

		MOVE.W	bounds+bottom(A1),D0
		SUB.W	bounds+top(A1),D0
		MULU	D1,D0		;calculate the size of this bitmap
		AND.L	#$FFFF,D0	;mask off the low word
		ADD.L	baseAddr(A1),D0	;calculate the last address of this bitmap
		BSR	CheckAddress
		BMI.S	retErrBitMap

		RTS

		ErrText	BitMapPtr,^BitMap
		ErrText	BitMap,BitMap
		ErrText	BaseAddr,baseAddr
		ErrText	Bounds,bounds
		ErrText	RowBytes,rowBytes

CheckCursor

;Given a cursor pointer in D0, this checks the hot spot.

		BSR	CheckAddress
		BMI.S	retErrCursorPtr
CheckCursor.
		MOVE.L	D0,A0		;point to that hot spot
		MOVE.W	hotSpot+h(A0),D0
		CMP.W	#16,D0
		BHI.S	retErrHotSpot
		MOVE.W	hotSpot+v(A0),D0
		CMP.W	#16,D0
		BHI.S	retErrHotSpot

		BRA	retOK

		ErrText	CursorPtr,^Cursor
		ErrText	HotSpot,hotSpot

CheckPPR

;Given an address in D0, this checks if it is a good Region or Picture
;or Polygon.
;It trashes A0, A1, D0 and D1.

		MOVE.L	D0,D1

		BSR	CheckFullHandle
		BMI.S	@1

		MOVE.L	D1,A0
		MOVE.L	(A0),A0
		MOVE.W	(A0)+,D0	;get the PPR length

		CMP.W	#10,D0
		BLT	retErr		;good lengths are >= 10

		MOVE.L	A0,D0		;get the PPR pointer
		BSR	CheckRect.
@1
		RTS

CheckPict
		BSR.S	CheckPPR
		BMI.S	retErrPict
		RTS

		ErrText	Pict,PicHandle

CheckPoly
		BSR.S	CheckPPR
		BMI.S	retErrPoly
		RTS

		ErrText	Poly,PolyHandle

CheckRgn
		BSR.S	CheckPPR
		BMI.S	retErrRgn
		RTS

		ErrText	Rgn,RgnHandle

CheckPort

;Given a grafPort in D0, this checks just about every thing that you
;can check.

		BSR	CheckRAM
		BMI.S	retErrPort
CheckPort.
		MOVE.L	D0,A2		;point to the port

		ADD.L	#portBits,D0	;point to the bitMap
		BSR	CheckBitMap.
		BMI	@3

		MOVE.L	A2,D0
		ADD.L	#portRect,D0	;point to the rectangle
		BSR	CheckRect.
		BMI.S	retErrPortRect

		MOVE.L	visRgn(A2),D0	;check this region
		BSR	CheckRgn
		BMI.S	retErrVisRgn

		MOVE.L	clipRgn(A2),D0	;check this region
		BSR	CheckRgn
		BMI.S	retErrClipRgn

		MOVE.L	grafProcs(A2),D0
		BEQ.S	@2
		BSR	CheckAddress
		BMI.S	retErrGrafProcs

		MOVE.L	D0,A0

		MOVEQ	#13-1,D1
@1
		MOVE.L	(A0)+,D0
		BSR	CheckAddress
		BMI.S	retErrGrafProcs
		DBRA	D1,@1
@2
		BRA	retOK
@3
		RTS

		ErrText	Port,GrafPtr
		ErrText	PortRect,portRect
		ErrText	VisRgn,visRgn
		ErrText	ClipRgn,clipRgn
		ErrText	GrafProcs,grafProcs

CheckWindow

		BSR	CheckAddress
		BMI	retErrWindow
CheckWindow.
		BSR	CheckPort.
		BMI	@4

		MOVE.L	structRgn(A2),D0	;check this region
		BSR	CheckRgn
		BMI	retErrStructRgn

		MOVE.L	contRgn(A2),D0		;check this region
		BSR	CheckRgn
		BMI	retErrContRgn

		MOVE.L	updateRgn(A2),D0	;check this region
		BSR	CheckRgn
		BMI	retErrUpdateRgn

		MOVE.L	windowDef(A2),D0	;check the defProc
		BSR	CheckFakeHandle
		BMI	retErrDefProc

		MOVE.L	wTitleHandle(A2),D0	;check the title
		BEQ.S	@1
		BSR	CheckFullHandle
		BMI	retErrWTitle
@1
		MOVE.L	wControlList(A2),D0	;check the control list
		BEQ.S	@2
		BSR	CheckFullHandle
		BMI	retErrControlList
@2
		MOVE.L	nextWindow(A2),D0	;check the next window
		BEQ.S	@3
		BSR	CheckRAM
		BMI	retErrNextWindow
@3
		MOVE.L	windowPic(A2),D0	;check the picture handle
		BEQ.S	@4
		BSR	CheckFullHandle
		BMI	retErrWindowPic
@4
		RTS

		ErrText	Window,WindowPtr
		ErrText	StructRgn,strucRgn
		ErrText	ContRgn,contRgn
		ErrText	UpdateRgn,updateRgn
		ErrText	WTitle,titleHandle
		ErrText	ControlList,controlList
		ErrText	NextWindow,nextWindow
		ErrText	WindowPic,windowPic

CheckBehind

		TST.L	D0
		BEQ	retOK
		CMP.L	MinusOne,D0		;-1 is also OK
		BEQ	retOK

		BSR	CheckWindow

		RTS

CheckControl

		MOVE.L	D0,A2

		BSR	CheckFullHandle
		BMI	retErrControl
CheckControl.
		MOVE.L	(A2),D0
		ADD.L	#contrlRect,D0		;point to the rectangle
		BSR	CheckRect.
		BMI	retErrContrlRect

		MOVE.L	(A2),A2

		MOVE.L	nextControl(A2),D0	;check the nextControl
		BEQ.S	@1
		BSR	CheckFullHandle
		BMI	retErrNextControl
@1
		MOVE.L	contrlDefHandle(A2),D0	;check the defProc
		BSR	CheckFakeHandle
		BMI	retErrDefProc

		MOVE.L	contrlAction(A2),D0	;check the actionProc
		BEQ.S	@2
		CMP.L	MinusOne,D0		;-1 is ok, too
		BEQ.S	@2
		BSR	CheckAddress
		BMI.S	retErrAction
@2
		MOVE.L	contrlOwner(A2),D0	;check the owner
		BSR	CheckRAM
		BMI.S	retErrContrlOwner

		RTS

		ErrText	Control,ControlHandle
		ErrText	ContrlRect,contrlRect
		ErrText	NextControl,nextControl
		ErrText	Action,actionProc
		ErrText	ContrlOwner,contrlOwner

CheckMenu

		MOVE.L	D0,A2

		BSR	CheckFullHandle
		BMI.S	retErrMenu

		MOVE.L	(A2),A2

		MOVE.L	menuDefHandle(A2),D0	;check the menu defProc
		BSR	CheckFakeHandle
		BMI.S	retErrDefProc

		RTS

		ErrText	Menu,MenuHandle
		ErrText	DefProc,defProc handle

CheckTERec

		MOVE.L	D0,A2

		BSR	CheckFullHandle
		BMI.S	retErrTE

		MOVE.L	(A2),D0
		ADD.L	#teDestRect,D0	;point to the rectangle
		BSR	CheckRect.
		BMI	retErrDestRect

		MOVE.L	(A2),D0
		ADD.L	#teViewRect,D0	;point to the rectangle
		BSR	CheckRect.
		BMI	retErrViewRect

		MOVE.L	(A2),A2

		MOVE.L	teTextH(A2),D0	;check the text
		BSR	CheckFullHandle
		BMI	retErrTextH

		MOVE.L	teWordBreak(A2),D0
		BEQ.S	@1
		BSR	CheckAddress
		BMI	retErrWordBreak
@1
		MOVE.L	teClikProc(A2),D0
		BEQ.S	@2
		BSR	CheckAddress
		BMI	retErrClikProc
@2
		MOVE.L	teHiHook(A2),D0
		BEQ.S	@3
		BSR	CheckAddress
		BMI	retErrHiHook
@3
		MOVE.L	teCarHook(A2),D0
		BEQ.S	@4
		BSR	CheckAddress
		BMI	retErrCarHook
@4
		MOVE.L	teGrafPort(A2),D0
		BSR	CheckRAM
		BMI	retErrInPort

		RTS

		ErrText	TE,TEHandle
		ErrText	DestRect,destRect
		ErrText	ViewRect,viewRect
		ErrText	TextH,text handle
		ErrText	WordBreak,wordBreak
		ErrText	ClikProc,clikLoop
		ErrText	HiHook,highHook
		ErrText	CarHook,caretHook
		ErrText InPort,TE GrafPtr

CheckDialog

		BSR	CheckAddress
		BMI.S	retErrDialog
CheckDialog.
		BSR	CheckWindow.
		BMI	@1

		MOVE.L	items(A2),D0
		BSR	CheckFullHandle
		BMI.S	retErrItemList

		MOVE.L	teHandle(A2),D0
		BEQ.S	@1
		BSR	CheckFullHandle
		BMI.S	retErrEditText
@1
		RTS

		ErrText	Dialog,DialogPtr
		ErrText	ItemList,item list
		ErrText	EditText,editText item

;+------------------------------------------------------------------+
;| The following code is for actual use of the Check... code above. |
;+------------------------------------------------------------------+

ROMA0
		MOVE.L	RegA0,D0	;get ROM location in register
.CheckROM	BRA	CheckROM

RAMA0
		MOVE.L	RegA0,D0	;get RAM location in register
.CheckRAM	BRA	CheckRAM

RAMA1
		MOVE.L	RegA1,D0	;get RAM location in register
		BRA.S	.CheckRAM

RAM0
		MOVE.L	Stack0,D0	;get RAM location in register
		BRA.S	.CheckRAM

RAM2
		MOVE.L	Stack2,D0	;get RAM location in register
		BRA.S	.CheckRAM

RAM4
		MOVE.L	Stack4,D0	;get RAM location in register
		BRA.S	.CheckRAM

RAM6
		MOVE.L	Stack6,D0	;get RAM location in register
		BRA.S	.CheckRAM

RAM8
		MOVE.L	Stack8,D0	;get RAM location in register
		BRA.S	.CheckRAM

RAM22
		MOVE.L	Stack22,D0	;get RAM location in register
		BRA.S	.CheckRAM

OddRAMA0
		MOVE.L	RegA0,D0	;get RAM location in register
.CheckOddRAM	BRA	CheckOddRAM

OddRAM4
		MOVE.L	Stack4,D0	;get RAM location in register
		BRA.S	.CheckOddRAM

AddressA0
		MOVE.L	RegA0,D0	;get address in register
.CheckAddress	BRA	CheckAddress

AddressA1
		MOVE.L	RegA1,D0	;get address in register
		BRA.S	.CheckAddress

Address0
		MOVE.L	Stack0,D0	;get address in register
		BRA.S	.CheckAddress

Address4
		MOVE.L	Stack4,D0	;get address in register
		BRA.S	.CheckAddress

Address8
		MOVE.L	Stack8,D0	;get address in register
		BRA.S	.CheckAddress

Address10
		MOVE.L	Stack10,D0	;get address in register
		BRA.S	.CheckAddress

Address16
		MOVE.L	Stack16,D0	;get address in register
		BRA.S	.CheckAddress

OddAddressA0
		MOVE.L	RegA0,D0	;get address in register
.CheckOddAddress
		BRA	CheckOddAddress

OddAddress0
		MOVE.L	Stack0,D0	;get address in register
		BRA.S	.CheckOddAddress

OddAddress4
		MOVE.L	Stack4,D0	;get address in register
		BRA.S	.CheckOddAddress

OddAddress8
		MOVE.L	Stack8,D0	;get address in register
		BRA.S	.CheckOddAddress

OddAddress12
		MOVE.L	Stack12,D0	;get address in register
		BRA.S	.CheckOddAddress

StringA0
		MOVE.L	RegA0,D0	;get string in register
.CheckString	BRA	CheckString

String0
		MOVE.L	Stack0,D0	;get string in register
		BRA.S	.CheckString

String2
		MOVE.L	Stack2,D0	;get string in register
		BRA.S	.CheckString

String4
		MOVE.L	Stack4,D0	;get string in register
		BRA.S	.CheckString

String10
		MOVE.L	Stack10,D0	;get string in register
		BRA.S	.CheckString

String14
		MOVE.L	Stack14,D0	;get string in register
		BRA.S	.CheckString

String16
		MOVE.L	Stack16,D0	;get string in register
		BRA.S	.CheckString

String18
		MOVE.L	Stack18,D0	;get string in register
		BRA.S	.CheckString

String20
		MOVE.L	Stack20,D0	;get string in register
		BRA.S	.CheckString

String26
		MOVE.L	Stack26,D0	;get string in register
		BRA.S	.CheckString

JTPC
		MOVE.L	RegPC,D0
.CheckJT	BRA	CheckJT

JT0
		MOVE.L	Stack0,D0
		BRA.S	.CheckJT

ZoneA0
		MOVE.L	RegA0,D0
.CheckZone	BRA	CheckZone

PtrA0
		MOVE.L	RegA0,D0	;get handle in register
.CheckPtr	BRA	CheckPtr

Ptr0
		MOVE.L	Stack0,D0	;get handle in register
		BRA.S	.CheckPtr

HandleA0
		MOVE.L	RegA0,D0	;get handle in register
.CheckHandle	BRA	CheckHandle

Handle0
		MOVE.L	Stack0,D0	;get handle in register
		BRA.S	.CheckHandle

Handle4
		MOVE.L	Stack4,D0	;get handle in register
		BRA.S	.CheckHandle

FullHandleA0
		MOVE.L	RegA0,D0	;get handle in register
.CheckFullHandle
		BRA	CheckFullHandle

FullHandleA1
		MOVE.L	RegA1,D0	;get handle in register
		BRA.S	.CheckFullHandle

FullHandle0
		MOVE.L	Stack0,D0	;get handle in register
		BRA.S	.CheckFullHandle

FullHandle2
		MOVE.L	Stack2,D0	;get handle in register
		BRA.S	.CheckFullHandle

FullHandle4
		MOVE.L	Stack4,D0	;get handle in register
		BRA.S	.CheckFullHandle

FullHandle8
		MOVE.L	Stack8,D0	;get handle in register
		BRA.S	.CheckFullHandle

FullHandle10
		MOVE.L	Stack10,D0	;get handle in register
		BRA.S	.CheckFullHandle

FakeFullHandle0
		MOVE.L	Stack0,D0	;get handle in register
.CheckFakeFullHandle
		BRA	CheckFakeFullHandle

Cursor0
		MOVE.L	Stack0,D0	;get cursor location in register
.CheckCursor	BRA	CheckCursor

Rect0
		MOVE.L	Stack0,D0	;get rectangle in register
.CheckRect	BRA	CheckRect
		RTS

Rect2
		MOVE.L	Stack2,D0	;get rectangle in register
		BRA.S	.CheckRect

Rect4
		MOVE.L	Stack4,D0	;get rectangle in register
		BRA.S	.CheckRect

Rect6
		MOVE.L	Stack6,D0	;get rectangle in register
		BRA.S	.CheckRect

Rect8
		MOVE.L	Stack8,D0	;get rectangle in register
		BRA.S	.CheckRect

Rect10
		MOVE.L	Stack10,D0	;get rectangle in register
		BRA.S	.CheckRect

Rect18
		MOVE.L	Stack18,D0	;get rectangle in register
		BRA.S	.CheckRect

Rect22
		MOVE.L	Stack22,D0	;get rectangle in register
		BRA.S	.CheckRect

Rgn0
		MOVE.L	Stack0,D0	;get region in register
.CheckRgn	BRA	CheckRgn

Rgn4
		MOVE.L	Stack4,D0	;get region in register
		BRA.S	.CheckRgn

Rgn8
		MOVE.L	Stack8,D0	;get region in register
		BRA.S	.CheckRgn

Rgn18
		MOVE.L	Stack18,D0	;get region in register
		BRA.S	.CheckRgn

Poly0
		MOVE.L	Stack0,D0	;get polygon in register
.CheckPoly	BRA	CheckPoly

Poly4
		MOVE.L	Stack4,D0	;get polygon in register
		BRA.S	.CheckPoly

Poly8
		MOVE.L	Stack8,D0	;get polygon in register
		BRA.S	.CheckPoly

Pict0
		MOVE.L	Stack0,D0	;get picture in register
.CheckPict	BRA	CheckPict

Pict4
		MOVE.L	Stack4,D0	;get picture in register
		BRA.S	.CheckPict

Port0
		MOVE.L	Stack0,D0	;get port in register
.CheckPort	BRA	CheckPort

Window0
		MOVE.L	Stack0,D0	;get window in register
.CheckWindow	BRA	CheckWindow

Window2
		MOVE.L	Stack2,D0	;get window in register
		BRA.S	.CheckWindow

Window4
		MOVE.L	Stack4,D0	;get window in register
		BRA.S	.CheckWindow

Window6
		MOVE.L	Stack6,D0	;get window in register
		BRA.S	.CheckWindow

Window8
		MOVE.L	Stack8,D0	;get window in register
		BRA.S	.CheckWindow

Window22
		MOVE.L	Stack22,D0	;get window in register
		BRA.S	.CheckWindow

Behind0
		MOVE.L	Stack0,D0	;check the behind field
.CheckBehind	BRA	CheckBehind

Behind6
		MOVE.L	Stack6,D0	;check the behind field
		BRA.S	.CheckBehind

Behind10
		MOVE.L	Stack10,D0	;check the behind field
		BRA.S	.CheckBehind

Dialog0
		MOVE.L	Stack0,D0	;check the dialog
.CheckDialog	BRA	CheckDialog

Dialog6
		MOVE.L	Stack6,D0	;check the dialog
		BRA.S	.CheckDialog

Dialog12
		MOVE.L	Stack12,D0	;check the dialog
		BRA.S	.CheckDialog

Dialog14
		MOVE.L	Stack14,D0	;check the dialog
		BRA.S	.CheckDialog

Menu0
		MOVE.L	Stack0,D0	;get menu handle in register
.CheckMenu	BRA	CheckMenu

Menu2
		MOVE.L	Stack2,D0	;get menu handle in register
		BRA.S	.CheckMenu

Menu4
		MOVE.L	Stack4,D0	;get menu handle in register
		BRA.S	.CheckMenu

Menu6
		MOVE.L	Stack6,D0	;get menu handle in register
		BRA.S	.CheckMenu

Control0
		MOVE.L	Stack0,D0	;get control handle in register
.CheckControl	BRA	CheckControl

Control2
		MOVE.L	Stack2,D0	;get control handle in register
		BRA.S	.CheckControl

Control4
		MOVE.L	Stack4,D0	;get control handle in register
		BRA.S	.CheckControl

Control8
		MOVE.L	Stack8,D0	;get control handle in register
		BRA.S	.CheckControl

Control14
		MOVE.L	Stack14,D0	;get control handle in register
		BRA.S	.CheckControl

ProcA0
		MOVE.L	RegA0,D0	;get the proc into a register
.CheckProc	BEQ	retOK
		BRA	CheckAddress

Proc0
		MOVE.L	Stack0,D0	;get the proc into a register
		BRA.S	.CheckProc

Proc4
		MOVE.L	Stack4,D0	;get the proc into a register
		BRA.S	.CheckProc

TERec0
		MOVE.L	Stack0,D0	;get TERec handle in register
.CheckTERec	BRA	CheckTERec

BitMap0
		MOVE.L	Stack0,D0	;get bitmap pointer in register
.CheckBitMap	BRA	CheckBitMap

BitMap14
SHAR_EOF
if test 29228 -ne "`wc -c EUA.Asm.4`"
then
echo shar: error transmitting EUA.Asm.4 '(should have been 29228 characters)'
fi
#	End of shell archive
exit 0
-- 
Darin Adler
{gatech,harvard,ihnp4,seismo}!ut-sally!ut-dillo!darin

darin@ut-dillo.UUCP (Darin Adler) (12/08/85)

Part 5 of the source code for the Extended User Area.

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
-----cut here-----cut here-----cut here-----cut here-----
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	EUA.Asm.5
# This archive created: Sun Dec  8 13:28:28 1985
# By:	Darin Adler ()
echo shar: extracting EUA.Asm.5 '(24839 characters)'
cat << \SHAR_EOF > EUA.Asm.5
		MOVE.L	Stack14,D0	;get bitmap pointer in register
		BRA.S	.CheckBitMap

BitMap18
		MOVE.L	Stack18,D0	;get bitmap pointer in register
		BRA.S	.CheckBitMap

;+-----------------------------------------------+
;| These are the trap-specific checking routines |
;+-----------------------------------------------+

SetTrapAddress
		BSR	ROMA0		;if it is ROM, it's fine
		BPL.S	@1

		MOVE.L	D0,A0
		MOVE.L	SysZone,D0	;check if this routine is in the system heap
		BSR	CheckBlock
		BMI.S	retErrSysZone
@1
		RTS

		ErrText	SysZone,not in SysZone

EqualRect
Address4Address0
		BSR	Address4
		BMI.S	@1

		BSR	Address0
@1
		RTS

TENew
Rect4Rect0
		BSR	Rect4		;check one of the rectangles
		BMI.S	@1

		BSR	Rect0		;check the other rectangle
@1
		RTS

ScalePt
MapPt
		BSR	RAM8		;check the ram address
		BMI.S	@1

		BSR	Rect4Rect0	;check the two rectangles
@1
		RTS

FillRect
FillOval
Rect4RAM0
		BSR	Rect4		;check the rectangle
		BMI.S	@1

		BSR	RAM0		;check the other pointer
@1
		RTS

FillRoundRect
FillArc
PtToAngle
		BSR	Rect8		;check the rectangle
		BMI.S	@1

		BSR	RAM0		;check the other pointer
@1
		RTS

SectRect
UnionRect
		BSR	Address8
		BMI.S	@1

		BSR	Address4
		BMI.S	@1

		BSR	RAM0		;check the destination
@1
		RTS

MapRect
		BSR	Address8	;check the destination "rectangle"
		BMI.S	@1

		BSR	Rect4Rect0	;check the mapping rectangles
@1
		RTS

FillPoly
		BSR	Poly4		;check the polygon
		BMI.S	@1

		BSR	RAM0		;check the other pointer
@1
		RTS

FillRgn
		BSR	Rgn4		;check the region
		BMI.S	@1

		BSR	RAM0		;check the other pointer
@1
		RTS

CopyRgn
EqualRgn
Rgn4Rgn0
		BSR	Rgn4		;check one of the regions
		BMI.S	@1

		BSR	Rgn0		;check the other region
@1
		RTS

SectRgn
UnionRgn
DiffRgn
XorRgn
		BSR	Rgn8		;check one of the regions
		BMI.S	@1

		BSR	Rgn4Rgn0	;check the other two
@1
		RTS

MapRgn
		BSR	Rgn8		;check the region
		BMI.S	@1

		BSR	Rect4Rect0	;check the two rectangles
@1
		RTS

MapPoly
		BSR	Poly8		;check the polygon
		BMI.S	@1

		BSR	Rect4Rect0	;check the two rectangles
@1
		RTS

RectRgn
		BSR	Rgn4		;check if the destination is a region
		BMI.S	@1

		BSR	Address0	;check the source
@1
		RTS

RectInRgn
		BSR	Address4	;check if the "rectangle"
		BMI.S	@1

		BSR	Rgn0		;check if this is a region
@1
		RTS

DrawPicture
		BSR	Pict4		;check if the picture is a picture
		BMI.S	@1

		BSR	Rect0		;check if the rect is a rectangle
@1
		RTS

Rect10Rect6
		BSR	Rect10
		BMI.S	@1

		BSR	Rect6
@1
		RTS

StdBits
StdBits.
		BSR	BitMap14
		BMI.S	@1

		BSR	Rect10Rect6
		BMI.S	@1

		MOVE.L	Stack0,D0	;get the region into a register
		BEQ	retOK
		BSR	CheckRgn
@1
		RTS

CopyBits
		BSR	BitMap18
		BMI.S	@1

		BSR.S	StdBits.	;check the rest of the parameters
@1
		RTS

DragGrayRgn
DragTheRgn
		BSR	Rgn18
		BMI.S	@1

		BSR	Rect10Rect6
		BMI.S	@1

		BSR	Proc0		;check the action proc
@1
		RTS

CalcVis
SystemClick
ClipAbove
		MOVE.L	Stack0,D0	;check the window parameter
		BEQ	retOK
		BSR	CheckWindow

		RTS

CalcVisBehind
PaintOne
PaintBehind
		MOVE.L	Stack4,D0	;check the window parameter
		BEQ.S	@1
		BSR	CheckWindow
		BMI.S	@2
@1
		BSR	Rgn0		;check the region parameter
@2
		RTS

NewWindow
		MOVE.L	Stack22,D0	;check the window storage
		BEQ.S	@1
		BSR	CheckRAM
		BMI.S	@2
@1
		BSR	Rect18		;check the window rectangle
		BMI.S	@2

		BSR	String14	;check the window title
		BMI.S	@2

		BSR	Behind6		;check the behind field
@2
		RTS

DisposeWindow
		BSR	Window0		;check the window
		BMI.S	@1

		BSR	Ptr0
@1
		RTS

NewDialog
		MOVE.L	Stack26,D0	;check the dialog storage
		BEQ.S	@1
		BSR	CheckRAM
		BMI.S	@2
@1
		BSR	Rect22		;check the window rectangle
		BMI.S	@2

		BSR	String18	;check the title
		BMI.S	@2

		BSR	Behind10	;check the behind field
		BMI.S	@2

		MOVE.L	Stack0,D0	;don't need an item handle just yet
		BEQ	retOK
		BSR	CheckFullHandle	;check the items handle
@2
		RTS

DisposDialog
		BSR	Dialog0		;check the dialog
		BMI.S	@1

		BSR	Ptr0
@1
		RTS

GetNewWindow
GetNewDialog
		MOVE.L	Stack4,D0	;check the storage
		BEQ.S	@1
		BSR	CheckRAM
		BMI.S	@2
@1
		BSR	Behind0
@2
		RTS

GetWTitle
FindControl
Window4RAM0
		BSR	Window4		;check the window
		BMI.S	@1

		BSR	RAM0		;check the result place
@1
		RTS

SetWTitle
		BSR	Window4		;check the window
		BMI.S	@1

		BSR	String0		;check the new title
@1
		RTS

SendBehind
		BSR	Window4		;check one window parameter
		BMI.S	@1

		MOVE.L	Stack0,D0
		BEQ	retOK
		BSR	CheckWindow	;check the behind parameter
@1
		RTS

UpdateInit
		LEA	Updating,A0
		MOVE.L	(A0),D1
		MOVE.L	Stack0,D0
		RTS
BeginUpdate
		BSR.S	UpdateInit
		MOVE.L	D0,(A0)
		TST.L	D1
		BNE.S	retErrBadBeginUpdate
		BRA.S	Update
EndUpdate
		BSR.S	UpdateInit
		CLR.L	(A0)
		CMP.L	D1,D0
		BNE.S	retErrBadEndUpdate
Update
		BSR	CheckPort
		BMI.S	@1

		MOVE.L	updateRgn(A2),D0	;check this region
		BSR	CheckRgn
		BMI	retErrUpdateRgn
@1
		RTS

		ErrText	BadBeginUpdate,no EndUpdate
		ErrText	BadEndUpdate,<> BeginUpdate

DragWindow
GrowWindow
		BSR	Window8		;check the window
		BMI.S	@1

		BSR	Rect0		;check the rectangle
@1
		RTS

GetItemIcon
GetItemStyle
GetItemMark
GetItem
		BSR	Menu6		;check the menu
		BMI.S	@1

		BSR	RAM0		;check the address
@1
		RTS

SetItem
		BSR	Menu6		;check the menu
		BMI.S	@1

		BSR	String0		;check the string
@1
		RTS

PlotIcon
		BSR	Rect4		;check the rectangle
		BMI.S	@1

		BSR	FakeFullHandle0	;check the handle
@1
		RTS

NewControl
		BSR	Window22	;check the window
		BMI.S	@1

		BSR	Rect18		;check the rectangle
		BMI.S	@1

		BSR	String14	;check the title
@1
		RTS

GetCTitle
		BSR	Control4	;check the control
		BMI.S	@1

		BSR	RAM0		;check the address
@1
		RTS

SetCTitle
		BSR	FullHandle4	;check the control
		BMI.S	@1

		BSR	String0
@1
		RTS

DragControl
		BSR	Control14	;check the control
		BMI.S	@1

		BSR	Rect6		;check the limitRect
		BMI.S	@1

		BSR	Rect2		;check the slopRect
@1
		RTS

Dequeue
Enqueue
		BSR	RAMA0
		BMI.S	@1
		
		BSR	RAMA1
@1
		RTS

DialogSelect
		BSR	Address8	;check the event
		BMI.S	DialogSelectRTS
RAM4RAM0
		BSR	RAM4		;check one result
		BMI.S	DialogSelectRTS

		BSR	RAM0		;check the other
DialogSelectRTS
		RTS

GetAppParms
RAM8RAM4RAM0
		BSR	RAM8		;check another
		BMI.S	@1

		BSR.S	RAM4RAM0	;check more
@1
		RTS

GetResInfo
GetResInfo.
		MOVE.L	Stack8,D0
		BEQ.S	@1
		BSR	CheckRAM
		BMI.S	@3
@1
		MOVE.L	Stack4,D0
		BEQ.S	@2
		BSR	CheckRAM
		BMI.S	@3
@2
		MOVE.L	Stack0,D0
		BEQ	retOK
		BSR	CheckRAM
@3
		RTS

GetDItem
		BSR	Dialog14	;check the dialog first
		BMI.S	@1

		BSR.S	GetResInfo.	;check the other parameters
@1
		RTS

SetDItem
		BSR	Dialog12	;check the dialog first
		BMI.S	@1

		MOVE.W	Stack8,D0	;check the item type we are setting
		AND.W	#$7F,D0		;extract the type
		BEQ.S	@2		;userItem (0) is a special case
		BSR	FullHandle4	;check the item handle
		BMI.S	@1
		BRA.S	@3
@2
		MOVE.L	Stack4,D0
		BEQ.S	@3
		BSR	CheckAddress	;check the userItem proc
		BMI.S	@1
@3
		BSR	Rect0		;check the rectangle
@1
		RTS

ModalDialog
		BSR	Proc4		;check the filterProc
		BMI.S	@1

		BSR	RAM0		;check the result address
@1
		RTS

TEUpdate
		BSR	Rect4		;check the update rect
		BMI.S	@1

		BSR	TERec0
@1
		RTS

PtrToHand
		BSR	OddAddressA0
		BMI.S	@1

		TST.B	RegD0
		BNE	retErrLength

		ADD.L	RegD0,D0
		BSR	CheckOddAddress
		BMI	retErrLength
@1
		RTS

PtrToXHand
PtrAndHand
		BSR	FullHandleA1
		BMI.S	@1

		BSR	PtrToHand
@1
		RTS

HandAndHand
		BSR	FullHandleA0
		BMI.S	@1

		BSR	FullHandleA1
@1
		RTS

GetScrap
		MOVE.L	Stack8,D0
		BEQ.S	@1
		BSR	CheckFullHandle	;check the destination handle
		BMI.S	@2
@1
		BSR	RAM0		;check the offset destination
@2
		RTS

PB
		BSR	RAMA0
		BMI.S	retErrParamBlock

		MOVE.L	RegA0,A0

		MOVE.L	RegPC,A1	;get the old PC value
		BTST	#asyncTrpBit,(A1)
		BEQ.S	@1
		MOVE.L	ioCompletion(A0),D0
		BEQ.S	@1
		BSR	CheckAddress
		BMI.S	retErrCompletion
@1
		BRA	retOK

		ErrText	ParamBlock,ParamBlock
		ErrText	Completion,ioCompletion

Open
OpenRF
Create
Delete
SetFileInfo
SetFilLock
RstFilLock
SetFilType
		BSR	PB
		BMI.S	@1

		MOVE.L	ioFileName(A0),D0
		BSR	CheckString
		BMI.S	retErrFileName
@1
		RTS

		ErrText	FileName,file name

Read
		BSR	PB
		BMI.S	@1

		TST.L	ioReqCount(A0)
		BEQ	retOK

		MOVE.L	ioBuffer(A0),D0
		BSR	CheckOddRAM
		BMI.S	retErrBuffer

		ADD.L	ioReqCount(A0),D0
		SUBQ.L	#1,D0
		BSR	CheckOddRAM
		BMI.S	retErrBuffer
@1
		RTS

		ErrText	Buffer,ioBuffer

Write
		BSR	PB
		BMI.S	@1

		TST.L	ioReqCount(A0)
		BEQ	retOK

		MOVE.L	ioBuffer(A0),D0
		BSR	CheckOddAddress
		BMI.S	retErrBuffer

		ADD.L	ioReqCount(A0),D0
		SUBQ.L	#1,D0
		BSR	CheckOddAddress
		BMI.S	retErrBuffer
@1
		RTS

SetVol
UnmountVol
FlushVol
Eject
OffLine
		BSR	PB
		BMI.S	@1

		MOVE.L	ioVNPtr(A0),D0
		BEQ	retOK
		BSR	CheckString
		BMI.S	retErrVolName
@1
		RTS

		ErrText	VolName,volume name

GetVolInfo
GetVol
		BSR	PB
		BMI.S	@1

		MOVE.L	ioVNPtr(A0),D0
		BEQ	retOK
		BSR	CheckOddRAM
		BMI.S	retErrVolName
@1
		RTS

Rename
		BSR	PB
		BMI.S	@1

		MOVE.L	ioNewName(A0),D0
		BSR	CheckString
		BMI.S	retErrNewName
@1
		RTS

		ErrText	NewName,new name

GetFileInfo
		BSR	PB
		BMI.S	@1

		TST.W	ioFDirIndex(A0)
		BMI.S	@2
		BEQ.S	@2

		TST.L	ioFileName(A0)
		BEQ	retOK
@2
		MOVE.L	ioFileName(A0),D0
		BSR	CheckOddAddress
		BMI	retErrFileName
@1
		RTS

InitZone
		BSR	AddressA0
		BMI.S	@1

		MOVE.L	D0,A0

		MOVE.L	startPtr(A0),D0
		BSR	CheckRAM
		BMI.S	retErrStartPtr

		MOVE.L	limitPtr(A0),D0
		ADD.L	#10,D0
		BSR	CheckRAM
		BMI.S	retErrLimitPtr

		MOVE.L	pGrowZone(A0),D0
		BEQ.S	@2
		BSR	CheckAddress
		BMI.S	retErrGrowZone
@2
		MOVEQ	#0,D0
		MOVE.W	cMoreMasters(A0),D0
		NEG.L	D0
		ASL.L	#2,D0
		SUB.L	#52,D0
		SUB.L	startPtr(A0),D0
		ADD.L	limitPtr(A0),D0
		BMI.S	retErrSmallZone

		BRA	retOK
@1
		RTS

		ErrText	StartPtr,startPtr
		ErrText	LimitPtr,limitPtr
		ErrText	GrowZone,pGrowZone
		ErrText	SmallZone,zone too small

RecoverHandle
		BSR	RAMA0
		BMI.S	@1

		MOVE.L	D0,A0

		MOVE.L	handle-blkData(A0),D0
		ADD.L	TheZone,D0

		BSR	CheckHandle
@1
		RTS

SetApplLimit
		MOVE.L	RegA0,D0
		SUBQ.L	#2,D0
		BSR	CheckRAM

		RTS

BlockMove.
		TST.L	RegD0
		BEQ	retOK

		MOVE.L	RegA0,D0
		BSR	CheckOddAddress
		BMI.S	@1

		ADD.L	RegD0,D0
		SUBQ.L	#1,D0
		BSR	CheckOddAddress
		BMI.S	retErrLength

		MOVE.L	RegA1,D0
		BSR	CheckOddRAM
		BMI.S	@1

		ADD.L	RegD0,D0
		SUBQ.L	#1,D0
		BSR	CheckOddRAM
		BMI.S	retErrLength
@1
		RTS

		ErrText	Length,length

VInstall.
VRemove
		BSR	RAMA0
		BMI.S	@1

		MOVE.L	D0,A0

		MOVE.L	vblAddr(A0),D0
		BSR	CheckAddress
		BMI.S	retErrVBL
@1
		RTS

		ErrText	VBL,vblAddr

WriteParam
		LEA	SysParam,A0
		CMP.L	RegA0,A0
		BNE.S	retErrSysParam

		MOVEQ	#-1,D0
		CMP.L	RegD0,D0
		BNE	retErrMinusOne

		BRA	retOK

		ErrText	SysParam,SysParam
		ErrText	MinusOne,MinusOne

CmpString
		MOVE.L	RegD0,D0
		TST.W	D0
		BEQ.S	@2

		MOVE.L	RegA0,D0
		BSR	CheckOddAddress
		BMI.S	@1

		MOVE.L	RegD0,D0
		SWAP	D0
		CLR.W	D0
		SWAP	D0
		ADD.L	RegA0,D0
		SUBQ.L	#1,D0
		BSR	CheckOddAddress
		BMI	retErrStringLength
@2
		TST.W	RegD0
		BEQ	retOK

		MOVE.L	RegA1,D0
		BSR	CheckOddAddress
		BMI.S	@1

		MOVEQ	#0,D0
		MOVE.W	RegD0,D0
		ADD.L	RegA1,D0
		SUBQ.L	#1,D0
		BSR	CheckOddAddress
		BMI	retErrStringLength
@1
		RTS

UprString
		MOVE.L	RegD0,D0
		TST.W	D0
		BEQ	retOK

		MOVE.L	RegA0,D0
		BSR	CheckOddRAM
		BMI.S	@1

		MOVE.L	RegD0,D0
		SWAP	D0
		CLR.W	D0
		SWAP	D0
		ADD.L	RegA0,D0
		SUBQ.L	#1,D0
		BSR	CheckOddRAM
		BMI	retErrStringLength
@1
		RTS

StuffHex
		BSR	String0
		BMI.S	@1

		BSR	OddRAM4
@1
		RTS

StdTxMeas
		TST.W	Stack16
		BEQ.S	@2

		BSR	OddAddress12
		BMI.S	@1

		MOVEQ	#0,D0
		MOVE.W	Stack16,D0
		ADD.L	Stack12,D0
		BSR	CheckOddAddress
		BMI	retErrLength
@2
		BSR	RAM8RAM4RAM0
@1
		RTS

ScrollRect
		BSR	Rect8
		BMI.S	@1

		BSR	Rgn0
@1
		RTS

StdComment
PicComment
		TST.W	Stack4
		BEQ	retOK

		MOVE.L	Stack0,D0
		BSR	CheckFakeFullHandle
		BMI.S	@1

		MOVEQ	#0,D0
		MOVE.W	Stack4,D0
		MOVE.L	Stack0,A0
		ADD.L	(A0),D0
		BSR	CheckOddAddress
@1
		RTS

GetFNum
		BSR	String4
		BMI.S	@1

		BSR	RAM0
@1
		RTS

SetString
		BSR	FullHandle4
		BMI.S	@1

		BSR	String0
@1
		RTS

AppendMenu
		BSR	Menu4
		BMI.S	@1

		BSR	String0
@1
		RTS

ParamText
		MOVE.L	Stack12,D0
		BEQ.S	@1
		BSR	CheckString
		BMI.S	@2
@1
		MOVE.L	Stack8,D0
		BEQ.S	@3
		BSR	CheckString
		BMI.S	@2
@3
		MOVE.L	Stack4,D0
		BEQ.S	@4
		BSR	CheckString
		BMI.S	@2
@4
		MOVE.L	Stack0,D0
		BEQ	retOK
		BSR	CheckString
@2
		RTS

SetIText
		BSR	FullHandle4
		BMI.S	@1

		BSR	String0
@1
		RTS

GetIText
		BSR	FullHandle4
		BMI.S	@1

		BSR	RAM0
@1
		RTS

Munger
		MOVE.L	Stack20,D0
		BSR	CheckFullHandle
		BMI.S	@1

		MOVE.L	Stack20,A0
		_GetHandleSize
		TST.L	D0
		BMI	retErrHandle

		CMP.L	Stack16,D0
		BLO	retErrOffset

		TST.L	Stack8
		BEQ.S	@2

		MOVE.L	Stack12,D0
		BEQ.S	@2
		BSR	CheckOddAddress
		BMI.S	@1

		TST.B	Stack8
		BNE	retErrLength

		ADD.L	Stack8,D0
		BSR	CheckOddAddress
		BMI	retErrLength
@2
		MOVE.L	Stack4,D0
		BEQ	retOK
		BSR	CheckOddAddress
		BMI.S	@1

		TST.B	Stack0
		BNE	retErrLength

		ADD.L	Stack0,D0
		BSR	CheckOddAddress
		BMI	retErrLength
@1
		RTS

		ErrText	Offset,offset

Launch
Chain
		BSR	AddressA0
		BMI.S	@1

		MOVE.L	D0,A0
		MOVE.L	(A0),D0
		BSR	CheckString
		BMI	retErrFileName
@1
		RTS

DIPack
		MOVE.W	Stack0,D0
		CMP.W	#DILoad,D0
		BEQ	retOK
		CMP.W	#DIUnload,D0
		BEQ	retOK
		CMP.W	#DIBadMount,D0
		BEQ	retOK
		CMP.W	#DIFormat,D0
		BEQ	retOK
		CMP.W	#DIVerify,D0
		BEQ	retOK
		CMP.W	#DIZero,D0
		BEQ	String2
		BRA.S	retErrSelector

		ErrText	Selector,selector

SFPack
		MOVE.W	Stack0,D0
		CMP.W	#SFPutFile,D0
		BEQ	SFPutFile.
		CMP.W	#SFPPutFile,D0
		BEQ	SFPPutFile.
		CMP.W	#SFGetFile,D0
		BEQ	SFGetFile.
		CMP.W	#SFPGetFile,D0
		BEQ	SFPGetFile.
		BRA.S	retErrSelector

SFPutFile.
		BSR	String14
		BMI.S	@1

		BSR	String10
		BMI.S	@1

		MOVE.L	Stack6,D0
		BEQ.S	@2
		BSR	CheckAddress
		BMI.S	@1
@2
		BSR	RAM2
@1
		RTS

SFPPutFile.
		BSR	String20
		BMI.S	@1

		BSR	String16
		BMI.S	@1

		MOVE.L	Stack12,D0
		BEQ.S	@2
		BSR	CheckAddress
		BMI.S	@1
@2
		BSR	RAM8
		BMI.S	@1

		MOVE.L	Stack2,D0
		BEQ	retOK
		BSR	CheckAddress
@1
		RTS

SFGetFile.
		BSR	String20
		BMI.S	@1

		MOVE.L	Stack16,D0
		BEQ.S	@2
		BSR	CheckAddress
		BMI.S	@1
@2
		MOVE.W	Stack12,D0
		BEQ.S	@3
		CMP.W	#-1,D0
		BEQ.S	@3

		BSR	Address10
		BMI.S	@1
@3
		MOVE.L	Stack6,D0
		BEQ.S	@4
		BSR	CheckAddress
		BMI.S	@1
@4
		BSR	RAM2
@1
		RTS

SFPGetFile.
		BSR	String26
		BMI.S	@1

		MOVE.L	Stack22,D0
		BEQ.S	@2
		BSR	CheckAddress
		BMI.S	@1
@2
		MOVE.W	Stack18,D0
		BEQ.S	@3
		CMP.W	#-1,D0
		BEQ.S	@3

		BSR	Address16
		BMI.S	@1
@3
		MOVE.L	Stack12,D0
		BEQ.S	@4
		BSR	CheckAddress
		BMI.S	@1
@4
		BSR	RAM8
		BMI.S	@1

		MOVE.L	Stack2,D0
		BEQ	retOK
		BSR	CheckAddress
@1
		RTS

SANEPack
		MOVE.W	Stack0,D0
		AND.W	#$7FF,D0
		CMP.W	#$1D,D0
		BHS	retErrSelector
		BRA	retOK

ElemsPack
		MOVE.W	Stack0,D0
		LEA	ElemsTable,A0
@1
		CMP.W	#$FFFF,(A0)
		BEQ	retErrSelector
		CMP.W	(A0)+,D0
		BEQ	retOK
		BRA.S	@1

ElemsTable
		DC.W	$0000,$0002,$0004,$0006,$0008,$000A,$000C,$000E
		DC.W	$8010,$8012,$C014,$C016,$0018,$001A,$001C,$001E
		DC.W	$0020,$FFFF

IUPack
		MOVE.W	Stack0,D0
		CMP.W	#IUDateString,D0
		BEQ	RAM2
		CMP.W	#IUDatePString,D0
		BEQ	IUDatePString.
		CMP.W	#IUTimeString,D0
		BEQ	RAM2
		CMP.W	#IUTimePString,D0
		BEQ	IUTimePString.
		CMP.W	#IUMetric,D0
		BEQ	retOK
		CMP.W	#IUGetIntl,D0
		BEQ	retOK
		CMP.W	#IUSetIntl,D0
		BEQ	FullHandle2
		CMP.W	#IUMagString,D0
		BEQ	IUMagString.
		CMP.W	#IUMagIDString,D0
		BEQ	IUMagIDString.
		BRA	retErrSelector

IUDatePString.
IUTimePString.
		BSR	RAM6
		BMI.S	@1

		BSR	FullHandle0
@1
		RTS

IUMagString.
IUMagIDString.
		TST.W	Stack4
		BEQ.S	@2

		MOVE.L	Stack10,D0
		BSR	CheckOddAddress
		BMI.S	@1

		MOVEQ	#0,D0
		MOVE.W	Stack4,D0
		ADD.L	Stack10,D0
		SUBQ.L	#1,D0
		BSR	CheckOddAddress
		BMI	retErrStringLength
@2
		TST.W	Stack2
		BEQ	retOK

		MOVE.L	Stack6,D0
		BSR	CheckOddAddress
		BMI.S	@1

		MOVEQ	#0,D0
		MOVE.W	Stack2,D0
		ADD.L	Stack6,D0
		SUBQ.L	#1,D0
		BSR	CheckOddAddress
		BMI	retErrStringLength
@1
		RTS

BDPack
		MOVE.W	Stack0,D0
		CMP.W	#NumToString,D0
		BEQ	OddRAMA0
		CMP.W	#StringToNum,D0
		BEQ	StringA0
		BRA	retErrSelector

;+--------------------------------------------------------------------+
;| These are the dispatch tables: 0 means no discipline for that trap |
;+--------------------------------------------------------------------+

OSTraps
		DC.W	Open-OSTraps		; 0 Open
		DC.W	PB-OSTraps		; 1 Close
		DC.W	Read-OSTraps		; 2 Read
		DC.W	Write-OSTraps		; 3 Write
		DC.W	PB-OSTraps		; 4 Control
		DC.W	PB-OSTraps		; 5 Status
		DC.W	PB-OSTraps		; 6 KillIO
		DC.W	GetVolInfo-OSTraps	; 7 GetVolInfo
		DC.W	Create-OSTraps		; 8 Create
		DC.W	Delete-OSTraps		; 9 Delete
		DC.W	OpenRF-OSTraps		; A OpenRF
		DC.W	Rename-OSTraps		; B Rename
		DC.W	GetFileInfo-OSTraps	; C GetFileInfo
		DC.W	SetFileInfo-OSTraps	; D SetFileInfo
		DC.W	UnmountVol-OSTraps	; E UnmountVol
		DC.W	PB-OSTraps		; F MountVol
		DC.W	PB-OSTraps		; 10 Allocate
		DC.W	PB-OSTraps		; 11 GetEOF
		DC.W	PB-OSTraps		; 12 SetEOF
		DC.W	FlushVol-OSTraps	; 13 FlushVol
		DC.W	GetVol-OSTraps		; 14 GetVol
		DC.W	SetVol-OSTraps		; 15 SetVol
		DC.W	0		; 16
		DC.W	Eject-OSTraps		; 17 Eject
		DC.W	PB-OSTraps		; 18 GetFPos
		DC.W	InitZone-OSTraps	; 19 InitZone
		DC.W	0		; 1A
		DC.W	ZoneA0-OSTraps		; 1B SetZone
		DCB.W	$1F-$1C,0	; 1C-1E
		DC.W	PtrA0-OSTraps		; 1F DisposPtr
		DC.W	PtrA0-OSTraps		; 20 SetPtrSize
		DC.W	PtrA0-OSTraps		; 21 GetPtrSize
		DC.W	0		; 22
		DC.W	HandleA0-OSTraps	; 23 DisposHandle
		DC.W	HandleA0-OSTraps	; 24 SetHandleSize
		DC.W	HandleA0-OSTraps	; 25 GetHandleSize
		DC.W	HandleA0-OSTraps	; 26 HandleZone
		DC.W	HandleA0-OSTraps	; 27 ReallocHandle
		DC.W	RecoverHandle-OSTraps	; 28 RecoverHandle
		DC.W	HandleA0-OSTraps	; 29 HLock
		DC.W	HandleA0-OSTraps	; 2A HUnlock
		DC.W	HandleA0-OSTraps	; 2B EmptyHandle
		DC.W	0		; 2C
		DC.W	SetApplLimit-OSTraps	; 2D SetApplLimit
		DC.W	BlockMove.-OSTraps	; 2E BlockMove
		DC.W	0		; 2F
		DC.W	RAMA0-OSTraps		; 30 OSEventAvail
		DC.W	RAMA0-OSTraps		; 31 GetOSEvent
		DC.W	0		; 32
		DC.W	VInstall.-OSTraps	; 33 VInstall
		DC.W	VRemove-OSTraps		; 34 VRemove
		DC.W	OffLine-OSTraps		; 35 OffLine
		DC.W	0		; 36
		DC.W	0		; 37
		DC.W	WriteParam-OSTraps	; 38 WriteParam
		DC.W	RAMA0-OSTraps		; 39 ReadDateTime
		DC.W	0		; 3A
		DC.W	0		; 3B
		DC.W	CmpString-OSTraps	; 3C CmpString
		DCB.W	$41-$3D,0	; 3D-40
		DC.W	SetFilLock-OSTraps	; 41 SetFilLock
		DC.W	RstFilLock-OSTraps	; 42 RstFilLock
		DC.W	SetFilType-OSTraps	; 43 SetFilType
		DC.W	PB-OSTraps		; 44 SetFPos
		DC.W	PB-OSTraps		; 45 FlushFile
		DC.W	0		; 46
		DC.W	SetTrapAddress-OSTraps	; 47 SetTrapAddress
		DC.W	PtrA0-OSTraps		; 48 PtrZone
		DC.W	HandleA0-OSTraps	; 49 HPurge
		DC.W	HandleA0-OSTraps	; 4A HNoPurge
		DC.W	ProcA0-OSTraps		; 4B SetGrowZone
		DCB.W	$54-$4C,0	; 4C-53
		DC.W	UprString-OSTraps	; 54 UprString
		DC.W	0		; 55
		DC.W	0		; 56
		DC.W	RAMA0-OSTraps		; 57 SetApplBase
		DCB.W	$100-$58,0	; 58-FF

ToolTraps
		DCB.W	$51-$0,0	; 0-50
		DC.W	Cursor0-ToolTraps	; 51 SetCursor
		DCB.W	$55-$52,0	; 52-54
		DC.W	Rect4-ToolTraps		; 55 ShieldCursor
		DCB.W	$5D-$56,0	; 56-5C
		DC.W	OddAddress4-ToolTraps	; 5D BitTst
		DC.W	OddRAM4-ToolTraps	; 5E BitSet
		DC.W	OddRAM4-ToolTraps	; 5F BitClr
		DCB.W	$66-$60,0	; 60-65
		DC.W	StuffHex-ToolTraps	; 66 StuffHex
		DCB.W	$6D-$67,0	; 67-6C
		DC.W	RAM0-ToolTraps		; 6D InitPort
		DC.W	RAM0-ToolTraps		; 6E InitGraf
		DC.W	RAM0-ToolTraps		; 6F OpenPort
		DC.W	RAM0-ToolTraps		; 70 LocalToGlobal
		DC.W	RAM0-ToolTraps		; 71 GlobalToLocal
		DC.W	0		; 72
		DC.W	0		; 73
		DC.W	RAM0-ToolTraps		; 74 GetPort
		DC.W	BitMap0-ToolTraps	; 75 SetPortBits
		DCB.W	$79-$76,0	; 76-78
		DC.W	Rgn0-ToolTraps		; 79 SetClip
		DC.W	Rgn0-ToolTraps		; 7A GetClip
		DC.W	Address0-ToolTraps	; 7B ClipRect
		DC.W	RAM0-ToolTraps		; 7C BackPat
		DC.W	Port0-ToolTraps		; 7D ClosePort
		DC.W	RAM0-ToolTraps		; 7E AddPt
		DC.W	RAM0-ToolTraps		; 7F SubPt
		DC.W	RAM4-ToolTraps		; 80 SetPt
		DC.W	0		; 81
		DC.W	OddAddress8-ToolTraps	; 82 StdText
		DC.W	0		; 83
		DC.W	String0-ToolTraps	; 84 DrawString
		DC.W	OddAddress4-ToolTraps	; 85 DrawText
		DC.W	OddAddress4-ToolTraps	; 86 TextWidth
		DCB.W	$8B-$87,0	; 87-8A
		DC.W	RAM0-ToolTraps		; 8B GetFontInfo
		DC.W	String0-ToolTraps	; 8C StringWidth
		DCB.W	$98-$8D,0	; 8D-97
		DC.W	RAM0-ToolTraps		; 98 GetPenState
		DC.W	RAM0-ToolTraps		; 99 SetPenState
		DC.W	RAM0-ToolTraps		; 9A GetPen
		DCB.W	$A0-$9B,0	; 9B-9F
		DC.W	Rect0-ToolTraps		; A0 StdRect
		DC.W	Rect0-ToolTraps		; A1 FrameRect
		DC.W	Rect0-ToolTraps		; A2 PaintRect
		DC.W	Rect0-ToolTraps		; A3 EraseRect
		DC.W	Rect0-ToolTraps		; A4 InvertRect
		DC.W	FillRect-ToolTraps	; A5 FillRect
		DC.W	EqualRect-ToolTraps	; A6 EqualRect
		DC.W	RAM8-ToolTraps		; A7 SetRect
		DC.W	Address4-ToolTraps	; A8 OffsetRect
		DC.W	Address4-ToolTraps	; A9 InsetRect
		DC.W	SectRect-ToolTraps	; AA SectRect
		DC.W	UnionRect-ToolTraps	; AB UnionRect
		DC.W	RAM0-ToolTraps		; AC Pt2Rect
		DC.W	Address0-ToolTraps	; AD PtInRect
		DC.W	Address0-ToolTraps	; AE EmptyRect
		DC.W	Rect4-ToolTraps		; AF StdRRect
		DC.W	Rect4-ToolTraps		; B0 FrameRoundRect
		DC.W	Rect4-ToolTraps		; B1 PaintRoundRect
		DC.W	Rect4-ToolTraps		; B2 EraseRoundRect
		DC.W	Rect4-ToolTraps		; B3 InvertRoundRect
		DC.W	FillRoundRect-ToolTraps	; B4 FillRoundRect
		DC.W	0		; B5
		DC.W	Rect0-ToolTraps		; B6 StdOval
		DC.W	Rect0-ToolTraps		; B7 FrameOval
		DC.W	Rect0-ToolTraps		; B8 PaintOval
		DC.W	Rect0-ToolTraps		; B9 EraseOval
		DC.W	Rect0-ToolTraps		; BA InvertOval
		DC.W	FillOval-ToolTraps	; BB FillOval
		DC.W	0		; BC
		DC.W	Rect4-ToolTraps		; BD StdArc
		DC.W	Rect4-ToolTraps		; BE FrameArc
		DC.W	Rect4-ToolTraps		; BF PaintArc
		DC.W	Rect4-ToolTraps		; C0 EraseArc
		DC.W	Rect4-ToolTraps		; C1 InvertArc
		DC.W	FillArc-ToolTraps	; C2 FillArc
		DC.W	PtToAngle-ToolTraps	; C3 PtToAngle
		DC.W	0		; C4
		DC.W	Poly0-ToolTraps		; C5 StdPoly
		DC.W	Poly0-ToolTraps		; C6 FramePoly
		DC.W	Poly0-ToolTraps		; C7 PaintPoly
		DC.W	Poly0-ToolTraps		; C8 ErasePoly
		DC.W	Poly0-ToolTraps		; C9 InvertPoly
		DC.W	FillPoly-ToolTraps	; CA FillPoly
		DC.W	0		; CB
		DC.W	0		; CC
		DC.W	Poly0-ToolTraps		; CD KillPoly
		DC.W	Poly4-ToolTraps		; CE OffsetPoly
		DC.W	0		; CF
		DC.W	0		; D0
		DC.W	Rgn0-ToolTraps		; D1 StdRgn
		DC.W	Rgn0-ToolTraps		; D2 FrameRgn
		DC.W	Rgn0-ToolTraps		; D3 PaintRgn
		DC.W	Rgn0-ToolTraps		; D4 EraseRgn
		DC.W	Rgn0-ToolTraps		; D5 InvertRgn
		DC.W	FillRgn-ToolTraps	; D6 FillRgn
		DC.W	0		; D7
		DC.W	0		; D8
		DC.W	Rgn0-ToolTraps		; D9 DisposeRgn
		DC.W	0		; DA
		DC.W	Rgn0-ToolTraps		; DB CloseRgn
		DC.W	CopyRgn-ToolTraps	; DC CopyRgn
		DC.W	Rgn0-ToolTraps		; DD SetEmptyRgn
		DC.W	Rgn8-ToolTraps		; DE SetRectRgn
		DC.W	RectRgn-ToolTraps	; DF RectRgn
		DC.W	Rgn4-ToolTraps		; E0 OffsetRgn
		DC.W	Rgn4-ToolTraps		; E1 InsetRgn
		DC.W	Rgn0-ToolTraps		; E2 EmptyRgn
		DC.W	EqualRgn-ToolTraps	; E3 EqualRgn
		DC.W	SectRgn-ToolTraps	; E4 SectRgn
		DC.W	UnionRgn-ToolTraps	; E5 UnionRgn
		DC.W	DiffRgn-ToolTraps	; E6 DiffRgn
		DC.W	XorRgn-ToolTraps	; E7 XorRgn
		DC.W	Rgn0-ToolTraps		; E8 PtInRgn
		DC.W	RectInRgn-ToolTraps	; E9 RectInRgn
		DC.W	RAM0-ToolTraps		; EA SetStdProcs
		DC.W	StdBits-ToolTraps	; EB StdBits
		DC.W	CopyBits-ToolTraps	; EC CopyBits
		DC.W	StdTxMeas-ToolTraps	; ED StdTxMeas
		DC.W	OddRAM4-ToolTraps	; EE StdGetPic
		DC.W	ScrollRect-ToolTraps	; EF ScrollRect
		DC.W	OddAddress4-ToolTraps	; F0 StdPutPic
		DC.W	StdComment-ToolTraps	; F1 StdComment
		DC.W	PicComment-ToolTraps	; F2 PicComment
		DC.W	Rect0-ToolTraps		; F3 OpenPicture
		DC.W	0		; F4
		DC.W	Pict0-ToolTraps		; F5 KillPicture
		DC.W	DrawPicture-ToolTraps	; F6 DrawPicture
		DC.W	0		; F7
		DC.W	ScalePt-ToolTraps	; F8 ScalePt
		DC.W	MapPt-ToolTraps		; F9 MapPt
		DC.W	MapRect-ToolTraps	; FA MapRect
		DC.W	MapRgn-ToolTraps	; FB MapRgn
		DC.W	MapPoly-ToolTraps	; FC MapPoly
		DC.W	0		; FD
		DC.W	0		; FE
		DC.W	RAM0-ToolTraps		; FF GetFontName
		DC.W	GetFNum-ToolTraps	; 100 GetFNum
		DC.W	RAM0-ToolTraps		; 101 SwapFont
		DC.W	0		; 102
		DC.W	0		; 103
		DC.W	Window0-ToolTraps	; 104 DrawGrowIcon
		DC.W	DragGrayRgn-ToolTraps	; 105 DragGrayRgn
		DC.W	String0-ToolTraps	; 106 NewString
		DC.W	SetString-ToolTraps	; 107 SetString
		DC.W	Window2-ToolTraps	; 108 ShowHide
		DC.W	CalcVis-ToolTraps	; 109 CalcVis
		DC.W	CalcVisBehind-ToolTraps	; 10A CalcVisBehind
		DC.W	ClipAbove-ToolTraps	; 10B ClipAbove
		DC.W	PaintOne-ToolTraps	; 10C PaintOne
		DC.W	PaintBehind-ToolTraps	; 10D PaintBehind
		DC.W	Window0-ToolTraps	; 10E SaveOld
		DC.W	Window2-ToolTraps	; 10F DrawNew
		DC.W	RAM0-ToolTraps		; 110 GetWMgrPort
		DC.W	RAM0-ToolTraps		; 111 CheckUpdate
		DC.W	0		; 112
		DC.W	NewWindow-ToolTraps	; 113 NewWindow
		DC.W	DisposeWindow-ToolTraps	; 114 DisposeWindow
		DC.W	Window0-ToolTraps	; 115 ShowWindow
		DC.W	Window0-ToolTraps	; 116 HideWindow
		DC.W	Window0-ToolTraps	; 117 GetWRefCon
		DC.W	Window4-ToolTraps	; 118 SetWRefCon
		DC.W	GetWTitle-ToolTraps	; 119 GetWTitle
		DC.W	SetWTitle-ToolTraps	; 11A SetWTitle
		DC.W	Window6-ToolTraps	; 11B MoveWindow
		DC.W	Window2-ToolTraps	; 11C HiliteWindow
		DC.W	Window6-ToolTraps	; 11D SizeWindow
		DC.W	Window4-ToolTraps	; 11E TrackGoAway
		DC.W	Window0-ToolTraps	; 11F SelectWindow
		DC.W	Window0-ToolTraps	; 120 BringToFront
		DC.W	SendBehind-ToolTraps	; 121 SendBehind
SHAR_EOF
if test 24839 -ne "`wc -c EUA.Asm.5`"
then
echo shar: error transmitting EUA.Asm.5 '(should have been 24839 characters)'
fi
#	End of shell archive
exit 0
-- 
Darin Adler
{gatech,harvard,ihnp4,seismo}!ut-sally!ut-dillo!darin

darin@ut-dillo.UUCP (Darin Adler) (12/08/85)

This is part 6 of the source code to the Extended User Area.


#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
-----cut here-----cut here-----cut here-----cut here-----
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	EUA.Asm.6
# This archive created: Sun Dec  8 13:28:36 1985
# By:	Darin Adler ()
echo shar: extracting EUA.Asm.6 '(17328 characters)'
cat << \SHAR_EOF > EUA.Asm.6
		DC.W	BeginUpdate-ToolTraps	; 122 BeginUpdate
		DC.W	EndUpdate-ToolTraps	; 123 EndUpdate
		DC.W	0		; 124
		DC.W	DragWindow-ToolTraps	; 125 DragWindow
		DC.W	DragTheRgn-ToolTraps	; 126 DragTheRgn
		DC.W	Rgn0-ToolTraps		; 127 InvalRgn
		DC.W	Address0-ToolTraps	; 128 InvalRect
		DC.W	Rgn0-ToolTraps		; 129 ValidRgn
		DC.W	Address0-ToolTraps	; 12A ValidRect
		DC.W	GrowWindow-ToolTraps	; 12B GrowWindow
		DC.W	RAM0-ToolTraps		; 12C FindWindow
		DC.W	Window0-ToolTraps	; 12D CloseWindow
		DC.W	Window4-ToolTraps	; 12E SetWindowPic
		DC.W	Window0-ToolTraps	; 12F GetWindowPic
		DC.W	0		; 130
		DC.W	String0-ToolTraps	; 131 NewMenu
		DC.W	Menu0-ToolTraps		; 132 DisposeMenu
		DC.W	AppendMenu-ToolTraps	; 133 AppendMenu
		DC.W	0		; 134
		DC.W	Menu2-ToolTraps		; 135 InsertMenu
		DCB.W	$139-$136,0	; 136-138
		DC.W	Menu2-ToolTraps		; 139 EnableItem
		DC.W	Menu2-ToolTraps		; 13A DisableItem
		DC.W	0		; 13B
		DC.W	FullHandle0-ToolTraps	; 13C SetMenuBar
		DC.W	0		; 13D
		DC.W	0		; 13E
		DC.W	GetItemIcon-ToolTraps	; 13F GetItemIcon
		DC.W	Menu4-ToolTraps		; 140 SetItemIcon
		DC.W	GetItemStyle-ToolTraps	; 141 GetItemStyle
		DC.W	Menu4-ToolTraps		; 142 SetItemStyle
		DC.W	GetItemMark-ToolTraps	; 143 GetItemMark
		DC.W	Menu4-ToolTraps		; 144 SetItemMark
		DC.W	Menu4-ToolTraps		; 145 CheckItem
		DC.W	GetItem-ToolTraps	; 146 GetItem
		DC.W	SetItem-ToolTraps	; 147 SetItem
		DC.W	Menu0-ToolTraps		; 148 CalcMenuSize
		DC.W	0		; 149
		DC.W	0		; 14A
		DC.W	PlotIcon-ToolTraps	; 14B PlotIcon
		DC.W	0		; 14C
		DC.W	Menu4-ToolTraps		; 14D AddResMenu
		DC.W	Rect4-ToolTraps		; 14E PinRect
		DC.W	0		; 14F
		DC.W	Menu0-ToolTraps		; 150 CountMItems
		DC.W	Menu6-ToolTraps		; 151 InsertResMenu
		DC.W	0		; 152
		DC.W	0		; 153
		DC.W	NewControl-ToolTraps	; 154 NewControl
		DC.W	Control0-ToolTraps	; 155 DisposeControl
		DC.W	Window0-ToolTraps	; 156 KillControls
		DC.W	Control0-ToolTraps	; 157 ShowControl
		DC.W	FullHandle0-ToolTraps	; 158 HideControl
		DC.W	Control4-ToolTraps	; 159 MoveControl
		DC.W	Control0-ToolTraps	; 15A GetCRefCon
		DC.W	Control4-ToolTraps	; 15B SetCRefCon
		DC.W	Control4-ToolTraps	; 15C SizeControl
		DC.W	Control2-ToolTraps	; 15D HiliteControl
		DC.W	GetCTitle-ToolTraps	; 15E GetCTitle
		DC.W	SetCTitle-ToolTraps	; 15F SetCTitle
		DC.W	Control0-ToolTraps	; 160 GetCtlValue
		DC.W	Control0-ToolTraps	; 161 GetCtlMin
		DC.W	Control0-ToolTraps	; 162 GetCtlMax
		DC.W	Control2-ToolTraps	; 163 SetCtlValue
		DC.W	Control2-ToolTraps	; 164 SetCtlMin
		DC.W	Control2-ToolTraps	; 165 SetCtlMax
		DC.W	Control4-ToolTraps	; 166 TestControl
		DC.W	DragControl-ToolTraps	; 167 DragControl
		DC.W	Control8-ToolTraps	; 168 TrackControl
		DC.W	Window0-ToolTraps	; 169 DrawControls
		DC.W	Control0-ToolTraps	; 16A GetCtlAction
		DC.W	Control4-ToolTraps	; 16B SetCtlAction
		DC.W	FindControl-ToolTraps	; 16C FindControl
		DC.W	0		; 16D
		DC.W	Dequeue-ToolTraps	; 16E Dequeue
		DC.W	Enqueue-ToolTraps	; 16F Enqueue
		DC.W	RAM0-ToolTraps		; 170 GetNextEvent
		DC.W	RAM0-ToolTraps		; 171 EventAvail
		DC.W	RAM0-ToolTraps		; 172 GetMouse
		DCB.W	$176-$173,0	; 173-175
		DC.W	RAM0-ToolTraps		; 176 GetKeys
		DCB.W	$17B-$177,0	; 177-17A
		DC.W	Proc0-ToolTraps		; 17B InitDialogs
		DC.W	GetNewDialog-ToolTraps	; 17C GetNewDialog
		DC.W	NewDialog-ToolTraps	; 17D NewDialog
		DC.W	Dialog6-ToolTraps	; 17E SelIText
		DC.W	Address0-ToolTraps	; 17F IsDialogEvent
		DC.W	DialogSelect-ToolTraps	; 180 DialogSelect
		DC.W	Dialog0-ToolTraps	; 181 DrawDialog
		DC.W	Dialog0-ToolTraps	; 182 CloseDialog
		DC.W	DisposDialog-ToolTraps	; 183 DisposDialog
		DC.W	0		; 184
		DC.W	Proc0-ToolTraps		; 185 Alert
		DC.W	Proc0-ToolTraps		; 186 StopAlert
		DC.W	Proc0-ToolTraps		; 187 NoteAlert
		DC.W	Proc0-ToolTraps		; 188 CautionAlert
		DC.W	0		; 189
		DC.W	0		; 18A
		DC.W	ParamText-ToolTraps	; 18B ParamText
		DC.W	Proc0-ToolTraps		; 18C ErrorSound
		DC.W	GetDItem-ToolTraps	; 18D GetDItem
		DC.W	SetDItem-ToolTraps	; 18E SetDItem
		DC.W	SetIText-ToolTraps	; 18F SetIText
		DC.W	GetIText-ToolTraps	; 190 GetIText
		DC.W	ModalDialog-ToolTraps	; 191 ModalDialog
		DCB.W	$19F-$192,0	; 192-19E
		DC.W	RAM2-ToolTraps		; 19F GetIndType
		DCB.W	$1A8-$1A0,0	; 1A0-1A7
		DC.W	GetResInfo-ToolTraps	; 1A8 GetResInfo
		DC.W	String0-ToolTraps	; 1A9 SetResInfo
		DC.W	0		; 1AA
		DC.W	String0-ToolTraps	; 1AB AddResorce
		DCB.W	$1B3-$1AC,0	; 1AC-1B2
		DC.W	SystemClick-ToolTraps	; 1B3 SystemClick
		DCB.W	$1BD-$1B4,0	; 1B4-1BC
		DC.W	GetNewWindow-ToolTraps	; 1BD GetNewWindow
		DC.W	Window0-ToolTraps	; 1BE GetNewControl
		DCB.W	$1C6-$1BF,0	; 1BF-1C5
		DC.W	RAMA0-ToolTraps		; 1C6 Secs2Date
		DC.W	RAMA0-ToolTraps		; 1C7 Date2Secs
		DCB.W	$1CB-$1C8,0	; 1C8-1CA
		DC.W	TERec0-ToolTraps	; 1CB TEGetText
		DC.W	0		; 1CC
		DC.W	TERec0-ToolTraps	; 1CD TEDispose
		DC.W	Rect2-ToolTraps		; 1CE TextBox
		DC.W	TERec0-ToolTraps	; 1CF TESetText
		DC.W	TERec0-ToolTraps	; 1D0 TECalText
		DC.W	TERec0-ToolTraps	; 1D1 TESetSelect
		DC.W	TENew-ToolTraps		; 1D2 TENew
		DC.W	TEUpdate-ToolTraps	; 1D3 TEUpdate
		DC.W	TERec0-ToolTraps	; 1D4 TEClick
		DC.W	TERec0-ToolTraps	; 1D5 TECopy
		DC.W	TERec0-ToolTraps	; 1D6 TECut
		DC.W	TERec0-ToolTraps	; 1D7 TEDelete
		DC.W	TERec0-ToolTraps	; 1D8 TEActivate
		DC.W	TERec0-ToolTraps	; 1D9 TEDeactivate
		DC.W	TERec0-ToolTraps	; 1DA TEIdle
		DC.W	TERec0-ToolTraps	; 1DB TEPaste
		DC.W	TERec0-ToolTraps	; 1DC TEKey
		DC.W	TERec0-ToolTraps	; 1DD TEScroll
		DC.W	TERec0-ToolTraps	; 1DE TEInsert
		DC.W	TERec0-ToolTraps	; 1DF TESetJust
		DC.W	Munger-ToolTraps	; 1E0 Munger
		DC.W	FullHandleA0-ToolTraps	; 1E1 HandToHand
		DC.W	PtrToXHand-ToolTraps	; 1E2 PtrToXHand
		DC.W	PtrToHand-ToolTraps	; 1E3 PtrToHand
		DC.W	HandAndHand-ToolTraps	; 1E4 HandAndHand
		DCB.W	$1E9-$1E5,0	; 1E5-1E8
		DC.W	DIPack-ToolTraps	; 1E9 Pack2
		DC.W	SFPack-ToolTraps	; 1EA Pack3
		DC.W	SANEPack-ToolTraps	; 1EB Pack4
		DC.W	ElemsPack-ToolTraps	; 1EC Pack5
		DC.W	IUPack-ToolTraps	; 1ED Pack6
		DC.W	BDPack-ToolTraps	; 1EE Pack7
		DC.W	PtrAndHand-ToolTraps	; 1EF PtrAndHand
		DC.W	JTPC-ToolTraps		; 1F0 LoadSeg
		DC.W	JT0-ToolTraps		; 1F1 UnloadSeg
		DC.W	Launch-ToolTraps	; 1F2 Launch
		DC.W	Chain-ToolTraps		; 1F3 Chain
		DC.W	0		; 1F4
		DC.W	GetAppParms-ToolTraps	; 1F5 GetAppParms
		DCB.W	$1FD-$1F6,0	; 1F6-1FC
		DC.W	GetScrap-ToolTraps	; 1FD GetScrap
		DC.W	OddAddress0-ToolTraps	; 1FE PutScrap
		DC.W	0		; 1FF


		;#############################
		;##                         ##
		;##  TMON patching section  ##
		;##                         ##
		;#############################

;+------------------------------------------------+
;| Find an area to patch in the main code of TMON |
;+------------------------------------------------+
;|
;|ENTRY: FindInTMON
;|
;|IN:   D0,D1	8 bytes to find in TMON's code
;|
;|OUT:  Z	set if found, clear if not found
;|	A0'	location of bytes in TMON code
;|
;|Destroys A0,A1.
;|

FindInTMON
		MOVE.L	TMONStart,A0		;Start at the beginning of TMON.
		LEA	A,A1			;End at the beginning of the user area.

@1		ADDQ	#2,A0			;(we can skip the WH at the beginning)
		CMP.L	A0,A1
		BLS.S	NotFoundInTMON
		CMP.L	(A0),D0			;Found?
		BNE.S	@1
		CMP.L	4(A0),D1		;Be sure that 8 bytes match.
		BNE.S	@1
FoundInTMON
		RTS
NotFoundInTMON
		MOVEQ	#1,D0			;To set the CC's to non-zero
		RTS


SavedBytes	EQU	$C0			;C0 bytes are saved after ScrnBase.

SavedScreen	LONG	0			;This is the start of the saved screen.
SaveMode	DC	0			;This is the screen saving mode.
MenuTop		DC	0			;This is the row of the top of the TMON menu.
MenuBottom	DC	0			;This is the row of the menu.

SeeThroughPatch
		LEA	A,A2			;As usual, we like A2 pointing to the User Area.

		MOVEQ	#3,D0			;Three lines above TMON chars.
		MULU	ScreenRow,D0
		MOVE.W	D0,MenuTop-A(A2)

		MOVE.W	#19,D0			;Twenty rows of the Menu Bar
		MULU	ScreenRow,D0		;Calculate the offset of the address of the start.
		MOVE.W	D0,MenuBottom-A(A2)

		MOVE.L	TMONStart,A4		;($FC) is the start of TMON.
		MOVE.L	4(A4),A0		;(4($FC)) is where a lot of info resides.

		MOVE.W	(A0)+,D0		;This is the actual user area size (not necessarily = AreaSize).
		LEA	SavedBytes(A2),A3	;The saved screen starts after the saved bytes.
		ADD.W	D0,A3
		MOVE.L	A3,SavedScreen-A(A2)

		MOVE.W	(A0)+,D1		;This is the screen saving mode.
		MOVE.W	D1,SaveMode-A(A2)

		TST.W	D1			;What is the screen mode?
		BNE.S	NotFullScreen

		;Now, we make the patch that allows the screen to be transparent, if screen saving is on full.

		;This is the original routine we are patching:
		;7607			MOVEQ	#7,D3
		;20C1		@1	MOVE.L	D1,(A0)+
		;20C1			MOVE.L	D1,(A0)+
		;51CB FFF8		DBRA	D3,@1

		MOVE.L	#$760720C1,D0		;This is the first 4 bytes of the routine.
		MOVE.L	#$20C151CB,D1		;These are the next 4.

		BSR	FindInTMON
		BNE.S	@1

		;The patch routine is:
		;4EB9 ???? ????		JSR	ScreenPatch
		;4E71			NOP
		;4E71			NOP

		MOVE.W	#$4EB9,(A0)+
		LEA	ScreenPatch,A1		;Calculate the address for JSR
		MOVE.L	A1,(A0)+
		MOVE.L	#$4E714E71,(A0)+
@1

NotFullScreen

		RTS


ScreenPatch
		MOVE.L	A0,A1			;Let's calcuate an address.
		SUB.L	ScrnBase,A1		;Make an offset from the start of the screen.

		CMP.W	MenuTop,A1		;Check if it is above the menu.
		BLO.S	NormalFill
		CMP.W	MenuBottom,A1		;Check if it is below the menu.
		BHS.S	NormalFill

BlackFill	MOVEQ	#$FFFFFFFF,D1
		BRA.S	FillLine
WhiteFill	MOVEQ	#$00000000,D1
NormalFill
		CMP.L	#$AFFFFFFF,D1		;$AAAAAAAA>$AFFFFFFF<-$55555555
		BMI.S	ShowThrough		;Show through if it is A's or 5's
FillLine
		MOVEQ	#15,D3			;This is the original fill routine
@1		MOVE.L	D1,(A0)+
		DBRA	D3,@1
		RTS

ShowThrough
		ADD.L	SavedScreen,A1		;Point to the saved screen.

		MOVEQ	#15,D3			;Allow the application to show through.
@1		MOVE.L	(A1)+,(A0)+
		DBRA	D3,@1
		RTS


DebuggerPatch
		;This patch allows TMON to step through the _Debugger opcode.

		;This is the original routine we are patching:
		;0240 F9FF		AND.W	#$F9FF,D0
		;0C40 A9FF		CMP.W	#$A9FF,D0

		MOVE.L	#$0240F9FF,D0		;This is the first 4 bytes of the routine.
		MOVE.L	#$0C40A9FF,D1		;These are the next 4.

		BSR	FindInTMON
		BNE.S	@1

		;The patch routine is:
		;0240 F9FF		AND.W	#$F9FF,D0
		;0C40 FFFF		CMP.W	#$FFFF,D0

		MOVE.B	#$FF,6(A0)
@1
		RTS


GetTrapAddressPatch
		;This patch allows TMON to work with the original HyperDrive
		;20 software (subsequently fixed by GCC) and some other software
		;that patches _GetTrapAddress and does not preserve register A2.

		;This is the recognition for the original routine:
		;2F0A			MOVE.L	A2,-(A7)
		;2602			MOVE.L	D2,D3
		;7046			MOVEQ	#GetTrapAddress,D0
		;A146			_GetTrapAddress

		MOVE.L	#$2F0A2602,D0		;This is the first 4 bytes of the recognizer routine.
		MOVE.L	#$7046A146,D1		;These are the next 4.

		BSR	FindInTMON
		BNE.S	@1

		;Changes go here: A2 to A3

		;0000:	2F0A			MOVE.L	A2,-(A7)
		;	2F0B			MOVE.L	A3,-(A7)

		MOVE.W	#$2F0B,$0000(A0)

		;0008:	2448			MOVE.L	A0,A2
		;	2648			MOVE.L	A0,A3

		MOVE.W	#$2648,$0008(A0)

		;0018:	4E92			JSR	(A2)
		;0018:	4E93			JSR	(A3)

		MOVE.W	#$4E93,$0018(A0)

		;002A:	245F			MOVE.L	(A7)+,A2
		;002A:	265F			MOVE.L	(A7)+,A3

		MOVE.W	#$265F,$002A(A0)
@1
		RTS


		;#############################
		;##                         ##
		;##  Cursor fixing section  ##
		;##                         ##
		;#############################


FirstSaved	EQU	ScrnBase
LastSaved	EQU	FirstSaved+SavedBytes
SavedBase	EQU	ScrnBase-LastSaved(A3)
SavedTemp	EQU	MTemp-LastSaved(A3)
SavedRaw	EQU	RawMouse-LastSaved(A3)
SavedMouse	EQU	Mouse-LastSaved(A3)
SavedPin	EQU	CrsrPin-LastSaved(A3)
CrsrPin.	EQU	CrsrPin+4
SavedPin.	EQU	CrsrPin.-LastSaved(A3)
SavedRect	EQU	CrsrRect-LastSaved(A3)
SavedCursor	EQU	TheCrsr-LastSaved(A3)
SavedAddr	EQU	CrsrAddr-LastSaved(A3)
SavedSave	EQU	CrsrSave-LastSaved(A3)
SavedVis	EQU	CrsrVis-LastSaved(A3)
SavedBusy	EQU	CrsrBusy-LastSaved(A3)
SavedNew	EQU	CrsrNew-LastSaved(A3)
SavedCouple	EQU	CrsrCouple-LastSaved(A3)
SavedState	EQU	CrsrState-LastSaved(A3)
SavedObscure	EQU	CrsrObscure-LastSaved(A3)
SavedScale	EQU	CrsrScale-LastSaved(A3)
SavedMask	EQU	MouseMask-LastSaved(A3)
SavedOffset	EQU	MouseOffset-LastSaved(A3)

;
;This fixes up the way the cursor works in TMON.
;

CursorEnter
		LEA	A,A2			;Point to A as usual.
		MOVE.L	SavedScreen,A3		;Point A3 to the saved cursor globals.

		TST.W	SaveMode-A(A2)		;Check out save mode.
		BNE.S	@1
		TST.B	SavedBusy		;If a cursor routine is executing,
		BNE.S	@1			;don't play with the cursor.
		TST.B	SavedVis		;If the cursor was not visible,
		BEQ.S	@1			;don't play with it.
		TST.B	SavedCouple		;If the cursor is not coupled,
		BEQ.S	@1			;don't play with it.

		MOVE.B	#1,CrsrBusy		;Mark the cursor busy.

		LEA	SavedRect,A0		;Restore the old cursor rectangle.
		LEA	CrsrRect,A1
		MOVE.L	(A0)+,(A1)+
		MOVE.L	(A0),(A1)

		MOVE.L	SavedAddr,D1		;Get the old cursor address.
		MOVE.L	D1,D0
		SUB.L	ScrnBase,D0
		ADD.L	SavedScreen,D0
		MOVE.L	D0,CrsrAddr		;Modify it to point to the buffer.

		LEA	SavedSave,A0		;Get the saved bytes.
		LEA	CrsrSave,A1		;Into the real bytes.
		MOVE.L	#4*16,D0
		_BlockMove

		SUB.W	#1,SavedState		;Subtract 1 to indicated Hiding.

		PEA	@1
		MOVE.L	JShowCursor,-(SP)
		MOVE.L	JHideCursor,-(SP)
		RTS
@1
		ST	CrsrCouple		;Now, make sure the cursor can be used.
		MOVEQ	#-1,D0
		MOVE.L	D0,MouseMask
		CLR.L	MouseOffset

		RTS				;Continue with the Record routine.

CursorExit
		LEA	A,A2			;Point to A as usual.
		MOVE.L	SavedScreen,A3		;Point A3 to the saved cursor globals.

		TST.W	SaveMode-A(A2)		;Check out save mode.
		BNE	@1
		TST.B	SavedBusy		;If a cursor routine is executing,
		BNE	@1			;don't play with the cursor.
		TST.B	SavedCouple		;If the mouse is not coupled to the cursor,
		BEQ	@1			;don't move it.

		MOVE.B	#1,CrsrBusy		;Mark the cursor busy.

		CLR.B	CrsrVis			;Fix up some variables.
		MOVE.W	SavedState,CrsrState
		MOVE.L	SavedMask,MouseMask
		MOVE.L	SavedOffset,MouseOffset
		LEA	SavedPin,A0		;Get the pin rectangle and the cursor.
		LEA	CrsrPin,A1
		MOVE.L	#2*8+2*(2*16)+4,D0
		_BlockMove

		MOVE.L	RawMouse,D0		;Get the current mouse address.
		BSR.S	DoPinStuff
		MOVE.L	D0,RawMouse		;Save it as Raw and Temp.
		MOVE.L	D0,MTemp
		AND.L	MouseMask,D0		;Mask it.
		MOVE.L	MouseOffset,D1		;Offset it?
		BEQ.S	@3
		ADD.L	D1,D0			;yes.
		BSR.S	DoPinStuff
@3		MOVE.L	D0,Mouse
		CLR.B	CrsrNew
		CLR.B	CrsrObscure
		TST.B	SavedObscure		;If it was obscured,
		BEQ.S	@4
		SNE	SavedVis		;pretend it was visible.
@4
		TST.B	SavedVis		;Was it visible when we entered?
		BEQ.S	@5

		MOVE.L	SavedScreen,ScrnBase	;Fake out the screen.
		CLR.W	CrsrState		;(just to make sure)
		PEA	@2
		MOVE.L	JShowCursor,-(SP)
		RTS
@2
		MOVE.B	#1,CrsrBusy
		MOVE.L	CrsrAddr,D0		;Get the address of saved data.
		SUB.L	ScrnBase,D0		;Subtract the value of the screen.
		ADD.L	SavedBase,D0		;Add the value of the real screen.
		MOVE.L	D0,CrsrAddr		;Set that address.
@5
		LEA	MTemp,A0		;Restore the variables.
		LEA	SavedTemp,A1		;Store over the saved variables.
		MOVE.L	#SavedBytes-4,D0	;Restore all but the ScrnBase.
		_BlockMove

		CLR.B	SavedBusy
		CLR.B	CrsrBusy
@1
		RTS

DoPinStuff
		CMP.W	left(A0),D0		;This routine is copied out of the ROM
		BGE.S	@1
		MOVE.W	left(A0),D0
@1
		CMP.W	right(A0),D0
		BLE.S	@2
		MOVE.W	right(A0),D0
		SUBQ.W	#1,D0
@2
		SWAP	D0

		CMP.W	top(A0),D0
		BGE.S	@3
		MOVE.W	top(A0),D0
@3
		CMP.W	bottom(A0),D0
		BLE.S	@4
		MOVE.W	bottom(A0),D0
		SUBQ.W	#1,D0
@4
		SWAP	D0

		RTS


		;#####################
		;##                 ##
		;##  Odds and Ends  ##
		;##                 ##
		;#####################


;
;The following makes the _Debugger trap work properly.
;

Debugger	EQU	$1FF

DebuggerInit
		MOVEQ	#12,D0
		_NewPtr,Sys

		MOVE.L	A0,A1
		MOVE.W	#$4EF9,(A0)+		;JMP ABS.L
		LEA	DebuggerIntercept,A3
		MOVE.L	A3,(A0)+

		MOVE.L	A0,A2
		MOVE.W	#$4EF9,(A0)+		;JMP ABS.L
		LEA	UndefinedIntercept,A3
		MOVE.L	A3,(A0)+

		MOVE.W	#Debugger,D0
		_GetTrapAddress
		MOVE.L	A0,A3

		MOVE.W	#Debugger,D0
		MOVE.L	A1,A0
		_SetTrapAddress

		MOVE.W	#Debugger-1,D1		;All traps except _Debugger
FixUndefined
		MOVE.W	D1,D0
		_GetTrapAddress
		CMP.L	A0,A3			;Same as Debugger?
		BNE.S	@1

		MOVE.W	D1,D0
		MOVE.L	A2,A0
		_SetTrapAddress
@1
		DBRA	D1,FixUndefined

		RTS

DebuggerIntercept
		MOVE.W	SR,-(SP)
		MOVEM.L	A0/A1,-(SP)
		MOVE.L	10(SP),A0
		CMP.L	TMONStart,A0
		BLO.S	@1
		LEA	EndUserArea,A1
		CMP.L	A1,A0
		BHS.S	@1
		MOVEM.L	(SP)+,A0/A1
		MOVE.W	(SP)+,SR
		RTS
@1
		MOVEM.L	(SP)+,A0/A1
		TRAPMon	'_Debugger'

UndefinedIntercept
		MOVE.W	SR,-(SP)
		MOVEM.L	A0/A1,-(SP)
		MOVE.L	10(SP),A0
		CMP.L	TMONStart,A0
		BLO.S	@1
		LEA	EndUserArea,A1
		CMP.L	A1,A0
		BHS.S	@1
		MOVEM.L	(SP)+,A0/A1
		MOVE.W	(SP)+,SR
		RTS
@1
		MOVEM.L	(SP)+,A0/A1
		TRAPMon	'Undefined A-trap'


;
;The following makes Free Form sound work properly.
;

VInstall	EQU	$33

FreeFormPatch
		MOVE.W	#VInstall,D0
		_GetTrapAddress
		CMP.W	#$6D1A,$34(A0)		;If it is the correct BLT.S
		BNE.S	DontPatchFreeForm
		MOVE.B	#$60,$34(A0)		;Make it a BRA.S
DontPatchFreeForm
		RTS


;
;The following allows the AppleTalk interface code to work properly.
;

AppleTalkPatch
		MOVE.B	#1,$E0			;Don't ask.
		RTS


;
;The following saves MemTop so it is valid later.  It seems Switcher likes
;to mess with it.
;

SaveMemTop
		LEA	RealMemTop,A0
		MOVE.L	MemTop,(A0)
		RTS

RealMemTop	LONG	0


		;##################################
		;##                              ##
		;##  End of User Area (padding)  ##
		;##                              ##
		;##################################


		DCB.B	AreaSize+A-*,0		;Fill out user area to a even multiple of 256
EndUserArea

		END
SHAR_EOF
if test 17328 -ne "`wc -c EUA.Asm.6`"
then
echo shar: error transmitting EUA.Asm.6 '(should have been 17328 characters)'
fi
#	End of shell archive
exit 0
-- 
Darin Adler
{gatech,harvard,ihnp4,seismo}!ut-sally!ut-dillo!darin

darin@ut-dillo.UUCP (Darin Adler) (12/08/85)

<>

The following is the LAST shell script that should be run (after parts 1-6).
I don't think that unshar will work on this, since it is not really an
archive.  What it does is concatenate EUA.Asm.[1-6] and extract a small file
(EUA.Link).  After executing this script, you can remove the files
EUA.Asm.[1-6].  The file EUA.Asm is the MDS Assembler source code to the
Extended User Area and the file EUA.Link is the MDS Linker link control
file.  The macput -u command is usefult for moving these files down to a
Macintosh from a Unix system.

Darin

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
-----cut here-----cut here-----cut here-----cut here-----
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	EUA.Asm (by concatenating EUA.Asm.[1-6])
#	EUA.Link
# This archive created: Sun Dec  8 13:28:49 1985
# By:	Darin Adler ()
echo shar: building EUA.Asm '(161948 characters)'
cat EUA.Asm.[1-6] > EUA.Asm
if test 161948 -ne "`wc -c EUA.Asm`"
then
echo shar: error building EUA.Asm '(should have been 161948 characters)'
fi
echo shar: extracting EUA.Link '(52 characters)'
cat << \SHAR_EOF > EUA.Link
]
/Output User Area
/Type 'USAR' 'TMON'
/Data
EUA
$
SHAR_EOF
if test 52 -ne "`wc -c EUA.Link`"
then
echo shar: error transmitting EUA.Link '(should have been 52 characters)'
fi
#	End of shell archive
exit 0
-- 
Darin Adler
{gatech,harvard,ihnp4,seismo}!ut-sally!ut-dillo!darin