
****************************************************************************
**  /\  |\     Silicon Department      Telefax     06404-64760
**  \_ o| \_ _  Software Entwicklung    Telefon        06404-7996
**    \|| |_)|)   Carsten Schlote         Egelseeweg 52     35423 Lich
** \__/||_/\_|     Branko Mikiç            Limmerstrasse 10   30451 Hannover
****************************************************************************
*
* $Id: CyberMap.asm 1.5 1996/03/29 11:10:28 schlote Exp schlote $
*
*	29/11/95  	39.2	ExtraTexts added
*	28/12/95	39.3	Small Bug Fix with SysCall
*       06/01/95  	39.4	Changed RESET Code
*	23/03/96	39.5ß	Added B2060 support
*	27/03/96        39.5ß	Changed CLR.W (4).W -> MOVE.L	#-1,(4).w;  Hint by Don & Gerald :-)
*				Debugged B2060 Routine.
*	28/03/96	39.5ß	Added release note and send mail
*	29/03/96	39.5	Fixed A2000 Reset Code, First release, fixed version id

		incdir 		include:
		include 	"dos/dos.i"
		include		"exec/funcdef.i"
		include		"exec/exec_lib.i"
		include		"exec/exec.i"
		include		"exec/lists.i"
		include		"exec/execbase.i"
		include		"exec/memory.i"
		include		"dos/dos_lib.i"
		include		"hardware/intbits.i"
		include		"hardware/custom.i"

_LVOFreeArgs	EQU		-$35A				* Stehen noch nicht in dos_lib.i
_LVOPutStr	EQU		-$3B4
_LVOPrintFault	EQU		-$1DA
_LVOReadArgs	EQU		-$31E

_custom		EQU		$DFF000

		MACHINE		68030
		opt !

****************************************************************************************************************

KickMem		EQUR		a3
SysBase		EQUR		a4
DOSBase		EQUR		a5

		SECTION		CyberMap_Main,CODE
ProgStart
		MOVEQ		#20,D7                  	; RC=20
		MOVE.L		(4).w,SysBase			; A4=SysBase

		LEA		(doslibrary.MSG,PC),A1		; A5=DOSBase
		MOVEQ		#37,D0
		MOVE.L		SysBase,A6
		JSR		(_LVOOpenLibrary,A6)
		MOVE.L		d0,DOSBase
		BEQ.W		.nodoslib

		LEA		(Template,PC),A1		; Argumente parsen
		MOVE.L		A1,D1
		LEA		(ArgsEntry0,PC),A1
		MOVE.L		A1,D2
		MOVEQ		#0,D3
		move.L		DOSBase,A6
		JSR		(_LVOReadArgs,A6)
		LEA		(ArgsHandle,PC),a0
		MOVE.L		D0,(a0)
		BNE.B		.argsoks

		JSR		(_LVOIoErr,A6)			; ReadArgs failed
		MOVE.L		D0,D1                  		; print reason
		MOVEQ		#0,D2
		JSR		(_LVOPrintFault,A6)
		BRA.B		.quit

.argsoks	MOVEQ		#0,D0	; Check Signals
		MOVE.L		D0,D1
		move.L		SysBase,A6
		JSR		(_LVOSetSignal,A6)

		BTST		#SIGBREAKB_CTRL_C,D0
		BEQ.B		.noctrlC

		MOVE.L		#304,D1
		MOVEQ		#0,D2
		move.L		DOSBase,A6
		JSR		(_LVOPrintFault,A6)
		BRA.B		.quit

