	OPT 0

;
; PowerWindows Module
; ~~~~~~~~~~~~~~~~~~~~~
; This modules doubles the default stack from Processes created with CreateNewProc()
; from 4000 Bytes to 8000 Bytes.
;
; Written by Georg Steger <georg.steger@rolmail.net>
; This source code is Public Domain.
;

	incdir	"ainclude:"

	include graphics/layers.i
	include intuition/screens.i
	include lvo/exec_lib.i

	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! ;-)

	cmp.w	#39,($c,a0)
	bhs.b	cont

fail:
	moveq	#0,d0
	rts

cont:
	move.l	a0,a3
	add.l	d0,a3
	lea	(_IntuitionEnd,pc),a5
	move.l	a3,(a5)

	lea	(intname,pc),a1
	jsr	(a2)
	tst.l	d0
	beq.s	fail
	
	lea	(_IntuitionStart,pc),a0
	move.l	d0,(a0)
	
	lea	(_SetAddressPointer,pc),a0
	lea	(ADDRESSARRAY,pc),a1
	move.l	a1,(a0)

_PatchROM:
	lea	RomSearch(pc),a0
	lea	RomPatch(pc),a1
	move.l	#RomSearchEnd-RomSearch,d2
	bsr	DoPatch

	lea	RomSearch2(pc),a0
	lea	RomPatch2(pc),a1
	move.l	#RomSearch2End-RomSearch2,d2
	bsr	DoPatch

	lea	RomSearch3(pc),a0
	lea	RomPatch3(pc),a1
	move.l	#RomSearch3End-RomSearch3,d2
	bsr	DoPatch
	
	move.l	4.w,a6
	move.l	#LastROMPatch-FirstROMPatch+1,d0
	moveq	#0,d1
	jsr	_LVOAllocMem(a6)

	tst.l	d0
	beq.s	fail

	move.l	d0,a5

	move.l	d0,-(sp)
	move.l	sp,a1
	lea	string(pc),a0
	jsr	(a4)
	addq.l	#4,sp

	lea	(FirstROMPatch,pc),a0
	move.l	a5,a1
	move.l	#LastROMPatch-FirstROMPatch+1,d0
	jsr	_LVOCopyMem(a6)

	lea	(FirstROMPatch,pc),a0
	move.l	a5,a1

	move	#LastROMPatch-FirstROMPatch+1,d0
	lsr	#1,d0
	subq	#1,d0

.loop:
	move	(a0)+,(a1)+
	dbf	d0,.loop

	lea	(ADDRESSARRAY,pc),a0
	lea	(SETADDRESSARRAY,pc),a1

.loop2:
	move.l	(a0)+,a2
	move.l	(a1)+,d0
	bmi.s	.loopdone
	
	cmp.l	#0,a2
	beq.s	.loop2

	add.l	a5,d0
	move.l	d0,-4(a2)
	
	bra.s	.loop2

.loopdone:
	jsr	_LVOCacheClearU(a6)

.done:
	moveq	#1,d0
	rts

	
DoPatch:
	move.l	a1,-(sp)

	move.l	_IntuitionStart(pc),a1
	move.l	_IntuitionEnd(pc),a2
	move.l	d2,d0
	bsr	SearchRom

	move.l	(sp)+,a1
	
	tst.l	d0
	bne.s	.ok
	
;	move.l	_ErrTextPointer(pc),-(sp)
;	jsr	_printf
;	addq.l	#4,sp
	
	bra.s	.raus

.ok:
	move.l	d0,a0

.copy:
	move	(a1)+,d0
	cmp	#$AFFE,d0
	beq.s	.copydone
	move	d0,(a0)+
	bra.s	.copy
	
.copydone:
	move.l	_SetAddressPointer(pc),a1
	move.l	a0,(a1)

.raus:
;	addq.l	#4,_ErrTextPointer
	addq.l	#4,_SetAddressPointer
	rts
	
;/**************************************************/

FirstROMPatch:
	CNOP 0,2
	
ROMPatch_CheckWindowPos:	;'(a0 = screen)
	move.w	d0,6(a2)

	btst	#7,sc_LayerInfo+li_Flags+1(a0)
	beq.s	.raus

	move.l	a2,a0
	bsr.s	ROMPatch_Set

.raus:
	move.l	(a7)+,a2
	rts
	
;/* =================================================================== */

ROMPatch_CheckWindowSize:	;'(a0 = screen)
	sub.l	d1,d0
	move.w	d0,-10(a5)
	
	btst	#7,sc_LayerInfo+li_Flags+1(a0)
	beq.s	.raus

	lea	-16(a5),a0
	bsr.s	ROMPatch_Set

