;,--------------------------------------------------------------.
;| FlickerFixer V2.3 - Verwandelt Pal-Amiga in NTSC-Amiga!!!	|
;| Verhindert schwarze Streifen und verzerrte Bilder		|
;| Verhindert Interlaceflimmern	fast voellig			|
;| Bewirkt bessere Bildqualitaet (In Spielen,Demos;nicht im CLI)|
;| ( Der VCR-Schalter des Monitors sollte gedrueckt sein.)	|
;`--------------------------------------------------------------'
;(C)	Felix Wente
;	Pappelweg 68
;	643 Bad Hersfeld
;	Tel:06621/15433
;
;	Dieses Programm ist nicht Public Domain.
;	Es darf nur fuer nicht-kommerzielle Zwecke benutzt werden.
;	Wer das Programm verbessert, sollte mir bitte schreiben.
;
;	Der 'Trick' des Programms ist ganz einfach:
;	Es wird auf Zeile 261 ( letzte Zeile bei NTSC) gewartet.
;	Dann wird in das VPOSW-Register der Wert der Zeile
;	312 ( letzte Zeile bei PAL) geschrieben.
;	Der Videochip glaubt dann,dass das Bild zuende ist und baut
;	ein neues auf. Der Monitor ( zumindest mein 1081) ist in der Lage,
;	das Bild neu zu synchronisieren,die Bildfrequenz betraegt jetzt
;	60 Hertz.
;	Besitzer eines MultiSync-Monitors koennen das Programm vielleicht
;	auch so abaendern,dass eine hoehere Aufloesung entsteht!!
;
;	Hat jemand Ahnung von den STR-Registern ($38-$3e) von Denise?
;	Haben sie etwas mit dem Refresh zu tun und sind sie im Bildaufbau
;	per Hand dringend noetig (Ich habe die Strobes wieder rausgenommen)?
;	Wer etwas Naeheres ueber diese Register weiss,sollte mir bitte
;	schreiben.Danke!
;
;	Bugs:	Manchmal gibt es Aerger mit den Floppies,deshalb nur ohne
;		NTSC schreiben.(Koennte an Disable liegen)
;		Beim Experimentieren mit den Bildschirmstrahlwerten ist
;		Vorsicht geboten:Unguenstige Werte koennen Teile des
;		Speichers loeschen (weiss jemand warum? Ich vermute,dass
;		entweder die BitPlane-DMA oder der Refresh gestoert wird).
;-----------------------------------------------------------------

	IVEC         = $78
	IVEC2        = $68

	AllocMem     = -198
	FreeMem      = -210
	OpenLibrary  = -552
	CloseLibrary = -414
	Disable      = -120
	Enable       = -126

	Output       = -60
	Write        = -48


start:	move.l	4.w,a6				;Open Dos
	moveq	#0,d0
	lea	dosname(PC),a1
	jsr	OpenLibrary(a6)
	tst.l	d0
	beq	ende

	move.l	d0,a6
	jsr	Output(a6)
	move.l	d0,d1
	cmp.l	#$fc0000,IVEC2			;schon installiert?
	bge.S	no_error
	move.l	#text2,d2
	move.l	#textend-text2,d3
close:	jsr	Write(a6)
	move.l	a6,a1
	move.l	4.w,a6
	jsr	CloseLibrary(a6)
	moveq	#0,d0
	rts

no_error:
	move.l	#text1,d2			;Write Info
	move.l	#text2-text1,d3
	bsr	close

	lea	gfxname(PC),a1			;Open Gfx
	jsr	OpenLibrary(a6)
	tst.l	d0
	beq	ende
	move.l	d0,gfxbase

	move.l	#schluss-IntHandler,d0		;Speicher besorgen
	move.l	#2+65536,d1
	jsr	AllocMem(a6)
	move.l	d0,d7
	tst.l	d0
	beq	ende


	jsr	Disable(a6)			;IntVecs veraendern
	move.l	d7,a0
	move.l	d7,a1
	move.l	IVEC,ih_end+2
	adda.l	#KeyHandler-IntHandler,a1
	move.l	IVEC2,kh_end+2
	move.l	a1,IVEC2

	move.l	gfxbase(PC),a2			;LoadView umbiegen
	move.l	a0,a1
	adda.l	#LoadView-IntHandler,a1
	move.l	-220(a2),LoadView+2
	move.l	a1,-220(a2)

	move.l	a0,a1				;ebenso ScrollVPort
	adda.l	#ScrollVPort-IntHandler,a1
	move.l	-586(a2),ScrollVPort+2
	move.l	a1,-586(a2)
	bsr	ShowDisp

	lea	IntHandler(PC),a1		;Copy IntHandler
	lea	schluss(PC),a2
loop:	move.b	(a1)+,(a0)+
	cmpa.l	a1,a2
	bne.S	loop
	jsr	Enable(a6)

	move.l	gfxbase,a1
	jsr	CloseLibrary(a6)
ende:	moveq	#0,d0
	rts


gfxname:dc.b	'graphics.library',0,0
dosname:dc.b	'dos.library',0
text1:	dc.b	$9b,'3;33;40',$6d
	dc.b	'NTSC V2.2 '
	dc.b	$9b,'2;32;40',$6d
	dc.b	'(c) Felix Wente',$a
	dc.b	$9b,'0;31;40',$6d
	dc.b	'Press SHIFT+F2 for NTSC,SHIFT+F1 for PAL',$a
	dc.b	'SHIFT+ESC will remove NTSC',$a
text2:	dc.b	'NTSC already installed!',$a
textend:
	even

;---------------------- Ab hier wirds interessanter ------------------------
;---------------------------- IntHandlers ----------------------------------
IntHandler:
	andi.w	#$4000,$dff01e		;Ist es der richtige INT?
	beq	ih_end
	movem.l	d0-d1,-(sp)
	move.w	SR,d1
	move.w	#$2700,SR		;INT Disable

	move.l	$dff004,d0
	and.l	#$80000000,d0
	beq.S	Short
	bra.S	Long
Short:	move.l	$dff004,d0
	lsr.l	#8,d0
	cmp.w	#260,d0
	bne.S	Short
	move.w	#20,d0
so_l1:	subq.w	#1,d0
	bne.S	so_l1
	move.l	#$136ff,$dff02a
	;move.w	#0,$dff038		;???????
	bra	int_on

Long:	move.l	$dff004,d0
	lsr.l	#8,d0
	cmp.w	#261,d0
	bne.S	Long
	move.w	#20,d0
lo_l1:	subq.w	#1,d0
	bne.S	lo_l1
	move.l	#$800137ff,$dff02a
	;move.w	#0,$dff038

int_on:	move.w	#$4000,$dff09c
	move.w	#$8020,$dff09c
	move.w	d1,SR
	movem.l	(sp)+,d0-d1
	rte
ih_end:	jmp	0
gfxbase:dc.l	0


KeyHandler:
	movem.l	d0/a0,-(sp)
	moveq	#0,d0
	move.b	$bfec01,d0
	lea	shftflg(PC),a0

	cmp.w	#63,d0
	bne.S	kh_1
	move.w	#$ffff,(a0)
	bra	kh_exit
kh_1:	cmp.w	#62,d0
	bne.S	kh_2
	move.w	#0,(a0)
	bra	kh_exit
kh_2:	tst.w	(a0)
	beq	kh_exit
	cmp.w	#117,d0			;Exit?
	bne.S	kh_3
	move.w	#$4000,$dff09a
	bsr	remove
	move.w	#$c000,$dff09a
	bra.S	kh_exit
kh_3:	cmp.w	#95,d0			;F1=PAL?
	bne.S	kh_4
	move.w	#$4000,$dff09a
	bsr	showpal
	move.w	#$c000,$dff09a
	bra	kh_exit
kh_4:	cmp.w	#93,d0			;F2=NTSC?
	bne.S	kh_exit
	move.w	#$4000,$dff09a
	bsr	showdisp
	bsr	showNTSC
	lea	IntHandler(PC),a0
	move.l	a0,IVEC
	move.w	#$c000,$dff09a
kh_exit:movem.l	(sp)+,d0/a0
kh_end:	jmp	0
shftflg:dc.w	0

LoadView:
	jsr	0
	bsr	showdisp
	rts
ScrollVPort:
	jsr	0
	bsr	showdisp
	rts
;---------------------------- Unterroutinen --------------------
showNTSC:
	lea	coplist(PC),a1
	move.l	a1,$dff080
	move.l	#0,$dff02a
	move.w	#1,$dff088
	rts

showdisp:
	movem.l	d0-d2/a0-a2,-(SP)	
	move.l	gfxbase(PC),a2
	move.l	34(a2),a0	;ActiView
	move.l	4(a0),a0	;cprlist
	move.l	4(a0),a0	;cprinstr
	lea	coplist(PC),a1
	bsr	sd_ccc

	;move.l	gfxbase(PC),a2
	;move.l	34(a2),a0	;ActiView
	;move.l	8(a0),a0	;cprlist
	;cmpa.l	#0,a0
	;beq.S	sd_gbck
	;move.l	4(a0),a0	;cprinstr
	;lea	coplist2(PC),a1
	;bsr	sd_ccc
sd_gbck:movem.l	(SP)+,d0-d2/a0-a2
	rts

sd_ccc:	move.l	208(a2),a2	;Sprites in neue Coplist
	move.l	#$120,d2
sd_sc:	tst.l	(a2)
	beq	sd_sz
	move.l	a2,d0
	move.l	(a2),a2		;SimpleSprite
	move.l	(a2),d1		;SpriteData
	move.l	d0,a2
	swap	d1
	move.w	d2,(a1)+
	addq.w	#2,d2
	move.w	d1,(a1)+
	move.w	d2,(a1)+
	addq.w	#2,d2
	swap	d1
	move.w	d1,(a1)+
	bra.S	sd_sch
sd_sz:	move.w	d2,(a1)+
	addq.w	#2,d2
	move.w	#0,(a1)+
	move.w	d2,(a1)+
	addq.w	#2,d2
	move.w	#0,(a1)+
sd_sch:	addq.l	#4,a2
	cmp.w	#$140,d2
	blt	sd_sc

	move.l	a1,a2		;SystemCoplist in neue List
	moveq	#0,d2
sd_cpl:	move.l	(a0)+,d0
	cmp.l	#$fffffffe,d0	;END ?
	bne.S	sd_goon
	btst	#0,d2
	bne.S	sd_e1
	move.l	#$fedffffe,(a1)+
	move.l	#$009cc000,(a1)+
sd_e1:	move.l	d0,(a1)+
	bra	sd_end
sd_goon:move.l	d0,d1
	swap	d1
	btst	#0,d1		;MOVE ?
	beq	sd_move

sd_wait:btst	#1,d2		;WAIT > 255 ?
	bne	sd_cpl		;dann weglassen
	cmp.w	#$fedf,d1	;WAIT > IntWAIT
	bhi.S	sd_w1
	bra.S	sd_ewt
sd_w1:	btst	#0,d2		;IntWait schon gesetzt?
	bne.S	sd_w2
	bset	#0,d2
	move.l	#$fedffffe,(a1)+	;eedf
	move.l	#$009cc000,(a1)+
	bra.S	sd_ewt
sd_w2:	cmp.w	#$ffdf,d1	;WAIT = 255 ?
	bne.S	sd_ewt
	bset	#1,d2		;Flag 255 setzen!
sd_ewt:	move.l	d0,(a1)+
	bra	sd_cpl

sd_move:cmp.w	#$090,d1	;DIWSTOP ?
	bne.S	sd_lcht
	and.w	#$ff,d0
	or.w	#$0e00,d0
	bra	sd_emov
sd_lcht:cmp.w	#$80,d1		;COP1LCH..
	beq.S	sd_lch
	cmp.w	#$84,d1		;oder COP2LCH ?
	beq.S	sd_lch
	bra.S	sd_lclt
sd_lch:	move.l	a2,d1
	swap	d1
	move.w	d1,d0
	bra.S	sd_emov
sd_lclt:cmp.w	#82,d1		;COP1LCL..
	beq.S	sd_lcl
	cmp.w	#$86,d1		;oder COP2LCL ?
	beq.S	sd_lcl
	bra.S	sd_emov
sd_lcl:	move.w	a2,d0
sd_emov:move.l	d0,(a1)+
	bra	sd_cpl
sd_end:	rts

;-----------------
remove:	move.w	#$4000,$dff09a
	move.l	ih_end+2(PC),IVEC
	move.l	kh_end+2(PC),IVEC2
	move.l	gfxbase(PC),a0
	move.l	LoadView+2(PC),-220(a0)
	move.l	ScrollVPort+2(PC),-586(a0)
	move.l	38(a0),$dff080
	move.w	#1,$dff088
	move.w	#$c000,$dff09a
	rts
;-----------------
showpal:move.w	#$4000,$dff09a
	move.l	ih_end+2(PC),IVEC
	move.l	gfxbase(PC),a0
	move.l	38(a0),$dff080
	move.w	#1,$dff088
	move.w	#$c000,$dff09a
	rts
;---------------------------- CopperListe ----------------------
coplist:
	blk.w	1024,0
coplist2:
	blk.w	1024,0
schluss:

