; FILE: Source:BlizKick.ASM          REV: 468 --- BlizKick
; History
;  1      Running OK!
;  15     Now BlizKick should work with all Blizzard turbos.
;  19     Now BlizKick should even support KS 1.0... (?)
;  25     Added LOCALFAST feature.
;  31     Added QUICKBOOT feature.
;  33     Added better Printf.
;  48     Added Better ROM identification code (checksum).
;  65     Added "real" cache clear routine.
;  69     Fixed _seek bug.
;  71     Fixed KS 1.3 SPEEDROM bug.
;  81     Replaced "execinit" patch with resident tag.
;  107    Fix for Blizzard 1260! 1230-IV too!!
;  111    Added original Kickstart restoration.
;  114    Implemented KS1.x KS restoration.
;  115    Improved error messages.
;  116    Improved MAPROM test and CacheClear routine.
;  125    Added HOGWAITBLIT feature.
;  129    Added SetPatch (680x0.library) check.
;  175    Added MODULE feature.
;  186    Added EXTRESBUF feature.
;  210    Added External patches and BKMF_ExtResBuf flag, fixed 1.x ROMTag support.
;  215    Fixed LOCALFAST feature not to force MEMF_LOCAL or MEMF_KICK!
;  220    Fixed KS 1.x ROMTag support.
;  225    Added special handling for 1230-IV and 1260. Fixed FORCE.
;  240    Removed need to be run before SetPatch on 1260 systems.
;  248    Can be used with Enforcer, CPU FASTROM, VMM etc.
;  257    Improved 040/060 cache flushing code. BlizKick release 1.6.
;  266    Fixed bug in 040/060 MMU test code.
;  276    Added XPK support.
;  277    Modified to work better with PowerPC... :)
;  279    Added better (Old)OpenLibrary code. Removed FindName() things.
;  289    Fixed XPK support.
;  293    Now will set memory node name if null.
;  300    Fixed EXTRESBUF.
;  302    Fixed negative return code bug.
;  307    Added ROM address validity test.
;  311    Fixed BLIZZARD 2060 code.
;  313    Fixed one terrible bug from B2060 code.
;  328    Fixing EXTRESBUF...
;  332    Finished! Now it should work with 1260, 2040 and 2060.
;  338    DOES work on 1260. Fixed one minor bug. SoftSCSI module doesn't work.
;  340    Added memheader move code to LOCALFAST. -> Speed AllocMem()
;  343    Fixed reset code!
;  344    Allowed BlizKick to kick same kickfile and rom chip version.
;  348    Fixed .testblizppcrunnommu. Added pseudofile (*) feature.
;  353    Added LastPatches (fix for MEMF_REVERSE svstack, etc.)
;  361    Fixed svstack trash, disabled SVSTACKTRASH.
;  377    Added QUIET switch, fixed LastPatches, KS 33.180 works now!
;  388    Got KS 33.180 finally work 100%.
;  389    Added handling for BKMODPATH env variable.
;  399    Improved HOGWAITBLIT.
;  400    Found out that 2040 and 2060 boards are almost identical.
;  403    Fixed reset code to *disable* caches.
;  404    1.11ß1: Trying to get EXTRESBUF into fastmem.
;  412    Did it. Seems to work 100%.
;  415    Fixed MAPROM test. Now should detect if MAPROM not set.
;  416    Disabled SUPERVISOR_NOREVERSE from LastPatches.
;  421    Added support for (A4000?) CPU Cards.
;  425    Now KS 1.x are only patched if they're original versions. This should
;         prevent problems with some patches 1.x ROM images.
;  426    Fixed bug in ROM image validation test.
;  427    9th Dec 1997: ARGH! Wrote nice CPUCard support but forgot to enable
;         it!!! ;-)
;  429    Added support for Cyberstorm PPC and MKIII. Now should work at least
;         with CBM CPU Cards, Cyberstorm MKI, MKIII and PPC.
;  439    Separated A1200 and other model's check routines. Hopefully fixed CS
;         MKIII/PPC support. Added CS MKII support. Now CPUCARD is only meant to
;         be used with CS MKI & compatible.
;  442    Fixed few typos etc.
;  443    Fixed stupid BUG from CS support... THANKS DUKEN!! =)
;  444    Had mixed 20x0 and CS MK II product IDs... doh! Thanks shido at #amiga!
;  445    Fixed some Lock bugs.
;  446    13th May 1998 Made the source public in hope someone would continue the
;         development.
;  450    6th July 1998 Added Blizzard PPC support.
;  458    8th July 1998 Fixed Blizzard PPC and CS MKII support (I hope).
;  459    17th July 1998 Fixed stupid bug from CS MKII support.
;  461    4th October 1998 Finally fixed the blizz ppc bug. hehe.
;  462    6th October 1998 Fixed support for old KS.
;  463    9th October 1998 Fixed MK2 bug. Ta ChaoZer.
;  464    13th October 1998 Another MK2 fix <sigh>. Ta ChaoZer.
;  467    3rd November 1998 Disabled rom checksum disable in SPEEDROM.
;  468    24th January 1999 Fixed stupid blizzppc (and probably CSPPC too)
;         bug, blizzppc/csppc kernel overwrote EXTRES buffer. Now allocates
;         1mb extra memory.
;

;
; I seriously doubt if this source code is useful for anything else.
; Hairy code everywhere, this one is really a bitch to maintain...
;

; TODO
; o Support for 2040 and 2060 scsi rom.
; o ROM checksum (restore orig rom if bad)

; (possibly)
; o IDEFix97 module (rs:LoadIDE.rs)
; o OxyPatcher module
; o ENVARC: ENV: etc.
; o args from file
; o module memory requirements inside the module itself ('$LEN: 280' ?)

; o Problem with MoveVBR module on 1240??
; o Crash when running BlizKick after SetPatch on 2040??
; ? FastExec (LOCALFAST) didn't work (on 1260) if started after SetPatch ??
;
; o Add possibility to plant any single hunk device or library.
; ^ Support for scsi.device module (GetSCSI)
; o Fix QUICKBOOT for 1230-IV & 1260
; ^ Fix 1230-IV scsi-kit problems ? PROBABLY FIXED

USE_STD_INCLUDES	SET	1
	IFNE	USE_STD_INCLUDES
	MACHINE	MC68040
	include	"exec/types.i"
	include	"exec/nodes.i"
	include	"exec/libraries.i"
	include	"exec/memory.i"
	include	"exec/execbase.i"
	include	"exec/resident.i"
	include	"exec/alerts.i"
	include	"dos/dos.i"
	include	"exec/exec_lib.i"
	include	"dos/dos_lib.i"
	include	"graphics/gfxbase.i"
	include	"graphics/graphics_lib.i"
call	MACRO
	jsr	(_LVO\1,a6)
	ENDM
	ELSE
	include	"Devpac:Gen.gs"
	ENDC
	include	"dos/dosextens.i"
	include	"libraries/configvars.i"
	include	"libraries/expansion_lib.i"
	include	"hardware/dmabits.i"
	include	"hardware/custom.i"

	include	"libraries/xpk.i"	; from xpk_dev

	include	"blizkickmodule.i"

ARG_KICKFILE	EQU	0
ARG_MODULE	EQU	4
ARG_EXTRESBUF	EQU	8
ARG_FORCE	EQU	12
ARG_LOCALFAST	EQU	16
ARG_QUICKBOOT	EQU	20
ARG_SPEEDROM	EQU	24
ARG_HOGWAITBLIT	EQU	28
ARG_CPUCARD	EQU	32
ARG_QUIET	EQU	36

BUFSIZEL	EQU	$10000
BLIZPROD	EQU	$2140
ROMSUMOFFS	EQU	-$18
ROMSIZEOFFS	EQU	-$14
IDOFFS	EQU	-$10
BLIZKICK_ID	EQU	'BlzK'

KEEP_CHECKSUM	EQU	1		;don't disable rom checksum

;SVSTACKTRASH	EQU	8*1024		;16384

CACHEFLUSH040	MACRO
	dc.w	$4E71		; nop
	dc.w	$F478		; CPUSHA BC	flush the data into memory
	dc.w	$4E71		; nop
	ENDM

FULLFLUSH040	MACRO
	dc.w	$4E71		; nop
	dc.w	$F478		; CPUSHA BC	flush the data into memory
	dc.w	$4E71		; nop
	dc.w	$F4D8		; INVA	BC	invalidate the data and inst caches
	dc.w	$4E71		; nop
	dc.w	$F518		; PFLUSHA	flush the address translation cache
	dc.w	$4E71		; nop
	ENDM

;;	dc.w	$F4F8		; CPUSHA DC	flush the data cache into memory


MOVQ	MACRO	*value
	IFGT	(127-(\1))
	moveq	#(\1),\2
	MEXIT
	ENDC
	IFEQ	((\1)&%1)
	IFGT	(256-(\1))
	moveq	#(\1)>>1,\2
	add.l	\2,\2
	MEXIT
	ENDC
	ENDC
	IFGT	(127-((\1)^$000000FF))
	moveq	#(\1)^$000000FF,\2
	not.b	\2
	MEXIT
	ENDC
	move.l	#(\1),\2
	ENDM


	SECTION	CODE_C,CODE_C

Main	move.l	a0,a2
	move.l	d0,d2
	moveq	#RETURN_FAIL,d7
	move.l	(4).w,a6
	move.l	a6,_ExecBase
	move.w	(AttnFlags,a6),_AttnFlags

	lea	(DosName,pc),a1
	moveq	#0,d0
	bsr	OpenLib
	move.l	d0,d6
	beq	.exit
	move.l	d0,a6

	moveq	#0,d4			Set default!!

	cmp.w	#37,(LIB_VERSION,a6)
	shs	d5

	bsr	getmmu
	move.b	d0,_mmuflag

	lea	_Array,a3
	tst.b	d5
	bne.b	.ks20
	clr.l	-1(a2,d2.l)
	subq.l	#1,d2
	beq.b	.do			RESTORE!
	move.l	a2,(a3)
	lea	(_13Help,pc),a0
	cmp.b	#'?',(a2)
	bne.b	.do
	subq.l	#1,d2
	beq.b	.printmsgexit
	bra.b	.do
.ks20	lea	(_Template,pc),a0
	move.l	a0,d1
	move.l	a3,d2
	moveq	#0,d3
	call	ReadArgs
	move.l	d0,d4
	beq.b	.badargs

.do
	move.l	(ARG_QUIET,a3),_Quiet

	tst.l	(ARG_CPUCARD,a3)
	beq.b	.no_cpucard
	bsr	CheckCPUCard
	sne	_CPUCard
	bne.b	.has_cpucard
	lea	(NoCPUCard,pc),a0
	bra.b	.printmsgexit
.no_cpucard
	bsr	TestBliz
	lea	(RequiresBliz,pc),a0
	move.l	d0,_BlizROM
	beq.b	.printmsgexit
.has_cpucard

	movem.l	d4-d6/a6,-(sp)
	moveq	#RETURN_ERROR,d7
	lea	(Messu,pc),a0
	bsr	_PrintHeaderf
	bsr	_HeadMain
	movem.l	(sp)+,d4-d6/a6

.freeargs	tst.b	d5
	beq.b	.closedos
	move.l	d4,d1
	call	FreeArgs
.closedos	move.l	d6,a1
	move.l	(_ExecBase,pc),a6
	call	CloseLibrary
.exit	move.l	d7,d0
	rts

.printmsgexit	bsr	_PrintHeaderf
	bra.b	.freeargs

.badargs	bsr.b	_PrintFault
	bra.b	.closedos


;  IN: d5=kickflag, d6=dosbase
; OUT: Fault printed
_PrintFault	tst.l	_Quiet
	beq.b	.print
	rts
.print	movem.l	d0-d2/a0-a1/a6,-(sp)
	move.l	d6,a6
	call	IoErr
	tst.b	d5
	beq.b	.oldie
	move.l	d0,d1
	moveq	#0,d2
	call	PrintFault
.exit	movem.l	(sp)+,d0-d2/a0-a1/a6
	rts

.oldie	move.l	d0,-(sp)
	beq.b	.noerr
	lea	(_ks13error,pc),a0
	move.l	sp,a1
	bsr	_Printf
.noerr	addq.l	#4,sp
	bra.b	.exit


;  IN: A0=FmtString, A1=Array, a2=Buffer
; OUT: Formatted text
_Sprintf	movem.l	d0-d1/a0-a3/a6,-(sp)
	move.l	a2,a3
	lea	(.putchar,pc),a2
	move.l	(_ExecBase,pc),a6
	call	RawDoFmt
	movem.l	(sp)+,d0-d1/a0-a3/a6
	rts
.putchar	move.b	d0,(a3)+
	rts