.noctrlC	MOVEQ		#0,D7                  		; RC=0

		MOVEQ		#8,D0				; $80000 Bytes alloc
		SWAP		D0
		MOVEQ		#(MEMF_PUBLIC|MEMF_CHIP),D1
		move.L		SysBase,A6
		JSR		(_LVOAllocMem,A6)
		move.L		D0,KickMem
		TST.L		d0				; A3=KickMem
		BEQ.W		.quit

		move.L		(ArgsEntry0,PC),d1		; File öffnen
		MOVE.L		#MODE_OLDFILE,D2
		move.L		DOSBase,A6
		JSR		(_LVOOpen,A6)
		MOVE.L		D0,D6	; D6=FileHandle
		BEQ.W		.freeMem

		MOVE.L		D6,D1				; 16 Bytes einlesen
		MOVE.L		KickMem,D2
		MOVEQ		#16,D3
		JSR		(_LVORead,A6)
		CMP.L		D3,D0
		BNE.W		.closefile

		move.L		#$F80000,A2			; Kickfile Hdr == "ROM" Hdr
		MOVE.L		(A2),D0
		CMP.L		(KickMem),D0
		BNE.W		.wrongKick

		MOVE.L		(4,A2),D0
		CMP.L		(4,KickMem),D0
		BNE.B		.wrongKick

		MOVE.L		(8,A2),D0
		CMP.L		(8,KickMem),D0
		BNE.B		.wrongKick

		MOVE.L		(12,A2),D0			; ROM Ver != File Ver
		CMP.L		(12,KickMem),D0
		BNE.B		.seekBegin

                MOVE.L		(ArgsEntry1,PC),d0		; Force mapping
		BEQ.B		.closefile              	; for same version

.seekBegin	MOVE.L		D6,D1	; Seek to File Start
		MOVEQ		#0,D2
		MOVEQ		#OFFSET_BEGINING,D3
		move.L		DOSBase,A6
		JSR		(_LVOSeek,A6)

		MOVE.L		D6,D1				; Read Kick to buffer
		MOVE.L		KickMem,D2
		MOVEQ		#8,D3
		SWAP		D3
		JSR		(_LVORead,A6)
		CMP.L		d3,D0
		BNE.B		.closefile

		move.l		KickMem,a0
		jsr		(_CheckKickSum,pc)
		beq		.crcok

                MOVE.L		(ArgsEntry1,PC),d0		; Force mapping
		BNE.B		.crcok                 		; for same version

		LEA		(BadKickCRC,PC),A0
		MOVE.L		A0,D1
               	move.L		DOSBase,A6
		JSR		(_LVOPutStr,A6)
		MOVEQ		#20,D7				; RC=20
		bra		.closefile

.crcok		move.L		SysBase,A6			; Forbid MultiTasking
		JSR		(_LVOForbid,A6)

		MOVEQ		#75,D1				; Warten
		ADD.L		D1,D1
		move.L		DOSBase,A6
		JSR		(_LVODelay,A6)

		MOVEQ		#(CACRF_EnableI|CACRF_IBE),D0
		MOVEQ		#-1,D1
		move.L		SysBase,A6
		JSR		(_LVOCacheControl,A6)
		MOVE.L		D0,d5				; alte CACR Bits merken

		MOVE.L		KickMem,A0			; KickBuff -> a0
                tst.l           ArgsEntry2
                beq.s		.maprom
     		JSR		_Kick2060
     		BRA.s		.fail
.maprom
		JSR		_KickIt				; Will not return if works !!!!!

.fail
		LEA		(NoMapROM,PC),A0
		MOVE.L		A0,D1
               	move.L		DOSBase,A6
		JSR		(_LVOPutStr,A6)
		MOVEQ		#20,D7				; RC=20

		MOVE.L		d5,D0				; alte Bits wiederholen
		MOVEQ		#-1,D1
		move.l		SysBase,A6
		JSR		(_LVOCacheControl,A6)
		JSR		(_LVOPermit,A6)
		BRA.B		.closefile

.wrongKick	LEA		(InvalidKick,PC),A0
		MOVE.L		A0,D1
               	move.L		DOSBase,A6
		JSR		(_LVOPutStr,A6)
		MOVEQ		#20,D7	; RC=20

.closefile	MOVE.L		D6,D1
               	move.L		DOSBase,A6
		JSR		(_LVOClose,A6)

.freeMem	move.L		KickMem,A1
		MOVEQ		#8,D0
		SWAP		D0
		move.L		SysBase,A6
		JSR		(_LVOFreeMem,A6)

.quit		MOVE.L		(ArgsHandle,PC),D1
		BEQ.B		.noArgs
		move.L		DOSBase,A6
		JSR		(_LVOFreeArgs,A6)

.noArgs		move.L		a6,A1
		move.L		SysBase,A6
		JSR		(_LVOCloseLibrary,A6)

.nodoslib	MOVE.L		D7,D0
		RTS

****************************************************************************************************************
**	a0 = KickMem
**	d0 == 0 -> OK
****************************************************************************************************************

