;
; 	Copyright (c) 1988, 1989  Motorola Inc.
; 	All Rights Reserved
;
;	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA INC.
;
;	The copyright notice above does not evidence any
;	actual or intended publication of such source code.
;
;*****************************************************************************
;
;tiov.m4	12/31/87	sample exception handler program
;	This program is a sample exception handler that gives an example of the 
;M88000 exception processing explained in section 7.5 of version 0.4 of the 
;User's Manual.  This program contains a vector table, a sample program which 
;causes the exception, and an exception handler.  This integer unit exception 
;is caused by an integer add overflow.
;	After the exception is detected:
;	
;	1.	The PSR goes into the SPSR.
;	2.	All pending data memory accesses complete or terminate in an
;		exception.  Data Memory Unit (DMU) exceptions are indicated
;		by setting the DEXC bit in the SPSR.
;	3.	Exceptions, interrupts, and the floating point unit are
;		disabled.  The shadow registers are frozen until exceptions
;		are re-enabled.  The register scoreboard is cleared.  The
;		processor switches to supervisor mode.
;	4.	The processor branches to the exception handler address 
;		written in the vector table.
;
;	The handler first checks the DEXC bit in the SPSR to see if there
;was a DMU exception.  If there was a DMU exception, then the handler branches
;to the DMU exception handler.  The DMU exception handler will need to save 
;and later restore the values of the shadow registers if it enables
;exceptions in handling the DMU error.  The DMU exception handler shown below
;is only a stub which saves and restores control register values.  An actual
;DMU exception handler is available.  The overflow handler must branch to the
;DMU handler before it re-enables exceptions with its rte.
;
;	The overflow exception handler writes the largest positive integer
;into the destination register whether the overflow resulted from an 
;addition or subtraction, or whether it was a positive overflow or a
;negative overflow.
;	After the exception handlers have done their work, any modified
;shadow register values must loaded into their respective control registers.
;Then an rte is performed.  During the rte:
;
;	1.	The processor waits for the register scoreboard to clear.
;	2.	The shadow registers are loaded into the registers that they
;		shadow, and the processor begins execution at the instruction
;		pointed to by the NIP.
;
;
;	This exception handler does not have interface routines to a UNIX
;operating system and is intended to be run on a one-user system in supervisor
;mode, but I hope that this example will clear up any questions
;that you have about exception handling.
;
;			Jeff Hopkins 	(512) 440-2617


define(STACK,0xff0)
define(TIOVFRAME,8)
define(DMUFRAME,24)
define(XR1,0)
define(XR2,4)
define(RETADDR,0)
define(XSPSR,4)
define(XSSB,8)
define(XSXIP,12)
define(XSNIP,16)
define(XSFIP,20)
define(psr,cr1)
define(spsr,cr2)
define(ssb,cr3)
define(sxip,cr4)
define(snip,cr5)
define(sfip,cr6)
define(dexc,27)

		text

trst:
                br              start
                or		r0,r0,r0	;nop
tint:
                br.n    tint
                or		r0,r0,r0
tcacc:
                br.n    tcacc
                or		r0,r0,r0
tdacc:
                br.n    tdacc
                or		r0,r0,r0
tma:
                br.n    tma
                or		r0,r0,r0
topc:
                br.n    topc
                or		r0,r0,r0
tprv:
                br.n    tprv
                or		r0,r0,r0
tbond:
                br.n    tbond
                or		r0,r0,r0
tidz:
                br.n    tidz
                or		r0,r0,r0
tiov:
                br	tiov_hand
                or		r0,r0,r0
t10:
                br.n    t10
                or		r0,r0,r0
t11:
                br.n    t11
                or		r0,r0,r0
t12:
                br.n    t12
                or		r0,r0,r0
t13:
                br.n    t13
                or		r0,r0,r0
t14:
                br.n    t14
                or		r0,r0,r0
t15:
                br.n    t15
                or		r0,r0,r0
t16:
                br.n    t16
                or		r0,r0,r0
t17:
                br.n    t17
                or		r0,r0,r0
t18:
                br.n    t18
                or		r0,r0,r0
t19:
                br.n    t19
                or		r0,r0,r0
t20:
                br.n    t20
                or		r0,r0,r0