;  IN: A0=FmtString, A1=Array, d6=dosbase
; OUT: Printed text, including program info header
_PrintHeaderf	movem.l	d0-d1/a0-a2/a6,-(sp)
	move.l	(_ExecBase,pc),a6
	moveq	#1,d0			; Allocate 64k buffer
	swap	d0
	moveq	#MEMF_ANY,d1
	call	AllocMem
	move.l	d0,-(sp)
	beq.b	.nomem
	movem.l	(3*4,sp),a0-a1
	move.l	(sp),a2
	bsr.b	_Sprintf
	pea	(_Copyright,pc)
	pea	(_Version,pc)
	lea	(.header,pc),a0
	move.l	sp,a1
	bsr.b	_Printf
	addq.l	#8,sp
.nomem	move.l	(sp)+,a1
	moveq	#1,d0
	swap	d0
	call	FreeMem
.exit	movem.l	(sp)+,d0-d1/a0-a2/a6
	rts
.header	dc.b	$9B,'1;32m%s',$9B,'31m %s.',$9B,'0m',10
	dc.b	'%s',0
	CNOP	0,2


	STRUCTURE pf_data,0
	APTR	pfd_DosBase
	APTR	pfd_Count
	STRUCT	pfd_Buffer,256
	LABEL	pf_data_SIZEOF

	CNOP	0,4
;;_OutputFH	dc.l	0
;  IN: A0=FmtString, A1=Array (may be 0), d6=dosbase
; OUT: Printed text
_Printf
Printf	tst.l	_Quiet
	beq.b	.print
	rts
.print	movem.l	a0-a3/a6/d0-d3,-(sp)
	lea	(-pf_data_SIZEOF,sp),sp
	move.l	sp,a3
	move.l	d6,(a3)+
	clr.l	(a3)+
	lea	(.newchar,pc),a2
	move.l	(_ExecBase,pc),a6
	call	RawDoFmt
	move.l	d6,a6
	IFD	_OutputFH
	move.l	_OutputFH,d1
	ELSE
	call	Output
	move.l	d0,d1
	ENDC
	move.l	a3,d2
	move.l	(-4,a3),d3
	call	Write
	lea	(pf_data_SIZEOF,sp),sp
	movem.l	(sp)+,a0-a3/a6/d0-d3
	rts
.newchar	movem.l	d0-d3/a0-a1/a3/a6,-(sp)
	move.l	a3,d2				for Write()
	move.l	-(a3),d1
	move.b	d0,4(a3,d1.l)
	addq.b	#1,d1
	move.l	d1,(a3)
	bne.b	.dont_print
	move.l	-(a3),a6
	IFD	_OutputFH
	move.l	_OutputFH,d1
	ELSE
	call	Output
	move.l	d0,d1
	ENDC
	moveq	#256>>2,d3
	lsl.l	#2,d3
	call	Write
.dont_print	movem.l	(sp)+,d0-d3/a0-a1/a3/a6
	rts


;  IN: d6=dosbase, should remain if you're going to call internal _xxx functions
;      a3=paramarray, is zero if null template, scratch
;      a6=dosbase, scratch
; OUT: d7=return code
_HeadMain	tst.l	(a3)			(ARG_KICKFILE,a3)
	bne.b	.norestore
	lea	(_restore,pc),a0
	bsr	runnommu
	bne	KickSys

	lea	(NoRem,pc),a0
	bra	_Printf
.norestore
	moveq	#0,d1			!!
	bsr	SetIoErr

	tst.l	(ARG_FORCE,a3)
	bne.b	.force1

	moveq	#RETURN_WARN,d7
	cmp.l	#BLIZKICK_ID,$01000000+IDOFFS Test for kicked ROM.
	beq	.exit
	moveq	#RETURN_ERROR,d7

.force1	move.l	(a3),a0			(ARG_KICKFILE,a3),a0
	cmp.b	#'*',(a0)
	bne.b	.not_pseudofile
	tst.b	(1,a0)
	bne.b	.not_pseudofile

	; Handle "*" -file:
	lea	$01000000+IDOFFS,a0	Will fail if kicked previously!
	cmp.l	#BLIZKICK_ID,(a0)	Test for kicked ROM.
	beq	.exit
	move.l	a0,a4
	move.l	-(a4),d3		a4=$01000000+ROMSIZEOFFS
	move.l	d3,d0
	moveq	#MEMF_PUBLIC,d1
	move.l	(_ExecBase,pc),a6
	call	AllocMem
	tst.l	d0
	beq	.exit
	move.l	a4,a0
	sub.l	d3,a0
	add.w	#-ROMSIZEOFFS,a0
	move.l	d0,a4
	move.l	a4,a1
	move.l	d3,d0
	call	CopyMemQuick
	move.l	d3,d1
	move.l	d3,d4
	bra.b	.cont_pseudo

.not_pseudofile
	bsr	XPKLoad
	beq	.exit
	move.l	a1,a4
	move.l	d1,d3
	move.l	d0,d4

.cont_pseudo	and.l	#$FFF3FFFF,d1		256K or 512K ROM
	bne	.free
	cmp.l	#$00080000,d3
	bhi	.free
	lea	ROMSUMOFFS(a4,d3.l),a5
	cmp.l	(4,a5),d3		Compare to romsize
	bne	.free

	move.l	(a4),d2
	and.l	#$FFF8FFFF,d2
	cmp.l	#$11104EF9,d2
	bne	.free
	move.l	(4,a4),d2		Test for relocated ROM
	add.l	d3,d2
	swap	d2
	cmp.w	#$0100,d2
	bne	.free

	move.l	a4,a0			Get original ROM checksum
	move.l	d3,d0
	bsr	ROMReSum
	move.l	d0,_OrigSum

	movem.l	($C,a4),d0/d1		Fix for old KS
	addq.l	#1,d0
	bne.b	.nofix
	move.l	d1,($C,a4)
.nofix
	tst.l	(ARG_FORCE,a3)
	bne.b	.force2

	moveq	#RETURN_WARN,d7
	lea	$01000000,a1
	move.l	a1,a0
	sub.l	(ROMSIZEOFFS,a0),a0
	move.l	($C,a0),d0		Test for different version.
	cmp.l	($C,a4),d0
	bne.b	.kick

	cmp.l	#BLIZKICK_ID,(8,a5)	Test for kicked file.
	beq.b	.free
	IFGT	0
	move.l	(a5),d0			Compare checksums:
	cmp.l	(ROMSUMOFFS,a1),d0
	bne.b	.kick
	; a0=rom start
	move.l	a4,a1			Compare first 256k:
	move.w	#BUFSIZEL-1,d0
.cmploop	cmpm.l	(a0)+,(a1)+
	bne.b	.kick
	dbf	d0,.cmploop
	bra.b	.free
	ENDC

.kick	moveq	#RETURN_ERROR,d7
.force2
	lea	(Messu2,pc),a0
	lea	($C,a4),a1
	bsr	_Printf
	move.l	d6,a6
	moveq	#10,d1
	call	Delay

	bsr.b	GoForIt

.free	move.l	(_ExecBase,pc),a6
	move.l	a4,a1
	move.l	d4,d0
	call	FreeMem

.exit	tst.l	d7
	bmi.b	.nexitok
	beq.b	.exitok
	bsr	_PrintFault
	lea	(Already,pc),a0
	cmp.w	#RETURN_WARN,d7
	beq.b	.thiserr
	lea	(CouldNotKick,pc),a0
.thiserr	move.l	a3,a1
	bra	_Printf
.nexitok	neg.l	d7			result IN d7!!
.exitok	rts


GoForIt	neg.l	d7
	move.l	(_ExecBase,pc),a6

	move.l	(ARG_EXTRESBUF,a3),a0
	move.l	a0,d0
	beq.b	.no_extbuf
	move.l	(a0),d1
	move.l	a4,a0
	move.l	d3,d0
	bsr	ExtResBuf
	bne.b	.got_extbuf
	bsr	_PrintFault
	bra.b	.fail
.got_extbuf	st	(ARG_LOCALFAST,a3)	Force LOCALFAST!!
.no_extbuf
	lea	(_QuickBoot,pc),a0
	move.w	(ARG_QUICKBOOT+2,a3),(a0)
	bne.b	.patch
	tst.l	(ARG_LOCALFAST,a3)
	beq.b	.no_patch
.patch	move.l	a4,a0
	move.l	d3,d0
	bsr	PlantLocalFast
.no_patch
	tst.l	(ARG_HOGWAITBLIT,a3)
	beq.b	.no_agawblit
	move.l	a4,a0
	move.l	d3,d0
	bsr	PutHogWaitBlit
.no_agawblit
	move.l	a4,a0
	move.l	d3,d0
	bsr	DoPlanting
	beq.b	.fail

	tst.l	(ARG_SPEEDROM,a3)
	beq.b	.no_patch2
	move.l	a4,a0
	move.l	d3,d0
	bsr	SpeedROM
.no_patch2

	move.l	a4,a0
	move.l	d3,d0
	bsr	LastPatches

	move.l	#BLIZKICK_ID,IDOFFS(a4,d3.l)
	move.l	a4,a0
	move.l	d3,d0
	bsr.b	ROMReSum
	move.l	d0,ROMSUMOFFS(a4,d3.l)
	bsr	CacheClearOS

	bsr	KickSys
.fail

;;	bra	FreeExtResBuf

;  IN: a6=execbase
; OUT: d0/d1/a0/a1 trashed
FreeExtResBuf	movem.l	(_erh_data,pc),d0/a1
	move.l	a1,d1
	beq.b	.xit
	move.l	_BlizMemHeader,d1
	beq.b	.xit
	move.l	d1,a0
	call	Deallocate
.xit	rts


ROMReSum	move.l	d0,d1
	lsr.l	#2,d1
	move.l	ROMSUMOFFS(a0,d0.l),d0
	not.l	d0
.loop	add.l	(a0)+,d0
	bcc.b	.skip
	addq.l	#1,d0
.skip	subq.l	#1,d1
	bne.b	.loop
	not.l	d0
	rts



_restore	cmp.l	#BLIZKICK_ID,$01000000+IDOFFS	Test for kicked ROM.
	bne.b	.exitrts
	lea	$0B80000,a4		Magic address!
	move.l	(ROMSIZEOFFS,a4),d3
	move.l	d3,d0
	and.l	#$FFF3FFFF,d0		256K or 512K ROM
	bne.b	.exitrts
	cmp.l	#$00080000,d3
	bhi.b	.exitrts
	sub.l	d3,a4
	move.l	(a4),d0
	and.l	#$FFF8FFFF,d0
	cmp.l	#$11104EF9,d0
	bne.b	.exitrts
	moveq	#1,d0
	rts
.exitrts	moveq	#0,d0
	rts


getmmu	movem.l	d1-a6,-(sp)
	moveq	#0,d7

	move.l	(_ExecBase,pc),a6
	move.w	(AttnFlags,a6),d0
	btst	#AFB_68020,d0
	beq.b	.exit
	cmp.w	#37,(LIB_VERSION,a6)
	blo.b	.oldtest

	moveq	#-1,d7
	lea	(.test040plus,pc),a5
	btst	#AFB_68040,d0
	bne.b	.test
.oldtest	moveq	#1,d7
	lea	(.test020plus,pc),a5

.test	call	Disable
	call	Supervisor
	call	Enable

.exit	move.l	d7,d0
	movem.l	(sp)+,d1-a6
	rts

.test040plus	or.w	#$700,sr		Disable interrupts.
	movec	vbr,a0			Get VBR
	move.l	($10,a0),-(sp)		Save Illegal Instruction vector
	move.l	a0,-(sp)		Save VBR
	lea	(.illegal040,pc),a1
	move.l	a1,($10,a0)

	bsr	_fullflush040
	movec	tc,d0			$4e7a0003	Test some "common" MMU regs:
	movec	urp,d1			$4e7a1806	Test 040/060 MMU only reg!!
	movec	srp,d1			$4e7a1807	Test 040/060 MMU only reg!!
	nop
	nop
.exit040
	move.l	(sp)+,a0
	move.l	(sp)+,($10,a0)		Restore Illegal Instruction vector
	bsr	_fullflush040
	nop
	rte


	CNOP	0,4
.illegal040	moveq	#0,d7
	lea	(.exit040,pc),a0
	move.l	a0,(2,sp)
	bsr	_fullflush040
	nop
	rte


.test020plus	or.w	#$700,sr		Disable interrupts.

	movec	vbr,a0			Get VBR
	move.l	($10,a0),-(sp)		Save Illegal Instruction vector
	move.l	($2C,a0),-(sp)		Save F-Line Emul vector
	move.l	($E0,a0),-(sp)		Save MMU Config Error vector
	move.l	($E4,a0),-(sp)		Save MMU Illegal Operation Error vector
	move.l	($E8,a0),-(sp)		Save MMU Access Level Violation Error vector
	move.l	a0,-(sp)		Save VBR

	lea	(.mmuinstfailure,pc),a1
	move.l	a1,($10,a0)
	move.l	a1,($2C,a0)
	move.l	a1,($E0,a0)
	move.l	a1,($E4,a0)
	move.l	a1,($E8,a0)

	bsr	_flush020

	subq.l	#4,sp			Try to get TC
	dc.w	$F017,$4200		pmove.l tc,(sp)
