mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-28 01:29:20 +00:00
1126 lines
38 KiB
Plaintext
1126 lines
38 KiB
Plaintext
;
|
|
; File: StartAlert.a
|
|
;
|
|
; Contains: This file contains the system alert manager, assembled as part of
|
|
; the ROM-based boot code. The system alert manager is called as the
|
|
; result of either a system error (when no debugger is installed) or
|
|
; through the SysAlert trap interface (used by Disk-switch). It assumes
|
|
; that the system is broken and tries to use as little of it as possible
|
|
; to get a message up on the screen. The message includes text, icons
|
|
; and some buttons, which execute user definable code when pushed.
|
|
;
|
|
; If the system alert manager was entered as the result of an NMI (system
|
|
; error 13), MicroBug is called. This the minimal set of get/set/go cmds
|
|
; for examining/altering the state of the machine. It uses the system alert
|
|
; rectangle as a display window.
|
|
;
|
|
; Written by: Andy Hertzfeld 20-Mar-83
|
|
; modified by Ken Krugler 4-May-85
|
|
;
|
|
; Copyright: © 1983-1991 by Apple Computer, Inc., all rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <4> 9/27/91 JSM DonÕt use hasCQD conditional, all future ROMs will have color
|
|
; QuickDraw.
|
|
; <3> 9/16/91 JSM Cleanup header.
|
|
; <2> 6/12/91 LN Changed #include 'HardwareEqu.a' to 'HardwarePrivateEqu.a'
|
|
; <1.5> 8/22/89 SES Removed references to nFiles.
|
|
; <1.4> 7/7/89 SWC NEEDED FOR AURORA: Zeroed DSErrCode when entering MicroBug since
|
|
; at that point, a fatal error hasn't occurred.
|
|
; <1.3> 5/4/89 SWC Code cleanup and conditionals reduction for universal ROM.
|
|
; <1.2> 1/16/89 GGD Added a scratch register parameter to the BigJMP macro calls
|
|
; since it will be needed when they change to use PC relative
|
|
; addressing.
|
|
; <1.1> 11/10/88 CCH Fixed Header.
|
|
; <1.0> 11/9/88 CCH Adding to EASE.
|
|
; <¥1.1> 9/23/88 CCH Got rid of inc.sum.d and empty nFiles
|
|
; <1.0> 2/10/88 BBM Adding file for the first time into EASEÉ
|
|
; <C966> 11/16/87 MSH Changed alert box sizing and placement to be like Mac 2.
|
|
; <C914> 10/29/87 rwh Port to Modern Victorian (onMvMac)
|
|
; <C882> 9/3/87 RDC Change check for NMI exception to D0=13 on all systems
|
|
; <C873> 9/1/87 MSH Added support for HcMac (Laguna)
|
|
; <C822> 2/15/87 RDC Fixed bug in DSErrHandler for fetch of error code on NuMac
|
|
; <C714> 1/28/87 WRL Dispose of the color icon after plotting it.
|
|
; <C682> 1/24/87 WRL When displaying a dialog box, SysErr now looks for a 'cicn'
|
|
; resource of the same ID as the icon it is about to display. This
|
|
; allows color icons to appear in system dialog boxes.
|
|
; <C651> 1/19/87 GWN Changed branch to test mgr to a branch to CritErr.
|
|
; <C584> 1/2/87 GWN Centered MicroBug port.
|
|
; <C578> 12/31/86 GWN Modified DrawSysErr so the box is centered on the screen
|
|
; depending upon the size of the screen. The objects drawn in the
|
|
; box are also centered.
|
|
; <C573> 12/30/86 GWN Fixed "MacsBug Installed" message. Temp hack for TFB video card.
|
|
; <C549> 12/19/86 bbm Fixed offset in hittest for buttons (global to localed the
|
|
; mouse)
|
|
; <C448> 11/20/86 DAH Jump to TestManager if no DSAlertTab.
|
|
; <A309> 10/31/86 DAH Once again change the sad mac code display so the major code is
|
|
; in d7 and the minor code is in d6 to match test fail codes.
|
|
; <A292> 10/29/86 DAH swap the error display in sad mac
|
|
; <C206> 10/9/86 bbm Modified to mpw aincludes.
|
|
; <C152> 9/18/86 WRL Made this a separate PROC.
|
|
; <C56> 6/26/86 WRL Moved SystemBeep function to :OS:Beep.a
|
|
; <C28> 6/3/86 CSL Added changes for Aladddin (onMacPP).
|
|
; <C25> 5/29/86 WRL DAH Support for new CritErr.
|
|
; <C1> 4/14/86 RDC Added changes for 68020 Reno project (NuMac) - Changed variable
|
|
; for NMI debounce
|
|
; 11/3/85 JTC Heighten erase rect in MicroBug command line.
|
|
; 10/23/85 EHB Set CurMap to SysMap in case font swap needed.
|
|
; 10/16/85 EHB Made DSError set clipping to the box (restore after)
|
|
; 10/16/85 EHB Commented out systemAlert which isn't used
|
|
; 10/16/85 EHB Made FakeRgn same size as QuickDraw's wide open clip.
|
|
; 10/16/85 EHB Made MicroBug set clipping to the box (restore after)
|
|
; 8/23/85 RDC Changed code for syserror msg display for MidMac
|
|
; 8/5/85 RDC Added code to adjust system error msg display for MidMac
|
|
; 7/23/85 RDC Added changes for MidMac - changed test for MicroBug jump -
|
|
; reset NMI indicator bit when keyboard char received
|
|
; 5/21/85 KWK Fixed non-save of D1/D2 in PrintNHex routines.
|
|
; 5/13/85 KWK G <address> works again, so does regular syserror stuff, also
|
|
; uses equate for setting up the DS alert rect.
|
|
; 5/12/85 KWK Re-added CritErr call if no DS table
|
|
; 5/10/85 KWK Errors in drawing/DSAT punt to MicroBug, fixed restore of error
|
|
; code after drawing box.
|
|
; 5/7/85 KWK Multiple MicroBug cleanup/enhancements
|
|
; 5/4/85 KWK Added MicroDB, new DeepShit entry code
|
|
; 4/29/85 SC D4 new parameter for boot beep
|
|
; 4/29/85 SC Made SystemBeep not beep if sound is active
|
|
; 8/16/83 SC Added parameter to SystemBeep
|
|
; 8/6/83 SC Added SystemBeep
|
|
; 6/23/83 AJH made it init VBL manager before tracking button
|
|
; 6/21/83 AJH made it recouple cursor
|
|
; 6/14/83 AJH made it stash deep shit ID in low mem
|
|
; 6/2/83 AJH made it check for no dsAlerts as the 1st thing
|
|
; 5/14/83 AJH made it init and show cursor if we have any buttons
|
|
; 4/13/83 AJH Made it increment buttonID if restProc installed
|
|
; 4/5/83 AJH Added procID field to alert definition structure
|
|
;
|
|
|
|
|
|
BLANKS ON
|
|
STRING ASIS
|
|
|
|
PRINT OFF ; <C152>
|
|
LOAD 'StandardEqu.d'
|
|
INCLUDE 'HardwarePrivateEqu.a'
|
|
PRINT ON ; <C152>
|
|
|
|
PROC
|
|
|
|
EXPORT AllocFakeRgns ; <C56>
|
|
EXPORT DSErrorHandler ; <C152>
|
|
IMPORT TMRestart ; TestManager entry point <C448>
|
|
IMPORT CritErr ; Critical Error handler, in case we fail.
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; Routine AllocFakeRgns 4a50
|
|
; Arguments
|
|
; Function Sets up a dummy vis and clip region for the system alert port
|
|
; ---------------------------------------------------------------------------
|
|
|
|
AllocFakeRgns
|
|
LEA VisRgn(A6),A1 ; get pointer to visRgn handle
|
|
LEA PortRec(A6),A0 ; point to fake master pointer
|
|
|
|
MOVE.L A0,(A1)+ ; set up visRgn's master pointer on the stack
|
|
ADDQ #4,A0
|
|
MOVE.L A0,(A1)+ ; ditto with the clipRgn's
|
|
|
|
LEA GetParam,A1 ; point the "master pointers" to a region
|
|
MOVE.L A1,(A0) ; at GetParam to prevent a ROM write
|
|
MOVE.L A1,-(A0) ; <1.3>
|
|
OpenClip ; clip wide open (used on exit from syserr)
|
|
LEA FakeRgn+10,A0 ; copy the region data to RAM <1.3>
|
|
LEA GetParam+10,A1 ; <1.3>
|
|
MOVE.L -(A0),-(A1) ; <1.3>
|
|
MOVE.L -(A0),-(A1) ; <1.3>
|
|
MOVE.W -(A0),-(A1) ; <1.3>
|
|
RTS
|
|
|
|
FakeRgn DC.W 10
|
|
DC.W $8001,$8001,$7FFF,$7FFF ; <16-Oct-85>
|
|
|
|
|
|
;---------------------------------------------------------------------------
|
|
; ClipBox 4a80 sets the clipRegion (stored in GetParam) to the DS Alert rect.
|
|
; Trashes A0 and A1.
|
|
;---------------------------------------------------------------------------
|
|
|
|
ClipBox LEA DSAlertRect+8,A0 ; point to our rect <16-Oct-85><1.3>
|
|
LEA GetParam+2+8,A1 ; point to vis/clip region <16-Oct-85><1.3>
|
|
MOVE.L -(A0),-(A1) ; DSAlertRect -> GetParam+2 <1.3>
|
|
MOVE.L -(A0),-(A1) ; <1.3>
|
|
MOVE.L A1,-(SP) ; offset the clip's rect <16-Oct-85>
|
|
BCLR #7,(A1) ; clear flag bit <16-Oct-85>
|
|
MOVE.L (A5),A0 ; get the port <16-Oct-85>
|
|
MOVE.L (A0),A0 ; <16-Oct-85>
|
|
MOVE.L PortBounds(A0),-(SP) ; push dh,dv <16-Oct-85>
|
|
_OffsetRect ; <16-Oct-85>
|
|
RTS ; <16-Oct-85>
|
|
|
|
|
|
;---------------------------------------------------------------------------
|
|
; Routine DSErrorHandler 4a9e
|
|
; Arguments DSErrCode (input) System error value
|
|
; Function Creates temporary QD world on stack & uses the current Deep shit
|
|
; alert table (DSAT) to decide what to draw/do based on the system
|
|
; error value. Allows 2 strings, 1 icon and N button to be drawn
|
|
; for any error value. The restart proc creates a default 'resume'
|
|
; button in addition to the main (typically 'restart') button. In
|
|
; addition, a procedure (called before drawing buttons) can be
|
|
; associated with an alert.
|
|
; Uses A0-A6/D0-D7
|
|
; NOTE: Interrupts off on entry, assumes reasonable SP, D7.L must
|
|
; always be DSAlertTab ptr after setup
|
|
; Called by SystemError & SystemAlert
|
|
;---------------------------------------------------------------------------
|
|
|
|
DSErrorHandler
|
|
MOVE.W #$2500,SR ; turn off interrupts 'cept power off <C448>
|
|
MOVEQ #0,D6 ; clear upper word stuff <C309><C448><1.3>
|
|
MOVE.W DSErrCode,D6 ; get saved error code <C822>
|
|
MOVE.L DSAlertTab,D7 ; get alert table pointer <C448>
|
|
BNE.S @GoAlert ; installed, go nuts <C448>
|
|
|
|
; no deepshit alert table, keymap/resource map probably not set up either, so just bailout
|
|
|
|
MOVEQ #15,D7 ; test 15 => system alert error <C309><C448><1.3>
|
|
BigJmp CritErr,A0 ; Go directly to CritErr <C448><C651><1.2>
|
|
|
|
; setup the world for QuickDraw
|
|
|
|
@GoAlert MOVE.W #$2000,SR ; turn on interrupts
|
|
MOVE.W CurMap,-(SP) ; save and set for System map, <24Oct85>
|
|
MOVE.W SysMap,CurMap ; to ensure FONT 0 is available <24Oct85>
|
|
LEA -4(SP),A5 ; start A5 here
|
|
SUB.W #GrafSize+140,SP ; allocate global, port space
|
|
MOVE.L SP,A6 ; remember start of port
|
|
|
|
PEA -4(A5) ; point to QD global space
|
|
MOVE.B QDExist,D3 ; preserve state of QDExist flag (don't let us affect it)
|
|
_InitGraf ; initialize QuickDraw
|
|
MOVE.B D3,QDExist
|
|
|
|
; allocate a grafPort using the space above the screen and initialize it
|
|
|
|
BSR.S AllocFakeRgns ; init dummy vis and clip
|
|
MOVE.L A6,-(SP) ; push address of grafPort
|
|
_InitPort ; initialize the port
|
|
|
|
; decide whether to draw box or not, also whether to fall into MicroBug
|
|
|
|
MOVE.W D6,D0 ; get error code <1.3>
|
|
BMI.S @SkipDBox ; neg => don't redraw alert box
|
|
|
|
CMP.W #13,D0 ; programmer's switch hit with no MacsBug?
|
|
BEQ MicroBug ; -> yes, use the ROM-based version
|
|
BSR DrawBox ; draw and clear the alert box
|
|
|
|
; move the port to the center of the screen
|
|
|
|
@SkipDBox TST.B DSAlertRect ; is this a system alert? (vs system error?)<C573>
|
|
BPL.S @IsSysAlert ; branch if so. <C573>
|
|
MOVE.L DSCtrAdj,-(SP) ; Adjust TL of screen <C573><C578>
|
|
_MovePortTo ; and move the port. <C573>
|
|
|
|
@IsSysAlert BSR.S ClipBox ; set the clip to the alert rect <EHB 16-Oct-85>
|
|
|
|
MOVE.W D6,D0 ; get error code <1.3>
|
|
BSR FindObject ; look it up, set A0 to pt to it
|
|
BNE.S @GotAlert ; found it, now draw everything associated with it
|
|
|
|
; tricky stuff...didn't find the specific alert id, so default to the first one. Note, this
|
|
; is required for the normal user alerts to work, as the 'Sorry, as system error has occured..'
|
|
; has an id of -1, thus will never be found, but it is the first alert in the table, thus it
|
|
; gets called for any system error (1..13), and its proc gets the exact error number from the
|
|
; DSErrCode location and draws the 'ID = <N>' string.
|
|
|
|
MOVE.L D7,A0 ; get start of table
|
|
ADDQ.W #6,A0 ; bump past #of entries, entry id, entry length <1.3>
|
|
|
|
; we found the alert definition record so draw any appropriate fields
|
|
|
|
@GotAlert MOVE.L A0,A3 ; keep record pointer in A3
|
|
BSR DrawText ; draw the message <C682>
|
|
BSR DrawText ; draw it <C682>
|
|
|
|
; Draw the icon, if any. It gets the icon structure (the bits
|
|
; and where to plot them) from the logical ID passed in D0...
|
|
|
|
MOVE.W (A3)+,D0 ; get the icon ID
|
|
BEQ.S @NoIcon ; skip if there isn't one
|
|
|
|
BSR.S FindObject ; get the icon data structure
|
|
BEQ.S @NoIcon ; if none, skip
|
|
|
|
CMPI.W #30,DSErrCode ; Is the error fatal?
|
|
BLO.S @FatalError ; If so, don't bug the resource manager.
|
|
|
|
MOVE.L A0,A2 ; Save the pointer to the rectangle in A2
|
|
|
|
SUBQ.W #4,SP ; make room for color icon handle <1.3>
|
|
MOVE.W -4(A2),-(SP) ; Push icon ID
|
|
_GetCIcon ; Get the color icon of the same ID if present
|
|
TST.L (SP) ; Did we get a color icon (leave the handle on the stack)?
|
|
BEQ.S @NoColor ; Branch if not
|
|
|
|
MOVE.L A2,-(SP) ; Push a pointer to the rectangle to plot it in <C714>
|
|
MOVE.L 4(SP),-(SP) ; Push a handle to the color icon. <C714>
|
|
_PlotCIcon ; Plot the color icon
|
|
_DisposCIcon ; Dispose of it <C714>
|
|
BRA.S @NoIcon ; Skip the black and white icon
|
|
|
|
@NoColor ADDQ.W #4,SP ; Restore stack. <C714>
|
|
MOVE.L A2,A0 ; Restore A0 so that we can plot the b/w version
|
|
|
|
@FatalError
|
|
PEA 8(A0) ; push a pointer to the icon bits
|
|
MOVE.L A0,-(SP) ; push a pointer to the rectangle
|
|
PEA 4(SP) ; push handle to the icon bits
|
|
_PlotIcon ; plot the icon
|
|
ADDQ.W #4,SP ; pop off the icon pointer
|
|
|
|
; call the alert's procedure, if any...
|
|
|
|
@NoIcon MOVE.W (A3)+,D0 ; get the proc ID
|
|
BEQ.S @NoProc ; if none, skip
|
|
|
|
BSR.S FindObject ;look up the proc
|
|
BEQ.S @NoProc ;if not found, skip
|
|
JSR (A0) ;invoke it
|
|
|
|
; draw any buttons...
|
|
|
|
@NoProc MOVE.W (A3)+,D0 ;get the buttonList
|
|
BEQ.S @NoSemantics ;if none, we're done
|
|
|
|
; if there's a restart proc installed, increment buttonID number
|
|
|
|
TST.L RestProc ;is a restart procedure installed?
|
|
BEQ.S @NoRestart
|
|
ADDQ.W #1,D0 ;yes, increment the buttonID number
|
|
@NoRestart BSR DoButtons ;draw the button list and hit test it
|
|
BEQ.S @NoSemantics ;if none, we're done <1.3>
|
|
|
|
; we got a semantic routine associated with a button so invoke it
|
|
|
|
MOVE.L A0,-(SP) ; set up routine <EHB 16-Oct85>
|
|
BRA OpenClip ; set clip to full size and jump to A0 routine <EHB 16-Oct85><1.3>
|
|
|
|
; there is no button list, or the button that was pushed denies responsibility,
|
|
; so just return to caller normally.
|
|
|
|
@NoSemantics
|
|
RTS2SysErr BSR OpenClip ; set clip back to full size <EHB 16-Oct85>
|
|
ADD.W #GrafSize+140,SP ; cut back the stack
|
|
MOVE.W (SP)+,CurMap ; restore CurMap from stuffed SysMap <24Oct85>
|
|
MOVEQ #0,D0 ; return no error
|
|
RTS ; exit back to SystemError code
|
|
|
|
|
|
;---------------------------------------------------------------------------
|
|
; FindObject 4b88 takes the logical alert ID in D0 and scans through the
|
|
; association until it finds an entry with the matching ID. It returns
|
|
; a pointer to the object body in A0, which is NIL if it couldn't
|
|
; find anything. The z-Flag will be set if we couldn't find it.
|
|
;---------------------------------------------------------------------------
|
|
|
|
FindObject MOVE.L D7,A0 ;point to DS data structure
|
|
MOVE.W (A0)+,D1 ;get the number of entries
|
|
BRA.S @GoFindIt
|
|
|
|
@NextObject CMP.W (A0)+,D0 ;is this the one we're looking for?
|
|
BEQ.S @FoundObj ;-> didn't find the object we want
|
|
ADDA.W (A0)+,A0 ;bump to the next object
|
|
@GoFindIt DBRA D1,@NextObject ;-> keep looping if not
|
|
|
|
SUBA.L A0,A0 ;couldn't find it so return NIL
|
|
MOVEQ #0,D0 ; and exit with BEQ
|
|
RTS
|
|
|
|
@FoundObj ADDQ.W #2,A0 ;skip length word to point to the data
|
|
MOVEQ #-1,D0 ; and exit with BNE
|
|
RTS
|
|
|
|
|
|
;---------------------------------------------------------------------------
|
|
; DrawText 4ba4 draws the deep shit text structure as specified by the ID in D0
|
|
;---------------------------------------------------------------------------
|
|
|
|
DrawText MOVE.W (A3)+,D0 ;get the text ID
|
|
BEQ.S @NoText ;if zero, nothing to do
|
|
|
|
BSR.S FindObject ;find the text structure
|
|
BEQ.S @NoText ;if not found, we're done
|
|
MOVE.L (A0)+,D3 ;get the start point
|
|
MOVEA.L A0,A2 ;remember start of the first line
|
|
|
|
; scan for a null ($00) indicating the end of the text or the line separation character
|
|
|
|
@ScanForEOL MOVE.B (A2)+,D0 ;get the next byte <1.3>
|
|
BEQ.S @DrawTxLine ;if null, go draw the last line
|
|
CMP.B #'/',D0 ;is it the line separator?
|
|
BNE.S @ScanForEOL ;if not, continue scanning
|
|
|
|
; we got a null or a line separator so draw the text line
|
|
|
|
@DrawTxLine MOVE.B D0,-(SP) ;preserve the delimiting character
|
|
|
|
MOVE.L A2,D0 ;calculate how many text characters <1.3>
|
|
SUB.L A0,D0 ; are on this line <1.3>
|
|
SUBQ.W #1,D0 ; (don't include the delimiter in the length)
|
|
MOVE.L A0,-(SP) ;pointer to the text to draw <1.3>
|
|
CLR.W -(SP) ;start at the beginning of the text
|
|
MOVE.W D0,-(SP) ;how many characters to draw
|
|
|
|
MOVE.L D3,-(SP) ;move to the starting text position
|
|
_MoveTo
|
|
|
|
_DrawText ; and draw a line of text
|
|
|
|
ADDI.L #$000E0000,D3 ;move the position to the start of the next line
|
|
|
|
MOVEA.L A2,A0 ;point A0 at the beginning of the next line
|
|
MOVE.B (SP)+,D0 ;was the delimiter a null?
|
|
BNE.S @ScanForEOL ;-> no, go do the next line
|
|
@NoText RTS
|
|
|
|
|
|
;---------------------------------------------------------------------------
|
|
; DrawBox 4bdc draws a dialog-box-like-box or a deepshit-like-box
|
|
;---------------------------------------------------------------------------
|
|
|
|
DrawBox MOVE.L DSDrawProc,D0 ; is a custom dialog draw procedure specified?
|
|
BLE.S @StdProc ; -> nope
|
|
MOVE.L D0,-(SP) ; push its address
|
|
BSET #7,DSDrawProc ; make it a one-shot
|
|
RTS ; go to it
|
|
|
|
@StdProc MOVE D6,D0
|
|
BSR.S FindObject
|
|
BEQ.S @old
|
|
|
|
CMPI #12,-2(A0)
|
|
BLT.S @old
|
|
MOVE 10(A0),D0
|
|
BSR.S FindObject
|
|
BEQ.S @old
|
|
|
|
MOVE.L (A0)+,DSAlertRect
|
|
MOVE.L (A0),DSAlertRect+4
|
|
PEA.L DSAlertRect
|
|
BSR NewAlertFunc
|
|
ADDQ #4,SP
|
|
|
|
@old LEA DSAlertRect,A0 ; pt A0 at rect
|
|
TST.B (A0) ; is this a system alert? (vs system error?)
|
|
BPL.S DrawSysAlert ; yes, draw normal, do _MovePortTo
|
|
|
|
; we know it's a system error, so go stuff the rect w/what we need
|
|
|
|
; 4c1c
|
|
DrawSysErr
|
|
MOVEM.L A1/D1,-(SP) ; save registers. <C578>
|
|
|
|
MOVE.L (A5),A1 ; <C578>
|
|
LEA ScreenBits+Bounds+bottom(A1),A1 ; <C578><1.3>
|
|
|
|
MOVEQ #100,D0 ; DSRect.top <- bounds.bottom/5.34 <1.3>
|
|
MULU (A1)+,D0 ; <1.3>
|
|
DIVU #534,D0 ; <C578>
|
|
MOVE.W D0,top(A0) ; <C578>
|
|
|
|
MOVEQ #-(DSRectTL>>16),D1 ; DSCtrAdj <- DSRect.top - (Mac DSRect.top) <1.3>
|
|
ADD.W D0,D1 ; <1.3>
|
|
MOVE.W D1,DSCtrAdj ; <1.3>
|
|
|
|
ADD.W #DSRectHei,D0 ; DSRect.bottom <- DSRect.top + DSRectHei <C578>
|
|
MOVE.W D0,bottom(A0) ; <C578>
|
|
|
|
MOVE.W (A1),D0 ; DSRect.left <- bounds.right/2 - DSRectLen/2 <C578>
|
|
LSR.W #1,D0 ; <C578>
|
|
SUB.W #DSRectLen/2,D0 ; <C578>
|
|
MOVE.W D0,left(A0) ; <C578>
|
|
|
|
MOVEQ #-(DSRectTL**$FFFF),D1 ; DSCtrAdj <- DSRect.left - (Mac DSRect.left) <1.3>
|
|
ADD.W D0,D1 ; <1.3>
|
|
MOVE.W D1,DSCtrAdj+2 ; <1.3>
|
|
|
|
ADD.W #DSRectLen,D0 ; DSRect.right <- bounds.right/2 + DSRectLen/2 <C578>
|
|
MOVE.W D0,right(A0) ; <C578>
|
|
|
|
BSR.S DrawBox2 ; draw it
|
|
|
|
BSET #7,DSAlertRect ; reset flag for system error
|
|
|
|
MOVEM.L (SP)+,A1/D1 ; restore registers.
|
|
RTS ; and return
|
|
|
|
; 4c6a
|
|
DrawSysAlert
|
|
BSR.S DrawBox2 ; draw it
|
|
MOVE.L DSAlertRect,-(SP) ; push TL of rect
|
|
_MovePortTo ; move there
|
|
RTS ; and return
|
|
|
|
; use rect at (A0)
|
|
|
|
; 4c74
|
|
DrawBox2 MOVE.L A0, -(SP) ; rect for EraseRect
|
|
MOVE.L A0, -(SP) ; rect for FrameRect
|
|
MOVE.L A0, -(SP) ; rect for InsetRect
|
|
MOVE.L A0, -(SP) ; rect for FrameRect
|
|
MOVE.L A0, -(SP) ; rect for InsetRect <19Mar85>
|
|
_EraseRect
|
|
_FrameRect
|
|
MOVE.L #$00020002, -(SP)
|
|
_PenSize
|
|
MOVE.L #$00030003, -(SP)
|
|
_InsetRect
|
|
_FrameRect ; draw the border
|
|
MOVE.L #$FFFDFFFD,-(SP) ; <19Mar85>
|
|
_InsetRect ; put the rect back to normal <19Mar85>
|
|
_PenNormal ; put the pen back to normal
|
|
NoButtons RTS
|
|
|
|
|
|
|
|
|
|
NewAlertFunc
|
|
Link A6, #-$8
|
|
MoveM.L A1-A3, -(A7)
|
|
MoveA.L $8(A6), A3
|
|
Lea.L -$8(A6), A2
|
|
MoveA.L (A5), A0
|
|
Lea.L -$74(A0), A0
|
|
Move.L (A0)+, (A2)
|
|
Move.L (A0), $4(A2)
|
|
SubQ #$2, A7
|
|
Move (MBarHeight), (A7)
|
|
Move (A7)+, D0
|
|
Add D0, (A2)
|
|
Move.L A3, -(A7)
|
|
Move $6(A2), D0
|
|
Add $2(A2), D0
|
|
AsR #$1, D0
|
|
Move D0, -(A7)
|
|
Move $6(A3), D0
|
|
Add $2(A3), D0
|
|
AsR #$1, D0
|
|
Sub D0, (A7)
|
|
Move (A2), D0
|
|
Add $4(A2), D0
|
|
AsR #$1, D0
|
|
Move D0, -(A7)
|
|
Move (A3), D0
|
|
Add $4(A3), D0
|
|
AsR #$1, D0
|
|
Sub D0, (A7)
|
|
_OffsetRect
|
|
Move (A3), D0
|
|
Sub (A2), D0
|
|
Ext.L D0
|
|
Neg.L D0
|
|
DivS #$3, D0
|
|
Move.L A3, -(A7)
|
|
Clr -(A7)
|
|
Move D0, -(A7)
|
|
_OffsetRect
|
|
MoveM.L (A7)+, A1-A3
|
|
Unlk A6
|
|
Rts
|
|
|
|
|
|
|
|
|
|
|
|
;---------------------------------------------------------------------------
|
|
; DoButtons draws some buttons as specified by the buttonList data structure
|
|
; defined by the ID in D0, and then hit-tests the mouse position against
|
|
; them. It returns a dispatch address in A0, which is NIL if the deep
|
|
; shit manager should just return
|
|
;---------------------------------------------------------------------------
|
|
|
|
DoButtons BSR FindObject ;find the buttonList data structure
|
|
BEQ.S NoButtons ;if none, we're done
|
|
|
|
MOVE.L A0,A2 ;remember the button base
|
|
MOVE.W (A0)+,D3 ;get the number of buttons
|
|
MOVE.L A0,A3 ;point A3 at the first button
|
|
|
|
; loop through the button list, drawing each button
|
|
|
|
@DrawBtnLp MOVE.L 2(A3),-(SP) ;push topLeft
|
|
ADD.L #$000E0004,(SP) ;offset it for pen position
|
|
_MoveTo ;position the pen
|
|
|
|
MOVE.W (A3)+,D0 ;get the string ID
|
|
BSR FindObject ;find the string
|
|
SUBQ.W #1,A0 ;point to low byte of length
|
|
MOVE.L A0,-(SP) ;push the string pointer
|
|
_DrawString ;draw the string
|
|
|
|
MOVE.L A3,-(SP) ;push the rectangle pointer
|
|
MOVE.L #$00100010,-(SP) ;push the roundness factor
|
|
_FrameRoundRect ;frame it
|
|
|
|
ADD.W #8+2,A3 ;bump to next button
|
|
SUBQ.W #1,D3 ;any more buttons to do?
|
|
BNE.S @DrawBtnLp ;-> yes
|
|
|
|
; set the cursor to the arrow and show it
|
|
|
|
MOVE.L (A5),A0 ;get global base
|
|
PEA Arrow(A0) ;push ptr to arrow image
|
|
_SetCursor ;make that the cursor
|
|
|
|
_ShowCursor ;make sure the cursor is visible
|
|
MOVE #$2000,SR ;make sure interrupts are on
|
|
ST CrsrCouple ;force the cursor to be coupled
|
|
CLR.B VBLQueue ;make sure VBL manager is cool
|
|
|
|
; OK, now the buttons are drawn so poll for a mouse button down
|
|
|
|
@Wait4Click TST.B MBState ;is the mouse button down?
|
|
BNE.S @Wait4Click ;-> nope, wait until it is
|
|
|
|
; the mouse button went down, so loop through the button data structure to
|
|
; determine which button, if any, it went down in
|
|
|
|
MOVE.L A2,A3 ;get start of button list
|
|
MOVE.W (A3)+,D3 ;get the number of buttons
|
|
ADDQ #2,A3 ;skip past the string ID
|
|
|
|
@FindBtnHit BSR.S myPtInRect ;test if we're in the button
|
|
BNE.S @TrackBtn ;if so, go track the button
|
|
|
|
; we're not in this button, so go test the next button. If we tested them
|
|
; all, go try again
|
|
|
|
ADD.W #8+2+2,A3 ;bump to the next button
|
|
SUBQ.W #1,D3 ;decrement button count
|
|
BNE.S @FindBtnHit ;if more to test, loop
|
|
BRA.S @Wait4Click ;go poll the mouse button
|
|
|
|
; at this point, we know the mouse has gone down in the rectangle pointed to
|
|
; by A3. Track the mouse until the button goes up
|
|
|
|
@TrackLoop BSR.S myPtInRect ;are we in the rectangle?
|
|
CMP.B D0,D3 ;did it change?
|
|
BEQ.S @NoChange ;skip if it didn't
|
|
|
|
; we've moved in if we were out or out if we were in so toggle our state
|
|
|
|
@TrackBtn MOVE.B D0,D3 ;flag the button on/off <1.3>
|
|
BSR.S InvertBut ; and hilite or unhilite it
|
|
|
|
; now see if the mouse button went up; continue tracking until it does
|
|
|
|
@NoChange TST.B MBState ;is the mouse button still down?
|
|
BEQ.S @TrackLoop ;-> nope, keep looping until it's not
|
|
|
|
; the mouse went up -- if it wasn't in a button, continue polling the mouse
|
|
; button. If it was, return the address of the appropriate semantic routine
|
|
|
|
TST.B D3 ;were we in the button?
|
|
BEQ.S @Wait4Click ;if not, go try again
|
|
|
|
MOVE.W 8(A3),D0 ;get ID of proc object
|
|
BRA FindObject ; and look it up <1.3>
|
|
|
|
; myPtInRect is a little code saving utility that tests if the current
|
|
; mouse position is in the rectangle pointed to by A3
|
|
|
|
myPtInRect SUBQ #2,SP ;make room for the function result
|
|
MOVE.L Mouse,-(SP) ;push the current mouse point
|
|
PEA (SP) ;push address of mouse point <C549>
|
|
_GlobalToLocal ;convert it to coordinates of alert <C549>
|
|
MOVE.L A3,-(SP) ;push the rectangle ptr
|
|
_PtInRect ;test if the point is in the button
|
|
MOVE.B (SP)+,D0 ;get the result in D0
|
|
RTS
|
|
|
|
; InvertBut is a utility to invert the button whose rectangle is pointed to by A3
|
|
|
|
InvertBut MOVE.L A3,-(SP) ;push the rectangle pointer
|
|
MOVE.L #$00100010,-(SP) ;push the rounding factor
|
|
_InverRoundRect ;invert it
|
|
RTS
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; Routine MicroBug
|
|
; Arguments
|
|
; Function Minimal debugger in Rom. Allows display/set of memory/registers,
|
|
; also Go [address]. Invoked by one of two ways:
|
|
;
|
|
; 1) System alert/error & no alert definition found for error number
|
|
; 2) NMI & no debugger installed.
|
|
;
|
|
; Registers D7 Previous command
|
|
; D6-D3 DM drawing
|
|
; D0-D2 Scratch
|
|
; A7 Stack
|
|
; A6 Input buffer current position ptr
|
|
; A5 Globals ptr
|
|
; A4 Input buffer start ptr
|
|
; A0-A3 Scratch
|
|
; ---------------------------------------------------------------------------
|
|
|
|
MicroBug CLR.W DSErrCode ; zero the deep shit code (no actual error) <1.4>
|
|
|
|
LEA DSAlertRect,A0 ; pt A0 at rect
|
|
BSR DrawSysErr ; erase/draw the deepshit error box
|
|
|
|
MOVE.L DSCtrAdj,-(SP) ; adjust TL of DS rect for screen size <C584>
|
|
ADD.L #DSrectTL+$00060006,(SP); so that text is inside of the rect <C584>
|
|
_MovePortTo ; and move the port <C584>
|
|
|
|
BSR ClipBox ; set the clipping to DSAlertRect <EHB 16-Oct-85>
|
|
SUB.W #evtBlkSize,SP ; room for event record <1.3>
|
|
CLR.W D7 ; clear previous cmd value
|
|
CLR.L MBdotAddr ; clear dot address
|
|
CLR.L MBlocAddr ; clear location
|
|
|
|
CmdReset MOVE.L #$001101B0,-(SP) ; BR = 120, 440 so we use 15, 440 (minus some)
|
|
; upped descender to 17 to catch ',' ';' etc. <03Nov85 JTC>
|
|
CLR.L -(SP) ; set TL = 0
|
|
BSR MBDoErase ; erase it
|
|
|
|
LEA MBbuffer+MBbufSize,A6 ; point to end of buffer
|
|
MOVEQ #0,D6 ; init counter
|
|
|
|
@0 MOVE.W #' ',-(A6) ; clear it
|
|
ADDQ.W #2,D6 ; bump counter
|
|
CMP.W #MBbufSize,D6 ; all done?
|
|
BNE.S @0 ; nope
|
|
MOVE.L A6,A4 ; set start/end ptr
|
|
|
|
MOVE.L #$000F000A,-(SP) ; push h,v = 10,15
|
|
_MoveTo ; move there
|
|
MOVEQ #'>',D0 ; get prompt char
|
|
MOVE.W D0,-(SP) ; push on stack
|
|
_DrawChar ; and draw it
|
|
|
|
; Command loop. Get events, stuff key-down chars into buffer and display them,
|
|
; wait for return. On return, process buffer.
|
|
|
|
CmdLoop MOVE.L SP,A0 ; Point to event record on stack
|
|
MOVEQ #1<<keyDwnEvt,D0 ; keydown only <1.3>
|
|
_GetOSEvent ; any keyDown events in the queue?
|
|
BNE.S CmdLoop ; -> no, wait for one
|
|
|
|
; we got a keydown event, process it
|
|
|
|
BCLR #7,NMIFlag ; clear NMI indicator bit <C1/14Apr86>
|
|
|
|
MOVEQ #$7F,D0 ; get the ASCII character value <1.3>
|
|
AND.B evtMessage+3(SP),D0 ; and force it to be less than 128 <1.3>
|
|
CMP.B #'a',D0 ; is it lower case?
|
|
BLT.S @0
|
|
BCLR #5,D0 ; yes, force it to be upper case
|
|
|
|
; now D0.B is the character code value
|
|
|
|
@0 CMP.B #13,D0 ; carriage return?
|
|
BEQ.S GotCommand ; -> yes, go process the buffer
|
|
|
|
CMP.B #8,D0 ; backspace?
|
|
BNE.S RegChar ; -> no, all ok
|
|
|
|
CMP.L A6,A4 ; anything in buffer?
|
|
BEQ.S CmdLoop ; no, bail out
|
|
|
|
ADDQ.W #1,D6 ; increment remaining buffer space count
|
|
SUBQ.W #1,A6 ; remove one char from buffer
|
|
|
|
SUBQ.W #4,SP ; room for pt
|
|
MOVE.L SP,-(SP) ; @pt
|
|
_GetPen ; get current pen pos, leave on stack
|
|
MOVE.L (SP),-(SP) ; make copy (building rect on stack)
|
|
|
|
SUBQ.W #2,SP ; room for result
|
|
MOVE.B (A6),D0 ; get last char
|
|
MOVE.W D0,-(SP)
|
|
_CharWidth ; and measure it
|
|
MOVE.W (SP)+,D3 ; get width
|
|
SUB.W D3,2(SP) ; adjust left point of rect on stack
|
|
CLR.W (SP) ; top pt = 0
|
|
MOVE.L SP,-(SP) ; push @rect
|
|
CLR.W -(SP) ; delta h = 0
|
|
MOVE.W #2,-(SP) ; delta v = 2
|
|
_OffsetRect ; offset it
|
|
BSR MBDoErase ; erase it
|
|
|
|
MOVE.B #$20,(A6)
|
|
MOVE.W D3,-(SP) ; char width
|
|
NEG.W (SP) ; negative movement
|
|
CLR.W -(SP) ; delta V = 0
|
|
_Move ; and reset the pen
|
|
BRA.S CmdLoop ; return
|
|
|
|
RegChar TST.W D6 ; any space left?
|
|
BEQ.S CmdLoop ; no, don't add any more chars
|
|
|
|
SUBQ.W #1,D6 ; dec buffer free space count
|
|
MOVE.B D0,(A6)+ ; buffer it up
|
|
MOVE.W D0,-(SP) ; push on stack
|
|
_DrawChar ; draw it
|
|
BRA.S CmdLoop ; and loop
|
|
|
|
GotCommand CMP.L A4,A6 ; any chars?
|
|
BNE.S @0 ; yes, do reg processing
|
|
MOVE.W D7,(A6)+ ; stuff previous command
|
|
|
|
@0 MOVE.W (A4)+,D7 ; get command word
|
|
LEA MBcmds,A0 ; point at command table
|
|
|
|
@1 MOVE.W (A0)+,D0 ; get routine name
|
|
BMI.S @3 ; last command, nothing matched
|
|
MOVE.W (A0)+,D2 ; get routine offset
|
|
CMP.B #'@',D0 ; register display routine (wildcard digit?)
|
|
BNE.S @2 ; nope
|
|
|
|
MOVE.B D7,D0 ; stuff input number
|
|
CMP.B #'0',D0 ; zero reg?
|
|
BMI.S @1 ; no, try next command
|
|
CMP.B #'7',D0 ; last reg
|
|
BGT.S @1 ; no, try next command
|
|
|
|
@2 CMP.W D0,D7 ; does input command match table
|
|
BNE.S @1 ; try next command
|
|
|
|
LEA MBcmds,A0 ; pt to start of this code
|
|
JSR 0(A0,D2.W) ; execute the routine
|
|
@3 BRA CmdReset ; and start cmd loop again
|
|
|
|
MBcmds DC.W 'G ', GCmd-MBcmds ; since command line cleared, 'G' only matches to G & null
|
|
DC.W 'DM', DMCmd-MBcmds
|
|
DC.W 'SM', SMCmd-MBcmds
|
|
DC.W 'TD', TDCmd-MBcmds
|
|
DC.W 'D@', DCmd-MBcmds
|
|
DC.W 'A@', ACmd-MBcmds
|
|
DC.W 'PC', PCCmd-MBcmds
|
|
DC.W 'SR', SRCmd-MBcmds
|
|
DC.W -1
|
|
|
|
; Go command. Try for address, if not there just return, else rts to it
|
|
|
|
GCmd BSR ReadToken ; try for address
|
|
BEQ.S GotResume
|
|
MOVE.L D0,-(SP) ; stuff address <EHB 16-Oct-85>
|
|
BSR OpenClip ; restore clipping <EHB 16-Oct-85>
|
|
RTS ; and go to it <EHB 16-Oct-85>
|
|
|
|
GotResume ADD.W #20,SP ; get rid of event record, RTS
|
|
CLR.B DSWndUpdate ; flag GNE to remove the alert . . .
|
|
BRA RTS2SysErr ; return to SysError handler
|
|
|
|
; Erase the rect on the stack
|
|
; Uses D0-D2/A0-A2
|
|
|
|
MBDoErase MOVE.L (SP)+,A2 ; preserve return address
|
|
MOVE.L SP,-(SP) ; push @rect
|
|
_EraseRect ; erase lower pane
|
|
ADDQ.W #8,SP ; flush rect
|
|
JMP (A2) ; and return
|
|
|
|
; Display memory command. Get Address, do full window for the guy
|
|
|
|
DMCmd MOVE.L #$007001B0,-(SP) ; push BR
|
|
CLR.L -(SP) ; TL = 0
|
|
BSR.S MBDoErase ; erase the rect
|
|
|
|
BSR ReadXToken ; get address
|
|
@0 BCLR #0,D0 ; force even address
|
|
MOVE.L D0,A3 ; set display address
|
|
MOVE.L D0,MBdotAddr ; save as dot addr
|
|
|
|
MOVEQ #6-1,D6 ; 6 lines
|
|
MOVEQ #15,D5 ; starting V coord
|
|
|
|
@1 ADD.W #15,D5 ; bump V coord
|
|
MOVE.W #10,-(SP) ; push h
|
|
MOVE.W D5,-(SP) ; push v
|
|
_MoveTo ; move there
|
|
MOVE.L A3,D0 ; get address
|
|
BSR.S Print6Hx ; print out
|
|
|
|
MOVEQ #7,D4 ; 8 words
|
|
MOVEQ #35,D3 ; starting h coord
|
|
|
|
@2 ADD.W #45,D3 ; bump h coord
|
|
MOVE.W D3,-(SP) ; push h
|
|
MOVE.W D5,-(SP) ; push v
|
|
_MoveTo ; move there
|
|
MOVE.W (A3)+,D0 ; get next word
|
|
BSR.S Print4Hx ; print word
|
|
DBRA D4,@2 ; word column loop
|
|
DBRA D6,@1 ; line loop
|
|
MOVE.L A3,MBlocAddr ; set up new address
|
|
RTS ; and return
|
|
|
|
Print6Hx SWAP D0
|
|
BSR.S Print4Hx
|
|
SWAP D0
|
|
|
|
Print4Hx MOVE.W D0,-(SP)
|
|
ROXR.W #8,D0
|
|
BSR.S Print2Hx
|
|
MOVE.W (SP)+,D0
|
|
|
|
Print2Hx MOVE.W D0,-(SP)
|
|
ROR.W #4,D0
|
|
BSR.S PUTHEX
|
|
MOVE.W (SP)+,D0
|
|
|
|
PUTHEX ANDI.B #$0F,D0
|
|
ORI.B #'0',D0
|
|
CMPI.B #'9',D0
|
|
BLE.S @0
|
|
ADDQ.W #7,D0
|
|
|
|
@0 MOVE.L D0,-(SP) ; save D0
|
|
MOVE.W D0,-(SP) ; push on stack
|
|
_DrawChar ; draw it
|
|
MOVE.L (SP)+,D0 ; restore D0
|
|
RTS ; and return
|
|
|
|
; Set Memory command. Get an address, and then keep stuffing values until we're done
|
|
; Uses D0-D6/A0-A1/A3
|
|
|
|
SMCmd BSR ReadXToken
|
|
MOVE.L D0,A1
|
|
LEA MBdotAddr,A0 ; point at storage
|
|
MOVE.L D0,(A0)+ ; set dot and loc addresses
|
|
MOVE.L D0,(A0)+
|
|
MOVE.W #'DM',D7 ; jam repeat cmd to DM
|
|
|
|
@1 BSR ReadToken
|
|
BEQ.S DMCmd ; using locAddr, draw lower pane
|
|
MOVE.L A1,A2 ; get fixed point for shifting bytes in
|
|
|
|
@2 MOVE.B D0,-1(A2,D1) ; stuff byte at last position indicated by size (D1.W)
|
|
ASR.L #8,D0 ; get next byte
|
|
ADDQ.L #1,A1 ; bump destination ptr
|
|
SUBQ.L #1,D1 ; dec offset ptr
|
|
BNE.S @2 ; not done w/this value, keep looping
|
|
BRA.S @1 ; any more tokens?
|
|
|
|
; TD command. Display memory where all the regs are saved.
|
|
|
|
TDCmd MOVE.L #SEVars,MBlocAddr ; set saved address to be location of regs
|
|
BRA.S DMCmd ; using locAddr, draw lower pane
|
|
|
|
; Dx command. Set/display data register
|
|
|
|
DCmd LEA SED0,A3 ; pt at reg 0
|
|
BRA.S SetR
|
|
|
|
ACmd LEA SEA0,A3
|
|
BRA.S SetR
|
|
|
|
PCCmd LEA SEPC,A3
|
|
BRA.S SetR0
|
|
|
|
SRCmd LEA SESR,A3
|
|
BSR.S ReadToken
|
|
BEQ.S SetR2 ; print value
|
|
MOVE.W D0,(A3) ; stuff input
|
|
RTS ; and return
|
|
|
|
SetR BSR.S GetHex ; convert ascii in D0.B to hex value
|
|
LSL.L #2,D0 ; turn into long offset
|
|
ADD.L D0,A3 ; add offset
|
|
|
|
SetR0 BSR.S ReadToken
|
|
BEQ.S SetR1 ; print value
|
|
MOVE.L D0,(A3) ; stuff value
|
|
RTS ; and return
|
|
|
|
SetR2 MOVEQ #-1,D6 ; normal branch to SetR1 has D6=0
|
|
|
|
SetR1 MOVE.L #$007001B0,-(SP) ; push BR
|
|
CLR.L -(SP) ; TL = 0
|
|
BSR.S MBDoErase ; erase the rect
|
|
MOVE.L #$00300010,-(SP) ; push 10,30 as drawing pt
|
|
_MoveTo ; go there
|
|
MOVE.W (A3)+,D0 ; get current value
|
|
TST.W D6 ; special SR case?
|
|
BNE.S @0 ; yes, only print word
|
|
BSR.S Print4Hx ; print high word
|
|
MOVE.W (A3)+,D0 ; get low word
|
|
@0 BRA.S Print4Hx ; print low word <1.3>
|
|
|
|
GetHex AND.L #$FF,D0 ; mask off anything but low byte
|
|
CMP.B #$39,D0 ; Hex digit
|
|
BLE.S @0 ; assume so
|
|
SUBQ.B #7,D0 ; assume 0..9
|
|
@0 AND.B #$F,D0 ; mask off low nybble
|
|
RTS ; and return
|
|
|
|
; ReadXToken will return either ReadToken value or (if nothing in input buffer)
|
|
; the saved long value
|
|
; ReadToken will return in D0.L the next value in the command line. CC=NE if
|
|
; something was there.
|
|
; Uses D0-D6/A0
|
|
|
|
ReadXToken BSR.S ReadToken ; try for something
|
|
BNE.S @0 ; we got something back, return it
|
|
MOVE.L MBlocAddr,D0 ; return saved address
|
|
@0 RTS ; and return
|
|
|
|
ReadToken MOVEQ #0,D4 ; clear accumulator
|
|
MOVEQ #0,D6 ; max # digits
|
|
|
|
ReadMore MOVEQ #0,D5 ; count # digits
|
|
CLR.W MBSign ; set sign to positive
|
|
MOVEQ #0,D3 ; assume no indirection
|
|
MOVEQ #0,D0
|
|
MOVEQ #0,D1 ; sub-number built here
|
|
|
|
blanks CMP.L A6,A4 ; any more chars?
|
|
BGE ReadExit ; if not escape
|
|
|
|
leadSP MOVE.B (A4)+,D0 ; get next char
|
|
CMPI.B #' ',D0 ; skip blanks
|
|
BLE.S blanks
|
|
|
|
; See if leading sign or indirection
|
|
|
|
CMP.B #'@',D0 ; leading @ indirection
|
|
BNE.S @0
|
|
ADDQ #1,D3 ; bump indirection counter
|
|
BRA.S leadSP
|
|
|
|
@0 CMP.B #'+',D0 ; leading plus
|
|
BEQ.S leadSP
|
|
CMP.B #'-',D0 ; leading minus
|
|
BNE.S getBase
|
|
NOT.B MBSign ; record sign change
|
|
BRA.S leadSP
|
|
|
|
getBase CMP.B #'$',D0 ; leading $?
|
|
BNE getLabel ; no, try for label
|
|
|
|
MOVEQ #0,D0 ; clear char value
|
|
MOVE.B (A4)+,D0 ; next character
|
|
|
|
getNumber BSR GetHex ; convert hex ascii digit in D0.B to number
|
|
|
|
ADDQ #1,D5 ; increment # digits
|
|
LSL.L #4,D1 ; multiply by 16
|
|
ADD.L D0,D1 ; add in this digit
|
|
|
|
; Are we done?
|
|
|
|
CMP.L A6,A4 ; any more chars?
|
|
BGE.S ReadExit ; if not escape
|
|
|
|
MOVE.B (A4)+,D0 ; get next char
|
|
|
|
CMP.B #'0',D0 ; < ASCII zero
|
|
BGE.S GetNumber ; go get more
|
|
|
|
ReadExit TST D3 ; any indirection?
|
|
BEQ.S @1
|
|
MOVEQ #8,D5 ; jam eight digits
|
|
|
|
@0 BCLR #0,D1 ; make sure it's even
|
|
MOVE.L D1,A0 ; indirect it
|
|
MOVE.L (A0),D1
|
|
SUBQ #1,D3
|
|
BNE.S @0
|
|
|
|
@1 TST.B MBSign ; negative?
|
|
BEQ.S @2 ; no, keep going
|
|
NEG.L D1
|
|
|
|
@2 ADD.L D1,D4 ; add into result
|
|
|
|
; Clean up the bytes counter
|
|
|
|
ADDQ.W #1,D5 ; round up
|
|
LSR.W #1,D5 ; convert # chars to number of bytes
|
|
CMP.W #4,D5 ; more than a long?
|
|
BLE.S @3 ; no
|
|
MOVEQ #4,D5 ; jam to a long
|
|
|
|
@3 CMP.W D6,D5 ; bump max # digits if D5 >
|
|
BLE.S @4
|
|
MOVE.W D5,D6 ; max # digits
|
|
|
|
@4 CMPI.B #'+',D0 ; if plus or minus add a new one
|
|
BEQ.S @5
|
|
CMPI.B #'-',D0
|
|
BNE.S @6
|
|
|
|
@5 MOVE.B D0,-(A4) ; push back on sign
|
|
BRA ReadMore ; and keep looping
|
|
|
|
@6 MOVE.L D4,D0 ; return the number
|
|
MOVE.L D6,D1 ; return max digits
|
|
RTS ; and return
|
|
|
|
; See if the text matches a label
|
|
|
|
getLabel CMP.B #'.',D0 ; dot?
|
|
BNE.S notDot
|
|
|
|
MOVE.L MBdotAddr,D1 ; get saved long
|
|
MOVEQ #1,D2 ; amount to skip
|
|
goLabel
|
|
MOVEQ #8,D5 ; all eight bytes
|
|
cleanExit
|
|
MOVE.B (A4)+,D0
|
|
SUBQ #1,D2
|
|
BNE cleanExit
|
|
|
|
BRA ReadExit
|
|
|
|
notDot MOVE D0,D2 ; build a word
|
|
LSL #8,D2
|
|
MOVE.B (A4),D2 ; get second byte
|
|
|
|
CMP #'PC',D2 ; PC?
|
|
BNE.S notPC
|
|
|
|
MOVE.L SEPC,D1 ; return the PC
|
|
|
|
go2Label MOVEQ #2,D2 ; amount to skip
|
|
BRA goLabel
|
|
|
|
notPC CMP.B #'R',D0 ; reg references start with R
|
|
BNE.S getNumber ; try for hex number
|
|
|
|
CMP.B #'A',D2 ; aregs
|
|
BNE.S notAs
|
|
|
|
LEA SEA0,A0 ; point to address regs loc
|
|
|
|
doReg MOVEQ #0,D2 ; calculate the index
|
|
MOVE.B 1(A4),D2
|
|
SUB #'0',D2
|
|
BMI.S getNumber ; RAx, x < '0'
|
|
|
|
CMP #7,D2
|
|
BGT.S getNumber ; RAx, x > '7'
|
|
|
|
LSL #2,D2
|
|
MOVE.L 0(A0,D2),D1
|
|
|
|
MOVEQ #3,D2 ; amount to skip
|
|
BRA goLabel
|
|
|
|
notAs
|
|
CMP.B #'D',D2 ; Dregs
|
|
BNE.S getNumber ; Rx, x <> A, x <> D
|
|
|
|
LEA SED0,A0 ; point to data regs loc
|
|
BRA doReg
|
|
|
|
ENDP ; <C152>
|
|
|
|
END ; <C152>
|
|
|