.raus:
	rts

;/* =================================================================== */

ROMPatch_CheckDragging:		;'(a1 = screen)
	sub.l   D1,D0
	move.w  D0,-6(A5)

	btst	#7,sc_LayerInfo+li_Flags+1(a1)
	beq.s	.raus

	lea	-12(a5),a0
	bsr.s	ROMPatch_Set

.raus:
	rts
	
ROMPatch_Set:
	move.l	#$C001C001,d0
	
	move.l	d0,(a0)+
	neg	d0
	swap	d0
	neg	d0
	move.l	d0,(a0)
	rts
	

	

LastROMPatch:

;/***************************************************/
	
RomSearch:
	movea.l $002E(A1),A0
	move.w  $000E(A0),D0
	ext.l   D0
	move.w  $000A(A1),D1
	ext.l   D1
	sub.l   D1,D0
	move.w  D0,$0006(A2)
	movea.l (A7)+,A2
	rts

RomSearchEnd:
	
RomPatch:
	movea.l $002E(A1),A0
	move.w  $000E(A0),D0
	ext.l   D0
	move.w  $000A(A1),D1
	ext.l   D1
	sub.l   D1,D0
	dc.w	$4EF9		;'jmp
	dc.l	ROMPatch_CheckWindowPos

RomPatchEnd:
	dc.w	$AFFE

;/***************************************************/

RomSearch2:
	move.w  D0,-12(A5)
	movea.l $002E(A2),A0
	move.w  $000E(A0),D0
	ext.l   D0
	move.w  $0006(A3),D1
	ext.l   D1
	sub.l   D1,D0
	move.w  D0,-10(A5)

RomSearch2End:

RomPatch2:
	move.w  D0,-12(A5)
	movea.l $002E(A2),A0
	move.w  $000E(A0),D0
	ext.l   D0
	move.w  $0006(A3),D1
	ext.l   D1
	dc.w	$4EB9	;'jsr
	dc.l	ROMPatch_CheckWindowSize
	
RomPatch2End:	
	dc.w	$AFFE


;/***************************************************/

RomSearch3:
	movea.l D2,A1
	move.w  $000C(A1),D0
	ext.l   D0
	move.w  $0008(A3),D1
	ext.l   D1
	sub.l   D1,D0
	move.w  D0,-8(A5)
	move.w  $000E(A1),D0
	ext.l   D0
	move.w  $000A(A3),D1
	ext.l   D1
	sub.l   D1,D0
	move.w  D0,-6(A5)

RomSearch3End:


RomPatch3:
	movea.l D2,A1
	move.w  $000C(A1),D0
	ext.l   D0
	move.w  $0008(A3),D1
	ext.l   D1
	sub.l   D1,D0
	move.w  D0,-8(A5)
	move.w  $000E(A1),D0
	ext.l   D0
	move.w  $000A(A3),D1
	ext.l   D1
	dc.w	$4EB9	;'jsr
	dc.l	ROMPatch_CheckDragging

RomPatch3End:	
	dc.w	$AFFE


;/* =================================================================== */

SearchRom:	;'a0 = what  a1 = startsearch  a2 = endsearch  d0 = searchsize
	movem.l	d2/a2-a4,-(sp)

	sub.l	d0,a2
	lsr	#1,d0
	subq	#1,d0

.outerloop:
	move	d0,d1
	move.l	a0,a3
	move.l	a1,a4

.loop:
	cmpm.w	(a3)+,(a4)+
	bne.s	.next
	
	subq	#1,d1
	bpl.s	.loop
	bra.s	.found

.next:
	addq.l	#2,a1
	cmp.l	a2,a1
	bls.s	.outerloop
	moveq	#0,d0
	bra.s	.raus

.found:
	move.l	a1,d0

.raus:
	movem.l	(sp)+,d2/a2-a4
	rts

	
;/* =================================================================== */


_IntuitionStart:
	dc.l	0

_IntuitionEnd:
	dc.l	0

_SetAddressPointer:
	dc.l 	0

ADDRESSARRAY:
	dc.l	0,0,0

SETADDRESSARRAY:
	dc.l	ROMPatch_CheckWindowPos-FirstROMPatch
	dc.l	ROMPatch_CheckWindowSize-FirstROMPatch
	dc.l	ROMPatch_CheckDragging-FirstROMPatch
	dc.l	-1
						
;***************************************************************************

intname:
	dc.b	'intuition.library',0

string: dc.b 'PowerWindows at ram %x\n',0

;***************************************************************************


	SECTION	VERSION,DATA

	dc.b	'$VER: PowerWindows_PATCH 0.9 (08.08.99)',0

	END