.exitsuper
	addq.l	#4,sp
	move.l	(sp)+,a0		Restore VBR
	move.l	(sp)+,($E8,a0)		Restore MMU Access Level Violation Error vector
	move.l	(sp)+,($E4,a0)		Restore MMU Illegal Operation vector
	move.l	(sp)+,($E0,a0)		Restore MMU Config Error vector
	move.l	(sp)+,($2C,a0)		Restore F-Line Emul vector
	move.l	(sp)+,($10,a0)		Restore Illegal...
.exitall	bsr.b	_flush020
	nop
	rte

.mmuinstfailure	moveq	#0,d7
	lea	(.exitsuper,pc),a0	Invalid mmu instruction!
	move.l	a0,(2,sp)
	bsr.b	_flush020
	nop
	rte

_flush020	move.l	d0,-(sp)
	movec	cacr,d0
	or.w	#CACRF_ClearI!CACRF_ClearD,d0
	movec	d0,cacr
	move.l	(sp)+,d0
	rts

;  IN: a0=code to run in supervisor, mmu off. *MUST* return with rts!!
; OUT: whatever values routine leaves to registers.
runnommu	movem.l	a5/a6,-(sp)
	move.l	(_ExecBase,pc),a6
	lea	(.discode,pc),a5
	call	Disable
	call	Supervisor
	call	Enable
	movem.l	(sp)+,a5/a6
	tst.l	d0
	rts
.discode	move.l	d0,-(sp)
	subq.l	#4,sp
	move.b	(_mmuflag,pc),d0
	beq.b	.nommua
	bmi.b	.is040a
	dc.w	$F017,$4200		pmove.l tc,(sp)
	clr.l	-(sp)
	dc.w	$F017,$4000		pmove.l	(sp),tc
	addq.l	#4,sp
	bsr	_flush020
	bra.b	.was030a
.is040a	bsr.b	_fullflush040
	movec	tc,d0
	move.l	d0,(sp)
	and.w	#$7FFF,d0
	movec	d0,tc
	bsr.b	_fullflush040
.was030a	move.l	(4,sp),d0
.nommua	nop
	jsr	(a0)
	move.l	d0,(4,sp)
	move.b	(_mmuflag,pc),d0
	beq.b	.nommub
	bmi.b	.is040b
	dc.w	$F017,$4000		pmove.l	(sp),tc
	bsr	_flush020
	bra.b	.nommub
.is040b	bsr.b	_fullflush040
	move.l	(sp),d0
	movec	d0,tc
	bsr.b	_fullflush040
.nommub	addq.l	#4,sp
	move.l	(sp)+,d0
	nop
	rte
_fullflush040	FULLFLUSH040
	rts


TestBliz	movem.l	d1-a6,-(sp)
	moveq	#0,d7			"No Blizzard board with maprom"
	move.l	(_ExecBase,pc),a6

	bsr	.testblizppc
	bne	.exit_np

	lea	(_ExpName,pc),a1
	moveq	#0,d0
	bsr	OpenLib
	beq	.exit_np
	move.l	d0,a6

	lea	(.boards,pc),a2
	moveq	#0,d2
	moveq	#0,d6
.bfloop	moveq	#0,d0
	moveq	#0,d1
	move.w	(a2)+,d0
	bmi.b	.bfnomatch
	move.w	(a2)+,d1
	move.w	(a2)+,d6
	move.l	(a2)+,d3
	sub.l	a0,a0
	call	FindConfigDev
	move.l	d0,d2
	beq.b	.bfloop
.bfnomatch	move.l	a6,a1
	move.l	(_ExecBase,pc),a6
	call	CloseLibrary
	tst.l	d2
	beq.b	.exit_np
	swap	d6
	move.l	d2,a0
	moveq	#0,d0
	move.b	(cd_Rom+er_Product,a0),d0
	move.w	d0,_BoardNum

	cmp.w	#$19,d0
	seq	_MK2
	cmp.w	#$18,d0
	seq	_B20x0
	cmp.w	#$64,d0
	seq	_PPC_MK3

	move.l	d3,d0
	lea	(.blizfindmem,pc),a0
	addq.l	#1,d0
	beq.b	.skip
	lea	(.csfindmem,pc),a0
.skip	call	Forbid
	lea	(MemList,a6),a5
	lea	(4,a5),a4
	jmp	(a0)

.exitsp
	move.l	d7,d0
.exit_known	call	Permit
.exit_np	tst.l	d0
	bne.b	.foundvalid
	clr.l	_BlizMemHeader
.foundvalid	movem.l	(sp)+,d1-a6
	rts



.testblizppc	btst	#AFB_68040,_AttnFlags+1
	beq	.pexit2

	lea	(.pidtag,pc),a1
	call	FindResident
	tst.l	d0
	bne.b	.foundit

	lea	(.nastyfind,pc),a0
	bsr	runnommu
	tst.l	d0
	beq	.pexit2

.foundit	call	Forbid

	lea	(MemList,a6),a5
	lea	(4,a5),a4
.pscanloop	move.l	(a5),a5
	cmp.l	a5,a4
	beq	.pexit
	move.w	(MH_ATTRIBUTES,a5),d0
	and.w	#MEMF_PUBLIC!MEMF_CHIP!MEMF_FAST!MEMF_LOCAL!MEMF_24BITDMA,d0
	cmp.w	#MEMF_FAST!MEMF_PUBLIC,d0
	bne.b	.pscanloop
	tst.l	(LN_NAME,a5)
	bne.b	.pscanloop
	cmp.l	#$40000000,(MH_LOWER,a5)
	blo.b	.pscanloop
	move.l	(MH_UPPER,a5),d0
	cmp.l	#$80000000,d0
	bhs.b	.pscanloop
	and.l	#$0007FFFF,d0
	beq.b	.pfoundit

.pexit	call	Permit
.pexit2	moveq	#0,d0
	rts

.pfoundit	bsr	.locmemprep

	call	Permit

	st	_BlizPPC

	move.l	#$FFF00000,d0
	rts


.nastyfind	lea	$F00020,a0
	move.l	#2000,d5
	lea	(.pidtag,pc),a1
	movem.l	(a1)+,d1-d4

.nf_find	cmp.l	(a0),d1
	bne.b	.nf_more
	cmp.l	(4,a0),d2
	bne.b	.nf_more
	cmp.l	(8,a0),d3
	bne.b	.nf_more
	cmp.l	(12,a0),d4
	bne.b	.nf_more

	moveq	#1,d0
	rts

.nf_more	addq.l	#1,a0
	subq.l	#1,d5
	bne.b	.nf_find

	moveq	#0,d0
	rts

.pidtag	dc.b	'BlizzardPPC.IDTag',0
	CNOP	0,2



.blizfindmem
.trymore	sub.l	a3,a3
.scanloop	move.l	(a5),a5
	cmp.l	a5,a4
	beq	.exitsp
	move.w	(MH_ATTRIBUTES,a5),d0
	and.w	#MEMF_CHIP!MEMF_FAST!MEMF_PUBLIC,d0	Public fast?
	cmp.w	#MEMF_FAST!MEMF_PUBLIC,d0
	bne.b	.scanloop
	cmp.l	#$01000000,(MH_LOWER,a5)	32bit?
	blo.b	.scanloop
	move.l	(LN_NAME,a5),d0
	beq.b	.found
	move.l	d0,a2
	move.l	(a2),d0
	or.l	#$20202020,d0		To lowercase
	cmp.l	#'bliz',d0
	beq.b	.found
	tst.b	(a2)			null name -> buggy AllocMem result test!
	bne.b	.scanloop
.found	move.l	(MH_UPPER,a5),a3

	bsr	.locmemprep

	move.l	a3,d0			Test for MapROM:
	beq.b	.exit
	and.l	#$0007FFFF,d0
	bne.b	.exit
	move.l	a3,d0
	and.l	#$00080000,d0
	beq.b	.exit

	move.l	d6,d0			"known"?
	bne	.exit_known

	move.l	a3,a2
	add.l	#$80000-4,a2
	lea	$00F80000+$80000-4,a1

	lea	(.testcode,pc),a0
	bsr	runnommu
.exit	tst.l	d7
	beq	.trymore
	bra	.exitsp


.locmemprep	move.l	a5,_BlizMemHeader	for Allocate_REVERSE

	lea	(_BlizData,pc),a0
	move.w	(MH_ATTRIBUTES,a5),d0
	and.l	#MEMF_PUBLIC!MEMF_FAST!MEMF_LOCAL!MEMF_24BITDMA!MEMF_KICK,d0
	move.l	d0,(a0)+
	move.l	(MH_LOWER,a5),d0
	clr.w	d0
	move.l	d0,(a0)+
	move.l	(MH_UPPER,a5),d1
	sub.l	d0,d1
	move.l	d1,(a0)+
	move.b	(LN_PRI,a5),(a0)+
	move.l	(LN_NAME,a5),d0
	beq.b	.lmpnoname
	move.l	d0,a1
	tst.b	(a1)
	beq.b	.lmpnoname
	moveq	#32-1,d0
.lmpcopy	move.b	(a1)+,(a0)+
	dbeq	d0,.lmpcopy
	beq.b	.lmpnoname
	clr.b	(a0)+
.lmpnoname	rts


.is_mk2	sub.l	a3,a3
	move.l	#$08000000,d1		these values were fooked
	move.l	#$10000000,d2
.mk2scanloop	move.l	(a5),a5
	cmp.l	a5,a4
	beq	.exitsp
	move.w	(MH_ATTRIBUTES,a5),d0
	and.w	#MEMF_CHIP!MEMF_FAST!MEMF_PUBLIC,d0	Public fast?
	cmp.w	#MEMF_FAST!MEMF_PUBLIC,d0
	bne.b	.mk2scanloop
	cmp.l	(MH_LOWER,a5),d1
	blo.b	.mk2scanloop
	cmp.l	(MH_UPPER,a5),d2
	blo.b	.mk2scanloop		this condition was fooked

	bsr	.locmemprep

	move.l	(MH_UPPER,a5),d0
	moveq	#8,d1
	move.l	d0,d2
	swap	d1			d1=$80000
	and.l	d1,d2
	bne.b	.mk2skip
	sub.l	d1,d0
.mk2skip	move.l	d0,d7
	bra	.exitsp



.csfindmem	tst.b	_MK2
	bne.b	.is_mk2

.cstrymore	sub.l	a3,a3
.csscanloop	move.l	(a5),a5
	cmp.l	a5,a4
	beq	.exitsp
	move.w	(MH_ATTRIBUTES,a5),d0
	and.w	#MEMF_CHIP!MEMF_FAST!MEMF_PUBLIC,d0	Public fast?
	cmp.w	#MEMF_FAST!MEMF_PUBLIC,d0
	bne.b	.csscanloop
	swap	d3
	cmp.w	(MH_LOWER,a5),d3
	blo.b	.csscanloop
	swap	d3
	cmp.w	(MH_UPPER,a5),d3
	blo.b	.csscanloop
	move.l	(MH_UPPER,a5),a3

	bsr	.locmemprep

	move.l	a3,d0			Test for MapROM:
	beq.b	.csexit
	and.l	#$0007FFFF,d0
	bne.b	.csexit

	move.l	d6,d0			"known"?
	bne	.exit_known

	tst.b	_B20x0
	beq.b	.no20x0a
	cmp.w	#$0800,_BlizData+1*4	Test for $08000000 mem.
	bne.b	.csexit
	move.l	a3,a2
	lea	(.testcode20x0,pc),a0
	bsr	runnommu
	bra.b	.csexit
.no20x0a
	move.l	a3,d7

.csexit	tst.l	d7
	beq	.cstrymore
	bra	.exitsp


; a1=ROM, a2=RAM
.testcode	or.w	#$700,sr		Disable interrupts
	move.l	(a2),d1
	cmp.l	(a1),d1
	bne.b	.exite
	not.l	d1
	move.l	d1,(a2)
	bsr.b	.cacheclr
	cmp.l	(a1),d1
	bne.b	.exite
	not.l	d1
	move.l	d1,(a2)
	bsr.b	.cacheclr
	move.l	a3,d7
.exite	rts

.cacheclr	btst	#AFB_68020,_AttnFlags+1
	bne	CacheClrS
	rts

; a1=ROM, a2=RAM
.testcode20x0
	or.w	#$700,sr		Disable interrupts
	movec	dfc,d0
	move.l	d0,-(sp)
	moveq	#3,d0			Entry FC for Control Registers (also num of areas-1)
	movec	d0,dfc
	bsr.b	.cacheclr
.tcloop	moveq	#0,d1
	bsr	SetMemShadow

	bsr.b	.cacheclr
	nop
	move.l	(a2),d2
	move.l	d2,-(sp)
	eor.l	#$BADC0DE5,d2
	move.l	d2,(a2)
	nop
	bsr.b	.cacheclr
	move.l	(a2),d3
	move.l	(sp)+,(a2)
	nop
	bsr.b	.cacheclr
	cmp.l	d2,d3
	beq.b	.tcfound
