*******************************************************************************
* NoGuru					 Copyright İ 1992/94 2-Cool/LSd
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* Simple and small program to redirect guru-meditations to a Soft-Reset routine
* so that the Amiga quickly reboots instead of having to go through multiple
* crashes that can lock the machine. The Program SHOULD ONLY BE EXECUTED *ONCE*
* All other re-executions of the program will simply abort peacefully! This is
* a very simple`n`quick hack written in 5 mins to stop crashes locking up 
* BBS`s for hours on end!
*
* Once installed and it requires only 48 bytes!!! Warning only execute from
* CLI, not from WB! Simply add it to your "startup-sequence" AFTER SetPatch!
*
* Features:	ğ Once installed takes up NO CPU time whatsoever
*		ğ Supports Relocated/Non-Relocated VBR (Vector Base Register)
*		ğ Handles MMU Errors
*		ğ Handles FPU Errors
*		ğ Handles CO-PROCESSOR Errors
*		ğ Reset code uses cache of Execbase Ptr for some more saftey
*		ğ Compatible with any version of kickstart!
*******************************************************************************
_LVOAllocMem:	equ	-$C6
_LVOSupervisor:	equ	-$1E
AbsExecBase:	equ	$4
AttnFlags:	equ	$128

		section	NoGuru,code		;public memory

*-------------- Get VectorBase Register

FindVBR:	lea	_ExecBase(pc),a0
		move.l	(AbsExecBase).w,a6
		move.l	a6,(a0)			;cache execbase ptr!
		suba.l	a4,a4			;a4=0.l
		move.w	AttnFlags(a6),d1	;get cpu type
		and.w	#15,d1			;are we on M68000
		beq.s	NoVBR			;if so skip

		lea	GetVBR(pc),a5		;ptr to VBR Get code
		jsr	_LVOSupervisor(a6)

*-------------- Check if we are already installed!

NoVBR:		cmp.l	#$FADEDEAD,$d8(a4)	;is it already installed?
		beq.s	ExitCLI

*-------------- Allocate memory for reset code

		moveq	#ResetEnd-ForceReset+4,d0
		moveq	#0,d1
		jsr	_LVOAllocMem(a6)	;allocate some memory
		tst.l	d0
		beq.w	ExitCLI

*-------------- Relocate Reset Code into Allocated memory

		addq.w	#2,d0
		bclr	#0,d0			;word align
		move.l	d0,a1
		
		lea	ForceReset(pc),a0
		moveq	#(ResetEnd-ForceReset)-1,d1
reloc_code:	move.b	(a0)+,(a1)+		;relocate into allocmem
		dbra	d1,reloc_code

*-------------- Patch Motorola Guru Error Handlers to my RESET Routine!

		move.l	#$FADEDEAD,$d8(a4)	;id - hope it don`t get used!
		move.l	d0,$08(a4)		;Bus Error
		move.l	d0,$0C(a4)		;Address Error
		move.l	d0,$10(a4)		;Illegal Instruction
		move.l	d0,$14(a4)		;Divide by Zero
		move.l	d0,$18(a4)		;CHK Error
		move.l	d0,$1C(a4)		;Trapv Error
		move.l	d0,$24(a4)		;Trace Exception
		move.l	d0,$28(a4)		;$Axxx emulation
		move.l	d0,$2C(a4)		;$Fxxx emulation
		move.l	d0,$34(a4)		;CP-Violation
		move.l	d0,$38(a4)		;Format Error
		move.l	d0,$C0(a4)		;(FPCP Bra/Set Unordered Con)
		move.l	d0,$C4(a4)		;(FPCP Inexact Result)
		move.l	d0,$C8(a4)		;(FPCP Divide by Zero)
		move.l	d0,$CC(a4)		;(FPCP Underflow)
		move.l	d0,$D0(a4)		;(FPCP Operand Error)
		move.l	d0,$D4(a4)		;(FPCP Signalling Not-A-Number)
		move.l	d0,$DC(a4)		;(PMMU Configuration Error)
		move.l	d0,$E0(a4)		;(PMMU Illegal Operation)
		move.l	d0,$E4(a4)		;(PMMU Illegal Operation)
		move.l	d0,$E8(a4)		;(PMMU Access Level Violation)
ExitCLI:	moveq	#0,d0
		rts

GetVBR:		movec	vbr,d1
		move.l	d1,a4
		rte

*******************************************************************************
* Perform Reset
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
*******************************************************************************

ForceReset:	clr.l	0.w			;bye bye guru no..
		move.l	_ExecBase(pc),a6	;get cache of execbase ptr!
		clr.l	$26(a6)			;kill exec chksum! bye bye exec
		lea	ResetCode(pc),a5
		move.w	#$ff0,$dff180		;yellow flash!
		jsr	_LVOSupervisor(a6)
		rts
		cnop	0,4
ResetCode:	lea	2.w,a0
		reset
		jmp	(a0)

_ExecBase	dc.l	0
ResetEnd:	even
