;	SafeKick	v1.5 (14.1.92)
;
;	Write-protects Kickstart at address $200000
;	and installs Bus-Error handler & ColdReboot Patch.
;
;	Assembled with DevPac 3.01
;	TAB Size: 10
;
;	This program is FREEWARE !

	include	"exec/funcdef.i"
	include	"exec/types.i"
	include	"exec/initializers.i"
	include	"exec/resident.i"
	include	"exec/libraries.i"
	include	"exec/memory.i"
	include	"exec/execbase.i"
	include	"exec/exec_lib.i"
	include	"dos/dos_lib.i"

start	move.l	($4).w,a6
	lea	(dosname,pc),a1
	moveq	#0,d0
	jsr	(_LVOOpenLibrary,a6)
	tst.l	d0
	beq	exit
	move.l	d0,a4
	exg	a4,a6
	jsr	(_LVOOutput,a6)
	move.l	d0,d7
	cmpi.w	#37,(LIB_VERSION,a4)
	bcs	badkick
	move.w	(AttnFlags,a4),d0
	btst	#AFB_68040,d0
	bne	future
	btst	#AFB_68030,d0
	beq	badcpu
	move.l	#template,d1
	clr.l	-(sp)
	move.l	sp,d2
	moveq	#0,d3
	jsr	(_LVOReadArgs,a6)
	move.l	(sp)+,d6
	tst.l	d0
	bne.s	argsok
	jsr	(_LVOIoErr,a6)
	move.l	d0,d1
	move.l	d3,d2
	jsr	(_LVOPrintFault,a6)
	bra	closedos
argsok	move.l	d0,d1
	jsr	(_LVOFreeArgs,a6)
	exg	a4,a6
	lea	(Get_TC,pc),a5
	jsr	(_LVOSupervisor,a6)
	tst.l	d0
	bmi	checkmmu
	tst.l	d6
	bne	mmuoff
	lea	($200000),a0
	cmpi.l	#$11144ef9,(a0)+
	bne.s	badaddr
	cmpi.l	#$2000d2,(a0)
	bne.s	badaddr
	moveq	#0,d0
	move.w	#592+BE_End-BE_Handler,d0
	move.l	d0,d6
	move.l	#MEMF_CLEAR|MEMF_PUBLIC,d1
	jsr	(_LVOAllocMem,a6)
	tst.l	d0
	beq.s	badmem
	move.l	d0,a0
	bsr	Create_Table
	movem.l	a0/a1,-(sp)
	moveq	#BE_End-BE_Handler,d0
	lea	(BE_Handler,pc),a0
	jsr	(_LVOCopyMem,a6)
	move.l	(4,sp),a0
	move.l	#_LVOColdReboot,d0
	lea	(New_Reset-BE_Handler,a0),a0
	move.l	(2,a6,d0.w),(MMU_Off-New_Reset-4,a0)
	exg	d0,a0
	move.l	a6,a1
	jsr	(_LVOSetFunction,a6)
	movem.l	(sp)+,a0/a2
	lea	(Activate_MMU,pc),a5
	jsr	(_LVOSupervisor,a6)
	lea	(text1,pc),a1
printmsg	exg	a4,a6
writemsg	moveq	#0,d3
	move.b	(a1)+,d3
	move.l	a1,d2
	move.l	d7,d1
	jsr	(_LVOWrite,a6)
closedos	exg	a4,a6
	move.l	a4,a1
	jsr	(_LVOCloseLibrary,a6)
exit	moveq	#0,d0
	rts

badaddr	lea	(text6,pc),a1
	bra.s	printmsg
future	lea	(text7,pc),a1
	bra.s	writemsg
badcpu	lea	(text3,pc),a1
	bra.s	writemsg
badmmu	tst.l	d6
	bne.s	mmuoff
	lea	(text4,pc),a1
	bra.s	printmsg
badmem	lea	(text5,pc),a1
	bra.s	printmsg
badkick	lea	(text2,pc),a1
	bra.s	writemsg
mmuoff	lea	(text8,pc),a1
	bra.s	printmsg

checkmmu	cmp.l	(MMU_TC,pc),d0
	bne.s	badmmu
	lea	(Get_CRP,pc),a5
	jsr	(_LVOSupervisor,a6)
	move.l	d0,a1
	cmpi.l	#'SAFE',(-16,a1)
	bne.s	badmmu
	lea	(Deactivate_MMU,pc),a5
	jsr	(_LVOSupervisor,a6)
	move.l	a1,-(sp)
	move.l	#_LVOColdReboot,d0
	move.l	(2,a6,d0.w),a0
	move.l	(MMU_Off-New_Reset-4,a0),a0
	exg	d0,a0
	move.l	a6,a1
	jsr	(_LVOSetFunction,a6)
	move.l	(sp)+,a1
	move.l	(-8,a1),d0
	move.l	(-4,a1),a1
	jsr	(_LVOFreeMem,a6)
	lea	(text9,pc),a1
	bra	printmsg

Get_TC	clr.l	-(sp)
	pmove.l	tc,(sp)		; get Translation Control
	move.l	(sp)+,d0
	rte