.tcnext	moveq	#1,d1
	bsr.b	SetMemShadow
	dbf	d0,.tcloop
.tcexit	move.l	(sp)+,d0
	movec	d0,dfc
	bsr.b	.cacheclr		BUG: here was an was rte!
	rts

.tcfound	move.b	d0,_B20x0Bank
	move.l	a3,d7
	moveq	#1,d1
	bsr.b	SetMemShadow		Uses d0!
	bra.b	.tcexit



BITEM	MACRO
	dc.w	\2,\3,\1
	dc.l	\4
	ENDM

.boards	BITEM $0000,BLIZPROD,$18,$08001000	18 2040-ERC/2060
	BITEM $0000,BLIZPROD,$0C,0		0C Cyberstorm MKI
	BITEM $0000,BLIZPROD,$19,0		19 Cyberstorm MKII
	BITEM $FFF0,BLIZPROD,$64,$08002000	64 Cyberstorm MKIII / PPC
	BITEM $4FF8,BLIZPROD,$11,-1		11 1230-IV / 1260 / 1240-T/ERC
	BITEM $1EF8,BLIZPROD,$0D,-1		0D 1230-III
	BITEM $0FF8,BLIZPROD,$0B,-1		0B 1230-II
;;	BITEM $????,BLIZPROD,$??,-1		0? 1230-I
	dc.w	-1


;
; This one is from old CyberMap I think...
; Modified a bit.
;
;*********************************************************
;*       writes memshadowregister of the given rambank
;*       setmemshadow(D0=bank,D1=on/off (bool))
;*********************************************************
;*       $ 8    2    c
;*       %100x yy10 1100 ---- ---- ---- ---- ----Shadow Register Format
;*					x = Set/Clr Flag  0=on 1=off
;*					y = Bank Number
MEMSHWREG	EQU	$82C00000		Shadow Enable Control Register
SetMemShadowN	move.b	_B20x0Bank,d0
; IN: d0=bank, d1=mode
SetMemShadow	movem.l	d0-d1/a0,-(sp)
	and.l	#3,d0			mask bank number
	ror.l	#6,d0			shift in place
	or.l	#MEMSHWREG,d0		mask in MEMSHWREG adr
	tst.l	d1
	bne.b	.sf_skip		=! 0 -> TRUE -> b28=0
	bset	#28,d0			== 0 -> FALSE -> b28=1
.sf_skip	move.l	d0,a0			Write Register
	moves.l	a0,(a0)
	movem.l	(sp)+,d0-d1/a0
;;	rts
	bra	_fullflush040



;  IN: a0=rom, d0=rom len
; OUT: d0=success, fail if no AGA or WaitBlit func couln't be found
PutHogWaitBlit	movem.l	d1-a6,-(sp)
	moveq	#0,d7

	cmp.w	#39,($C,a0)		Requires rom 39+
	blo.b	.exit

	lea	(a0,d0.l),a1

	move.w	$DFF004,d0		Test AGA:
	and.w	#$7F00,d0
	lsr.w	#8,d0
	bclr	#4,d0
	cmp.b	#$22,d0
	beq.b	.aga
	cmp.b	#$23,d0
	bne.b	.exit
.aga
	move.l	#$08390006,d0
.find	addq.l	#2,a0
	cmp.l	a1,a0
	beq.b	.exit
	cmp.l	(a0),d0
	bne.b	.find
	cmp.l	#$00DFF002,(4,a0)
	bne.b	.find
	cmp.l	#$66024E75,(8,a0)
	bne.b	.find

	cmp.l	#$08390006,(-8,a0)	No KS 1.x!
	beq.b	.exit
	cmp.l	#$4A3900DF,(-6,a0)	KS 2.x/3.x:
	bne.b	.exit
	subq.l	#6,a0
	lea	(.waitblit,pc),a1
	moveq	#(.waitblitend-.waitblit)/2-1,d0
.copy	move.w	(a1)+,(a0)+
	dbf	d0,.copy
	moveq	#1,d7

.exit	move.l	d7,d0
	movem.l	(sp)+,d1-a6
	rts

	; 1.x  36 bytes
	; 2.05 40 bytes
	; 3.0  48 bytes
	; 3.1  48 bytes
.waitblit	btst	#DMAB_BLTDONE-8,$DFF000+dmaconr			8
	bne.b	.gowait						2
	rts							2
.gowait	move.l	a0,-(sp)					2
	lea	($DFF000+dmaconr),a0				6
	move.w	#DMAF_SETCLR!DMAF_BLITHOG,(dmacon-dmaconr,a0)	6
.wait	btst	#DMAB_BLTDONE-8,(a0)				4
	bne.b	.wait						2
	move.w	#DMAF_BLITHOG,(dmacon-dmaconr,a0)		6
	move.l	(sp)+,a0					2
	rts							2 =42
	IFGT	0
.gowait	move.w	#DMAF_SETCLR!DMAF_BLITHOG,$DFF000+dmacon	8
.wait	btst	#DMAB_BLTDONE-8,$DFF000+dmaconr	8
	bne.b	.wait				2
	move.w	#DMAF_BLITHOG,$DFF000+dmacon	8
	rts					2 =40
	ENDC
.waitblitend
	IFGT	(.waitblitend-.waitblit)-42
	FAIL	!! WAITBLIT routine too long !!
	ENDC


;  IN: a0=rom, d0=rom len
; OUT: d0=success
PlantLocalFast	movem.l	d1-a6,-(sp)
	move.l	(_ExecBase,pc),a6

	tst.l	_BlizMemHeader
	beq	.xit

	move.l	d0,-(sp)

	tst.b	_CPUCard
	bne.b	.noaddmem
	tst.b	_MK2
	bne.b	.noaddmem
	tst.b	_PPC_MK3
	bne.b	.noaddmem
	tst.b	_B20x0
	bne.b	.noaddmem
	tst.b	_BlizPPC
	beq.b	.addmem
.noaddmem
	lea	(_localfast_module,pc),a1
	move.b	#$60,(BLIZPPCBRA1,a1)	force bra, no quickboot
	move.l	#$4E714E71,d1
	move.w	d1,(BLIZPPCNOP1,a1)	disable this 'n' that
	move.w	d1,(BLIZPPCNOP2,a1)
	move.l	d1,(BLIZPPCNOPS1,a1)
	move.l	d1,(BLIZPPCNOPS2,a1)
	move.l	d1,(BLIZPPCNOPS3,a1)

	lea	(.namstr,pc),a1
	lea	(_bliz_name,pc),a2
.nam_cpy	move.b	(a1)+,(a2)+
	bne.b	.nam_cpy
.addmem
	moveq	#119,d1
	tst.b	_BlizPPC
	bne.b	.has_blizppc

	moveq	#105,d1			Get exec.library pri+1 (def 106)
	move.l	(LN_NAME,a6),a1
	bsr.b	FindResident
	beq.b	.nores
	move.l	d0,a1
	move.b	(RT_PRI,a1),d1
.nores	addq.b	#1,d1

.has_blizppc	lea	(_localfast_module,pc),a1
	move.b	d1,(bkm_ResTag+RT_PRI,a1)
	move.l	(sp)+,d0
	bsr	InstallModule

.xit	movem.l	(sp)+,d1-a6
	rts

.namstr	dc.b	'BlizKick EXTRESBUF',0


;  IN: a0=rom start (buf)
;      d0=rom len
;      a1=name
; OUT: d0=ptr to resident (buf) or NULL
FindResident	movem.l	d1-a6,-(sp)
	moveq	#1,d6
	move.l	a1,a3
	move.l	#$01000000,d2
	sub.l	d0,d2			d2=rom start (rom)
	move.l	a0,a5
	sub.l	d2,a5			a5=difference
.findres	moveq	#RT_SIZE-2,d1
	sub.l	d1,d0
	move.w	#RTC_MATCHWORD,d1
	subq.l	#2,a0
.find	addq.l	#2,a0
	subq.l	#2,d0
	bls.b	.try_extres
	cmp.w	(a0),d1
	bne.b	.find
	move.l	(RT_MATCHTAG,a0),d2
	add.l	a5,d2
	cmp.l	a0,d2
	bne.b	.find
	move.l	(RT_NAME,a0),a1
	add.l	a5,a1
	move.l	a3,a2
.compare	cmpm.b	(a2)+,(a1)+
	bne.b	.find
	tst.b	(-1,a2)
	bne.b	.compare
	bra.b	.exit_found

.exit_nf	sub.l	a0,a0
.exit_found	move.l	a0,d0
	movem.l	(sp)+,d1-a6
	rts

.try_extres	tst.l	d6
	beq.b	.exit_nf
	movem.l	(_erh_data,pc),d0/a0
	tst.l	d0
	beq.b	.exit_nf
	moveq	#0,d6
	sub.l	a5,a5			Difference=0
	bra.b	.findres


PATHBUF_SIZE	EQU	256

;  IN: a0=ptr to rom (buf), d0=rom len, a3=array  (d6=dosbase)
; OUT: d0=success, will print doserror if failed
DoPlanting	movem.l	d1-a6,-(sp)
	lea	(-PATHBUF_SIZE,sp),sp
	move.l	sp,a5
	move.l	d6,a6

	move.l	d0,d1
	move.l	(ARG_MODULE,a3),d0
	beq	.exit			OK! ;-)
	move.l	d0,a2

	moveq	#0,d3
	moveq	#0,d4			null!
	cmp.w	#37,(LIB_VERSION,a6)
	blo	.not20
	movem.l	d1-d2/a0,-(sp)
	sub.l	a1,a1
	move.l	(_ExecBase,pc),a6
	call	FindTask
	move.l	d6,a6
	move.l	d0,a0
	lea	(pr_WindowPtr,a0),a0
	move.l	(a0),-(sp)
	move.l	a0,-(sp)
	moveq	#-1,d0
	move.l	d0,(a0)
	lea	(_EnvName,pc),a0
	move.b	#':',(3,a0)
	move.l	a0,d1
	bsr	_lockread
	move.l	d0,d2
	call	UnLock
	move.l	(sp)+,a0
	move.l	(sp)+,(a0)
	tst.l	d2
	bne.b	.has_env

	lea	(_EnvArcName,pc),a0
	move.l	a0,d1
	bsr	_lockread
	beq.b	.no_envarclock
	move.l	d0,d2
	lea	(_EnvName,pc),a0
	clr.b	(3,a0)
	move.l	a0,d1
	call	AssignLock
	move.l	d0,d3			d3=assignstate
	bne.b	.got_assign
	move.l	d2,d1
	call	UnLock
.got_assign
.no_envarclock
.has_env
	lea	(_VarName,pc),a0
	move.l	a0,d1
	move.l	a5,d2
	move.l	d3,-(sp)
	MOVQ	PATHBUF_SIZE,d3		d4=0
	call	GetVar
	move.l	(sp)+,d3
	addq.l	#1,d0
	beq.b	.novar
	move.l	a5,d1
	bsr	_lockread
	beq.b	.nolock
	move.l	d0,d4
	move.l	d4,d1
	call	CurrentDir
	move.l	d0,d7			oldlock
.nolock
.novar	movem.l	(sp)+,d1-d2/a0
.not20

.loop	move.l	(a2)+,d0
	beq.b	.exit2
	move.l	d0,a1
	move.l	d1,d0
	bsr.b	FilePlant
	bne.b	.loop
	bsr	_PrintFault		IN: d5=kickflag, d6=dosbase
	lea	(PlantError,pc),a0
	move.l	a2,a1
	subq.l	#4,a1
	bsr	_Printf
	moveq	#-1,d0

.exit2	tst.l	d4
	beq.b	.nodirlock
	move.l	d0,-(sp)
	move.l	d7,d1
	call	CurrentDir
	move.l	d4,d1
	call	UnLock
	move.l	(sp)+,d0
.nodirlock	tst.l	d3
	beq.b	.noassign
	move.l	d0,d7
	lea	(_EnvName,pc),a0
	clr.b	(3,a0)
	move.l	a0,d1
	moveq	#0,d2
	call	AssignLock
	move.l	d7,d0
.noassign

.exit	not.l	d0
	lea	(PATHBUF_SIZE,sp),sp
	movem.l	(sp)+,d1-a6
	rts

_lockread	moveq	#ACCESS_READ,d2
	call	Lock
	move.l	d0,d1
	rts

;  IN: a1=ptr to filename, a0=ptr to rom (buf), d0=rom len  (d6=dosbase)
; OUT: d0=success
FilePlant	movem.l	d1-a6,-(sp)
	move.l	d6,a6
	moveq	#0,d7

	movem.l	d0/a0,-(sp)
	move.l	a1,d1
	call	LoadSeg
	move.l	d0,d5
	movem.l	(sp)+,d0/a0		Doesn't set cond codes!
	beq.b	.exit

	move.l	d5,a1
	add.l	a1,a1
	addq.l	#2,a1			;-)
	add.l	a1,a1
	bsr.b	InstallModule
	move.l	d0,d7

	move.l	d5,d1
	call	UnLoadSeg