_CheckKickSum:	movem.l		d2,-(sp)

		MOVEQ		#0,D1			* Laufvaraiblen
		MOVEQ		#0,D0

		MOVE.L		#($80000/16)-1,D2

.loop		ADD.L		(A0)+,D0
		ADDX.L		D1,D0
		ADD.L		(A0)+,D0
		ADDX.L		D1,D0
		ADD.L		(A0)+,D0
		ADDX.L		D1,D0
		ADD.L		(A0)+,D0
		ADDX.L		D1,D0
		DBRA		D2,.loop

		ADDQ.L		#1,D0
		movem.l		(sp)+,d2
                TST.L   	d0
                RTS

****************************************************************************************************************

ArgsHandle	dc.l		0			; ReadArgs Stuff
ArgsEntry0	dc.l		0
ArgsEntry1      dc.l		0
ArgsEntry2      dc.l		0

doslibrary.MSG	dc.b	'dos.library',0
Template	dc.b	'FILE/A,F=FORCE/S,B2=B2060/S',0
		dc.b	'$VER: CyberMap 39.5 (29.03.96)\n'
		dc.b	'©1995,1996 by Carsten Schlote. Written for phase5 digital products.\r\n',0,0
InvalidKick	dc.b	'Invalid Kickstart file.',$A,0
BadKickCRC	dc.b	'Checksum failure on Kickimage.',$A,0
NoMapROM	dc.b	'No mapping hardware detected or hardware malfunction.',10,0


****************************************************************************************************************

INTFLAGS	equ	(INTF_TBE|INTF_DSKBLK|INTF_SOFTINT|INTF_PORTS|INTF_COPER|INTF_VERTB|INTF_BLIT|INTF_AUD0|INTF_AUD1|INTF_AUD2|INTF_AUD3|INTF_RBF|INTF_DSKSYNC|INTF_EXTER)

		SECTION		CyberMap_CyberStorm,CODE_C

_KickIt		MOVEM.L		A5/A6,-(SP)
		move.L		(4).W,A6
		LEA		(_KickSuperCode,PC),A5
		JSR		(_LVOSupervisor,A6)
		MOVEM.L		(SP)+,A5/A6
		RTS


_KickSuperCode
		ORI.W		#$700,SR		; Lock all IRQs !

		MOVE.B		#0,($DE0000).L		; Gary BootFlags = ColdStart
		MOVE.B		#0,($DE0001).L

		NOP
		MOVE.L		#1,($80F80000).L	; Trigger MapROM

		NOP     	                        ; Sync Pipelines
		MOVE.L		($7F80000).L,D0         ; Hat es funktioniert ?
		CMP.L		($F80000).L,D0
		BNE.B		.MapROMfail

		MOVE.L		D0,D1			; Zweiter Test...
		NOT.L		D1
		MOVE.L		D1,($7F80000).L
		CMP.L		($F80000).L,D1
		BEQ.B		.MapROMok

		MOVE.L		D0,($7F80000).L
.MapROMfail	MOVE.B		#$80,($DE0000).L	; Gray BootFlag = Warmstart
		RTE

.MapROMok	move.L		#$7F80000,A1		; KickImage kopieren
		MOVE.L		#$20000,D0
		BRA.B		.llentry

.llouter	SWAP		D0
.llinner	MOVE.L		(A0)+,(A1)+
.llentry	DBRA		D0,.llinner
		SWAP		D0
		DBRA		D0,.llouter

		MOVE.B		#$80,($DE0000).L        ; Gray BootFlag = ColdBoot
		MOVE.B		#$80,($DE0001).L

		MOVE.W		#INTF_INTEN,(_custom+intena).L	; Alle Interrupts aus
		MOVE.W		#INTFLAGS,(_custom+intreq).L    ; IRQ Requests löschen

                MOVE.L		#-1,(4).W		; ExecBase löschen

		LEA		($F80002).L,A0		; Reset Vector holen
		cnop		0,4
		RESET
		JMP		(A0)

****************************************************************************************************************
****************************************************************************************************************
****************************************************************************************************************
****************************************************************************************************************
*
*	%x000 01yy 1100 ---- ---- ---- ---- ----	Shadow Register Format
*                                                       x = Set/Clr Flag
*							y = Bank Number