t21:
                br.n    t21
                or		r0,r0,r0
t22:
                br.n    t22
                or		r0,r0,r0
t23:
                br.n    t23
                or		r0,r0,r0
t24:
                br.n    t24
                or		r0,r0,r0
t25:
                br.n    t25
                or		r0,r0,r0
t26:
                br.n    t26
                or		r0,r0,r0
t27:
                br.n    t27
                or		r0,r0,r0
t28:
                br.n    t28
                or		r0,r0,r0
t29:
                br.n    t29
                or		r0,r0,r0
t30:
                br.n    t30
                or		r0,r0,r0
t31:
                br.n    t31
                or		r0,r0,r0
t32:
                br.n    t32
                or		r0,r0,r0
t33:
                br.n    t33
                or		r0,r0,r0
t34:
                br.n    t34
                or		r0,r0,r0
t35:
                br.n    t35
                or		r0,r0,r0
t36:
                br.n    t36
                or		r0,r0,r0
t37:
                br.n    t37
                or		r0,r0,r0
t38:
                br.n    t38
                or		r0,r0,r0
t39:
                br.n    t39
                or		r0,r0,r0
t40:
                br.n    t40
                or		r0,r0,r0
t41:
                br.n    t41
                or		r0,r0,r0
t42:
                br.n    t42
                or		r0,r0,r0
t43:
                br.n    t43
                or		r0,r0,r0
t44:
                br.n    t44
                or		r0,r0,r0
t45:
                br.n    t45
                or		r0,r0,r0
t46:
                br.n    t46
                or		r0,r0,r0
t47:
                br.n    t47
                or		r0,r0,r0
t48:
                br.n    t48
                or		r0,r0,r0
t49:
                br.n    t49
                or		r0,r0,r0
t50:
                br.n    t50
                or		r0,r0,r0
t51:
                br.n    t51
                or		r0,r0,r0
t52:
                br.n    t52
                or		r0,r0,r0
t53:
                br.n    t53
                or		r0,r0,r0
t54:
                br.n    t54
                or		r0,r0,r0
t55:
                br.n    t55
                or		r0,r0,r0
t56:
                br.n    t56
                or		r0,r0,r0
t57:
                br.n    t57
                or		r0,r0,r0
t58:
                br.n    t58
                or		r0,r0,r0
t59:
                br.n    t59
                or		r0,r0,r0
t60:
                br.n    t60
                or		r0,r0,r0
t61:
                br.n    t61
                or		r0,r0,r0
t62:
                br.n    t62
                or		r0,r0,r0
t63:
                br.n    t63
                or		r0,r0,r0
t64:
                br.n    t64
                or		r0,r0,r0
t65:
                br.n    t65
                or		r0,r0,r0
t66:
                br.n    t66
                or		r0,r0,r0
t67:
                br.n    t67
                or		r0,r0,r0
t68:
                br.n    t68
                or		r0,r0,r0
t69:
                br.n    t69
                or		r0,r0,r0
t70:
                br.n    t70
                or		r0,r0,r0
t71:
                br.n    t71
                or		r0,r0,r0
t72:
                br.n    t72
                or		r0,r0,r0
t73:
                br.n    t73
                or		r0,r0,r0
t74:
                br.n    t74
                or		r0,r0,r0
t75:
                br.n    t75
                or		r0,r0,r0
t76:
                br.n    t76
                or		r0,r0,r0
t77:
                br.n    t77
                or		r0,r0,r0
t78:
                br.n    t78
                or		r0,r0,r0
t79:
                br.n    t79
                or		r0,r0,r0
t80:
                br.n    t80
                or		r0,r0,r0
t81:
                br.n    t81
                or		r0,r0,r0
t82:
                br.n    t82
                or		r0,r0,r0
t83:
                br.n    t83
                or		r0,r0,r0
t84:
                br.n    t84
                or		r0,r0,r0
t85:
                br.n    t85
                or		r0,r0,r0
t86:
                br.n    t86
                or		r0,r0,r0
t87:
                br.n    t87
                or		r0,r0,r0
t88:
                br.n    t88
                or		r0,r0,r0
t89:
                br.n    t89
                or		r0,r0,r0