.exit	move.l	d7,d0
	movem.l	(sp)+,d1-a6
	rts


;  IN: d1.l=error (d6=dosbase)
SetIoErr	movem.l	d0-d1/a0-a1/a6,-(sp)
	move.l	d6,a6
	cmp.w	#36,(LIB_VERSION,a6)
	blo.b	.old
	call	SetIoErr
	bra.b	.exit
.old	move.l	(_ExecBase,pc),a6
	sub.l	a1,a1
	call	FindTask
	move.l	d0,a0
	move.l	(4,sp),(pr_Result2,a0)
.exit	movem.l	(sp)+,d0-d1/a0-a1/a6
	rts


;  IN: a1=ptr to module, a0=ptr to rom (buf), d0=rom len  (d6=dosbase)
; OUT: d0=success
InstallModule	movem.l	d1-a6,-(sp)
	moveq	#0,d7
	MOVQ	ERROR_OBJECT_WRONG_TYPE,d1
	bsr.b	SetIoErr

	move.l	#$01000000,d2
	sub.l	d0,d2
	move.l	a0,a5
	sub.l	d2,a5			a5=difference

	cmp.l	#BKMODULE_ID,(a1)+	(bkm_ID)
	bne.b	.exit
	move.w	(a1)+,d4		d4=bkm_Flags, a1=bkm_ResTag
	move.w	d4,d1
	and.w	#~BKMF_ALL,d1		Test validity:
	bne.b	.exit
	cmp.w	#BKEP_ID,(a1)		Test for patch module:
	beq	.is_epatch
	cmp.l	#RTC_MATCHWORD<<16,(a1)
	bne.b	.exit

	MOVQ	ERROR_OBJECT_TOO_LARGE,d1
	bsr.b	SetIoErr

	lea	(.replace_test,pc),a3
	lsr.w	#1,d4			btst	#BKMB_ReplaceMode,d4
	bcs.b	.replace
	lea	(.single_test,pc),a3
	lsr.w	#1,d4			btst	#BKMB_SingleMode,d4
	bcc.b	.no_findresident
.replace	movem.l	d0/a1,-(sp)
	add.l	(RT_NAME,a1),a1
	bsr	FindResident
	move.l	d0,a2
	movem.l	(sp)+,d0/a1
	jmp	(a3)
.no_findresident
.is_single
.is_erbf	move.l	(RT_ENDSKIP,a1),d1
	lsr.w	#1,d4			btst	#BKMB_ExtResBuf,d4
	bcc.b	.no_extresbuf1
	neg.l	d1
.no_extresbuf1	bsr	FindSpace
	beq.b	.exit

.go_replace	move.l	d0,a3			a3=ptr to func (buf)
	move.l	d1,a2			a2=ptr to func (ROM)

	move.w	($C,a0),d1		d1=rom version
	move.l	a1,a0
	lea	(RT_VERSION,a0),a4
	cmp.b	(a4),d1			Test version!
	blo.b	.nofail
	move.b	d1,(a4)			Force current version!
	cmp.w	#36,d1
	shs	d1
	move.l	a3,a1			a2=ptr to func (ROM)
	bsr	PutResident

.nofail	moveq	#1,d7
.exit	move.l	d7,d0
.exit2	bsr	CacheClearOS		Clear caches.
	movem.l	(sp)+,d1-a6
	rts


.replace_test	beq.b	.exit			If no match exit!
	move.b	(RT_PRI,a2),d1
	cmp.b	(RT_PRI,a1),d1
	bne.b	.exit			If no match exit!

	lsr.w	#1,d4
	btst	#0,d4			btst BKMB_ExtResBuf,d4
	bne.b	.is_erbf

	move.l	(RT_ENDSKIP,a2),d1	d1=ptr to ENDSKIP (ROM)
	add.l	a5,d1			d1=ptr to ENDSKIP (buf)
	sub.l	a2,d1
	cmp.l	(RT_ENDSKIP,a1),d1
	ble.b	.exit
	move.l	a2,d0
	move.l	d0,d1
	sub.l	a5,d1
	bra.b	.go_replace


.single_test	beq.b	.is_single		SINGLE: If no match continue!
	move.b	(RT_PRI,a2),d1
	cmp.b	(RT_PRI,a1),d1
	bne.b	.is_single		SINGLE: If no match continue!
	MOVQ	ERROR_TOO_MANY_ARGS,d1
	bsr	SetIoErr
	move.l	d0,d7
	bra.b	.exit

; a0=ptr to rom start (buf), a1=ptr to epatch, d0=rom len, d2=ptr to rom start (ROM)
.is_epatch	lea	(2,a1),a5
	move.l	d2,a1
	lea	(FindResident,pc),a2
	lea	(InstallModule,pc),a3
	lea	(_Printf,pc),a4
	move.l	(_ExecBase,pc),a6
	jsr	(a5)
	bra.b	.exit2


;  IN: a0=rom (buf), d0=rom len, d1=required space (negate if ExtResBuf required)
; OUT: d0=ptr to area (buf) or NULL, d1=ptr to area (rom)
FindSpace	movem.l	d2-d3/d6-d7/a0-a2,-(sp)
	moveq	#0,d7

	move.l	#$01000000,d2
	sub.l	d0,d2
	move.l	a0,d6
	sub.l	d2,d6			d6=difference (buf-rom)

	tst.l	d1
	bmi.b	.required_extres

	lea	ROMSUMOFFS(a0,d0.l),a1
	bsr.b	.find
	bhs.b	.found			Big enough 'empty' space.

	moveq	#$0004,d2
	swap	d2
	cmp.l	d2,d0			Test for >$40000 ROM
	bls.b	.try_extres

	lea	(a0,d0.l),a1
	sub.l	d2,a1			a1=$FC0000
	move.l	(a1),d2
	and.l	#$FFF8FFFF,d2
	cmp.l	#$11104EF9,d2
	bne.b	.try_extres
	bsr.b	.find
	blo.b	.try_extres

.found	move.l	a1,d7
	addq.l	#1+3,d7
	and.w	#-4,d7

.exit	move.l	d7,d1
	sub.l	d6,d1
	move.l	d7,d0
	movem.l	(sp)+,d2-d3/d6-d7/a0-a2
	rts

.find	moveq	#-1,d2
.null	move.b	-(a1),d3
	addq.l	#1,d2
	not.b	d3
	beq.b	.null
	cmp.l	d1,d2
	rts

.required_extres
	neg.l	d1
.try_extres	movem.l	(_erh_data,pc),d0/a1
	tst.l	d0
	beq.b	.exit
	add.l	d0,a1
	bsr.b	.find
	blo.b	.exit
	moveq	#0,d6			NULL difference!
	bra.b	.found


;  IN: a0=resident
;      a1=adr to "free" buf
;      a2=adr to "free" buf (rom)
;      d1.b=zero if <V36 ROM
PutResident	bsr	CacheClearOS		336r: Added coz bad move16 optimized copymem patches?
	movem.l	d0-a6,-(sp)
	move.l	(_ExecBase,pc),a6
	lea	(RT_MATCHTAG,a1),a3
	lea	(4,a1),a4
	move.l	(RT_ENDSKIP,a0),d0
	call	CopyMem
	bsr	CacheClearOS		336r: Added coz bad move16 optimized copymem patches?
	move.l	a2,d0
	move.l	d0,(a3)+		RT_MATCHTAG
	add.l	d0,(a3)+		RT_ENDSKIP
	tst.b	(4+3,sp)
	bne.b	.no_incomp
	move.b	(a3),d1
	and.b	#~(RTF_AUTOINIT!RTW_COLDSTART),d1
	beq.b	.no_incomp
	and.b	#RTF_AUTOINIT!RTW_COLDSTART,(a3) Mask out incompatible bits
	or.b	#RTW_COLDSTART,(a3)
.no_incomp	move.b	(a3),d1
	addq.l	#RT_NAME-RT_FLAGS,a3
	add.l	d0,(a3)+		RT_NAME
	add.l	d0,(a3)+		RT_IDSTRING
	and.b	#RTF_AUTOINIT,d1
	beq.b	.noauto
	add.l	(a3),a4
	add.l	d0,(a4)+
	add.l	d0,(a4)+
	add.l	d0,(a4)+
.noauto	add.l	d0,(a3)+		RT_INIT
	movem.l	(sp)+,d0-a6
	rts


;  IN: a0=rom (buf), d0=rom len, d1=required buffer len, a3=array
; OUT: d0=ptr to extres buffer or NULL, (d1=aligned to 8 byte boundary)
ExtResBuf	movem.l	d0-a6,-(sp)
	move.l	d0,d5			d5=rom len
	move.l	a0,a5			a0=buf strt
	moveq	#0,d7

	tst.l	_BlizMemHeader
	beq	.exit

	move.l	#MIN_EXTRESBUF,d2
	cmp.l	d2,d1
	bhs.b	.ok
	move.l	d2,d1
.ok
	addq.l	#7,d1
	and.w	#-8,d1
	move.l	d1,(4,sp)

	moveq	#-1,d1
	move.l	#'chip',d2
	move.l	#' mem',d3
	move.l	#'ory'<<8,d4

.find	addq.l	#2,a0
	subq.l	#2,d0
	beq	.exit
	cmp.l	(a0),d1
	bne.b	.find
	cmp.l	(1*4,a0),d2
	bne.b	.find
	cmp.l	(2*4,a0),d3
	bne.b	.find
	cmp.l	(3*4,a0),d4
	bne.b	.find
	move.l	a0,a2
	sub.l	a5,a0			-bufstrt
	add.l	#$01000000+4,a0		(+4 = skip $ffffffff)
	sub.l	d5,a0			+romstart
	move.l	a0,_erh_rompos

	lea	(_erh_data,pc),a3
	move.l	#ERHANDLER_SIZEOF+8,d0
	add.l	(4,sp),d0
	move.l	d0,(a3)+		must be quadword even!

	move.l	_BlizMemHeader,a0

	; This thing ensures extres buffer won't get
	; overwritten (blizzppc kernel did this for
	; example)...
	add.l	#$100000,d0

	bsr	Allocate_REVERSE
	move.l	d0,(a3)
	beq	.exit

;;	move.l	_BlizMemHeader,a0
;;	move.l	(MH_UPPER,a0),d1
;;	sub.l	d0,d1
;;	sub.l	d1,_BlizData+2*4	Substract EXTRESBUF size from localfast len
	; d0=buf

	addq.l	#8,d0
	move.l	d0,d7
	move.l	d0,(a2)+		ScanStart
	add.l	-(a3),d0
	subq.l	#8,d0
	move.l	d0,(a2)+		ScanEnd
	moveq	#-1,d0
	move.l	d0,(a2)			EndMark ($FFFFFFFF)

	move.l	d7,a0			Fill area with $FFFFFFFF:
	move.l	(a3),d0
	subq.l	#8,d0
	moveq	#-1,d1
.fill	move.l	d1,(a0)+
	move.l	d1,(a0)+
	subq.l	#8,d0
	bgt.b	.fill

	cmp.w	#39,($C,a5)		rom version <39?
	bhs.b	.nofix

	; Fix V37 rom:
	move.l	#$FFFFFF80,d2
	move.l	#$41FAFF80,d3
	move.l	#512/2,d0
	move.l	a2,a0
.ffind	addq.l	#2,a0
	subq.l	#1,d0
	beq.b	.fexit
	move.l	(a0),d1
	and.l	d2,d1
	cmp.l	d3,d1
	bne.b	.ffind
	move.l	(1*4,a0),d1
	and.l	#$FFFF0000,d1
	cmp.l	#$61000000,d1
	bne.b	.ffind
	cmp.l	#$2D40012C,(2*4,a0)
	bne.b	.ffind
	addq.l	#2,a0
	move.l	a0,a1
	add.w	(a0),a0
	move.l	a0,d0
	sub.l	a2,d0
	cmp.l	#200,d0			238 bytes in 37.300
	blo.b	.fexit
	move.l	a2,a0
	move.l	#$F18060FE,d1
	moveq	#(256/2)-1,d0
.ffind2	subq.l	#2,a0
	subq.l	#1,d0
	beq.b	.fexit
	cmp.l	(a0),d1
	bne.b	.ffind2
	addq.l	#4,a0
	sub.l	a1,a0
	move.w	a0,(a1)			Fix it!
.fexit
.nofix
	move.l	a5,a0			a0=ptr to rom (buf)
	move.w	($C,a0),d1		d1=rom version
	lea	(_erhandler_res,pc),a0
	move.b	d1,(RT_VERSION,a0)	Force current version!
	cmp.w	#36,d1
	shs	d1
	move.l	d7,a1
	move.l	d7,a2
	bsr	PutResident

.exit	move.l	d7,d0
	addq.l	#4,sp
	movem.l	(sp)+,d1-a6
	rts


;  IN: a0=memHeader, d0=byteSize
; OUT: d0=memoryBlock or null
Allocate_REVERSE
	move.l	d2,-(sp)
	move.l	d0,d2

	moveq	#0,d1
	jsr	(_LVOForbid,a6)
	move.l	(MH_FIRST,a0),d0
	beq.b	.fail
