; FILE: Source:modules/AlertFix.ASM          REV: 3 --- cool Alert fix for 040/060

;
; AlertFix patch for BlizKick ("patch" Module)
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;
; This patch fixes the problems with pending alerts & 680x0.library
; being resident in blizzppc flash. Probably only useful with
; Blizzard PPC boards.
;
; Written by Harry "Piru" Sintonen.
; This source code is Public Domain.

	include	"blizkickmodule.i"	; Some required...

	SECTION	PATCH,CODE
_DUMMY_LABEL
	BK_PTC

; Code is run with following incoming parameters:
;
; a0=ptr to ROM start (buffer)	eg. $1DE087B8
; a1=ptr to ROM start (ROM)	eg. $00F80000 (do *not* access!)
; d0=ROM lenght in bytes	eg. $00080000
; a2=ptr to _FindResident routine (will search ROM buffer for resident tag):
;    CALL: jsr (a2)
;      IN: a0=ptr to ROM, d0=rom len, a1=ptr to resident name
;     OUT: d0=ptr to resident (buf) or NULL
; a3=ptr to _InstallModule routine (can be used to plant a "module"):
;    CALL: jsr (a3)
;      IN: a0=ptr to ROM, d0=rom len, a1=ptr to module, d6=dosbase
;     OUT: d0=success
; a4=ptr to _Printf routine (will dump some silly things (errormsg?) to stdout ;-)
;    CALL: jsr (a4)
;      IN: a0=FmtString, a1=Array (may be 0), d6=dosbase
;     OUT: -
; d6=dosbase, a6=execbase
;
; Code should return:
;
; d0=true if succeeded, false if failed.
; d1-d7/a0-a6 can be trashed. a7 *must* be preserved! ;-)

	moveq	#0,d7

	cmp.w	#37,($C,a0)		;requires V37+ rom image
	blo	.exit

	lea	(regs,pc),a5
	movem.l	d0/a0-a4,(a5)

	lea	(.resname,pc),a1
	movem.l	(regs,pc),d0/a0
	move.l	(findresident,pc),a2
	jsr	(a2)
	lea	(.nores,pc),a1
	tst.l	d0
	beq	.err

	move.l	d0,a2
	move.l	(RT_INIT,a2),a2
	;test if inside rom bounds?
	move.l	(rom_log,pc),d0
	cmp.l	d0,a2
	blo.b	.nofix
	add.l	(rom_size,pc),d0
	cmp.l	d0,a2
	bhs.b	.nofix
	; inside rom, so generate ram buffer address
	sub.l	(rom_log,pc),a2		-$f80000
	add.l	(rom_phys,pc),a2	+buffer
.nofix
	lea	(.badres,pc),a1
	cmp.l	#$42B80000,(a2)
	bne	.err
	cmp.w	#$48E7,(4,a2)
	bne	.err
	cmp.w	#$242E,(8,a2)
	move.l	a2,d2

	move.w	#1024/2,d0
.find	subq.w	#1,d0
	beq	.err
	addq.l	#2,a2
	cmp.l	#$42B80000,(a2)
	bne.b	.find
	cmp.w	#$70FF,(4,a2)
	bne.b	.find
	move.l	a2,d3

	lea	(.badrom,pc),a1
	move.l	(rom_phys,pc),a2
	move.w	#32768/2,d0
.find2	subq.w	#1,d0
	beq	.err
	addq.l	#2,a2
	cmp.l	#$203C<<16|'HE',(a2)
	bne.b	.find2
	cmp.l	#'LP'<<16|$B0B8,(4,a2)
	bne.b	.find2
	cmp.l	#$21C00000,(12,a2)
	bne.b	.find2
	cmp.l	#$41F80100,(16,a2)
	bne.b	.find2

	; finally ready for patching

	movem.l	(regs,pc),d0/a0
	lea	(_AlertFix_module,pc),a1
	move.l	(installmodule,pc),a3
	jsr	(a3)

	movem.l	(regs,pc),d0/a0
	lea	(_name,pc),a1
	move.l	(findresident,pc),a3
	jsr	(a3)

	lea	(.plantfail,pc),a1
	tst.l	d0
	beq.b	.err

	move.l	d0,a3
	move.l	(RT_INIT,a3),a3

	;lea	(_ahook1-_init,a3),a1
	move.l	d2,a0
	move.w	#$4EB9,(a0)+
	;move.l	a1,(a0)+
	move.l	a3,(a0)+
	move.w	(a0),(_movemregs-_init,a3)

	lea	(_ahook2-_init,a3),a1
	move.l	d3,a0
	move.w	#$4EB9,(a0)+
	move.l	a1,(a0)+

	lea	(_alert1-_init,a3),a1
	move.w	#$4EB9,(a2)+
	move.l	a1,(a2)+

	lea	(_alert2-_init,a3),a1
	addq.l	#6,a2
	move.w	#$4EB9,(a2)+
	move.l	a1,(a2)+

	moveq	#1,d7