t90:
                br.n    t90
                or		r0,r0,r0
t91:
                br.n    t91
                or		r0,r0,r0
t92:
                br.n    t92
                or		r0,r0,r0
t93:
                br.n    t93
                or		r0,r0,r0
t94:
                br.n    t94
                or		r0,r0,r0
t95:
                br.n    t95
                or		r0,r0,r0
t96:
                br.n    t96
                or		r0,r0,r0
t97:
                br.n    t97
                or		r0,r0,r0
t98:
                br.n    t98
                or		r0,r0,r0
t99:
                br.n    t99
                or		r0,r0,r0
t100:
                br.n    t100
                or		r0,r0,r0
t101:
                br.n    t101
                or		r0,r0,r0
t102:
                br.n    t102
                or		r0,r0,r0
t103:
                br.n    t103
                or		r0,r0,r0
t104:
                br.n    t104
                or		r0,r0,r0
t105:
                br.n    t105
                or		r0,r0,r0
t106:
                br.n    t106
                or		r0,r0,r0
t107:
                br.n    t107
                or		r0,r0,r0
t108:
                br.n    t108
                or		r0,r0,r0
t109:
                br.n    t109
                or		r0,r0,r0
t110:
                br.n    t110
                or		r0,r0,r0
t111:
                br.n    t111
                or		r0,r0,r0
t112:
                br.n    t112
                or		r0,r0,r0
t113:
                br.n    t113
                or		r0,r0,r0
sfu1p:
                br.n    sfu1p
                or		r0,r0,r0
sfu1i:
                br.n    sfu1i
                or		r0,r0,r0
sfu2p:
                br.n    sfu2p
                or		r0,r0,r0
sfu2i:
                br.n    sfu2i
                or		r0,r0,r0
sfu3p:
                br.n    sfu3p
                or		r0,r0,r0
sfu3i:
                br.n    sfu3i
                or		r0,r0,r0
sfu4p:
                br.n    sfu4p
                or		r0,r0,r0
sfu4i:
                br.n    sfu4i
                or		r0,r0,r0
sfu5p:
                br.n    sfu5p
                or		r0,r0,r0
sfu5i:
                br.n    sfu5i
                or		r0,r0,r0
sfu6p:
                br.n    sfu6p
                or		r0,r0,r0
sfu6i:
                br.n    sfu6i
                or		r0,r0,r0
sfu7p:
                br.n    sfu7p
                or		r0,r0,r0
sfu7i:
                br.n    sfu7i
                or		r0,r0,r0
t128:
                br.n    t128
                or		r0,r0,r0
t129:
                br.n    t129
                or		r0,r0,r0

;Program segment which caused the exception.
start:		or	r30,r0,r0	;initialize r30 to zeros
		or	r31,r0,STACK	;set stack pointer value for r31
		stcr	r0,ssb		;clear the shadow scoreboard
		or.u	r1,r0,0x8000	;set to supervisor mode so that I
					;do not have to worry about switching
					;between supervisor and user stacks.
		stcr	r1,psr		;enable exceptions
		set	r1,r0,31<0>	;set r1 to 0x7fffffff
		set	r2,r0,31<0>	;set r2 to 0x7fffffff
		add	r3,r1,r2	;add will cause overflow

END:		br	END		;infinite loop at end of program

;This code is the exception handler.  The DMU exception handler is shown
;below, but it does no useful work beyond saving and restoring shadow registers.
;To begin, the supervisor stack is decremented to save some values.
;R1, r2, and r3 are used as scratch registers.  If the DEXC bit is
;set in the SPSR, then branch the the DMU exception handler.
tiov_hand:	subu	r31,r31,TIOVFRAME	;adjust stack pointer
		st	r1,r31,XR1	;save r1
		ldcr	r1,spsr		;load in the SPSR
		bb0	dexc,r1,nodaccfault	;if no DMU exception, then do
						;not save the shadow registers
		bsr	daccfault	;branch to the DMU exception handler

