****************************************************************************
*		    Amiga Software Reboot, Revisited
*
*		 	   By Bryce Nesbitt
*
*	Copyright 1990 Commodore-Amiga, Inc.  Permission granted to
*	reproduce in full ONLY.  The information contained herein is
*	subject to change without notice, and is provided "as is" without
*	warranty of any kind, either express or implied.  The entire risk
*	as to the use of this information is assumed by the user.
*
*
* Sometimes applications need to be able to reboot the Amiga under software
* control.  However, rebooting the machine is very tricky, and most attempts
* have been flawed.  The RESET instruction, for example, unconfigures all
* memory; after RESET there is no reliable place to run user code.  Most
* reboot code will break whenever the memory or CPU configuration is
* changed.  Other reset code will not work properly on the Amiga 1000.
*
* In fact, rebooting the Amiga is so tricky that even the official reboot
* code published by Commodore will not work in every case. (This article
* replaces "The Official Way to Software Reboot an Amiga" from the
* July/August 1989 issue of Amiga Mail, Exec, page III-9.)  Some versions of
* the A2000 have a 0.1 uf capacitor (C909) on the hardware reset line.
* This capacitor has the effect of rejecting short reset pulses, including
* some of those generated by the CPU RESET instruction.
*
* The ColdReboot() function listed below should be used whenever an
* application needs to reboot the Amiga.  ColdReboot() is the only officially
* supported way to reboot an Amiga under software control.
*
* Even this code will fail under some circumstances.  Certain processor
* cards developed by Great Valley Products (GVP) lock up when the RESET
* instruction is used.  GVP offers an upgrade PAL to fix this problem.
* Likewise, if the user has a 68020 or 68030 coprocessor card and has copied
* the Kickstart ROM image into 32-bit memory with the command SetCPU FASTROM,
* the NewReboot() function will not work properly.  To fix this, give the
* command SetCPU NOFASTROM.
*
* TECHNICAL DESCRIPTION: The code below precalculates a jump address,
* executes a RESET instruction, then relies on CPU prefetch to execute the
* jump.  The precalculated jump is constructed to enter the system ROM at the
* location of a second RESET instruction.
*
*
*
****************************************************************************
*
*   NAME
*	ColdReboot - Official code to reset any Amiga (Version 2)
*
*   SYNOPSIS
*	ColdReboot()
*
*	void ColdReboot(void);
*
*   FUNCTION
*	Reboot the machine.  All external memory and peripherals will be
*	RESET, and the machine will start its power up diagnostics.
*
*   NOTE
*	Rebooting an Amiga in software is very tricky.	Differing memory
*	configurations and processor cards require careful treatment.  This
*	code represents the best available general purpose reset.
*
*	The MagicResetCode must be used exactly as specified here. The code
*	_must_ be longword aligned.  Failure to duplicate the code EXACTLY
*	may result in improper operation under certain system configurations.
*
*   RESULT
*	This function never returns.
*
****************************************************************************

		INCLUDE "exec/types.i"
		INCLUDE "exec/libraries.i"

		XDEF	_ColdReboot
		XREF	_LVOSupervisor

ABSEXECBASE	    EQU 4	    ;Pointer to the Exec library base
MAGIC_ROMEND	    EQU $01000000   ;End of Kickstart ROM
MAGIC_SIZEOFFSET    EQU -$14	    ;Offset from end of ROM to Kickstart size
V36_EXEC	    EQU 36	    ;Exec with the ColdReboot() function
TEMP_ColdReboot     EQU -726	    ;Offset of the V36 ColdReboot function


_ColdReboot:	move.l	ABSEXECBASE,a6
		cmp.w	#V36_EXEC,LIB_VERSION(a6)
		blt.s	old_exec
		jmp	TEMP_ColdReboot(a6)     ;Let Exec do it...
		;NOTE: Control flow never returns to here


;---- manually reset the Amiga ---------------------------------------------
old_exec:	lea.l	GoAway(pc),a5           ;address of code to execute
		jsr	_LVOSupervisor(a6)      ;trap to code at (a5)...
		;NOTE: Control flow never returns to here


;-------------- MagicResetCode ---------DO NOT CHANGE-----------------------
		CNOP	0,4			;IMPORTANT! Longword align!
GoAway: 	lea.l	MAGIC_ROMEND,a0 	;(end of ROM)
		sub.l	MAGIC_SIZEOFFSET(a0),a0 ;(end of ROM)-(ROM size)=PC
		move.l	4(a0),a0                ;Get Initial Program Counter
		subq.l	#2,a0			;now points to second RESET
		reset				;first RESET instruction
		jmp	(a0)                    ;CPU Prefetch executes this
		;NOTE: the RESET and JMP instructions must share a longword!
;---------------------------------------DO NOT CHANGE-----------------------
		END



