*
*	ZKick V2.10 -- Copyright (C) 1990 by Daniel Zenchelsky
*
*		This program may be freely copied, as long as all copyright
*		notices are left intact and unchanged.
*


   SECTION   code

   NOLIST
   INCLUDE "exec/types.i"
   INCLUDE "exec/initializers.i"
   INCLUDE "exec/libraries.i"
   INCLUDE "exec/lists.i"
   INCLUDE "exec/alerts.i"
   INCLUDE "exec/resident.i"
   INCLUDE "exec/memory.i"
   INCLUDE "exec/tasks.i"
   INCLUDE "libraries/expansion.i"

   INCLUDE "zkick.i"
   INCLUDE "mmu.i"

   LIST

   XDEF   Reboot
   XDEF   _MakeRomTag
   XDEF   _config
   XDEF   _connum
   XDEF   _memory
   XDEF   _memnum
   XDEF   _Survive
   XDEF   _MMU

   ;------ These don't have to be external, but it helps some
   ;------ debuggers to have them globally visible
   XDEF   modName
   XDEF   MemName
   XDEF   _InitRoutine
   XDEF   initDDescrip
   XDEF   ExecBase
   XDEF   SaveMem
   XDEF   KickMem
   XDEF   KickTag
   XDEF   expansionname
   XDEF   ExpansionBase
   XDEF   ConfigCopy
   XDEF   AddMem
   XDEF   EndTag

   XREF   _LVOSumKickData

   XREF   _LVOOpenLibrary
   XREF   _LVOCloseLibrary
   XREF   _LVOAddConfigDev
   XREF   _LVOAllocConfigDev
   XREF   _LVOCopyMem
   XREF   _LVOAddMemList
   XREF   _LVOSetFunction
   XREF   _LVOSuperState
   XREF   _LVOSupervisor
   XREF   _LVODisable

   XREF	  _ColdReboot

;
; Offsets from ExecBase
;

KickMemPtr	EQU	$222
KickTagPtr	EQU	$226
KickCheckSum	EQU	$22a
WarmCapture	EQU	50
CoolCapture	EQU	46
ColdCapture	EQU	42
ExecVersion	EQU	$14

ROMVersion	EQU	$FC0010

VERSION:	EQU	2
REVISION:	EQU	10


_MakeRomTag:
	move.l ExecBase,a6
;
; Set up KickMemPtr
;
	lea.l KickMem+14,a0
	move.w #1,(a0)+
	lea.l SaveMem,a1
	move.l a1,(a0)+
	lea.l EndTag-SaveMem,a1
	move.l a1,(a0)+
	lea.l KickMem,a0
	move.l a0,KickMemPtr(a6)
	
;
; Set up KickTagPtr
;
	lea KickTag,a0
	move.l a0,KickTagPtr(a6)

;
; Calculate checksum
;

	jsr _LVOSumKickData(a6)
	move.l d0,KickCheckSum(a6)
;
; Setup reboot code
;
	jsr SetVectors
	rts

;-----------------------------------------------------------------------
; From here on is protected from erasure during reboot
;-----------------------------------------------------------------------

SaveMem:

KickMem:
	DC.L 0,0,0,0,0,0

KickTag:
	DC.L	initDDescrip
	DC.L	$0

OldAddMemList:	DC.L	$00000000
_Survive:	DC.L	$00000000
_MMU:		DC.L	$00000000

;
; Set up the reboot routines
;

SetVectors:

	lea.l ColdRoutine,a0
	move.l a0,ColdCapture(a6)

	lea.l CoolRoutine,a0
	move.l a0,CoolCapture(a6)

; Recalculate checksum

	lea $22(a6),a0
	moveq #$16,d0
	moveq #0,d1
sumloop:
	add.w (a0)+,d1
	dbra d0,sumloop
	not.w d1
	move.w d1,$52(a6)

	rts

ColdRoutine:
	
	cmp.l #$B7FC0004,$1e(a5)	; Verify that this is really 1.2/1.3
	bne.s skipfix
	move.l $3E(A6),A3		; Skip version and >512k chip mem
	jmp $1e(a5)			; checks

skipfix:
	jmp (a5)

CoolRoutine:
	move.l ExecBase,a6
	
	movea.l a6,a1			; Keep exec from stomping
	lea.l NewAddMemList,a0		; on the first few bytes
	move.l a0,d0			; of kickstart memory.
	lea.l _LVOAddMemList,a0
	jsr _LVOSetFunction(a6)
	move.l d0,OldAddMemList

	rts

NewAddMemList:

	rts

;-----------------------------------------------------------------------
; A romtag structure.  Both "exec" and "ramlib" look for
; this structure to discover magic constants about you
; (such as where to start running you from...).
;-----------------------------------------------------------------------

   ; Most people will not need a priority and should leave it at zero.
   ; the RT_PRI field is used for _configuring the roms.  Use "mods" from
   ; wack to look at the other romtags in the system

MYPRI   EQU   107 	

initDDescrip:
               ;STRUCTURE RT,0
     DC.W    RTC_MATCHWORD      ; UWORD RT_MATCHWORD
     DC.L    initDDescrip       ; APTR  RT_MATCHTAG
     DC.L    EndTag             ; APTR  RT_ENDSKIP
     DC.B    RTF_COLDSTART      ; UBYTE RT_FLAGS
     DC.B    VERSION            ; UBYTE RT_VERSION
     DC.B    NT_UNKNOWN         ; UBYTE RT_TYPE
     DC.B    MYPRI              ; BYTE  RT_PRI
     DC.L    modName            ; APTR  RT_NAME
     DC.L    idString           ; APTR  RT_IDSTRING
     DC.L    _InitRoutine       ; APTR  RT_INIT


   ; this is the name that the module will have
