; kill 2090 - by J Davis 08/1990
; ---------
;
; version 1.0 
;
; THIS MUST BE ASSEMBLED TO FORCELOAD TO CHIPMEM!!!
;
; very simple program to reboot 2000 with all autoconfig boards off
;
; this allows you to boot off floppies without worrying about
; rogue programs attacking your hard-disk
; 
; the drive is only killed until the next reboot - so ctrl-amiga-amiga
; will re-anable it
; 
; how it does it -
;                 this is basically a modified version of the 'official'
;                 reboot code in the rkm:hardware, with the addition of
;		  a coldcapture routine that 'fakes out' all the expansion 
;		  boards, stopping exec from seeing/using them
; 
;
; YES THIS IS A HACK!! It manipulates the system in a manner contrary
; to the rkm quidelines - so don't blame me if it doesn't work!! :-)
;
;
; changes for version .05(beta)
;
;    sends 5 flashes when cold capt code starts
;    back to brute force approach to finding all boards
;
; changes for version .06(beta)
;
;    now sends all boards that don't support shut_up to $200000
;    ( instead of $d00000 as before ). This gets around problems
;    with memory boards overlaying the custom chips and killing the
;    whole system
;
; changes for version 1.0 
; 
;    added code to switch super agnus to PAL/NTSC
;
;    by altering the conditional compilation switches Go_NTSC and
;    Kill_boards, you can set whether to switch to PAL or NTSC at
;    boot-time, and also whether to just reset, or kill exp boards
;    as well, giving four possible versions of this program


;===========================================================
; vary these flags to build all 4 possible versions

kill_boards	equ	0	; set to 0 to just build reset program

go_ntsc		equ	0	; set to 1 will toggle superAgnus to NTSC
				; set to 0 will toggle to PAL

;=============================================

forbid		equ	-$084	; offsets for various exec and int calls
getmsg		equ	-$174	; saves long includes and compile times
replymsg	equ	-$17a
waitport	equ	-$180
findtask	equ	-$126
autoreq		equ	-$15c
openlib		equ	-$228
closelib	equ	-$19e
supervisor	equ 	-$01e	

attnflags	equ	$128	; offset for execbase.attnflags word
afb_68020	equ	1<<1	; bit mask for 020 flag

pr_cli		equ	$0Ac	; process cli flag offset
pr_msgport	equ	$05c	; process msgport offset

; hisoft devpac and Argasm don't support the 010+ movec command!
; so we jam them in as consts instead
movec_cacr_d0	equ     %0000000000000010
movec_d0_cacr	equ	%1000000000000010

;=========================================

		section	main,code_c		; make sure we're in CHIP

startup:	move.l	$4,a6
		move.l	#0,a1
		jsr	findtask(a6)		; find ourselves

		move.l	d0,a4			; save our process pointer

		move.l	pr_cli(a4),d0
		bne	fromdos			; was a DOS startup

		; was started from WB

		lea	pr_msgport(a4),a0
		jsr	waitport(a6)		; wait for startup msg
		lea	pr_msgport(a4),a0
		jsr	getmsg(a6)		; get the wb msg

		move.l	d0,wbmsg		; save pointer to our startup msg
		move.l	#1,wb			; flag we started from wb

fromdos:	lea	intuiname,a1
		move.l	#0,d0
		move.l	$4,a6
		jsr	openlib(a6) 		; open intuition lib

		move.l	d0,a6			; save ibase
		
		move.l	#0,a0			; window to display in
		move.l	#bodyitext,a1		; body text
		move.l	#yesitext,a2 		; postive text
		move.l	#noitext,a3  		; negative text
		move.l	#0,d0			; pflags
		move.l	#0,d1			; nflags
		move.l	#460,d2			; width
		move.l	#60,d3			; height
		jsr	autoreq(a6)		; request user confirmation

		cmp.l	#0,d0
		bne	reboot			; user selected ok, kill!

		; user cancelled reboot
		
		move.l	a6,a1			; close intuition lib
		move.l	$4,a6
		jsr	closelib(A6)
		
exit:		move.l	wb,d0
		cmp.l	#0,d0			; was this a CLI invocation
		beq	exit_dos

		; workbench exit

		move.l	$4,a6
		jsr	forbid(a6)		; lock out everyone else

		move.l	wbmsg,a1
		jsr	replymsg(a6)		; reply to Wbstartup msg

exit_dos:	move.l	#0,d0			; return with return code 0
		rts			



;=====================================
; the following does the actual reboot 
		
reboot:		jsr	instcold		; install coldcapture handler
						; exec will run coldcapt once and then
						; kill it - exactly what we want!	
	
		move.l	$4,a6 			; RESET must be run in Smode, so go to it
		move.l	#reboot_c,a5		; code to run in supervisor mode
		jsr	supervisor(A6)		; go into supervisor mode

		cnop	0,4			; longword align code
		
