;!OPT -m
;!CPY LCP:CPUClr
;
;CpuClr V4.0
;Based on my CpuClr V2.5 and CpuClear V3.100 by Peter Simons
;
;
;-------------------------------------- Includes -----------
	include "patchtags.i"

;-------------------------------------- Exec ---------------
eb_AttnFlags    equ     $0128
lib_Version     equ     $0014

AF_68020        equ     1

;-------------------------------------- Labels -------------
execbase	equ	4
_DOSBase        equr    A5
_PATCHBase      equr    A4

_LVOFindPatch		equ	-48	;patch.library
_LVOInstallPatchTagsA	equ	-54
_LVORemovePatchTagsA	equ	-60

_LVOBltClear		equ	-300	;graphics.library
_LVOWaitBlit		equ	-228

_LVOCacheClearU		equ	-636	;exec.library
_LVOOpenLibrary		equ	-552
_LVOCloseLibrary	equ	-414

;-------------------------------------- Macros -------------
REVISION        MACRO
                dc.b "4.0"
                ENDM
REVDATE         MACRO
                dc.b "23.03.94"
                ENDM


Main:
	sub.l	_DOSBase,_DOSBase
	sub.l	_PATCHBase,_PATCHBase
	move.l	execbase,a6
	btst	#AF_68020,eb_AttnFlags+1(a6)   ; 68020+ ?
	beq	CPUFailed

	lea.l	dosname(pc),a1		;Open Dos Library
	moveq.l	#0,d0
	jsr	_LVOOpenLibrary(a6)
	tst.l	d0
	beq	DosFailed
	move.l	d0,_DOSBase

	lea.l	Header(pc),a0		;Print Title Text
	bsr	TextOutput

	lea.l	patchname(pc),a1	;Open Patch Library Version 2
	moveq.l	#2,d0
	jsr	_LVOOpenLibrary(a6)
	tst.l	d0
	beq	PatchFailed
	move.l	d0,_PATCHBase

	lea.l	IDString(pc),a0		;Is Patch Installed
	move.l	_PATCHBase,a6
	jsr	_LVOFindPatch(a6)
	tst.l	d0
	beq	install			;No ->install

	move.l	d0,a0			;Remove Patch
	lea.l	RemoveTags(pc),a1
	jsr	_LVORemovePatchTagsA(a6)
	lea.l	RemoveText(pc),a0
	tst.l	d0
	beq	exit
	lea.l	RemoveFailText(pc),a0
	bra	exit

install:
	lea.l	InstallTags(pc),a1

	lea.l	gfxname(pc),a0
	move.l	a0,4(a1)
	lea.l	IDString(pc),a0
	move.l	a0,12(a1)

	lea.l	NewBltClr(pc),a0
	move.l	#_LVOBltClear,d0
	jsr	_LVOInstallPatchTagsA(a6)
	lea.l	InstalledText(pc),a0
	tst.l	d0
	bne	exit
	lea.l	InstallFailText(pc),a0

exit:
	bsr	TextOutput
	move.l	execbase,a6
	move.l	_PATCHBase,a1
	jsr	_LVOCloseLibrary(a6)		;Close patch Library

PatchFailed:
	cmp.l	#0,_PATCHBase
	bne	PatchFailedSkip
	lea.l	ReqPatchLib(pc),a0
	bsr	TextOutput

PatchFailedSkip:
	move.l	execbase,a6
	move.l	_DOSBase,a1
	jsr	_LVOCloseLibrary(a6)		;Close dos Library
DosFailed:
CPUFailed:
	rts
******************************************************************V1.3*
* Name:		TextOutput
* Function:	Writes a C-string to std output (CLI,PRT,...)
* Version:	V1.2	(works)
* Assembler:	MasterSeka V1.75 & OMA V1.81
* Copyright:	1991 Stefan Fuchs
*
* Inputs:	a0 = Pointer to a C-string
* Assumptions:	DosBase
* Results:	
* Destroyed registers:
* Code:		pc-relative
* Known bugs:	
* See also:	
* Notes:	Exits without any output,
*		if the Outputhandle or a0 is null
***********************************************************************
TextOutput:
	movem.l d0-d3/a0/a1/a6,-(sp)
	moveq.l #0,d3
	move.l a0,d2
	beq.s TextOutputExit