.findfree_r	move.l	d0,a1
	cmp.l	(MC_BYTES,a1),d2
	bhi.b	.findskip_r
	move.l	a1,d1
.findskip_r	move.l	(a1),d0			; MC_NEXT
	bne.b	.findfree_r
	tst.l	d1
	beq.b	.fail
	move.l	d1,a1
	move.l	(MC_BYTES,a1),d0
	sub.l	d2,d0
	and.w	#$FFF8,d0
	add.l	d0,a1
	move.l	d2,d0
	jsr	(_LVOAllocAbs,a6)
	jsr	(_LVOPermit,a6)
	move.l	(sp)+,d2
	tst.l	d0
	rts

.fail	jsr	(_LVOPermit,a6)
	move.l	(sp)+,d2
	moveq	#0,d0
	rts


_erhandler_res
.x	dc.w	RTC_MATCHWORD
	dc.l	0
	dc.l	_erhandler_end-.x
	dc.b	RTF_SINGLETASK		RTF_COLDSTART on 1.x!!?
	dc.b	1
	dc.b	NT_UNKNOWN
	dc.b	127
	dc.l	_erh_name-.x
	dc.l	_erh_name-.x
	dc.l	.ERHandler-.x

	; d0=0, a0=0, a6=execbase
.ERHandler	movem.l	d2-d3/a2,-(sp)
	move.l	#$F80000,d0
_erh_rompos	EQU	*-4
	move.l	d0,d1
	addq.l	#_erh_pseudoname-_erh_chipname,d1
	lea	(_erh_chipname,pc),a0
	move.l	a0,d2
	addq.l	#_erh_pseudoname-_erh_chipname,a0
	move.l	a0,d3
	lea	(MemList,a6),a2
	lea	(4,a2),a1
.scanloop	move.l	(a2),a2
	cmp.l	a2,a1
	beq.b	.scandone
	lea	(LN_NAME,a2),a0
	cmp.l	(a0),d0
	bne.b	.notchip
	move.l	d2,(a0)
.notchip	cmp.l	(a0),d1
	bne.b	.notfast
	move.l	d3,(a0)
.notfast	bra.b	.scanloop
.scandone	movem.l	(sp)+,d2-d3/a2
	rts

_erh_chipname	dc.b	'chip '
_erh_pseudoname	dc.b	'memory',0
_erh_name	dc.b	'EXTRES Handler',0
	CNOP	0,2
_erhandler_end
ERHANDLER_SIZEOF EQU	(*-_erhandler_res+7)&$FFFFFFF8


CacheClearOS	movem.l	d0-d1/a0-a1/a6,-(sp)
	pea	(.cleanexit,pc)
	move.l	(_ExecBase,pc),a6
	cmp.w	#37,(LIB_VERSION,a6)
	blo.b	CacheClear
	jmp	(_LVOCacheClearU,a6)	OK! ;-)
.cleanexit	movem.l	(sp)+,d0-d1/a0-a1/a6
	rts
CacheClear	btst	#AFB_68020,_AttnFlags+1
	beq.b	.no68020
	movem.l	a5/a6,-(sp)
	lea	(.cacheclrsv,pc),a5
	move.l	(_ExecBase,pc),a6
	call	Supervisor
	movem.l	(sp)+,a5/a6
.no68020	rts
.cacheclrsv	or.w	#$700,sr		Disable interrupts
	bsr.b	CacheClrS
	nop
	rte
CacheClrS	btst	#AFB_68040,_AttnFlags+1
	beq.b	.not040
	CACHEFLUSH040
	rts
.not040	move.l	d0,-(sp)
	movec	cacr,d0
	or.w	#CACRF_ClearI!CACRF_ClearD,d0
	movec	d0,cacr
	move.l	(sp)+,d0
	rts

DisableCache	btst	#AFB_68020,_AttnFlags+1
	beq.b	.no68020
	movem.l	a5/a6,-(sp)
	lea	(.discachesv,pc),a5
	move.l	(_ExecBase,pc),a6
	call	Supervisor
	movem.l	(sp)+,a5/a6
.no68020	rts
.discachesv	or.w	#$700,sr		Disable interrupts
	bsr.b	DisableCacheS
	nop
	rte
DisableCacheS	move.l	d0,-(sp)
	btst	#AFB_68040,_AttnFlags+1
	beq.b	.not040

	dc.w	$F4F8		CPUSHA	BC
	nop
	movec.l	cacr,d0
	and.l	#~(CACRF_CopyBack!1<<15),d0
	movec.l	d0,cacr
	nop
	bra.b	.exit

.not040	movec.l	cacr,d0
	and.w	#~(CACRF_EnableI!CACRF_IBE!CACRF_EnableD!CACRF_DBE),d0
	or.w	#CACRF_ClearI!CACRF_ClearD,d0
	movec.l	d0,cacr
.exit	move.l	(sp)+,d0
	rts

; IN: a1=libname, d0=version, a6=execbase
FindLib	bsr.b	OpenLib
	beq.b	.exit
	move.l	d0,-(sp)
	move.l	d0,a1
	call	CloseLibrary
	move.l	(sp)+,d0
.exit	rts
; IN: a1=libname, d0=version, a6=execbase
OpenLib	move.w	#_LVOOldOpenLibrary,d1
	cmp.w	#33,(LIB_VERSION,a6)
	blo.b	.oldol
	move.w	#_LVOOpenLibrary,d1
.oldol	jsr	0(a6,d1.w)
	tst.l	d0
	rts


;  IN: a0=filename (d6=dosbase, _Printf)
; OUT: a1=buffer, d0=buffer len, d1=file len

XPKLoad	movem.l	d2-d7/a2-a6,-(sp)
	move.l	a0,a3
	sub.l	a5,a5
	moveq	#0,d6
	moveq	#0,d7

	move.l	(4*4,sp),a6
	move.l	a3,d1
;;	moveq	#ACCESS_READ,d2
;;	call	Lock
;;	move.l	d0,d1
	bsr	_lockread

	beq	.exit
	move.l	d1,-(sp)
	lea	(-fib_SIZEOF,sp),sp
	move.l	sp,d2
	call	Examine
	move.l	d0,d2
	move.l	(fib_Size,sp),d3
	lea	(fib_SIZEOF,sp),sp
	move.l	(sp)+,d1
	call	UnLock
	tst.l	d2
	beq.b	.exit

	move.l	a3,d1
	move.l	#MODE_OLDFILE,d2
	call	Open
	move.l	d0,d5
	beq.b	.exit

	move.l	d5,d1
	subq.l	#4,sp
	move.l	sp,d2
	move.l	d3,-(sp)
	moveq	#4,d3
	call	Read
	move.l	(sp)+,d3
	move.l	(sp)+,d4
	subq.l	#4,d0
	bne.b	.exit
	move.l	d5,d1
	moveq	#0,d2
	move.l	d3,-(sp)
	moveq	#OFFSET_BEGINNING,d3
	call	Seek
	move.l	(sp)+,d3
	subq.l	#4,d0
	bne.b	.exit
	cmp.l	#'XPKF',d4
	beq.b	.tryxpk

.noxpk	move.l	(_ExecBase,pc),a6
	move.l	d3,d0
	moveq	#MEMF_PUBLIC,d1
	call	AllocMem
	move.l	(4*4,sp),a6
	move.l	d0,d2
	beq.b	.close

	move.l	d5,d1
	call	Read
	cmp.l	d0,d3
	bne.b	.free

	move.l	d3,d7
	move.l	d3,d6
	move.l	d2,a5
	bra.b	.close

.free	move.l	(_ExecBase,pc),a6
	move.l	d2,a1
	move.l	d3,d0
	call	FreeMem
	move.l	(4*4,sp),a6

.close	move.l	d5,d1
	call	Close

.exit	move.l	a5,a1
	move.l	d6,d0
	move.l	d7,d1
	movem.l	(sp)+,d2-d7/a2-a6
	rts


.tryxpk	move.l	(_ExecBase,pc),a6
	lea	(.xpkname,pc),a1
	moveq	#0,d0
	bsr	OpenLib
	beq	.noxpk
	move.l	d0,d2

	move.l	(4*4,sp),a6
	move.l	d5,d1
	call	Close
	exg	d2,a6

XPKERRSIZE	EQU	((XPKERRMSGSIZE+1+3)&-4)

	lea	(-XPKERRSIZE,sp),sp
	move.l	sp,a4
	clr.l	-(sp)
	move.l	sp,d3
	clr.l	-(sp)
	move.l	sp,d4
	clr.l	-(sp)
	move.l	sp,d5
	clr.l	-(sp)
	moveq	#-1,d0
	move.l	d0,-(sp)
	pea	XPK_PassThru		Allow uncompressed file
	pea	MEMF_PUBLIC
	pea	XPK_OutMemType
	move.l	d5,-(sp)		buflen
	pea	XPK_GetOutBufLen
	move.l	d4,-(sp)		filelen
	pea	XPK_GetOutLen
	move.l	d3,-(sp)		outbuf
	pea	XPK_GetOutBuf
	move.l	a4,-(sp)		errbuf
	pea	XPK_GetError
	move.l	a3,-(sp)
	pea	XPK_InName
	move.l	sp,a0
	call	XpkUnpack
	move.l	d5,sp

	move.l	(sp)+,d6		d6=buflen
	move.l	(sp)+,d7		d7=filelen
	move.l	(sp)+,a5		a5=outbuf

	tst.l	d0
	beq.b	.allok
	; a4=errbuf
	move.l	a4,a0
.finde	tst.b	(a0)+
	bne.b	.finde
	move.b	#10,(-1,a0)
	clr.b	(a0)
	move.l	a4,a0
	exg	d2,d6
	bsr	_Printf
	exg	d2,d6

.allok	lea	(XPKERRSIZE,sp),sp

	move.l	a6,a1
	move.l	(_ExecBase,pc),a6
	call	CloseLibrary
	bra	.exit


.xpkname	dc.b	'xpkmaster.library',0
	CNOP	0,2


_localfast_module
 BK_MOD 0,_patch_end,(RTF_SINGLETASK)<<24!30<<16!NT_UNKNOWN<<8!127,_bliz_name,_bliz_name,.AddLocalFast

;  IN: d0=0, a0=0?, a6=execbase
.AddLocalFast	movem.l	d0-a6,-(sp)
	lea	(LibList,a6),a0		Should OpenLibrary?
	lea	(_ExpName,pc),a1
	call	FindName
	move.l	d0,d6
	beq.b	.exit			NOTE: .b !
BLIZPPCNOP1	EQU	*-_localfast_module-2

	sub.l	a0,a0
	move.w	#BLIZPROD,d0
	move.w	(_BoardNum,pc),d1
	exg	d6,a6
	call	FindConfigDev
BLIZPPCNOPS1	EQU	*-_localfast_module-4
	exg	d6,a6
	tst.l	d0
	beq.b	.exit			NOTE: .b !
BLIZPPCNOP2	EQU	*-_localfast_module-2

	move.l	d0,a5

	lea	(_BlizData+3*4,pc),a1
	move.l	-(a1),d0		Mem len
	move.l	-(a1),a0		Mem start
	bsr.b	_testmem		NOTE: .b !
	bne.b	.exit			NOTE: .b !
BLIZPPCNOPS2	EQU	*-_localfast_module-4

	subq.l	#4+2,a1
	tst.w	(a1)+
BLIZPPCBRA1	EQU	*-_localfast_module
	beq.b	.noquick
	bclr	#ERTB_DIAGVALID,(cd_Rom+er_Type,a5)	Don't run init code!
.noquick
	move.l	(a1)+,d1		Mem attributes
	move.l	(a1)+,a0		Mem start
	move.l	(a1)+,d0		Mem len
	move.b	(a1)+,d2		Mem priority
	call	AddMemList		a1=name
BLIZPPCNOPS3	EQU	*-_localfast_module-4

	lea	(_erh_data,pc),a0
	move.l	(a0)+,d0
	beq.b	.extresbufs
	move.l	(a0),a1
	call	AllocAbs
	tst.l	d0
	bne.b	.extresbufs
	move.l	#AT_DeadEnd!AG_NoMemory,d7
	jmp	(_LVOAlert,a6)		Really! :-)
.extresbufs
	bsr.b	MoveChipHeader

.exit	movem.l	(sp)+,d0-a6
	rts

_testmem	movem.l	d0-d2/a0-a1,-(sp)
	lea	-$40(a0,d0.l),a1
	call	TypeOfMem
	tst.l	d0
	bne.b	.inva
	movem.l	(sp),d0-d2/a0-a1
	bsr.b	.test
	bne.b	.inva
	lea	-$40(a0,d0.l),a0
	bsr.b	.test
.inva	movem.l	(sp)+,d0-d2/a0-a1
	rts