Get_CRP
	subq.w	#8,sp
	pmove.d	crp,(sp)		; get CPU Root Pointer
	addq.w	#4,sp
	move.l	(sp)+,d0
	rte

Activate_MMU
	clr.l	-(sp)
	pmove.l	(sp),tt0		; clear TT0
	pmove.l	(sp),tt1		; clear TT1
	move.l	a0,(sp)		; set Table Base
	clr.l	-(sp)
	bset	#31,(sp)		; L/U = 1
	addq.b	#2,(3,sp)		; DT = 2
	pmove.d	(sp),crp		; set CPU Root Pointer
	move.l	(MMU_TC,pc),(sp)	; get Translation Control
	pmove.l	(sp),tc		; set TC
	addq.w	#8,sp
	movec	vbr,a1		; get Vector Base
	move.l	(8,a1),(-12,a0)	; store old vector
	move.l	a2,(8,a1)		; set Bus Error vector
	rte

Deactivate_MMU
	movec	vbr,a0		; get Vector Base
	move.l	(-12,a1),(8,a0)	; restore old vector
	bra.s	MMU_Off

BE_Handler
	andi.b	#$fe,($a,sp)	; clear exception
	rte
New_Reset	lea	(MMU_Off,pc),a5
	jsr	(_LVOSupervisor,a6)
	jmp	$f80000
MMU_Off	clr.l	-(sp)
	pmove.l	(sp),tc		; disable TC
	addq.w	#4,sp
	rte
BE_End

Create_Table
	moveq	#31,d0		; ensure 16 Bytes alignment
	add.l	a0,d0
	andi.b	#$f0,d0
	move.l	d0,a1		; real Table Base
	move.l	a0,(-4,a1)	; remember memory base
	move.l	d6,(-8,a1)	; remember memory size
	move.l	#'SAFE',(-16,a1)	; set "SAFE" mark
	move.l	a1,a0		; copy Base
	clr.l	-(sp)
	addq.l	#1,(sp)
	moveq	#127,d0		; 128 Entries in Table_A
	bra.s	Create_first_A
Create_loop_A
	addq.b	#1,(sp)		; increment address
Create_first_A
	move.l	(sp),(a1)+	; store table entry
	dbf	d0,Create_loop_A
	move.l	a1,(a0)		; store Table_B address
	addq.l	#2,(a0)		; DT = 2
	move.l	a1,a2		; copy base B
	moveq	#7,d0		; 8 Entries in Table_B
	clr.l	(sp)
	addq.l	#1,(sp)		; DT = 1
	bra.s	Create_first_B
Create_loop_B
	add.w	#32,(sp)		; increment address
Create_first_B
	move.l	(sp),(a1)+	; store table entry
	dbf	d0,Create_loop_B
	move.l	a1,(4,a2)		; store Table_C address
	addq.l	#2,(4,a2)		; DT = 2
	moveq	#3,d0		; 4 entries in Table_C
	move.l	#$200005,(sp)	; start $200000, WP = 1, DT = 1
	bra.s	Create_first_C
Create_loop_C
	andi.b	#$fb,(3,sp)	; no WP for other entries
	addq.w	#8,(sp)		; increment address
Create_first_C
	move.l	(sp),(a1)+	; store table entry
	dbf	d0,Create_loop_C
	addq.w	#4,sp
	rts

MMU_TC	dc.b	%10000000		; MMU enabled
				; no Supervisor Root Pointer
				; no Function Code Lookup
	dc.b	%11110001		; Pagesize 32K
				; Initial Shift 1
	dc.b	%01110011		; Table Index A = 7 ( 16 MB Blocks)
				; Table Index B = 3 (  2 MB Blocks)
	dc.b	%00100100		; Table Index C = 2 (512 KB Blocks)
				; Table Index D = 4

dosname	dc.b	"dos.library",0
template	dc.b	"OFF/S",0
text1	dc.b	text2-text1-1
	dc.b	$9b,"0;33;40m>>> SafeKick v1.5 <<<",$9b
	dc.b	"0;31;40m  (c) 1991/92 by Martin Berndt",10
	dc.b	"Kickstart at $200000 write-protected, "
	dc.b	"Bus-Error and ColdReboot patched.",10
text2	dc.b	text3-text2-1
	dc.b	"This program needs Kickstart v37 or higher",10
text3	dc.b	text4-text3-1
	dc.b	"This program needs a 68030 MMU",10
text4	dc.b	text5-text4-1
	dc.b	"Alien MMU already active",10
text5	dc.b	text6-text5-1
	dc.b	"Oh dear... There's no memory for the MMU-table!",10
text6	dc.b	text7-text6-1
	dc.b	"Oh dear... There's no kickstart at $200000!",10
text7	dc.b	text8-text7-1
	dc.b	"Sorry, but 68040 is not supported, yet.",10
text8	dc.b	text9-text8-1
	dc.b	"SafeKick is not active",10
text9	dc.b	text10-text9-1
	dc.b	$9b,"0;33;40mSafeKick v1.5",$9b,"0;31;40m removed.",10
text10	dc.b	0,"$VER: SafeKick 1.5 (14.1.92)",0

	even
	end
	