TextOutputLoop:
	addq.l #1,d3
	tst.b (a0)+
	bne.S TextOutputLoop
	move.l _DOSBase,a6
	jsr -60(a6)	;OutPut
	move.l d0,d1
	beq.s TextOutputExit
	jsr -48(a6)	;Write
TextOutputExit:
	movem.l (sp)+,d0-d3/a0/a1/a6
	rts
;------------------------------------------------------------------------
NewBltClr:                      ; A1=&MemBlock A6=&GraphicsLibraryBase
                                ; D0=bytecount D1=flags

                move.l  d2,a0                   ; save register
                btst    #1,d1                   ; bytes per row?
                beq     ByteSize                ; Nope -> length is alright
                move.l  d0,d2                   ; Yep  -> calc size of block
                swap    d2
                mulu.w  d2,d0
ByteSize:	bclr    #0,d0                   ; only even number of bytes
                tst.l   d0                      ; bytecount > 0 ?
                beq	Finished                ; Nope -> Exit!

                moveq   #0,d2                   ; clear memory or fill with
                btst    #2,d1                   ; pattern??
                beq	DataOK
                move.l  d1,d2
                swap    d1                      ; --> fill with pattern
                move.w  d1,d2
DataOK:         jsr	_LVOWaitBlit(a6)        ; syncronisation!

		cmp.l 	#100,d0
		bhi	FewStuffSkip


;This routine will only be called, if only a few bytes have to be cleared (NO Overhead!)
		lsr.l	#1,d0
		subq.l	#1,d0
Loop0:		move.w	d2,(a1)+
		dbra	d0,Loop0
		bra	Finished


FewStuffSkip:
		add.l	d0,a1
                move.w  a1,d1
                btst    #1,d1			; Longword aligned?
                beq	LongAlignSkip
		move.w	d2,-(a1)		; No -> Clear a word
		subq.l	#2,d0
		beq	Finished

LongAlignSkip:	move.l	d0,d1
		cmp.l 	#400,d0
		blo	LotsOfStuffSkip


;This routine will only be called, if lots of bytes have to be cleared (Overhead!)
                movem.l	d3-d5,-(SP)
		move.l	d2,d3
		move.l	d2,d4
		move.l	d2,d5
		lsr.l 	#4,d0
		subq.l	#1,d0
Loop2:		movem.l	d2-d5,-(a1)		; ClearLoop
		dbra	d0,Loop2		; dbra limits the max size to clear
						; to 1MB, but i don't think that's
						; a problem
                movem.l	(SP)+,d3-d5
		move.l	d1,d0
		and.l	#%1100,d0
		beq	LastWord


LotsOfStuffSkip:
		lsr.l	#2,d0			; calculate number of LWs
		subq.l	#1,d0
Loop:		move.l	d2,-(a1)		; ClearLoop
		dbra	d0,Loop

LastWord:	btst    #1,d1			; Still a Word to clear?
                beq	LongAlignSkip2
		move.w	d2,-(a1)		; Clear it

LongAlignSkip2:
Finished:       move.l  a0,d2
                pea     (a6)
		move.l	execbase,a6
                cmp.w   #37,lib_Version(a6)	; Kickstart 2.04+ ?
                bmi     Exit
                jsr	_LVOCacheClearU(a6)     ; write back memory on '40
Exit:		move.l  (SP)+,a6
                rts

NewBltClr_len   equ     (*-NewBltClr)           ; length of routine

;----------------------------------------------------------------------
InstallTags:	dc.l PATT_LibraryName,0
		dc.l PATT_PatchName,0
		dc.l PATT_NewCodeSize,NewBltClr_len
		dc.l 0
RemoveTags:	dc.l PATT_TimeOut,50
		dc.l 0

gfxname         dc.b    "graphics.library",0
dosname         dc.b    "dos.library",0
patchname	dc.b	"patch.library",0
Header          dc.b    $9B,"1;33",$6D
                dc.b    "$VER: CPUClr"
                dc.b    " "
                REVISION
                dc.b    " ("
                REVDATE
                dc.b    ")"
                dc.b    $9B,$6D
                dc.b    " by Stefan Fuchs",10,0
ReqPatchLib:	dc.b "*** Requires patch.library V2+ in libs:",10,0
InstalledText:	dc.b "Patch successfully installed",10,0
InstallFailText:dc.b "*** Failed to install patch",10,0
RemoveText:	dc.b "Patch successfully removed",10,0
RemoveFailText:	dc.b "*** Failed to remove patch",10,0
IDString:	dc.b "CPUClr",0

                END
