Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site ut-dillo.UUCP Path: utzoo!watmath!clyde!bonnie!akgua!gatech!ut-sally!ut-ngp!ut-dillo!darin From: darin@ut-dillo.UUCP (Darin Adler) Newsgroups: net.sources.mac Subject: Source code for TMON Extended User Area (part 2 of 7) Message-ID: <232@ut-dillo.UUCP> Date: Sun, 8-Dec-85 14:34:18 EST Article-I.D.: ut-dillo.232 Posted: Sun Dec 8 14:34:18 1985 Date-Received: Tue, 10-Dec-85 05:47:35 EST Distribution: net Organization: UTexas Computation Center, Austin, Texas Lines: 1224 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