reboot_c:	move.l	$4,a6
		btst.b	#afb_68020,attnflags+1(a6)
		beq	kill			; is system 020/030 powered ?

		; if it is an 020 or 030, take extra steps for cache 
	
		dc.w	movec_cacr_d0   	; twiddle the cache control reg
		bset.l	#3,d0
		dc.w	movec_d0_cacr
	 
	 	bra	kill
	 
 		cnop	0,4			; long word align code

kill:		move.l	#$2,a1			; where to jump to in rom
		reset
		jmp (a1)			; now run reset code in rom



;=======================================
; routine to install coldcapture handler

instcold:	move.l	$4,a6			; get execbase
		lea	cold,a0			; get address of our coldcapt routine
		move.l	a0,$2a(a6)		; set coldcapture vect

		lea	34(a6),a0		; start of checksummed area in execbase
		move.w	#$16,d0			; number of checksummed words
		move.w	#$0,d1			; clear counter
	
sum:		add.w	(A0)+,d1		; sum execbase and update checksum
		dbf	d0,sum
	
		not.w	d1
		move.w	d1,82(a6)		; save fixed checksum

		rts


;===========================================================================
; our actual cold capture handler, flashes led,zaps boards,toggles agnus etc

cold:		move.w	#$0f8a,$dff180	; set screen colour to pink

	IFNE 	go_ntsc		; go_ntsc=1 switch to ntsc
		move.w	#$00,$dff1dc	; set NTSC mode on agnus
	ELSEIF
		move.w	#$20,$dff1dc	; set PAL mode on agnus
	ENDC


		move.l	#9,d0			; flash power led 5 times 
						; to let know we're running

lloop:		bchg	#1,$bfe001		; toggle led
		move.l	#$ffff,d1
lwait:		dbf	d1,lwait		; delay
		dbf	d0,lloop


	IFNE	kill_boards			; kill_boards=1, so add kill code

		move.l	#$7,d1			; max no boards we fix = 8 

bchk:		move.w	$e80008,d0		; get flag byte from board
		not.w	d0			; invert
		btst.l	#14,d0			; see if board supports shut_up
		beq	shut_up			; bit=0 means board shuts up ok

		; board doesn't support shut up, so 
		; config board to $200000 (only gap big enough for 8mb
		; boards)
	
		move.w	#$0000,$e8004a  	; fake board out to $200000
		move.w	#$2000,$e80048  
		
		bra	nboard			; carry on

shut_up:	move.b	#$ff,$e8004c    	; tell the board to shut up

nboard:		dbf	d1,bchk			; loop thru all boards
	ENDC

bexit:		jmp	(a5)			; chain thru to rest of reset routine
	
;=============================================================
		
wb:		dc.l	0			; run mode flag 0=dos process 1=wbprocess
wbmsg:		dc.l	0			; where we save our workbench msg

intuiname:	dc.b	"intuition.library",0

; stuff for our autorequester

bodyitext:	dc.b	0	   	; front pen
		dc.b	1	   	; back pen
		dc.b	0	   	; draw mode
		dc.w	70	   	; leftedge
		dc.w	6	   	; topedge
		dc.l	0	   	; textattr = default
		dc.l	bodytext1  	; actual text
		dc.l	bodyitext2 	; next

bodyitext2:	dc.b	0	   	; front pen
		dc.b	1	   	; back pen
		dc.b	0	   	; draw mode
		dc.w	35	   	; leftedge
		dc.w	15	  	; topedge
		dc.l	0	   	; textattr = default
		dc.l	bodytext2 	; actual text
		dc.l	0 	   	; next

		
yesitext:	dc.b	2		; front pen
		dc.b	1		; back pen
		dc.b	0		; draw mode
		dc.w	4		; leftedge
		dc.w	4		; topedge
		dc.l	0		; textattr = default
		dc.l	yestext		; actual text
		dc.l	0		; next
		
noitext:	dc.b	2		; front pen
		dc.b	1		; back pen
		dc.b	0		; draw mode
		dc.w	4		; leftedge
		dc.w	4		; topedge
		dc.l	0		; textattr = default
		dc.l	notext		; actual text
		dc.l	0		; next		

		; actual text for our requester

	IFNE	kill_boards
bodytext1:	dc.b	"Kill2090"
        ELSEIF
bodytext1:	dc.b	" Reset"
	ENDC
		
		dc.b	 " by J Davis, 08-1990 v1.0 "

	IFNE	go_ntsc	
		dc.b	"NTSC"
	ELSEIF
		dc.b	"PAL "
	ENDC
		dc.b	0

bodytext2:	dc.b	"About to kill system, finish ALL disk activity",0

yestext:	dc.b	"Go ahead, make my day!",0
notext:		dc.b	"No, I was just kidding!",0

		END