.test	move.l	(a0)+,-(sp)		Save memory
	move.l	(a0),-(sp)
	move.l	#$F0BAC0DE,d1
	move.l	d1,-(a0)		Write test long
	nop
	move.l	#'BFix',(4,a0)		Trash bus
	cmp.l	(a0),d1			Test long
	sne	d2
	bne.b	.texit
	not.l	(a0)			Write test long
	nop
	not.l	(4,a0)			Trash bus
	not.l	d1
	cmp.l	(a0),d1			Test long
	sne	d2
.texit	move.l	(sp)+,(4,a0)		Restore memory
	move.l	(sp)+,(a0)
	tst.b	d2
	rts

; Routines taken from FastExec 2.5 public domain source code by
; Torbjörn A. Andersson. Modified by Harry Sintonen.
******************************************************************************

MoveChipHeader	call	Forbid

.loop0	move.l	(MemList,a6),d2

.loop1	move.l	d2,a2
	move.l	(a2),d2
	beq.b	.quit

	cmp.l	#$1000000,a2		; address
	bhs.b	.loop1

	moveq	#MH_SIZE,d0
	moveq	#MEMF_PUBLIC!MEMF_FAST,d1
	call	AllocMem
	tst.l	d0
	beq.b	.quit
	move.l	d0,a3

	lea	(LN_TYPE,a2),a0		; source
	lea	(LN_TYPE,a3),a1		; dest
	moveq	#MH_SIZE-LN_TYPE,d0
	call	CopyMem

	lea	(MH_SIZE,a2),a0
	cmp.l	(MH_LOWER,a2),a0
	bne.b	.ok
	move.l	a2,(MH_LOWER,a3)
.ok
	move.l	a2,a1			; node
	call	Remove
	lea	(MemList,a6),a0		; list
	move.l	a3,a1			; node
	call	Enqueue

;	cmp.w	#36,(LIB_VERSION,a6)
;	blo.b	.loop0

	move.l	a2,a1			; memoryBlock
	moveq	#MH_SIZE,d0

	move.l	d0,d1
	add.l	a1,d1
	lea	(MemList,a6),a0
.floop	move.l	(a0),a0
	tst.l	(a0)
	beq.b	.fdone
	cmp.l	(MH_LOWER,a0),a1
	blo.b	.floop
	cmp.l	(MH_UPPER,a0),a1
	bhs.b	.floop
	cmp.l	(MH_UPPER,a0),d1
	bhi.b	.fdone
	call	FreeMem
.fdone	bra.b	.loop0

.quit	jmp	(_LVOPermit,a6)
;;	rts

_ExpName	dc.b	'expansion.library',0
	CNOP	0,2
_erh_data	ds.l	2
_BoardNum	ds.w	1
_QuickBoot	ds.w	1
_BlizData	ds.l	3
	ds.b	1
_bliz_name	dc.b	'Blizzard_Mem',0,'                   ',0
		;123456789012  3  4567890123456789012
	CNOP	0,2
_patch_end
MIN_EXTRESBUF	EQU	(_patch_end-_localfast_module+7)&$FFFFFFF8


;  IN: a0=rom, d0=rom len
; OUT: d0=success (number of patches done, or zero)
LastPatches	movem.l	d1-a6,-(sp)
	moveq	#0,d7
	move.l	a0,a6
	move.l	d0,d6

	move.l	_OrigSum,d0
	cmp.l	ROMSUMOFFS(a6,d6.l),d0
	seq	d5

SUPERVISOR_NOREVERSE	SET	0
	IFNE	SUPERVISOR_NOREVERSE
	move.w	#2048/2-1,d0		during first 2k
	move.l	#$2D40003A,d1
.scan	addq.l	#2,a0
	cmp.l	(a0),d1
	dbeq	d0,.scan
	tst.w	d0
	bmi.b	.not0
	cmp.l	#$6608223C,(4,a0)
	bne.b	.scan
	cmp.l	#MEMF_CLEAR!MEMF_REVERSE,(8,a0)
	bne.b	.scan
	cmp.w	#$60EC,(12,a0)
	bne.b	.scan

	move.w	#MEMF_CLEAR>>16,(8,a0)
	addq.l	#1,d7
.not0
	ENDC

	tst.b	d5
	beq	.not_correct_chksum

	cmp.l	#33<<16!180,($C,a6)
	bne.b	.not_33180
	cmp.l	#$56F2E2A6,_OrigSum		Must be original to patch!
	bne.b	.not_33180


;ABSDEBUG	EQU	$1EC00000
	IFD	ABSDEBUG
	move.w	#$4EF9,($13A,a6)
	move.l	#ABSDEBUG,($13A+2,a6)
	lea	(.code,pc),a0
	lea	ABSDEBUG,a1
	moveq	#((.codeend-.code)/2)-1,d0
.dcopy	move.w	(a0)+,(a1)+
	dbf	d0,.dcopy
	bra	.after

.code	moveq	#45,d1
	lea	(.handler,pc),a1
	jmp	$00FC0000+$142
ROMJMPA_OFFS	EQU	*-.code-4
.handler	or.w	#$700,sr
	movec	cacr,d0
	and.w	#~(CACRF_EnableI!CACRF_IBE!CACRF_EnableD!CACRF_DBE),d0
	or.w	#CACRF_ClearI!CACRF_ClearD,d0
	movec	d0,cacr
	lea	(.data,pc),a0
	move.l	#'33.1',(a0)+
	move.l	#'80: ',(a0)+
	move.l	sp,(a0)+
	move.w	#'SR',(a0)+
	move.w	(sp),(a0)+
	move.l	(2,sp),(a0)+
	move.l	(2+4,sp),(a0)+
	lea	$00B00000,a0
	lea	$1EF80000,a1
	move.w	#(512*1024/16)-1,d0
.drcopy	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
	dbf	d0,.drcopy
.djam	addq.l	#1,d0
	move.w	d0,$DFF180
	bra.b	.djam

	CNOP	0,4
.data	dc.l	0,0,0,0,0,0,0,0
.codeend
.after
	ENDC

	move.w	#$0020,($19C,a6)		2MB chip ram
	move.l	#$FF000001,($3000,a6)		ExecBase address mask

	IFGT	0
	move.l	#$4E714E71,d0			expansion.library bug
	move.l	d0,($4D9A,a6)
	move.l	#$4EAEFF3A,($4D9A+4,a6)
	move.l	#$4A80672E,($4D9A+8,a6)
	move.l	#$24002200,($4D9A+12,a6)
	move.l	#$20434280,($4D9A+16,a6)
	move.l	#$302F0002,($4D9A+20,a6)
	move.w	d0,($4D9A+24,a6)
	ENDC
	
	move.l	#$4E714E71,d0			expansion.library bug
	move.w	d0,($4D9A,a6)
	move.l	d0,($4D9A+2,a6)
	move.l	#$4A80672C,($4DA4,a6)
	move.l	#$24002240,($4DA4+4,a6)
	move.l	#$20437000,($4DA4+8,a6)
	move.b	#$30,($4DA4+12,a6)

	; my:
	move.l	#$99CC4ED5,($1E6,a6)		no $C00000 mem, please !!
;;	move.b	#0,($56D,a6)			disable cache (instruction)

	addq.l	#1,d7
.not_33180

	cmp.l	#34<<16!5,($C,a6)
	bne.b	.not_3405
	cmp.l	#$15267DB3,_OrigSum		Must be original to patch!
	bne.b	.not_3405

	move.w	#$0020,($19C,a6)		2MB chip ram
	move.l	#$FF000001,($303C,a6)		ExecBase address mask

	addq.l	#1,d7
.not_3405

.not_correct_chksum

	move.l	d7,d0
	movem.l	(sp)+,d1-a6
	rts


;  IN: a0=rom, d0=rom len
; OUT: d0=success (number of patches done, or zero)
SpeedROM	movem.l	d1-a6,-(sp)

	moveq	#0,d7
	move.l	a0,a2
	move.l	d0,d4
	move.l	#$01000000,d2
	sub.l	d4,d2
	move.l	a2,a5
	sub.l	d2,a5			a5=difference

	move.l	(4,a2),a1
	add.l	a5,a1

	cmp.w	#$203C,(6,a1)		KS 1.x start: (34.5)
	bne.b	.nosp1
	cmp.l	#$53806EFC,(12,a1)
	bne.b	.nosp1
	move.w	#$6008,(6,a1)
	addq.l	#1,d7
.nosp1
	IFEQ	KEEP_CHECKSUM
	cmp.l	#$41F900F8,(4,a1)	KS 3.0 chksum:
	bne.b	.nosp2
	cmp.l	#$72FF7401,(10,a1)
	bne.b	.nosp2
	move.l	#$7AFF6010,(10,a1)
	addq.l	#1,d7
.nosp2
	cmp.l	#$41FAFF28,(4,a1)	KS 3.1 chksum:
	bne.b	.nosp3
	cmp.l	#$72FF7401,(8,a1)
	bne.b	.nosp3
	move.l	#$7AFF6010,(8,a1)
	addq.l	#1,d7
.nosp3
	ENDC

	move.l	a2,a0			Reconnect resident modules:
	move.l	d4,d1
	sub.l	a1,a1
	subq.l	#2,a0
.find	addq.l	#2,a0
	subq.l	#2,d1
	bls.b	.done
	cmp.w	#RTC_MATCHWORD,(a0)
	bne.b	.find
	move.l	(RT_MATCHTAG,a0),d0
	add.l	a5,d0
	cmp.l	a0,d0
	bne.b	.find
	move.l	a1,d0
	beq.b	.is_1st
	move.l	a0,d0
	sub.l	a5,d0
	move.l	d0,(RT_ENDSKIP,a1)
.is_1st	move.l	a0,a1
	bra.b	.find
.done	addq.l	#1,d7

	move.l	d7,d0
	movem.l	(sp)+,d1-a6
	rts


KickSys	move.l	(_ExecBase,pc),a6
	lea	(GfxName,pc),a1
	moveq	#0,d0
	bsr	FindLib
	move.l	d0,a2
	exg	a2,a6
	sub.l	a1,a1
	call	LoadView
	call	WaitTOF
	cmp.w	#39,(LIB_VERSION,a6)
	blo.b	.noaga
	btst	#GFXB_AA_ALICE,(gb_ChipRevBits0,a6)
	beq.b	.noaga
	lea	$DFF106,a0
	move.w	#$0C00,(a0)		Reset AGA hardware.
	move.w	#$0000,($1FC-$106,a0)
.noaga	call	WaitTOF
	exg	a2,a6

	tst.b	_CPUCard
	bne	.mapcpucard

	lea	(.super,pc),a0
	bra	runnommu

.super	ori.w	#$700,sr		Disable all ints!

	bset	#7,$DE0002		Set Gary Coldstart

	tst.b	_B20x0
	beq.b	.noB20x0a
	movec	dfc,d5
	moveq	#3,d0			Entry FC for Control Registers
	movec	d0,dfc
	moveq	#0,d1			Turn shadow off:
	bsr	SetMemShadowN
.noB20x0a
	move.l	_BlizROM,a0
	move.l	a0,a1

	moveq	#8,d0			move.l	#$80000,d0
	swap	d0
	cmp.l	d0,d3
	bhs.b	.no1st

	move.l	d3,d0			Copy 256k:
	lsr.l	#4,d0
	subq.l	#1,d0
	move.l	a4,a2
.copy1	move.l	(a2)+,(a0)+
	move.l	(a2)+,(a0)+
	move.l	(a2)+,(a0)+
	move.l	(a2)+,(a0)+
	dbf	d0,.copy1
.no1st
	move.l	d3,d0			Copy ROM:
	lsr.l	#4,d0
	subq.l	#1,d0
	move.l	a4,a0
.copy	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
	dbf	d0,.copy

	tst.b	_B20x0
	beq.b	.noB20x0b
	moveq	#1,d1			Turn shadow back on:
	bsr	SetMemShadowN
	movec	d5,dfc
	bsr	_fullflush040
.noB20x0b
	moveq	#-1,d0			Trash execbase:
	move.l	d0,(4).w
	bsr	DisableCacheS		Disable all caches.

	tst.b	_MK2
	beq.b	.no_mk2
	move.b	#$2A,$880000E3		Trigger MKII maprom
	nop
	bra.b	.doreset
.no_mk2
	tst.b	_PPC_MK3
	beq.b	.no_ppc_mk3
	lea	$00F60020,a0		Trigger PPC/MKIII maprom
	move.b	#$60,(a0)
	nop
	move.b	#$50,(a0)
	nop
	move.b	#$30,(a0)
	nop
	move.b	#1,(-8,a0)
	nop
	move.b	#0,(a0)
	nop
	bra.b	.doreset
.no_ppc_mk3
	tst.b	_BlizPPC
	beq.b	.no_blizppc
	lea	$00F60012,a0		Trigger Bliz PPC maprom
	move.b	#0,(a0)
	nop
.no_blizppc