;Passing the instruction address in r2, branch to the routine instfetch to
;obtain the instruction.  The instruction will be returned in r2.
;0x7ffffff, the largest positive integer, is then either written into r1, r2, or
;r3 in memory, or directly into the register using a jump table.
nodaccfault:	st	r2,r31,XR2	;save values to get scratch registers
		ldcr	r2,sxip		;load pointer to excepting instruction
		bsr.n	instfetch	;branch to fetch the
					;instruction, return the result in r2
		clr	r2,r2,2<0>	;align address to word boundary
		extu	r2,r2,5<21>	;get destination register number
		lda	r1,r0,jmptable	;load the address of the jump table
		lda.d	r1,r1[r2]	;scale the pointer into the jump table
					;by 2X the register number
		jmp.n	r1
		set	r2,r0,31<0>	;set r2 to maximum positive integer
jmptable:	br.n	return
		or	r0,r2,r0
		br.n	return
		st	r2,r31,XR1	;load into memory
		br.n	return
		st	r2,r31,XR2
		br.n	return
		or	r3,r2,r0	;load directly into the register
		br.n	return
		or	r4,r2,r0	;load directly into the register
		br.n	return
		or	r5,r2,r0
		br.n	return
		or	r6,r2,r0
		br.n	return
		or	r7,r2,r0
		br.n	return
		or	r8,r2,r0
		br.n	return
		or	r9,r2,r0
		br.n	return
		or	r10,r2,r0
		br.n	return
		or	r11,r2,r0
		br.n	return
		or	r12,r2,r0
		br.n	return
		or	r13,r2,r0
		br.n	return
		or	r14,r2,r0
		br.n	return
		or	r15,r2,r0
		br.n	return
		or	r16,r2,r0
		br.n	return
		or	r17,r2,r0
		br.n	return
		or	r18,r2,r0
		br.n	return
		or	r19,r2,r0
		br.n	return
		or	r20,r2,r0
		br.n	return
		or	r21,r2,r0
		br.n	return
		or	r22,r2,r0
		br.n	return
		or	r23,r2,r0
		br.n	return
		or	r24,r2,r0
		br.n	return
		or	r25,r2,r0
		br.n	return
		or	r26,r2,r0
		br.n	return
		or	r27,r2,r0
		br.n	return
		or	r28,r2,r0
		br.n	return
		or	r29,r2,r0
		br.n	return
		or	r30,r2,r0
		br.n	return		;If you are in this routine because of
		or	r0,r0,r0	;an overflow of r31, then you have 
					;overflowed your stack, and you need 
					;more than this routine to handle that
					;problem.

;The add or sub will write an undefined value to the destination register 
;and clear the scoreboard bit before the overflow is detected.  Therefore, 
;the exception handler does not need to clear the destination register bit 
;in the SSB.
return:		ld	r1,r31,XR1	
		ld	r2,r31,XR2	
		addu	r31,r31,TIOVFRAME
		rte			;return from exception handler


;Stub for the DMU exception handler.  The DEXC bit does not need to be
;cleared because it will be set to its proper value at the next exception.
daccfault:	subu	r31,r31,DMUFRAME	;allocate space for saving
		st	r1,r31,RETADDR	;save return address
		ldcr	r1,spsr		;save the shadow registers
		st	r1,r31,XSPSR	
		ldcr	r1,ssb
		st	r1,r31,XSSB
		ldcr	r1,sxip		
		st	r1,r31,XSXIP
		ldcr	r1,snip
		st	r1,r31,XSNIP
		ldcr	r1,sfip
		st	r1,r31,XSFIP
;If there was any code for the DMU exception handler, it would go here.
		ld	r1,r31,XSPSR	;restore shadow registers
		stcr	r1,spsr
		ld	r1,r31,XSSB
		stcr	r1,ssb
		ld	r1,r31,XSXIP
		stcr	r1,sxip
		ld	r1,r31,XSNIP
		stcr	r1,snip
		ld	r1,r31,XSFIP
		stcr	r1,sfip
		ld	r1,r31,RETADDR	;load return address
		jmp.n	r1		;necessary for program to link
		addu	r31,r31,DMUFRAME;readjust stack pointer


;instfetch receives the instruction address in r2, and returns the instruction
;in r2.  Code for loading the instruction from text space is dependent on 
;CMMU convfiguration, so this subroutine may need to be modified.
instfetch:	jmp.n	r1
		ld	r2,r2,0



