home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
programs
/
system
/
cpuclear
/
source.lha
/
sources
/
CPUClr.asm
next >
Wrap
Assembly Source File
|
1992-10-20
|
16KB
|
423 lines
;****** Auto-Revision Header (do not edit) *******************************
;*
;* © This is Freeware (All rights are reserved by Peter Simons!)
;*
;* Filename : CpuClr.asm
;* Created on : 23-Jul-92
;* Created by : Peter Simons
;* Current revision : V3.100
;*
;*
;* Purpose: This program replaces the system-routine BltClear() with a
;* highly optimized 68020/30/40 routine.
;*
;*
;* V3.100 : released in: Kickstart-Magazin, Germany
;* Peter Simons (20-Okt-92)
;*
;* V3.005 : added a "40" in the version-string, if the SPECIAL40-flag
;* is set.
;*
;* V3.004 : rescuing registers before WaitBlit() is unnecessary :-)
;*
;* V3.003 : added special-68040-switch for safety (When set, the copyback
;* is flushed after the clear-loop.)
;*
;* V3.002 : didn't rescue the registers before jumping into WaitBlit()
;*
;* V3.001 : used the wrong address-register in the copy-routine for
;* long-aligned blocksize and word-aligned blockaddress
;* Thanks to Stefan Thielscher for reporting.
;*
;* V3.000 : The new "perfect" version has been sold to the Kickstart-
;* computer-magazin, Germany. Thanks for allowing me to
;* distribute it via Fred Fish!
;* Peter Simons (17-Okt-92)
;*
;* V2.104 : Fixed nasty bug, that caused NewBltClear() to crash with very
;* small block-sizes.
;* Thanks to Stefan Thielscher for reporting.
;*
;* V2.103 : Rewrote NewBltClear() completely! The clear-loop now clears
;* as many long-words in a row as possible. This should maximize
;* performance.
;*
;* V2.102 : CPUClear used to trash the window, if the size was chosen
;* very small, so I added a WaitBlit().
;* Thanks to Franz Schwarz for reporting the bug and Chris Hames
;* for giving me the blitter-problem-hint!
;*
;* V2.101 : NewBltClr() has been rewritten completely for even more
;* performance. NewBltClr() now uses the longword-loop only, if
;* the address of the memoryblock is longword-aligned, not if
;* the size is.
;*
;* V2.100 : released: Peter Simons (03-Okt-92)
;*
;* V2.024 : changed short branches from ".s" to Motorola's ".b"-style
;*
;* V2.023 : added security-check to catch odd numbers of byte to clear
;*
;* V2.022 : changed the way, the end of the "blit" is recognized from
;* >BCC< to >BNE<. This saved 8 byte.
;*
;* V2.021 : test for zero-length-calls works now with bytes/row-mode, too
;*
;* V2.020 : Added a delay before the memory of NewBltClr() will be freed,
;* because this could possibly crash the machine if the new
;* routine is used while CPUClear tries to remove it.
;*
;* V2.011 : The last version included a trashed revision-date!
;* Peter Simons (23-Aug-92)
;*
;* V2.010 : added cache-flushing-routines for 68040 compatiblity
;*
;* V2.000 : Final version! (??) released: Peter Simons (24-Jul-92)
;*
;* V1.042 : fixed bug in CPU-recognition
;*
;* V1.040 : Changed addressing mode in clear-loop! Again saved a few
;* bytes and cyles...
;*
;* V1.034 : I corrected a few typing-errors in the sourcecode
;*
;* V1.033 : I called SetFunction() with wrong parameters, which caused
;* the machine to crash immediately. (I'll never find out why it
;* worked on my Amiga all the time?? Don't ask! It's magic!)
;*
;* V1.032 : Added secure/unsecure switch
;*
;* V1.031 : released: Peter Simons (24-Jul-92)
;*
;* V1.030 : saved again 4 bytes by changing the addressing mode in the
;* clear loop
;*
;* V1.028 : NewBltClr won't crash the machine any longer if a blocksize
;* of ZERO is specified
;*
;* V1.027 : NewBltClr has only one exit-point now --> saves some bytes
;*
;* V1.026 : saved one swap-command in long-align-routine
;*
;* V1.025 : fixed minor bug: SIZE % 4 = 0 was NOT recognized by NewBltClr
;*
;* V1.020 : deleted opcodes in size-calculation: clearing the upper word
;* was a waste, because MULU works only on WORD-size
;*
;* V1.011 : optimized output-routines and saved some bytes
;*
;* V1.010 : the way how the patch is installed, has been completely re-
;* written and is shorter and, in my eyes, system-friendlier...
;*
;* V1.006 : program won't crash, if no standard-output is available!
;* (for example, if started out of DME...)
;*
;* V1.005 : program checks for at least OS 2.04 and 68020 or higher
;*
;* V1.004 : changed program-output and added OS 2.0-version-string
;*
;* V1.003 : minor changes to the source-code
;* revision header added
;* changed to Macro68k-Assembler
;*
;* V1.002 : merged hunks --> program is position independent
;*
;* V1.001 : I continue development: Peter Simons (23-Jul-92)
;*
;* V1.000 : written by Oliver Wagner
;*
;* V0.000 : --- Initial release ---
;*
;*************************************************************************
;
;
;***************************************************************************
;* *
;* SEKTION: Labels, Macros, Switches, Structures *
;* *
;***************************************************************************
;-------------------------------------- Switches -----------
MC68000
EXEOBJ
OBJFILE "RAM:CPUClr"
NEWSYNTAX
SECURECODE set 1 ; test everything that could possibly
; crash the machine
SPECIAL40 set 0 ; flush copyback after clearing the memory
;-------------------------------------- Exec ---------------
eb_AttnFlags equ $0128
lib_Version equ $0014
MEMF_PUBLIC equ 1<<0
AF_68020 equ 1
;-------------------------------------- Labels -------------
MACLIB "DATAS:Offsets.preass"
KICKVERSION equ 37
_DOSBase equr A5
_GfxBase equr A4
_NewBltClr equr A3
_OutputHandle equr D7
;-------------------------------------- Macros -------------
REVISION MACRO
dc.b "3.100"
ENDM
REVDATE MACRO
dc.b "20-Okt-92"
ENDM
;***************************************************************************
;* *
;* SEKTION: Program *
;* *
;***************************************************************************
START: move.l ($4).w,a6
IFNE SECURECODE
cmp.w #KICKVERSION,(lib_Version,a6) ; Kickstart 2.04+ ?
bmi .ErrorExit
btst #AF_68020,(eb_AttnFlags+1,a6) ; 68020+ ?
beq .ErrorExit
ENDC
lea (dosname,PC),a1
jsr (_LVOOldOpenLibrary,a6) ; open Dos-Library
IFNE SECURECODE
tst.l d0
beq .ErrorExit
ENDC
move.l d0,_DOSBase
lea (gfxname,PC),a1
jsr (_LVOOldOpenLibrary,a6) ; open Graphics-Lib
IFNE SECURECODE
tst.l d0
beq .CloseDosLib
ENDC
move.l d0,_GfxBase
move.l _DOSBase,a6
jsr (_LVOOutput,a6) ; get standard-
move.l d0,_OutputHandle ; outputhandle
move.l _OutputHandle,d1
IFNE SECURECODE
beq.b .SkipWrite
ENDC
lea (Header,PC),a0 ; write standard-
move.l a0,d2 ; header
moveq #Header_len,d3
jsr (_LVOWrite,a6)
.SkipWrite move.l (_LVOBltClear+2,_GfxBase),_NewBltClr ; is the patch
cmp.l #'FAST',(new_ID,_NewBltClr) ; already installed?
beq.b .RemovePatch ; Yep->remove
;-------------------------------------- install patch ------
move.l #NewBltClr_len,d0
moveq #MEMF_PUBLIC,d1
move.l ($4).W,a6
jsr (_LVOAllocVec,a6)
IFNE SECURECODE
tst.l d0 ; Can't allocate
beq.b .CloseGfxLib ; buffer for new
ENDC ; routine
move.l d0,_NewBltClr
lea (NewBltClr,PC),a0
move.l _NewBltClr,a1 ; copy patch into
move.l #NewBltClr_len,d0 ; reserved buffer
jsr (_LVOCopyMem,a6)
jsr (_LVOForbid,a6)
move.l _GfxBase,a1
move.w #_LVOBltClear,a0 ; patch OS-function
move.l _NewBltClr,d0
jsr (_LVOSetFunction,a6)
move.l d0,(new_OldBltClr,_NewBltClr) ; save old vector
jsr (_LVOCacheClearU,a6) ; flush caches for
jsr (_LVOPermit,a6) ; '40 compatiblity
lea (Install,PC),a0 ; give feedback :-)
moveq #Install_len,d3
bra.b .exit
;-------------------------------------- remove patch -------
.RemovePatch move.l _GfxBase,a1
move.w #_LVOBltClear,a0
move.l (new_OldBltClr,_NewBltClr),d0
move.l ($4).W,a6
jsr (_LVOSetFunction,a6) ; replace old
move.l d0,a2 ; function and
; release memory
move.l _DOSBase,a6
moveq #100,d1
jsr (_LVODelay,a6)
move.l a2,a1
move.l ($4).W,a6
jsr (_LVOFreeVec,a6)
move.l _DOSBase,a6
lea (Remove,PC),a0
moveq #Remove_len,d3
;-------------------------------------- exit gracefully ----
.exit move.l _OutputHandle,d1
IFNE SECURECODE
beq.b .CloseGfxLib
ENDC
move.l a0,d2
move.l _DOSBase,a6
jsr (_LVOWrite,a6)
move.l _OutputHandle,d1
lea (Returns,PC),a0
move.l a0,d2
moveq #Returns_len,d3
jsr (_LVOWrite,a6)
.CloseGfxLib move.l _GfxBase,a1
move.l ($4).W,a6 ; close resources
jsr (_LVOCloseLibrary,a6) ; and leave
.CloseDosLib move.l _DOSBase,a1
jsr (_LVOCloseLibrary,a6)
.ErrorExit moveq #0,d0
rts
;***************************************************************************
;* *
;* SEKTION: new BltClear()-Routine *
;* *
;***************************************************************************
NewBltClr: ; A1=&MemBlock A6=&GraphicsLibraryBase
; D0=bytecount D1=flags
move.l d2,a0 ; save register
btst #1,d1 ; bytes per row?
beq.b .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.b .finished ; Nope -> Exit!
moveq #0,d2 ; clear memory or fill with
btst #2,d1 ; pattern??
beq.b .DataOK
move.l d1,d2
swap d1 ; --> fill with pattern
move.w d1,d2
.DataOK jsr (_LVOWaitBlit,a6) ; syncronisation!
btst #1,d0
beq.b .LongSize
move.w a1,d1
btst #1,d1
bne.b .WordNotEasy
subq.l #2,d0
beq.b .GoOn1
... move.l d2,(a1)+ ; blocksize word-aligned
subq.l #4,d0 ; memoryblock long-aligned
bne.b ...
.GoOn1 move.w d2,(a1)+
bra.b .finished
.WordNotEasy move.w d2,(a1)+ ; blocksize word-aligned
subq.l #2,d0 ; memoryblock word-aligned
beq.b .finished
... move.l d2,(a1)+
subq.l #4,d0
bne.b ...
bra.b .finished
.LongSize move.w a1,d1
btst #1,d1
bne.b .LongNotEasy
... move.l d2,(a1)+ ; blocksize and memoryblock
subq.l #4,d0 ; both long-aligned
bne.b ...
.finished move.l a0,d2
IFNE SPECIAL40
pea (a6)
move.l ($4).w,a6
jsr (_LVOCacheClearU,a6) ; write back memory on '40
move.l (SP)+,a6
ENDC
rts
.LongNotEasy move.w d2,(a1)+
subq.l #4,d0 ; long-aligned blocksize
bmi.b .finished ; word-aligned memoryblock
... move.l d2,(a1)+
subq.l #4,d0
bne.b ...
move.w d2,(a1)+
bra.b .finished
cnop 0,4
new_ID equ (*-NewBltClr) ; Offsets for routine-ID and
.ID dc.l "FAST" ; buffer for OldBltClr
new_OldBltClr equ (*-NewBltClr)
.OldBltClr dc.l 0
NewBltClr_len equ (*-NewBltClr) ; length of routine
;***************************************************************************
;* *
;* SEKTION: Daten, Zeiger *
;* *
;***************************************************************************
gfxname dc.b "graphics.library",0
dosname dc.b "dos.library",0
IFNE SECURECODE
Header dc.b $9B,"1;33",$6D
dc.b "$VER: CPUClr"
IFNE SPECIAL40
dc.b "40"
ENDC
dc.b " "
REVISION
dc.b " ("
REVDATE
dc.b ")"
dc.b $9B,$6D
dc.b " coding by Peter Simons",$0A
Header_len equ (*-Header)
ELSE
dc.b "$VER: "
Header dc.b "CPUClr"
IFNE SPECIAL40
dc.b "40"
ENDC
dc.b " "
REVISION
dc.b ": "
Header_len equ (*-Header)
ENDC
Install dc.b "Installed"
Install_len equ (*-Install)
Remove dc.b "Removed"
Remove_len equ (*-Remove)
Returns dc.b "...",$0A,$0A
Returns_len equ (*-Returns)
END