.err	tst.l	d7
	bne.b	.exit
	lea	(.errh,pc),a0
	move.l	a1,-(sp)
	move.l	sp,a1
	move.l	(printf,pc),a2
	jsr	(a2)
	addq.l	#4,sp
.exit	move.l	d7,d0
	rts


.resname	dc.b	'alert.hook',13,10,0

.errh	dc.b	'AlertFix: couldn''t %s!',10,0

.nores	dc.b	'find alert.hook',0
.badres	dc.b	'patch alert.hook',0
.badrom	dc.b	'patch Alert()',0
.plantfail	dc.b	'InstallModule(), add some EXTRESBUF',0

	CNOP	0,2
_AlertFix_module
 BK_MOD BKMF_SingleMode!BKMF_ExtResBuf,_end,(0)<<24+37<<16+NT_UNKNOWN<<8+(256-54),_name,_idstr,_init

; Singlemode on,
; never init this module, requires KS V37.x or better, module type NT_UNKNOWN, priority -54.

_init	; this code will never be called directly!
_ahook1	move.l	(sp)+,d0
	movem.l	d2/d7/a2/a3/a6,-(sp)
_movemregs	EQU	*-2
	addq.l	#2,d0
	move.l	d0,-(sp)
	moveq	#0,d0
	sub.l	a0,a0
	bra.b	_write

_ahook2	moveq	#0,d0
	sub.l	a0,a0
	bsr.b	_write
	moveq	#-1,d0
	rts

_alert1	addq.l	#4,(sp)
	sub.l	a0,a0
	bsr.b	_read
	cmp.l	#'HELP',d0
	rts

_alert2	addq.l	#6,(sp)
	sub.l	a0,a0
	move.l	#'HELP',d0
	bsr.b	_write

	lea	($100).w,a0
	move.l	d7,d0
	bsr.b	_write
	move.l	a5,d0
	;bra.b	_write

;  IN: a0.l=address
;      d0.l=data
_write	movem.l	d1-d2/a5/a6,-(sp)
	move.l	(4).w,a6
	lea	(.write_s,pc),a5
	jsr	(-$1E,a6)
	movem.l	(sp)+,d1-d2/a5/a6
	move.l	d0,(a0)+		also write mmu dest
	rts
.write_s	movec	dfc,d2			store old dfc
	moveq	#0,d1			destination function code=0
	movec	d1,dfc
	moves.l	d0,(a0)			write bypassing MMU!
	movec	d2,dfc			restore old dfc
	nop				sync pipelines
	rte

;  IN: a0.l=address
; OUT: d0.l=data
_read	movem.l	d1/a5/a6,-(sp)
	move.l	(4).w,a6
	lea	(.read_s,pc),a5
	jsr	(-$1E,a6)
	movem.l	(sp)+,d1/a5/a6
	rts
.read_s	movec	sfc,d1			store old sfc
	moveq	#0,d0			source function code=0
	movec	d0,sfc
	moves.l	(a0)+,d0		read bypassing MMU!
	movec	d1,sfc			restore old sfc
	nop				sync pipelines
	rte

_name
_idstr	dc.b	'AlertFix.patchcode',0

	CNOP	0,2
_end


	CNOP	0,2
regs
rom_size	ds.l	1
rom_phys	ds.l	1
rom_log	ds.l	1
findresident	ds.l	1
installmodule	ds.l	1
printf	ds.l	1

	SECTION	VERSION,DATA

	dc.b	'$VER: AlertFix_PATCH 1.0 (12.11.99)',0