modName:	DC.B   'zkick.romtag',0

idString:   dc.b   'zkick.romtag 2.0 (8/11/90)',13,10,0

MemName:	dc.b  'zkick memory',0

expansionname:	dc.b  'expansion.library',0

	CNOP 0,4

ExecBase	EQU 	$00000004
ExpansionBase:	DC.L 	$00000000
ConfigCopy:	DC.L 	$00000000


_InitRoutine:

	movem.l d0-d6/a0-a6,-(a7)

	move.l ExecBase,a6			; If we're running under 1.2/1.3
	move.l ROMVersion,a0		; we wan't to start KickStart
	cmp.l ExecVersion(a6),a0		; from $200000
	bne okversion

	lea.l	$200000,a0		; Checksum KickStart image
	move.l	#$80000,d1		; at $200000
	jsr 	CheckSum
	cmp.l	#0,d0
	bne.s	panic
							; Let's be doubly cautious:
	jsr 	_LVOSuperState(a6)
	lea	$200000,a0			; Verify that there's a
	move.l	(a0),d0			; KickStart image at
	cmp.w	#$4ef9,2(a0)		; $200000
	bne.s	panic

	move.l	ExecBase,a6		; If there is an MMU
	jsr		_LVODisable(a6)	; disable it before
	cmp.l	#0,_MMU			; starting KickStart
	beq		1$
	move.l	#0,a0
	jsr		SetTC

1$:	jmp	2(a0)				; Start KickStart

panic:						; Uh oh, doesn't look like
	move.l	#0,ColdCapture(a6)	; KickStart at $200000
	move.l	#0,CoolCapture(a6)
	move.l	#0,WarmCapture(a6)	; Clear vectors and reboot
	move.l	#0,KickTagPtr(a6)
	move.l	#0,KickMemPtr(a6)

	jmp Reboot
	
okversion:

	cmp.l #0,_Survive		; Do we want to survive?
	beq.s 2$
	jsr SetVectors			; Set up Capture vectors
						; for reboot survival

2$:	lea.l expansionname,A1
	move.l #0,D0	
	jsr _LVOOpenLibrary(a6)		; Open expansion.library
	move.l D0,ExpansionBase
	cmp.l #0,D0
	bne.s 1$
	jmp exit

1$:
	lea.l _config,a2
	move.l _connum,a3

loop:	cmp.l #0,a3
	beq.s close

	move.l ExpansionBase,a6		; For each configdev structure we
	jsr _LVOAllocConfigDev(a6)	; saved, allocate a fresh configdev
	move.l D0,ConfigCopy		; structure.
	cmp.l #0,D0
	bne.s 2$
	jmp close

2$:	
	move.l a2,A0
	move.l ConfigCopy,A1		; Copy the old configdev onto
	move.l #end_config-_config,D0	; the new one
	move.l ExecBase,a6
	jsr _LVOCopyMem(a6)

	move.l ConfigCopy,A0
	move.l ExpansionBase,a6
	jsr _LVOAddConfigDev(a6)		; Add it to the configdev list

	sub.l #1,a3
	add.l #end_config-_config,a2	; Go get another configdev structure
	jmp loop

close:
	move.l ExpansionBase,A1
	move.l ExecBase,a6		; Close expansion.library
	jsr _LVOCloseLibrary(a6)

AddMem:

	lea _memory,a2			; Do the same thing
	move.l _memnum,a3		; for the memory lists

1$:	cmp.l #0,a3
	beq.s exit

	move.l (a2),a0
	add.l #4,a2
	move.l (a2),d0
	add.l #4,a2
	move.l #MEMF_FAST+MEMF_PUBLIC,d1
	move.l #0,d2
	lea.l MemName,a1
	move.l ExecBase,a6
	jsr _LVOAddMemList(a6)
	
	sub.l #1,a3
	jmp 1$

exit:
	movem.l (a7)+,d0-d6/a0-a6
	rts

CheckSum:
	lsr.l	#2,d1
	subq.l	#1,d1
	moveq	#0,d0

1$:	add.l	(a0)+,d0
	bcc.s	2$
	addq.l	#1,d0

2$:	dbra	d1,1$
	sub.l	#$10000,d1
	bpl.s	1$
	addq.l	#1,d0
	rts

;======================================================================
;
;	This function sets the MMU TC register.  It assumes a 68020 
;	system with MMU, or a 68030 based system (eg, test for MMU before
;	you call this, or you wind up in The Guru Zone).  
;
;	SetTC(ULONG)
;		a0
;======================================================================

SetTC:
	move.l	4,a6				; Get ExecBase
	move.l	a5,-(sp)
	lea.l	1$,a5			; Get the start of the supervisor code
 	CALLSYS	Supervisor
	move.l	(sp)+,a5
	rts
1$
	_PMOVE	(a0),tc			; Just set the TC register
	rte

Reboot:
	move.l	ExecBase,a6		; If there is an MMU,
	jsr		_LVODisable(a6)	; disable it before
	cmp.l	#0,_MMU			; rebooting.
	beq		nommu
	move.l	#0,a0
	jsr		SetTC
nommu:
	jmp		_ColdReboot

EndCode:

*********

	CNOP 0,4	; LongWord Align (For CopyMem)

_connum:	DC.L 0

_config:
	DC.L 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
end_config:
	DC.L 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	DC.L 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	DC.L 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	DC.L 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	DC.L 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	DC.L 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	DC.L 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

_memnum:	DC.L 0

_memory:
	DC.L 0,0
end_memory:
	DC.L 0,0
	DC.L 0,0
	DC.L 0,0
	DC.L 0,0
	DC.L 0,0
	DC.L 0,0
	DC.L 0,0

EndTag:

   END
