	opt	l-,c+	; no link, case dependant, must be on first line!
*---------------------------------------------------------------------------
*    :Program.    PatchMrg.s
*    :Contents.	  Korrigiert die Routine Graphics.MrgCop
*    :Author.     Bernd Preusing
*    :Address.	  Gerhardstr. 16  D-2200 Elmshorn
*    :Phone.	  04121/22486
*    :Copyright.  Public Domain
*    :Language.	  68000-Assembler
*    :Translator. DevPac 2.11
*    :History.	  V 1.1  20-May-89
*    :Imports.	  CreatePort.i (Meine Macros)
*    :Bugs.	  none
*    :Remark.     Norddeutschlands Antwort auf OverScnTrouble (Amok #1)
*    :Remark.	  Fehler trat auf bei Hires-4Planes-Overscan
*    :Usage.	  Starten vom CLI oder Workbench, nochmaliges Starten
*    :Usage.	  macht alles wieder rückgängig.
*---------------------------------------------------------------------------

	incdir	"a:devpac/include/"	where to look
 nolist
	include exec/exec.i
	include	exec/exec_lib.i		I want to call EXEC
	include graphics/graphics_lib.i
	include misc/easystart.i ; Workbench-CLI-Interface
	include misc/CreatePort.i ; meine Macros CreatePort, DeletePort
	include libraries/dos_lib.i
; list


start
	lea	grafname,a1
	moveq	#0,d0
	CALLEXEC OpenLibrary
	move.l	d0,_GfxBase		save pointer
	beq	quit_err
	lea	dosname,a1
	moveq	#0,d0
	CALLSYS OpenLibrary
	move.l	d0,_DOSBase
	beq	quit_err

	lea	PortName,a1
	CALLSYS FindPort
	tst.l	d0
	beq.s	MakeIt

; Port schon da, also löschen
	move.l	d0,a3
	move.l	MP_SIGTASK(A3),A4 ; code-addr
	move.l	OldFunc-MrgCop(A4),d0
	move.l	_GfxBase,A1
	move.w	#_LVOMrgCop,a0
	CALLSYS SetFunction
	move.l	Size-MrgCop(A4),d0
	move.l	a4,a1
	CALLSYS FreeMem
	DeletePort a3 ; löscht auch mein Signal, aber ich habe ja keins
	lea	UnpMsg,a5
	moveq	#UnpLen,d5
	bra	quit_ok

MakeIt:
	move.l	#MrgEnd-MrgCop,D0
	moveq	#MEMF_PUBLIC,D1
	CALLEXEC AllocMem
	move.l	d0,CodeMem
	beq	quit_err
	move.l	d0,a4

	move.l	d0,A1
	move.l	#MrgCop,A0
	move.l	#MrgEnd-MrgCop,D0
	CALLSYS CopyMem
	
	move.l	a4,a0
	add.w	#PortName-MrgCop,a0
	CreatePort (a0),0 ; wg. lea
	move.l	d0,a3
	move.l	d0,MyPort
	beq.s	quit_err

	move.l	_GfxBase,A1
	move.w	#_LVOMrgCop,a0
	move.l	a4,d0
	CALLSYS SetFunction
	move.l	d0,OldFunc-MrgCop(A4)
	move.l	#MrgEnd-MrgCop,Size-MrgCop(A4)
	move.l	a4,MP_SIGTASK(A3)
	lea	PMsg,a5
	moveq	#PLen,d5
quit_ok:
	moveq	#0,D4
CloseAll:
	move.l	a6,-(a7)
	CALLDOS Output
	tst.l	d0
	beq.s	NoOutput
	move.l	d0,d1
	move.l	a5,d2
	move.l	d5,d3
	CALLDOS Write
NoOutput:
	move.l	(a7)+,a6
	move.l	_GfxBase,d0
	beq.s	NoGfx
	move.l	d0,a1
	CALLSYS CloseLibrary
NoGfx
	move.l	_DOSBase,d0
	beq.s	NoDos
	move.l	d0,a1
	CALLSYS	CloseLibrary
NoDos:
	move.l	D4,d0
	rts

quit_err:
	move.l	CodeMem,d0
	beq.s	NoCodeMem
	move.l	d0,a1
	move.l	#MrgEnd-MrgCop,d0
	CALLSYS FreeMem
NoCodeMem:
	move.l	MyPort,d0
	beq.s	NoPort
	DeletePort d0
NoPort:
	moveq	#10,D4
	lea	ErrMsg,a5
	moveq	#ErrLen,d5
	bra.s	CloseAll

;============================================================
	section	Merge,code

; disass kick 1.3 bp 16.5.89
; für fehler overscan nur bis vpos 256

MrgCop:
	bra	MrgCop2
OldFunc:	dc.l 0 ; alter MrgCop-Sprung
Size:		dc.l 0 ; Code-Länge für FreeMem
PortName: dc.b 'PatchMrgCop_1.1',0

; Die folgenden Unterprogramme sind aus Kickstart 1.3 extrahiert.
; Alle JSR sind in BSR umgewandelt, um es PC-relativ zu machen.
; 2 Fehler sind korrigiert und einige sehr kleine Optimierungen
; vorgenommen worden. Der ViewPtr kommt nun direkt in A1 statt Stack


; Diese Routine sucht beim Wait-Splitting den richtigen X-Wert, hier
; ist auch die Sonderbehandlung für 4-Plane-OverScan-Hires.
; (WAIT 300,20 wird zu WAIT 255,?? und WAIT 44,20)
; Hierin war ein kleinerer Fehler, der aber nur bei Address-Überlauf
; über eine Wortgrenze auftritt.
; Liefert Wert von DDFSTART, wenn Hires und 4 Planes und DDFSTOP=$D4,
; sonst immer 222.
; Ich weiß nicht genau, warum (vielleicht DMA-Timing?), aber es funktioniert!
LFCA3F0:
FindX:
	MOVEM.L	D2-5,-(A7)
	MOVEA.L	$14(A7),A0
	CLR.W	D5		; Flag: 1. Suche
	MOVEA.L	#$DFF000,A1
	MOVE.L	4(A0),D3
	MOVE.l	D3,D1		; korrigiert, war .W-Arithmetik!!!
	SUB.l	$1C(A0),D1	; war sub.w $1E(a0),d1
	MOVE.W	D1,D4		; hier kann .w bleiben
	ASR.W	#2,D4		; /4 = Anzahl Cpr-Instruktionen
	LEA	$100(A1),A0
	MOVE.W	A0,D0
	ANDI.W	#$1FE,D0	; 1.: suche MOVE ??,BPLCON0
	BRA.S	LFCA46E

LFCA41A	SUBQ.L	#2,D3
	MOVEA.L	D3,A0
	MOVE.W	(A0),D2
	SUBQ.L	#2,D3
	MOVEA.L	D3,A0
	MOVE.W	(A0),D1
	CMP.W	D0,D1
	BNE.S	LFCA46E		; Wert nicht gefunden, weitersuchen
	MOVE.W	D5,D1
	BLE.S	LFCA43C		; 1. Suche: BPLCON0
	CMPI.W	#1,D1
	BEQ.S	LFCA456		; 2. Suche: DDFSTOP
	CMPI.W	#2,D1
	BLT.S	LFCA46E		; Blödsinn: ist schon abgefragt
	BRA.S	LFCA46C		; 3. Suche: DDFSTART

; 1. Suche erfolgreich, BPLCON0 gefunden
LFCA43C	ANDI.W	#$F000,D2
	CMPI.W	#$C000,D2	; Hires und 4 Planes?
	BEQ.S	LFCA448		; ja, weitermachen
	BRA.S	LFCA476		; nein, RETURN 222
LFCA448	LEA	$94(A1),A0
	MOVE.W	A0,D0
	ANDI.W	#$1FE,D0	; 2. Suche: DDFSTOP
	MOVEQ	#1,D5		; Flag: suche DDFSTOP
	BRA.S	LFCA46E
; 2. Suche erfolgreich, DDFSTOP gefunden
LFCA456	CMPI.W	#$D4,D2
	BEQ.S	LFCA45E		; Wert = $D4? (EINE Art Overscan)
	BRA.S	LFCA476		; Nein, RETURN 222
LFCA45E	LEA	$92(A1),A0	; 3. Suche: DDFSTART
	MOVE.W	A0,D0
	ANDI.W	#$1FE,D0
	MOVEQ	#2,D5		; Flag: suche DDFSTART
	BRA.S	LFCA46E
; 3. Suche erfolgreich: DDFSTART gefunden
LFCA46C
	BRA.S	LFCA47A		; RETURN Wert von DDFSTART


LFCA46E	MOVE.W	D4,D1
	SUBQ.W	#1,D4
	TST.W	D1
	BNE.S	LFCA41A	; Zähler noch nicht 0, suchen
LFCA476	MOVE.W	#$DE,D2 ; RETURN 222

LFCA47A	MOVE.W	D2,D0
	EXT.L	D0
	MOVEM.L	(A7)+,D2-5
	RTS

; Generiere eine WAIT-Instruktion, splitte evtl. auf in 2
; copList
; copPtr
; var record -32
;
LFCA484:
GenWait:
	MOVEM.L	D2-4/A2-3,-(A7)
	MOVEA.L	$18(A7),A2 ; a2:=record
	MOVEA.L	$1C(A7),A3 ; a3:=copPtr
	MOVEA.L	$20(A7),A1 ; a1:=copList
	MOVE.L	A6,D1  ; GfxBase
	MOVEA.L	8(A1),A0 ; a0:=viewPort
	MOVE.W	$1E(A0),D2 ; d2:=dyOffset
	ADD.W	2(A3),D2 ; +=vWaitPos
	BTST	#2,$21(A0) ; lace?
	BEQ.S	LFCA4B0 ; nein
	MOVE.W	D2,D0
	ASR.W	#1,D0 ; sonst /2
	MOVE.W	D0,D2
LFCA4B0	ADD.W	$18(A2),D2 ; +dyOffset aus record, aso View
	MOVEA.L	D1,A0   ; a0:=GfxBase
	MOVE.W	$D4(A0),D0 ; Offset 212 = ^.maxDisplayRow
	CMP.W	D2,D0
	BHI.S	LFCA4C6 ; max>dieser: nix
	MOVEA.L	D1,A0
	MOVE.W	$D4(A0),D2 ; sonst max-1
	SUBQ.W	#1,D2
LFCA4C6	MOVE.W	4(A3),D3 ; hWaitPos
	MOVE.W	D2,D4
	CMPI.W	#$FF,D2
	BLE.S	LFCA4F0 ; y<=255: ok
	MOVE.W	#$FF,D2 ; y:=255
	CMPI.W	#$FF,D3
	BEQ.S	LFCA4F0 ; x=255? ja, ok
	BSeT	#0,$1B(A2) ; record.27 = local: -5, flag, neu:setze
	BNE	LFCA556 ; wir sind schon über 256
	MOVE.L	A2,-(A7)
	BSR	FindX ; suche X-Wert
	MOVE.W	D0,D3
	ADDQ.L	#4,A7
LFCA4F0	CMP.W	$E(A2),D3
	BNE.S	LFCA4FC ; = letztem Wert?
	CMP.W	$10(A2),D4 ; war ,d2 dadurch >255 auch doppelte Waits
	BEQ.S	LFCA54A ; identisch vorigem Wait, also auslassen
LFCA4FC	MOVE.W	D3,D1
	ANDI.W	#$FE,D1 ; WAIT generieren
	MOVE.W	D2,D0
	EXT.L	D0
	ASL.L	#8,D0
	ORI.W	#1,D0
	OR.W	D0,D1
	MOVEA.L	4(A2),A0
	ADDQ.L	#2,4(A2)
	MOVE.W	D1,(A0)
	MOVEA.L	4(A2),A0
	ADDQ.L	#2,4(A2)
	MOVE.W	#$FFFE,(A0) ; Maske immer FFFE
	MOVE.W	D3,$E(A2)
	MOVE.W	D4,$10(A2) ; letzte Werte merken
	BTST	#2,$13(A2) ; lace?
	BEQ.S	LFCA54A	   ; nein, fertig
	MOVEA.L	8(A2),A0
	ADDQ.L	#2,8(A2)   ; ja, auch in SHFCprList eintragen
	MOVE.W	D1,(A0)
	MOVEA.L	8(A2),A0
	ADDQ.L	#2,8(A2)
	MOVE.W	#$FFFE,(A0)
LFCA54A	CMPI.W	#$FF,D2	   ; Y=255?
	BNE.S	LFCA568    ; nein, fertig
	btst	#0,$1B(A2) ; neu: test, ob verdoppeltes Wait
	beq.s	LFCA568    ; wir sind noch unter 255
;	CMPI.W	#$DE,D3 ; das war Unsinn und DER Fehler!
;	BNE.S	LFCA568
LFCA556	MOVE.W	D4,D2	; nun 2. Wait anhängen WAIT y-256,x
	SUBI.W	#$100,D2
	MOVE.W	4(A3),D3
	ORI.W	#1,$1A(A2)
	BRA.S	LFCA4F0
LFCA568	MOVEM.L	(A7)+,D2-4/A2-3
	RTS

; viewportptr
; dspIns (CopListPtr)
; var long
; zählt instruktionen (alle counts zusammen) nach 12(long) und verkettet sie
LFCA56E:
CountCop:
	MOVE.L	D2,-(A7)
	MOVEA.L	8(A7),A1 ; long
	MOVEA.L	$C(A7),A0 ; copList
	MOVE.L	$10(A7),D1 ; viewPort
	MOVE.L	A0,D0
	BEQ.S	LFCA5B0 ; keine copList
	TST.W	$1C(A0) ; count
	BEQ.S	LFCA5B0 ; =0, raus
	MOVE.L	(A1),D2 ; d2:=long
	MOVE.L	A0,(A1) ; long:=copList
	BRA.S	LFCA5AC

LFCA58C	CLR.L	$18(A0) ; copSStart
	CLR.L	$14(A0) ; copLStart
	MOVE.L	D2,4(A0) ; .copList:=long
	MOVE.L	D1,8(A0) ; .viewPort:=viewPort
	MOVE.L	$C(A0),$10(A0) ; copPtr:=copIns
	MOVE.W	$1C(A0),D0 ; d0:=count
	ADD.W	D0,$C(A1) ; 12(long)+=count
	MOVEA.L	(A0),A0 ; next copList
LFCA5AC	MOVE.L	A0,D0
	BNE.S	LFCA58C ; noch copList
LFCA5B0	MOVE.L	(A7)+,D2
	RTS

; Haupt-Routine:
MrgCop2: ; (view(a1)):
; VAR (ein Record)
; -4.l LofCprList.start
; -6.w 0
; -8.w dyOffset
;-10.w (shfCprList.maxCount)
;-12.w lofCprList.maxCount
;-14.w view.modes
;-16.w 0
;-18.w 0
;-20.w 0 gesamtcount?
;-24.l shfCprList.start oder NIL, wenn kein lace
;-28.l lofCprList.start
;-32.l 0 verkettete copIns

	LINK	A5,#-$20
	MOVEM.L	D2-5/A2-4,-(A7)
	MOVEA.L	a1,A2 ; view. Geändert, statt stack direkt in Register
;	MOVE.L	#AllocCopper,D4
;	MOVE.L	#CountCop,D3 ; routine, nicht aus reg benutzt
	CLR.L	-$20(A5)
	CLR.W	-$14(A5)
	MOVE.W	$C(A2),-8(A5) ; dyOffset
	MOVEA.L	(A2),A3 ; viewPort
	BRA.S	LFCA63C ; rep until nextviewport=nil

LFCA5DE	MOVEQ	#0,D0
	MOVE.W	$20(A3),D0 ; modes
	ANDI.L	#$2000,D0 ; vpHide gesetzt?
	BNE.S	LFCA63A ; ja, gleich next viewPort
	MOVE.L	A3,-(A7) ; viewPort
	MOVE.L	8(A3),-(A7) ; dspIns (CopListPtr)
	PEA	-$20(A5) ; var, noch 0
	BSR	CountCop
	MOVE.L	A3,-(A7)
	MOVE.L	$C(A3),-(A7) ; sprIns
	PEA	-$20(A5)
	BSR	CountCop
	MOVE.L	A3,-(A7)
	MOVE.L	$10(A3),-(A7) ; clrIns
	PEA	-$20(A5)
	BSR	CountCop

	MOVE.L	$14(A3),D2 ; uCopIns
	LEA	$24(A7),A7 ; stack wieder ok
	BRA.S	LFCA636
LFCA620	MOVE.L	A3,-(A7)
	MOVEA.L	D2,A4
	MOVE.L	4(A4),-(A7) ; firstCopList
	PEA	-$20(A5)
	BSR	CountCop
	MOVE.L	(A4),D2 ; next (ucoplist)
	LEA	$C(A7),A7
LFCA636	TST.L	D2
	BNE.S	LFCA620 ; alle durch

LFCA63A	MOVEA.L	(A3),A3
LFCA63C	MOVE.L	A3,D0
	BNE.S	LFCA5DE ; until alle viewPorts

	TST.L	-$20(A5)
	BNE.S	LFCA64A
	BRA	LFCA8BA ; nix da, raus

LFCA64A	ADDQ.W	#1,-$14(A5)
	ADDQ.W	#2,-$14(A5) ; gescount+3 (für evtl. Umschaltung Lof<->Shf)
	CLR.W	D0
	MOVE.W	D0,-$10(A5)
	MOVE.W	D0,-$12(A5)
	MOVE.W	$10(A2),-$E(A5) ; view.modes
	CLR.W	-6(A5)
	MOVE.L	4(A2),D3 ; lofCprList
	BNE.S	LFCA69C ; schon eine da
; neue cprlist anlegen
	PEA	1.W ; public
	PEA	$A.W ; CprList-Size
	BSR	AllocCopper
	MOVE.L	D0,D3
	MOVE.L	D3,4(A2) ; lofCprList
	MOVEA.L	D3,A3
	CLR.L	(A3) ; .next:=NIL
	PEA	3.W ; public,chip
	MOVE.W	-$14(A5),D1 ; gesamtcount
	EXT.L	D1
	ASL.L	#2,D1 ; *4
	MOVE.L	D1,-(A7)
	BSR	AllocCopper
	MOVEA.L	D3,A3
	BRA.S	LFCA6D2

; cprlist schon da
LFCA69C	MOVE.W	-$14(A5),D0 ; gesamtcount
	MOVEA.L	D3,A0 ; lofcprlist
	CMP.W	8(A0),D0 ; maxcount
	BLE.S	LFCA6E0 ; genug platz da
	MOVEA.L	D3,A3 ; lofcprlist
	MOVE.W	8(A3),D1 ; maxcount
	EXT.L	D1
	ASL.L	#2,D1 ; *4
	MOVE.L	D1,-(A7)
	MOVE.L	4(A3),-(A7) ; start
	BSR	FreeMem ; (=fd3c4c) free old
	PEA	3.W ; publ,chip
	MOVE.W	-$14(A5),D1
	EXT.L	D1
	ASL.L	#2,D1
	MOVE.L	D1,-(A7)
	BSR	AllocCopper ; alloc new

LFCA6D2	MOVE.L	D0,4(A3) ; CprList.start
	MOVE.W	-$14(A5),8(A3) ; maxCount
	LEA	$10(A7),A7 ; stack
; nu CprList fertig
LFCA6E0	MOVEA.L	D3,A0 ; lofCprList
	MOVE.W	8(A0),-$C(A5) ; maxCount
	MOVE.L	4(A0),-$1C(A5) ; start
	MOVE.L	4(A0),-4(A5) ; start
	BTST	#2,-$D(A5) ; lace?
	BEQ.S	LFCA74E ; nein

	MOVE.L	8(A2),D5 ; shfCprList
	BNE.S	LFCA73E ; eine da
	PEA	1.W
	PEA	$A.W
	BSR	AllocCopper
	MOVE.L	D0,D5
	MOVE.L	D5,8(A2) ; shfCprList
	MOVEA.L	D5,A3
	CLR.L	(A3)
	PEA	3.W
	MOVE.W	-$14(A5),D1
	EXT.L	D1
	ASL.L	#2,D1
	MOVE.L	D1,-(A7)
	BSR	AllocCopper
	MOVEA.L	D5,A3
	MOVE.L	D0,4(A3)
	MOVE.W	-$14(A5),8(A3)
	LEA	$10(A7),A7
LFCA73E	MOVEA.L	D5,A0
	MOVE.W	8(A0),-$A(A5)
	MOVE.L	4(A0),-$18(A5)
	BRA.S	LFCA752

LFCA74E	CLR.L	-$18(A5)
LFCA752	BRA	LFCA82A

; loop durch screen
LFCA756	LEA	-$20(A5),A0 ; copList ; LEA, trick!
	MOVE.L	A0,D4
	MOVEA.L	(A0),A3 ; a3:=.next, hier:erste
	BRA.S	LFCA7A8

LFCA760	MOVE.L	$10(A3),-(A7) ; copPtr
	PEA	-$20(A5) ; copList, ist aber view!! oder?
	BSR	GenMoves
	MOVEA.L	D0,A1 ; letzter OpCode
	CMPI.W	#2,(A1) ; 2=next
	ADDQ.L	#8,A7
	BNE.S	LFCA798
; ja, opcode ist next
	MOVEA.L	2(A1),A3
	LEA	-$20(A5),A0
	CMP.L	A0,D4
	BNE.S	LFCA78A
	MOVE.L	A3,-$20(A5)
	BRA.S	LFCA798
LFCA78A	MOVEA.L	D4,A0
	BRA.S	LFCA794

LFCA78E	MOVE.L	A3,4(A0)
	MOVEA.L	(A0),A0
LFCA794	MOVE.L	A0,D0
	BNE.S	LFCA78E ; weiter

LFCA798	CMPI.W	#2,(A1) ; next??
	BEQ.S	LFCA760
	MOVE.L	A1,$10(A3) ; copPtr
	MOVE.L	A3,D4
	MOVEA.L	4(A3),A3 ; copList

LFCA7A8	MOVE.L	A3,D0
	BNE.S	LFCA760 ; noch next da
	MOVE.L	#$1388000,D4 ; y=20000 ?? Startwert MinY
	MOVEA.L	-$20(A5),A3
	BRA.S	LFCA7F8

LFCA7B8	MOVEA.L	$10(A3),A1 ; copPtr
	MOVEA.L	8(A3),A0 ; viewPort
	MOVE.W	$1E(A0),D1 ; .dyOffset
	EXT.L	D1
	MOVE.W	2(A1),D0 ; vWaitPos
	EXT.L	D0
	ADD.L	D0,D1 ; +
	BTST	#2,$21(A0) ; lace?
	BEQ.S	LFCA7DC ; nein
	MOVE.L	D1,D0
	ASR.L	#1,D0
	MOVE.L	D0,D1 ; sonst /2
LFCA7DC	MOVE.L	D1,D0
	MOVEQ	#$A,D1
	ASL.L	D1,D0 ; shl 10
	MOVE.W	4(A1),D1 ; hwaitpos
	EXT.L	D1
	ADD.L	D1,D0 ; +
	MOVE.L	D0,D1
	CMP.L	D0,D4
	BLE.S	LFCA7F4 ; >d4, nix
	MOVE.L	A3,D2 ; d2:=CopList
	MOVE.L	D1,D4 ; d4 neues Minimum
LFCA7F4	MOVEA.L	4(A3),A3 ; .copList
LFCA7F8	MOVE.L	A3,D0
	BNE.S	LFCA7B8 ; nächster

	MOVEA.L	D2,A0
	TST.L	$14(A0) ; copLStart
	BNE.S	LFCA812 ; ist da
	MOVEA.L	D2,A0
	MOVE.L	-$1C(A5),$14(A0) ; copLStart:=lofcprlist
	MOVE.L	-$18(A5),$18(A0) ; copSStart:=shfcprlist
LFCA812	MOVE.L	D2,-(A7) ; copList
	MOVEA.L	D2,A3
	MOVE.L	$10(A3),-(A7) ; copPtr
	PEA	-$20(A5) ; record
	BSR	GenWait
	ADDQ.L	#6,$10(A3) ; copPtr auf next copInstruction
	LEA	$C(A7),A7

LFCA82A	CMPI.W	#$FF,-$12(A5)
	BLT	LFCA756 ; loop bis vpos>=255

	BTST	#2,$11(A2) ; view.lace?
	BEQ	LFCA8BA
	MOVEA.L	#$DFF000,A3 ; generiere Copper-Umschaltung Lof<->Shf
	MOVEA.L	-$18(A5),A2
	MOVEA.L	-$1C(A5),A1
	MOVE.W	-4(A1),D0
	MOVE.W	D0,4(A1)
	MOVE.W	D0,4(A2)
	MOVE.W	-2(A1),D0
	MOVE.W	D0,6(A1)
	MOVE.W	D0,6(A2)
	LEA	$84(A3),A0
	MOVE.L	A0,D0
	ANDI.L	#$1FE,D0
	MOVE.W	D0,-4(A1)
	MOVE.W	D0,-4(A2)
	LEA	$84(A3),A0
	MOVE.L	A0,D0
	ADDQ.L	#2,D0
	ANDI.L	#$1FE,D0
	MOVE.W	D0,(A1)
	MOVE.W	D0,(A2)
	MOVEA.L	D3,A4
	MOVE.L	4(A4),D0
	MOVEQ	#$10,D1
	ASR.L	D1,D0
	MOVE.W	D0,-2(A1)
	MOVE.W	D0,-2(A2)
	MOVE.W	6(A4),D0
	MOVE.W	D0,2(A1)
	MOVE.W	D0,2(A2)
	MOVEA.L	D5,A4
	MOVE.L	4(A4),D0
	LSR.L	D1,D0
	MOVE.W	D0,-2(A1)
	MOVE.W	6(A4),2(A1)
LFCA8BA	MOVEM.L	-$3C(A5),D2-5/A2-4
	UNLK	A5
	RTS

...
; GenMoves:
; Erzeugt MOVE-Instruktionen, solange welche da sind
; copPtr: CopInsPtr
; var xx:CopListPtr lofcprlist, shfcprlist...
LFD16F0:
GenMoves:
	MOVEM.L	4(A7),A0-1 ; a1=CopInsPtr, A0:=Zeiger Record
	MOVE.W	(A1),D1 ; opCode
	MOVE.W	D1,D0
	ANDI.W	#3,D0 ; nur code ohne sht,lof
	BNE.S	LFD1756 ; nicht move: raus
; opCode 0: move
	MOVEM.L	D2-4/A2-3,-(A7)
	MOVE.L	#$1FEFFFF,D2
	MOVEQ	#3,D3
	MOVEQ	#$E,D4
	MOVEM.L	4(A0),A2-3 ; lofcprList und shfCprList
	ADDQ.L	#2,A1 ; copIns auf destAddr
	CMPA.W	#0,A3
	BNE.S	LFD1730 ; shfCprList#NIL
LFD171C	MOVE.L	(A1)+,D0 ; destAddr, destData
	AND.L	D2,D0 ; addr ausmaskieren
	BTST	D4,D1 ; opCode bit sht gesetzt?
	BNE.S	LFD1726 ; ja
	MOVE.L	D0,(A2)+ ; codes in cprList
LFD1726	MOVE.W	(A1)+,D1 ; next opCode
	MOVE.W	D1,D0
	AND.W	D3,D0
	BEQ.S	LFD171C ; next move
	BRA.S	LFD174A

LFD1730	MOVE.L	(A1)+,D0
	AND.L	D2,D0
	BTST	D4,D1 ; bit 14 = sht gesetzt?
	BNE.S	LFD173A
	MOVE.L	D0,(A2)+
LFD173A	BTST	#$F,D1 ; lof
	BNE.S	LFD1742
	MOVE.L	D0,(A3)+
LFD1742	MOVE.W	(A1)+,D1
	MOVE.W	D1,D0
	AND.W	D3,D0
	BEQ.S	LFD1730
LFD174A	SUBQ.L	#2,A1
	MOVEM.L	A2-3,4(A0)
	MOVEM.L	(A7)+,D2-4/A2-3

LFD1756	MOVE.L	A1,D0
	RTS

; Alloziert Speicher in, wenn nichts da: GURU 82010000
AllocCopper:
	MOVE.L	4(A7),D0
	MOVE.L	8(A7),D1
	MOVE.L	D1,-(A7)
	MOVE.L	D0,-(A7)
	BSR	AllocMemory
	MOVE.L	D0,D0
	ADDQ.L	#8,A7
	BNE.S	LFD149C
	MOVE.L	#$82010000,-(A7)
	BSR	Alert ; guru
	MOVEQ	#0,D0
	ADDQ.L	#4,A7
	BRA	LFD149C
LFD149C	RTS



LFD3BA8:
Alert:
	MOVEM.L	D7/A5-6,-(A7)
	MOVEA.L	4,A6
	MOVE.L	$10(A7),D7
	MOVEA.L	$14(A7),A5
	JSR	-$6C(A6)
	MOVEM.L	(A7)+,D7/A5-6
	RTS

AllocMemory:
	MOVE.L	A6,-(A7)
	MOVEA.L	4,A6
	MOVEM.L	8(A7),D0-1
	JSR	-$C6(A6)
	MOVEA.L	(A7)+,A6
	RTS

FreeMem:
LFD3C4C:
	MOVE.L	A6,-(A7)
	MOVEA.L	4,A6
	MOVEA.L	8(A7),A1
	MOVE.L	$C(A7),D0
	JSR	-$D2(A6)
	MOVEA.L	(A7)+,A6
	RTS
MrgEnd:
;============================================================

	section MyDats,data

_GfxBase	dc.l 0
_DOSBase	dc.l 0
CodeMem		dc.l 0
MyPort		dc.l 0

grafname	GRAFNAME
dosname		DOSNAME
UnpMsg:	dc.b 'Un'
PMsg:	dc.b 'Patched MrgCop.',10,0
PLen	EQU  	*-PMsg
UnpLen	EQu	*-UnpMsg
ErrMsg  dc.b 'Error!',10,0
ErrLen	EQU	*-ErrMsg
	even

	END