.doreset	nop
	bsr	CacheClrS		flush caches

	lea	$DFF09A,a0
	move.w	#$4000,(a0)+		All interrupts off
	move.w	#$3FFF,(a0)+		All DMA off

	nop
	nop
	nop
	nop

	lea	$01000000+4,a0		...and reboot...
	sub.l	(ROMSIZEOFFS-4,a0),a0
	move.l	(a0),a0
	subq.l	#2,a0
	bra.b	.reset
	nop
	CNOP	0,4
.reset	reset
	jmp	(a0)



.mapcpucard	call	Forbid			Must be V37+ if got here
	bsr.b	cachecontroli

	lea	(.nommucpuc,pc),a0
	bra	runnommu

.nommucpuc	ori.w	#$700,sr		Lock All Irqs

	move.l	a4,a0			a0=ptr to ROM Image

	move.b	#0,$DE0000		Gary bootflags=ColdStart
	move.b	#0,$DE0001
	nop
	move.l	#1,$80F80000		Trigger maprom
	nop

	move.l	#$07F80000,a1		Copy ROM Image
	move.w	#$80000/16-1,d0
.ccloop	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
	dbf	d0,.ccloop

	move.b	#$80,$DE0000		Gary BootFlag=ColdBoot
	move.b	#$80,$DE0001
	move.w	#$4000,$DFF09A		All interrupts off
	move.w	#$3FFF,$DFF09C		All DMA off

	moveq	#-1,d0			Trash execbase:
	move.l	d0,(4).w
	bra	.doreset


cachecontroli	moveq	#CACRF_EnableI!CACRF_IBE,d0
cachecontrol	move.l	#~CACRF_WriteAllocate,d1
	jmp	(_LVOCacheControl,a6)

;  IN: -
; OUT: d0,cc=nonzero if CPU Card with MAPROM present, else zero
CheckCPUCard	movem.l	d7/a6,-(sp)
	moveq	#0,d7
	move.l	(_ExecBase,pc),a6
	cmp.w	#37,(LIB_VERSION,a6)
	blo.b	.exit
	call	Forbid

	bsr.b	cachecontroli
	move.l	d0,-(sp)

	lea	(.nommu,pc),a0
	bsr	runnommu

	move.l	(sp)+,d0
	bsr.b	cachecontrol

	call	Permit
.exit	move.l	d7,d0
	movem.l	(sp)+,d7/a6
	rts

.nommu	ori.w	#$700,sr		Lock All Irqs
	move.b	#0,$DE0000		Gary bootflags=ColdStart
	move.b	#0,$DE0001
	nop
	move.l	#1,$80F80000		Trigger maprom
	nop
	move.l	$07F80000,d0		Test MAPROM
	cmp.l	$00F80000,d0
	bne.b	.nomap
	move.l	d0,d1			2nd test
	not.l	d1
	move.l	d1,$07F80000
	cmp.l	$F80000,d1
	beq.b	.does_map
.xit	move.l	d0,$07F80000
.nomap	move.b	#$80,$DE0000		Gary bootflags=Warmstart
	rts

.does_map	moveq	#1,d7
	bra.b	.xit


	CNOP	0,4
_ExecBase	dc.l	0

DosName	dc.b	'dos.library',0
_mmuflag	EQU	*-1
GfxName	dc.b	'graphics.library',0
	dc.b	'$VER:'
_Version	dc.b	'BlizKick 1.17 (24.1.99)',0
	dc.b	'$COPYRIGHT:'
_Copyright	dc.b	'Copyright © 1996-1999 PitPlane Productions',0
_Template	dc.b	'KICKFILE,MODULE/M,EXTRESBUF/N,FORCE/S,LOCALFAST/S,QUICKBOOT/S,'
	dc.b	'SPEEDROM/S,HOGWAITBLIT/S,CPUCARD=CSMKI/S,QUIET/S',0
_13Help	dc.b	'Usage: BlizKick ',$9b,'1mKICKFILE',$9b,'0m',10
	dc.b	'KICKFILE is full path for the ROM image to kick.',10,0
_ks13error	dc.b	'DOS Error #%ld!',10,0
_EnvName	dc.b	'ENVx',0
_EnvArcName	dc.b	'ENVARC:',0
_VarName	dc.b	'BKMODPATH',0

RequiresBliz	dc.b	'BlizKick requires turbo board/CPU-card with MAPROM feature.',10,0
NoCPUCard	dc.b	'Couldn''t find CPU Card!',10,0
PlantError	dc.b	'Couldn''t plant module ''%s''!',10,0
Messu	dc.b	'Blizzard turbo board MapROM tool written by Harry Sintonen.',10,0
Messu2	dc.b	'Kicking AMIGA ROM Operating System %d.%d.',10,0
Already	dc.b	'Kickstart is already kicked!',10,0
CouldNotKick	dc.b	'Couldn''t kick file ''%s''!',10,0
NoRem	dc.b	'Kickstart wasn''t kicked using BlizKick!',10,0


;;	SECTION	BSS_C,BSS_C

	ds.l	0
_Array	ds.l	10
_BlizMemHeader	ds.l	1
_BlizROM	ds.l	1
_Quiet	ds.l	1
_OrigSum	ds.l	1
_AttnFlags	ds.w	1
_B20x0	ds.b	1
_B20x0Bank	ds.b	1
_CPUCard	ds.b	1
_PPC_MK3	ds.b	1
_MK2	ds.b	1
_BlizPPC	ds.b	1

	END


; model     id       mem     start     end        notes  maprom
;turbo mem 2140/?    -        ?       - ?          A500
; 1220     2140/0C   4 meg   $00200000-$00600000  A1200
; 1230-I   2140/0?   ? meg   $????????-$????????  A1200  $????????
; 1230-II  2140/0B   4 meg   $0E000000-$0E400000  A1200  $0FF80000 ! ??
; 1230-II  2140/0B   8 meg   $????????-$????????  A1200  $1EF80000 ! ??
; 1230-III 2140/0D   8 meg   $1DC00000-$1E400000  A1200  $1EF80000
; 1230-III 2140/0D  32 meg   $1D000000-$1EF80000  A1200  $1EF80000
; 1230-IV  2140/11   8 meg   $78000000-$78800000  A1200  $4FF80000
; 1230-IV  2140/11   2 meg   $78000000-$78200000  A1200  $4FF80000?
; 1230-IV  2140/11  16 meg   $68000000-$68F80000  A1200  $4FF80000?
;?1260     2140/11   4 meg   $68000000-$68400000  A1200  $4FF80000 040&060 flag set!
;>1260     2140/11   8 meg   $78000000-$78800000  A1200  $4FF80000 040&060 flag set!
;?1260     2140/11  16 meg   $68000000-$69000000  A1200  $4FF80000 040&060 flag set!
; 1260     2140/11   4 meg   $68000000-$68380000  A1200  $4FF80000? 040&060 flag set!
; 1240-T   2140/11  16 meg   $68000000-$69000000  A1200  $4FF80000? 040 flag set!
; 2040-ERC 2140/18   8 meg   $08000000-$08800000  A2000  $???????? 040 flag set!  'blizzard fastram'
; 2060     2140/18  20 meg   $08000000-$09400000  A2000  $???????? 040&060 flag set!
; 4030     2140/?    -        ?       - ?         A4000

; CSMKI    2140/0C  32 meg   $08000000-$0A000000  A4000  csmagic  040 flag set
; CSMKII   2140/19  80 meg   $08000000-$0D000000  A4000  csmagic
; CS-PPC   2140/64   ? meg    ?       - ?         A4000 
; BLIZPPC  2140/6E  16 meg   $68000000-$68800000  A1200  $FFF00000 040 flag set

 Board (unidentified):   Prod=8512/25($2140/$19) (@$EA0000 128K)
 Board (unidentified):   Prod=2092/18($82C/$12) (@$E90000 64K)
 Board (unidentified):   Prod=2167/201($877/$C9) (@$EC0000 64K)
 Board (unidentified):   Prod=8512/34($2140/$22) (@$40000000, size 64meg, subsize same)

last one is CV 64

 VERS:   Kickstart version 40.70, Exec version 40.10, Disk version 40.42
 RAM:    Node type $A, Attributes $505 (FAST), at $8000000-$CFFFFFF (80.0 meg)


*** CS MK I:

PROCESSOR:	CPU 68040/68882fpu
CUSTOM CHIPS:	AA PAL Alice (id=$0023), AA Lisa (id=$00F8)
VERS:	Kickstart version 39.106, Exec version 39.47, Disk version 39.29
RAM:	Node type $A, Attributes $505 (FAST), at $8000000-$9FFFFFF (32.0 meg)
	Node type $A, Attributes $703 (CHIP), at $2000-$1FFFFF (~2.0 meg)
BOARDS:
=======================================================================
 Board (unidentified):   Prod=2195/10($893/$A)
     (@$40000000, size 4meg, subsize same)
 ConfigDev structure found at location $27F8
==== Board ID (ExpansionRom) information:
er_Manufacturer         =2195=$893=(~$F76C)
er_Product              =10=$A=(~$F5)
er_Type                 =$8F
  (type 2 (Zorro III), size 4meg, subsize same)
  (not for free list, no ROM diag vec, chained to next)
er_Flags                =$10
  (no space preference, can be shut up)
er_InitDiagVec          =$0
==== Configuration (ConfigDev) information:
cd_BoardAddr            =$40000000
cd_BoardSize            =$1000000 (16384K)
cd_Flags                =$0  (CONFIGME bit cleared)
=======================================================================
 Board + ROM (HD?) (unidentified):   Prod=8512/12($2140/$C) (@$E90000 64K)
 ConfigDev structure found at location $2840
==== Board ID (ExpansionRom) information:
er_Manufacturer         =8512=$2140=(~$DEBF)
er_Product              =12=$C=(~$F3)
er_Type                 =$D1
  (type 3, size 64K, not for free list, ROM diag vec valid, not chained)
er_Flags                =$0
  (no space preference, can be shut up)
er_InitDiagVec          =$80
DiagCopy at             =$8003320
==== Configuration (ConfigDev) information:
cd_BoardAddr            =$E90000
cd_BoardSize            =$10000 (64K)
cd_Flags                =$0  (CONFIGME bit cleared)
=======================================================================
 Board + ROM (HD?) (unidentified):   Prod=2195/11($893/$B) (@$EA0000 64K)
 ConfigDev structure found at location $2888
==== Board ID (ExpansionRom) information:
er_Manufacturer         =2195=$893=(~$F76C)
er_Product              =11=$B=(~$F4)
er_Type                 =$D1
  (type 3, size 64K, not for free list, ROM diag vec valid, not chained)
er_Flags                =$40
  (no space preference, can not be shut up)
er_InitDiagVec          =$0
==== Configuration (ConfigDev) information:
cd_BoardAddr            =$EA0000
cd_BoardSize            =$10000 (64K)
cd_Flags                =$2  (CONFIGME bit still set)
=======================================================================
 Board (unidentified):   Prod=5000/1($1388/$1) (@$EB0000 64K)
 ConfigDev structure found at location $28D0
==== Board ID (ExpansionRom) information:
er_Manufacturer         =5000=$1388=(~$EC77)
er_Product              =1=$1=(~$FE)
er_Type                 =$C1
  (type 3, size 64K, not for free list, no ROM diag vec, not chained)
er_Flags                =$40
  (no space preference, can not be shut up)
er_InitDiagVec          =$0
==== Configuration (ConfigDev) information:
cd_BoardAddr            =$EB0000
cd_BoardSize            =$10000 (64K)
cd_Flags                =$0  (CONFIGME bit cleared)
=======================================================================
 Board + ROM (HD?) (unidentified):   Prod=2017/11($7E1/$B) (@$EC0000 64K)
 ConfigDev structure found at location $2918
==== Board ID (ExpansionRom) information:
er_Manufacturer         =2017=$7E1=(~$F81E)
er_Product              =11=$B=(~$F4)
er_Type                 =$D1
  (type 3, size 64K, not for free list, ROM diag vec valid, not chained)
er_Flags                =$0
  (no space preference, can be shut up)
er_InitDiagVec          =$8000
==== Configuration (ConfigDev) information:
cd_BoardAddr            =$EC0000
cd_BoardSize            =$10000 (64K)
cd_Flags                =$0  (CONFIGME bit cleared)
=======================================================================


; Apollo:

; 1230/28  2222/23   4 meg   $01C00000-02000000  A1200  none      030 flag set 'Apollo 32Bit Power'
;                    8 meg   $03C00000-04400000 'Apollo 32Bit Power'
; 1230/50  2222/23   4 meg   $01C00000-02000000  A1200  none      030 flag set 'Apollo 32Bit Power'
; 1240/40  2222/23   4 meg   $01C00000-02000000  A1200  none      040 flag set '32Bit Power-Burstm'??
; 1240     2222/23   8 meg   $01C00000-02400000  A1200  none      040 flag set '32Bit Power-Burstm'??
; 1260     2222/23   4 meg   $01C00000-02000000  A1200  none      040&060 flag set '32Bit Power-Burstm'??
; 4060     2222/23  32 meg   $08000000-0A000000  A4000  none      040&060 flag set 'Apollo 32Bit Power'