MEMSHWREG	equ	$82c00000      	* Shadow Enable	Control Register
MYFC		equ	3		* Entry FC for Control Registers

		SECTION		CyberMap_Blizzard,CODE

_Kick2060	MOVEM.L		d0-d7/a0-A6,-(SP)
                move.l		(4).w,a6
		move.l          MemList(a6),d0		; get start of memory list
.nextnode:	NEXTNODE        d0,a2,.nofast		; Nächste Memnode holen, oder Ende
		move.l          MH_LOWER(a2),d1
		and.l		#$ffff0000,d1
                cmp.l		#$08000000,d1		; Richtige Node ????
                bne.s		.nextnode
                move.l		MH_UPPER(a2),a2		; Addresse des ShadowBereiches.
                move.l		a2,d0
		subq.l		#1,d0
		and.l		#$00f0000,d0		; so jetzt noch testen, ob das Ram auf eine 0.5 MB Grenze endet
		cmp.l		#$0070000,d0
		bne.l		.nofast			; wohl nicht, also ende.

		LEA		(_KickSuperCode2060,PC),A5	; der Rest im Supervisior Mode...
		JSR		(_LVOSupervisor,A6)
.nofast
		MOVEM.L		(SP)+,d0-d7/a0-A6
		RTS

********* a0 = Start of KickImage
********* a2 = Start of ShadowRam

_KickSuperCode2060:
		ORI.W		#$700,SR		; Lock all IRQs !
		movec		DFC,D7			; save old dfc
		moveq		#MYFC,D1
		movec		D1,DFC			; set new dfc

                moveq		#3,d0
		moveq		#0,d1      		; Der Reihe nach das Shadow deaktivieren
							; Nur eine Bank kann aktiv sein !!!!!
.shadowfind:
		bsr.s		_setmemshadow       	; Shadow für Bank <D0> aus
                bsr.s		_testmem		; a2=Shadowstart -> ist da jetzt RAM
                beq.s		.MapperOk
                dbra		d0,.shadowfind
.nobank	                                        	; Alle Bänke durchgespielt, kein RAM aufgetaucht.....
		movec		D7,DFC			;get back old dfc
		rte


.MapperOk	move.L		A2,A1			; KickImage kopieren (a0)->(a1)
		MOVE.L		#$20000,D4
		BRA.B		.llentry
.llouter	SWAP		D4
.llinner	MOVE.L		(A0)+,(A1)+
.llentry	DBRA		D4,.llinner
		SWAP		D4
		DBRA		D4,.llouter

		moveq		#1,d1
		bsr.s		_setmemshadow		; Shadow wieder an.

		movec		D7,DFC			; get back old dfc

		MOVE.W		#INTF_INTEN,(_custom+intena).L	; Alle Interrupts aus
		MOVE.W		#INTFLAGS,(_custom+intreq).L    ; IRQ Requests löschen

                MOVE.L		#-1,(4).W		; ExecBase löschen

		LEA		($F80002).L,A0		; Reset Vector holen
                cnop		0,4
		RESET
		JMP		(A0)



*********************************************************
*	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

_setmemshadow:
		movem.l		d0-d1/a6,-(sp)
		and.l		#3,D0
		ror.l		#6,D0			;shift in place
		ori.l		#MEMSHWREG,d0		;mask in MEMSHWREG adr
		tst.l		D1			;
		bne		shwnotset 		; =! 0 -> TRUE -> b28=0
		bset		#28,d0                  ; == 0 -> FALSE -> b28=1
shwnotset:
		move.l		D0,A6			; Write Register
		moves.l		A6,(A6)
		movem.l		(sp)+,d0-d1/a6
		rts

*********************************************************
* 	testmem
*	a2= shadow adr start
*********************************************************

_testmem:
		move.l		(a2),d4			; speicher retten
		move.l		4(a2),d5
		move.l		#$DEADBEEF,(a2)         ; write test long
		nop
		move.l          #$CAFECAFE,4(a2)	; trash bus
		nop
		move.l		(a2),d6                 ; read testval long
		nop
		move.l		d4,(a2) 		; restore memory
		move.l		d5,4(a2)
		nop
		cmp.l		#$DEADBEEF,d6
		rts

		END


