
	include	"SNES.i"

	incdir	"!includes:OS3.0"
	include	"intuition/intuition.i"
	include	"graphics/gfx.i"
	include	"exec/types.i"

	incdir	"!includes:"
	include	"LVO/graphics_lib.i"
	include	"LVO/dos_lib.i"
	include	"LVO/intuition_lib.i"

	* prevent execution

	move.l	#-1,d0
	rts

	section	code,code

GFX_BuildFade
* * * * * * * * * * * * * * * * * * * * * * * * *
* Initializes fade-table for use with INIDISP.	*
*						*
* IN:	a0 - ptr to CPU-structure.		*
*	a6 - ptr to hardware-structure.		*
*						*
* * * * * * * * * * * * * * * * * * * * * * * * *

	movem.l	d0-a6,-(sp)

	lea.l	prg_FadeTable,a0

	move.l	#0,d4
	
	move.l	#16-1,d7
.FadeTableBuild

	move.l	#32-1,d6
.ColourBuild

	;calculate and set faded colour

	move.l	d6,d0
	eor.l	#31,d0
	muls.l	d4,d0
	asr.l	#1,d0

	move.b	d0,(a0)+

	;fill rest of longword with correct value(amiga standard)

	move.b	#$ff,(a0)+
	move.w	#$ffff,(a0)+

	dbra	d6,.ColourBuild

	add.l	#1,d4

	dbra	d7,.FadeTableBuild

	movem.l	(sp)+,d0-a6
	rts

GFX_UpdatePalette
* * * * * * * * * * * * * * * * * * * * * * * * *
* Remixes and changes the palette if program	*
* written into CGRAM. This gives great		*
* improvements when writing entire palettes.	*
* Supports fading with INIDISP.			*
*						*
* IN:	a0 - ptr to CPU-structure.		*
*	a6 - ptr to hardware-structure.		*
*						*
* * * * * * * * * * * * * * * * * * * * * * * * *

	movem.l	d0-a6,-(sp)

	tst.l	SHW_PaletteChange(a6)
	beq	.no_change

	* prepare header

	lea.l	SHW_ColorRAM(a6),a1
	lea.l	.palette_Table,a2
	lea.l	prg_FadeTable,a3

	* calculate offset in fading table

	move.l	SHW_ScreenBrightness(a6),d5
	asl.l	#5,d5

	move.l	#$01000000,(a2)+

	* fill in palette entries

	move.l	#256-1,d7

.ColourCopyLoop

	clr.l	d1
	move.w	(a1)+,d1

	move.w	d1,d2
	move.w	d1,d3

	and.l	#$1f,d1	;R
	add.l	d5,d1
	move.l	(a3,d1*4),(a2)+

	lsr.l	#5,d2	;G
	and.l	#$1f,d2
	add.l	d5,d2
	move.l	(a3,d2*4),(a2)+

	lsr.l	#8,d3	;B
	lsr.l	#2,d3
	and.l	#$1f,d3
	add.l	d5,d3
	move.l	(a3,d3*4),(a2)+

	dbra	d7,.ColourCopyLoop

	* finish list

	move.l	#$00000000,(a2)+

	* set entire palette

	move.l	a6,-(sp)

	move.l	_GfxBase,a6

	move.l	ptr_EmulationScreen,a0
	lea.l	sc_ViewPort(a0),a0
	lea.l	.palette_Table,a1
	jsr	_LVOLoadRGB32(a6)

	move.l	(sp)+,a6

	* reset notification

	clr.l	SHW_PaletteChange(a6)

.no_change

	movem.l	(sp)+,d0-a6
	rts

.palette_Table	ds.l	256*3+2


GFX_RenderScreen
* * * * * * * * * * * * * * * * * * * * * * * * *
* Checks screen-parameters and updates the	*
* screen buffer.				*
*						*
* IN:	a0 - ptr to CPU-structure.		*
*	a6 - ptr to hardware-structure.		*
*						*
* MODES SUPPORTED:				*
*	MODE 0: 4 Layers			*
*	MODE 1: 3 Layers			*
*						*
* The rendering is line-by-line, instead of	*
* tile-by-tile, as before. This adds more	*
* functionality.				*
*						*
* TODO:	Implement more modes.			*
*	Add HDMA support.			*
*	Add HW-scrolling.			*
*						*
* * * * * * * * * * * * * * * * * * * * * * * * *

	movem.l	d0-a6,-(sp)

	tst.l	SHW_ScreenEnable(a6)
	beq	.ScreenOff

	tst	prg_FrameSkip
	bne	.NoUpdate

	tst.l	SHW_ScreenChange(a6)
	beq	.NoUpdate

	lea.l	prg_ConfigBuffer,a2

	move.l	CFG_FrameSkip(a2),prg_FrameSkip

	* mask layers to prevent illegal modes

	lea.l	prg_BGTable,a0
	move.l	SHW_ScreenMode(a6),d0
	move.l	(a0,d0*4),d0
	and.l	d0,SHW_BGEnable(a6)

	move.l	SHW_BGEnable(a6),.BGEnable

	move.l	SHW_BGMask(a6),d0
	and.l	d0,.BGEnable

	* fill in global settings for render-buffer

	lea.l	prg_ScreenRender,a2
	move.l	SHW_ScreenSettings(a6),SCR_ScreenMode(a2)

	* render BG1

	move.l	.BGEnable,d0
	btst.b	#0,d0
	beq	.no_BG1Render

	;fill in local settings for render-buffer
	lea.l	prg_ScreenRender,a2
	move.l	SHW_ScreenPixelation(a6),d0
	btst.b	#0,d0
	bne	.KeepBG1Pixelation
	clr.l	d0
.KeepBG1Pixelation
	move.l	d0,SCR_Pixelation(a2)

	clr.l	d0
	move.w	SHW_BG1HorizScroll(a6),d0
	move.l	d0,SCR_HorizScroll(a2)

	clr.l	d0
	move.w	SHW_BG1VertScroll(a6),d0
	move.l	d0,SCR_VertScroll(a2)

	clr.l	d0
	move.w	SHW_BG1SCAddress(a6),d0
	lsl.w	#1,d0
	clr.l	d1
	move.w	SHW_BG1SCSize(a6),d1
	jsr	GFX_UpdateBuffer

	move.l	ptr_RenderBufferBG1,a0
	move.l	ptr_RenderMask,a1


	clr.l	d1
	move.w	SHW_BG1TileAddress(a6),d1
	lsl.w	#1,d1

	lea.l	prg_RenderTable,a3
	move.l	SHW_ScreenMode(a6),d3
	asl.l	#2,d3
	move.l	0*4(a3,d3*4),a3
	move.l	#0,d2
	jsr	(a3)

.no_BG1Render

	* render BG2

	move.l	.BGEnable,d0
	btst.b	#1,d0
	beq	.no_BG2Render

	;fill in local settings for render-buffer
	lea.l	prg_ScreenRender,a2
	move.l	SHW_ScreenPixelation(a6),d0
	btst.b	#1,d0
	bne	.KeepBG2Pixelation
	clr.l	d0
.KeepBG2Pixelation
	move.l	d0,SCR_Pixelation(a2)

	clr.l	d0
	move.w	SHW_BG2HorizScroll(a6),d0
	move.l	d0,SCR_HorizScroll(a2)

	clr.l	d0
	move.w	SHW_BG2VertScroll(a6),d0
	move.l	d0,SCR_VertScroll(a2)

	clr.l	d0
	move.w	SHW_BG2SCAddress(a6),d0
	lsl.w	#1,d0
	clr.l	d1
	move.w	SHW_BG2SCSize(a6),d1
	jsr	GFX_UpdateBuffer

	move.l	ptr_RenderBufferBG2,a0
	move.l	ptr_RenderMask,a1
	lea.l	PLANESIZE(a1),a1

	clr.l	d1
	move.w	SHW_BG2TileAddress(a6),d1
	lsl.w	#1,d1

	lea.l	prg_RenderTable,a3
	move.l	SHW_ScreenMode(a6),d3
	asl.l	#2,d3
	move.l	1*4(a3,d3*4),a3
	move.l	#1,d2
	jsr	(a3)

.no_BG2Render

	* render BG3

	move.l	.BGEnable,d0
	btst.b	#2,d0
	beq	.no_BG3Render

	;fill in local settings for render-buffer
	lea.l	prg_ScreenRender,a2
	move.l	SHW_ScreenPixelation(a6),d0
	btst.b	#2,d0
	bne	.KeepBG3Pixelation
	clr.l	d0
.KeepBG3Pixelation
	move.l	d0,SCR_Pixelation(a2)

	clr.l	d0
	move.w	SHW_BG3HorizScroll(a6),d0
	move.l	d0,SCR_HorizScroll(a2)

	clr.l	d0
	move.w	SHW_BG3VertScroll(a6),d0
	move.l	d0,SCR_VertScroll(a2)

	clr.l	d0
	move.w	SHW_BG3SCAddress(a6),d0
	lsl.w	#1,d0
	clr.l	d1
	move.w	SHW_BG3SCSize(a6),d1
	jsr	GFX_UpdateBuffer

	move.l	ptr_RenderBufferBG3,a0
	move.l	ptr_RenderMask,a1
	lea.l	2*PLANESIZE(a1),a1

	clr.l	d1
	move.w	SHW_BG3TileAddress(a6),d1
	lsl.w	#1,d1

	lea.l	prg_RenderTable,a3
	move.l	SHW_ScreenMode(a6),d3
	asl.l	#2,d3
	move.l	2*4(a3,d3*4),a3
	move.l	#2,d2
	jsr	(a3)

.no_BG3Render

	* render BG4

	move.l	.BGEnable,d0
	btst.b	#3,d0
	beq	.no_BG4Render

	;fill in local settings for render-buffer
	lea.l	prg_ScreenRender,a2
	move.l	SHW_ScreenPixelation(a6),d0
	btst.b	#3,d0
	bne	.KeepBG4Pixelation
	clr.l	d0
.KeepBG4Pixelation
	move.l	d0,SCR_Pixelation(a2)

	clr.l	d0
	move.w	SHW_BG4HorizScroll(a6),d0
	move.l	d0,SCR_HorizScroll(a2)

	clr.l	d0
	move.w	SHW_BG4VertScroll(a6),d0
	move.l	d0,SCR_VertScroll(a2)

	clr.l	d0
	move.w	SHW_BG4SCAddress(a6),d0
	lsl.w	#1,d0
	clr.l	d1
	move.w	SHW_BG4SCSize(a6),d1
	jsr	GFX_UpdateBuffer

	move.l	ptr_RenderBufferBG4,a0
	move.l	ptr_RenderMask,a1
	lea.l	3*PLANESIZE(a1),a1

	clr.l	d1
	move.w	SHW_BG4TileAddress(a6),d1
	lsl.w	#1,d1

	lea.l	prg_RenderTable,a3
	move.l	SHW_ScreenMode(a6),d3
	asl.l	#2,d3
	move.l	3*4(a3,d3*4),a3
	move.l	#3,d2
	jsr	(a3)

.no_BG4Render

	* copy to display

	lea.l	prg_MixTable,a0
	move.l	.BGEnable,d0
	and.l	#$f,d0
	move.l	(a0,d0.l*4),a0
	jsr	(a0)

	* clear screenchange

	move.l	ptr_SNESHardware,a6
	clr.l	SHW_ScreenChange(a6)

.NoUpdate

	movem.l	(sp)+,d0-a6
	rts

.ScreenOff

	* reset palette if not already reset(faster than screen clear)

	lea.l	.palette_Table,a2

	move.l	#$01000000,(a2)+

	* fill in palette entries

	move.l	#256-1,d7

.ColourCopyLoop

	clr.l	(a2)+
	clr.l	(a2)+
	clr.l	(a2)+

	dbra	d7,.ColourCopyLoop

	* finish list

	move.l	#$00000000,(a2)+

	* set entire palette

	move.l	_GfxBase,a6

	move.l	ptr_EmulationScreen,a0
	lea.l	sc_ViewPort(a0),a0
	lea.l	.palette_Table,a1
	jsr	_LVOLoadRGB32(a6)

	movem.l	(sp)+,d0-a6
	rts

.BGEnable	ds.l	1
.palette_Table	ds.l	256*3+2

GFX_UpdateBuffer
* * * * * * * * * * * * * * * * * * * * * * * * *
* Copies the defined screen to the SC-buffer.	*
*						*
* IN:	d0 - SC pointer				*
*	d1 - SCSize				*
*						*
* * * * * * * * * * * * * * * * * * * * * * * * *

	movem.l	d0-a6,-(sp)

	move.l	ptr_SNESVRam,a0
	add.l	d0,a0

	move.l	ptr_SCBuffer,a1

	and.l	#3,d1
	lea.l	.copytable,a2
	move.l	(a2,d1*4),a2
	jsr	(a2)

	movem.l	(sp)+,d0-a6
	rts

.copytable
	dc.l	CopySC_32x32
	dc.l	CopySC_32x64
	dc.l	CopySC_64x32
	dc.l	CopySC_64x64

CopySC_32x32

	move.l	#32-1,d7
.yloop_copy

	move.l	#32-1,d6
.xloop_copy
	move.w	(a0)+,(a1)+
	dbra	d6,.xloop_copy

	move.l	#32-1,d6
.xloop_clear
	move.w	#-1,(a1)+
	dbra	d6,.xloop_clear

	dbra	d7,.yloop_copy

	move.l	#32-1,d7
.yloop_clear

	rept	32
	move.w	#-1,(a1)+
	endr

	dbra	d7,.yloop_clear

	rts

CopySC_32x64

	move.l	#64-1,d7
.yloop_copy

	move.l	#32-1,d6
.xloop_copy
	move.w	(a0)+,(a1)+
	dbra	d6,.xloop_copy

	move.l	#32-1,d6
.xloop_clear
	move.w	#-1,(a1)+
	dbra	d6,.xloop_clear

	dbra	d7,.yloop_copy

	rts

CopySC_64x32
	move.l	#32-1,d7
.yloop_copy

	move.l	#64-1,d6
.xloop_copy
	move.w	(a0)+,(a1)+
	dbra	d6,.xloop_copy

	dbra	d7,.yloop_copy

	move.l	#32-1,d7
.yloop_clear

	rept	32
	move.w	#-1,(a1)+
	endr

	dbra	d7,.yloop_clear

	rts

CopySC_64x64

	move.l	#64-1,d7
.yloop_copy

	move.l	#64-1,d6
.xloop_copy
	move.w	(a0)+,(a1)+
	dbra	d6,.xloop_copy

	dbra	d7,.yloop_copy

	rts


	* macro for joining several planes

JPLANES	MACRO

C_COUNT	set	(\1+\2+\3+\4)-1

	;\1 - BG1 included
	;\2 - BG2 included
	;\3 - BG3 included
	;\4 - BG4 included

	IFNE	C_COUNT

	IFNE	\1
	move.l	ptr_RenderBufferBG1,a0
	ENDIF

	IFNE	\2
	move.l	ptr_RenderBufferBG2,a1
	ENDIF

	IFNE	\3
	move.l	ptr_RenderBufferBG3,a2
	ENDIF

	IFNE	\4
	move.l	ptr_RenderBufferBG4,a3
	ENDIF

	move.l	ptr_RenderBuffer,a4

	move.l	#8-1,d7
.CopyToChip_P\@

	move.l	ptr_RenderMask,a5

	move.l	#240-1,d5
.CopyToChip_Y\@

	move.l	#(32)/4-1,d6
.CopyToChip_X\@

	IFNE	\1
	move.l	(a0)+,d1
	ENDIF
	IFNE	\2
	move.l	(a1)+,d2
	ENDIF
	IFNE	\3
	move.l	(a2)+,d3
	ENDIF
	IFNE	\4
	move.l	(a3)+,d4
	ELSE
	clr.l	d4
	ENDIF

	;mask out BG1

	IFNE	\1
	move.l	(a5),d0
	not.l	d0
	IFNE	\2
	and.l	d0,d2
	ENDIF
	IFNE	\3
	and.l	d0,d3
	ENDIF
	IFNE	\4
	and.l	d0,d4
	ENDIF
	ENDIF

	;mask out BG2

	IFNE	\2
	move.l	PLANESIZE(a5),d0
	not.l	d0
	IFNE	\3
	and.l	d0,d3
	ENDIF
	IFNE	\4
	and.l	d0,d4
	ENDIF
	ENDIF

	;mask out BG3

	IFNE	\3
	IFNE	\4
	move.l	PLANESIZE*2(a5),d0
	not.l	d0
	and.l	d0,d4
	ENDIF
	ENDIF

	IFNE	\1
	or.l	d1,d4
	ENDIF
	IFNE	\2
	or.l	d2,d4
	ENDIF
	IFNE	\3
	or.l	d3,d4
	ENDIF

	lea.l	4(a5),a5

	move.l	d4,(a4)+

	dbra	d6,.CopyToChip_X\@

	dbra	d5,.CopyToChip_Y\@

	dbra	d7,.CopyToChip_P\@

	ELSE

	IFNE	\1
	move.l	ptr_RenderBufferBG1,a0
	ENDIF

	IFNE	\2
	move.l	ptr_RenderBufferBG2,a0
	ENDIF

	IFNE	\3
	move.l	ptr_RenderBufferBG3,a0
	ENDIF

	IFNE	\4
	move.l	ptr_RenderBufferBG4,a0
	ENDIF

	move.l	ptr_RenderBuffer,a1

	move.l	#(32*240*8)/16-1,d7
.CopyMerge\@

	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+
	move.l	(a0)+,(a1)+

	dbra	d7,.CopyMerge\@

	ENDIF

	ENDM

prg_MixTable
	dc.l	.0BGMix_0000	;0000 OK
	dc.l	.1BGMix_0001	;0001 OK
	dc.l	.1BGMix_0010	;0010 OK
	dc.l	.2BGMix_0011	;0011 OK
	dc.l	.1BGMix_0100	;0100 OK
	dc.l	.2BGMix_0101	;0101 OK
	dc.l	.2BGMix_0110	;0110 OK
	dc.l	.3BGMix_0111	;0111 OK
	dc.l	.1BGMix_1000	;1000 OK
	dc.l	.2BGMix_1001	;1001 OK
	dc.l	.2BGMix_1010	;1010 OK
	dc.l	.3BGMix_1011	;1011 OK
	dc.l	.2BGMix_1100	;1100 OK
	dc.l	.3BGMix_1101	;1101 OK
	dc.l	.3BGMix_1110	;1110 OK
	dc.l	.4BGMix_1111	;1111 OK

.0BGMix_0000

	;render no planes, just clear display-buffer

	move.l	ptr_RenderBuffer,a0

	move.l	#(PLANESIZE*8)/16-1,d7
.ClearChip_0000

	clr.l	(a0)+
	clr.l	(a0)+
	clr.l	(a0)+
	clr.l	(a0)+

	dbra	d7,.ClearChip_0000

	rts

.1BGMix_0001
	JPLANES	1,0,0,0
	rts

.1BGMix_0010
	JPLANES	0,1,0,0
	rts

.2BGMix_0011
	JPLANES	1,1,0,0
	rts

.1BGMix_0100
	JPLANES	0,0,1,0
	rts

.2BGMix_0101
	JPLANES	1,0,1,0
	rts

.2BGMix_0110
	JPLANES	0,1,1,0
	rts

.3BGMix_0111
	JPLANES	1,1,1,0
	rts

.1BGMix_1000
	JPLANES	0,0,0,1
	rts

.2BGMix_1001
	JPLANES	1,0,0,1
	rts

.2BGMix_1010
	JPLANES	0,1,0,1
	rts

.3BGMix_1011
	JPLANES	1,1,0,1
	rts

.2BGMix_1100
	JPLANES	0,0,1,1
	rts

.3BGMix_1101
	JPLANES	1,0,1,1
	rts

.3BGMix_1110
	JPLANES	0,1,1,1
	rts

.4BGMix_1111
	JPLANES	1,1,1,1
	rts

prg_BGTable
	;0
	dc.l	%1111
	;1
	dc.l	%0111
	;2
	dc.l	%0000
	;3
	dc.l	%0000
	;4
	dc.l	%0000
	;5
	dc.l	%0000
	;6
	dc.l	%0000
	;7
	dc.l	%0001

prg_RenderTable
	;0
	dc.l	render_Mode0,render_Mode0,render_Mode0,render_Mode0
	;1
	dc.l	render_Mode1,render_Mode1,render_Mode0,noRender
	;2
	dc.l	noRender,noRender,noRender,noRender
	;3
	dc.l	noRender,noRender,noRender,noRender
	;4
	dc.l	noRender,noRender,noRender,noRender
	;5
	dc.l	noRender,noRender,noRender,noRender
	;6
	dc.l	noRender,noRender,noRender,noRender
	;7
	dc.l	noRender,noRender,noRender,noRender

*
* Input to rendering routines:
*
* a0 - pointer to output screen buffer
* a1 - pointer to output screen mask
* d0 - offset in VRAM for SC-table.
* d1 - offset in VRAM for tiles.

noRender
	rts

PST_TILELINE_M0	MACRO

	;\1 = tile-number

	clr.l	d0
	clr.l	d1
	clr.l	d2
	clr.l	d3

	move.w	\1*2(a4),d5	;d5 = current tile
	rol.w	#8,d5		;convert big endian
	bmi	.NoTile\@

	and.w	#$03ff,d5	;mask away attributes
	lsl.l	#4,d5		;d5 = offset in tile-data
	add.l	d4,d5		;offset down in tile

	move.b	00(a5,d5),d0
	move.b	01(a5,d5),d1

.NoTile\@

	move.b	d0,d6
	or.b	d1,d6

	move.b	d0,\1+(0*TPLANEWIDTH)(a3)
	move.b	d1,\1+(1*TPLANEWIDTH)(a3)
	move.b	d6,\1(a2)

	;remap line

	move.l	\1*4(a6),d0

	move.b	d0,d1
	and.b	d6,d1
	move.b	d1,\1+(4*TPLANEWIDTH)(a3)

	move.w	d0,d1
	ror.l	#8,d1
	and.b	d6,d1
	move.b	d1,\1+(5*TPLANEWIDTH)(a3)

	move.l	d0,d1
	rol.l	#8,d1
	and.b	d6,d1
	move.b	d1,\1+(6*TPLANEWIDTH)(a3)

	ENDM

render_Mode0
	movem.l	d0-a6,-(sp)

	move.l	ptr_SNESVRam,a4
	move.l	a4,a5

	move.l	ptr_SCBuffer,a4
	add.l	d1,a5	;a5 = tile base

	move.l	#(28*8)-1,d7

	lea.l	prg_ScreenRender,a6

	move.l	SCR_ScreenMode(a6),d0
	btst.l	#3,d0			;Check PAL/NTSC
	beq	.scrNTSC

	move.l	#(30*8)-1,d7

.scrNTSC

	move.l	#7,d3
	clr.l	d4

	;hardware-scrolling y (byte AND bit)

	move.l	SCR_VertScroll(a6),d0
	move.l	d0,d1
	lsr.l	#3,d0
	lsl.l	#7,d0
	add.l	d0,a4

	and.l	#7,d1
	sub.l	d1,d3
	lsl.l	#4,d1
	add.l	d1,d4

	;hardware scrolling x byte(and prepare bit)
	move.l	SCR_HorizScroll(a6),d0
	move.l	d0,d1
	lsr.l	#3,d0
	lsl.l	#1,d0
	add.l	d0,a4

	and.l	#7,d1
	eor.l	#7,d1
	move.l	d1,.HScroll

.render_YLoop

	lea.l	prg_ScreenRender,a6

	;build remap-table for all 32 tiles

	lea.l	.RemapTable,a6

TILE	set	0

	rept	33

	move.w	TILE*2(a4),d0
	rol.w	#8,d0
	move.l	d0,d5
	and.l	#$1c00,d5	;$fd00 for xy aswell
	lsr.w	#8,d5
	lsr.w	#2,d5

	clr.l	d0
	btst.b	#2,d5
	sne.b	d0
	rol.l	#8,d0
	rol.l	#8,d0
	btst.b	#1,d5
	sne.b	d0
	rol.l	#8,d0
	btst.b	#0,d5
	sne.b	d0

	move.l	d0,TILE*4(a6)

TILE	set	TILE+1

	endr

.RenderYSameTile

	move.l	d4,a2
	exg.l	d4,a2
	lsr.l	#4,d4
	lsl.l	#1,d4

TILE	set	0

	movem.l	d2-d3/a2-a3,-(sp)

	lea.l	.MaskBuffer,a2
	lea.l	.RenderBuffer,a3

	rept	33

	PST_TILELINE_M0	TILE

TILE	set	TILE+1

	endr

	move.l	.HScroll,d1
	clr.l	d2

	move.l	#(32/2)-1,d3
.CopyToRender

	;copy graphics

TILEC	set	0

	rept	7

	move.l	TILEC*TPLANEWIDTH(a3,d2),d0
	lsl.l	d1,d0
	swap	d0
	move.w	d0,TILEC*PLANESIZE(a0,d2)

TILEC	set	TILEC+1

	endr

	;copy mask

	move.l	(a2,d2),d0
	lsl.l	d1,d0
	swap	d0
	move.w	d0,(a1,d2)

	add.l	#2,d2

	dbra	d3,.CopyToRender

	movem.l	(sp)+,d2-d3/a2-a3

	lea.l	PLANEWIDTH(a0),a0	;one line down
	lea.l	PLANEWIDTH(a1),a1

	exg.l	d4,a2
	add.l	#16,d4

	subq.l	#1,d7
	bmi	.EndOfScreen

	subq.l	#1,d3
	bmi	.EndOfTiles

	bra	.RenderYSameTile

.EndOfTiles

	move.l	#8-1,d3
	clr.l	d4

	lea.l	64*2(a4),a4	;one tile row down

	bra	.render_YLoop

.EndOfScreen

	movem.l	(sp)+,d0-a6

	rts

.HScroll	ds.l	1
.RemapTable	ds.l	TPLANEWIDTH
.RenderBuffer	ds.b	TPLANEWIDTH*8
.MaskBuffer	ds.b	TPLANEWIDTH

PST_TILELINE_M1	MACRO

	;\1 = tile-number

	clr.l	d0
	clr.l	d1
	clr.l	d2
	clr.l	d3

	move.w	\1*2(a4),d5	;d5 = current tile
	rol.w	#8,d5		;convert big endian
	bmi	.NoTile\@

	and.w	#$03ff,d5	;mask away attributes
	lsl.l	#5,d5		;d5 = offset in tile-data
	add.l	d4,d5		;offset down in tile

	move.b	00(a5,d5),d0
	move.b	01(a5,d5),d1
	move.b	16(a5,d5),d2
	move.b	17(a5,d5),d3

.NoTile\@

	move.b	d0,d6
	or.b	d1,d6
	or.b	d2,d6
	or.b	d3,d6

	move.b	d0,\1+(0*TPLANEWIDTH)(a3)
	move.b	d1,\1+(1*TPLANEWIDTH)(a3)
	move.b	d2,\1+(2*TPLANEWIDTH)(a3)
	move.b	d3,\1+(3*TPLANEWIDTH)(a3)
	move.b	d6,\1(a2)

	;remap line

	move.l	\1*4(a6),d0

	move.b	d0,d1
	and.b	d6,d1
	move.b	d1,\1+(4*TPLANEWIDTH)(a3)

	move.w	d0,d1
	ror.l	#8,d1
	and.b	d6,d1
	move.b	d1,\1+(5*TPLANEWIDTH)(a3)

	move.l	d0,d1
	rol.l	#8,d1
	and.b	d6,d1
	move.b	d1,\1+(6*TPLANEWIDTH)(a3)

	move.b	#0,\1+(7*TPLANEWIDTH)(a3)

	ENDM

render_Mode1
	movem.l	d0-a6,-(sp)

	move.l	ptr_SNESVRam,a4
	move.l	a4,a5

	move.l	ptr_SCBuffer,a4
	add.l	d1,a5	;a5 = tile base

	move.l	#(28*8)-1,d7

	lea.l	prg_ScreenRender,a6

	move.l	SCR_ScreenMode(a6),d0
	btst.l	#3,d0			;Check PAL/NTSC
	beq	.scrNTSC

	move.l	#(30*8)-1,d7

.scrNTSC

	move.l	#7,d3
	clr.l	d4

	;screen pixelation(incorrect, but.. :)
	move.l	#16*16,d0
	sub.l	SCR_Pixelation(a6),d0
	lsr.l	#4,d0
	move.l	d0,a3

	;hardware-scrolling y (byte AND bit)

	move.l	SCR_VertScroll(a6),d0
	move.l	d0,d1
	lsr.l	#3,d0
	lsl.l	#7,d0
	add.l	d0,a4

	and.l	#7,d1
	sub.l	d1,d3
	move.l	a3,d0
	muls.l	d0,d1
	add.l	d1,d4

	;hardware scrolling x byte(and prepare bit)
	move.l	SCR_HorizScroll(a6),d0
	move.l	d0,d1
	lsr.l	#3,d0
	lsl.l	#1,d0
	add.l	d0,a4

	and.l	#7,d1
	move.l	d1,.HScroll

.render_YLoop

	lea.l	prg_ScreenRender,a6

	;build remap-table for all 32 tiles

	lea.l	.RemapTable,a6

TILE	set	0

	rept	33

	move.w	TILE*2(a4),d0
	rol.w	#8,d0
	move.l	d0,d5
	and.l	#$1c00,d5	;$fd00 for xy aswell
	lsr.w	#8,d5
	lsr.w	#2,d5

	clr.l	d0
	btst.b	#2,d5
	sne.b	d0
	rol.l	#8,d0
	rol.l	#8,d0
	btst.b	#1,d5
	sne.b	d0
	rol.l	#8,d0
	btst.b	#0,d5
	sne.b	d0

	move.l	d0,TILE*4(a6)

TILE	set	TILE+1

	endr

.RenderYSameTile

	move.l	d4,a2
	lsr.l	#4,d4
	lsl.l	#1,d4

TILE	set	0

	movem.l	d2-d3/a2-a3,-(sp)

	lea.l	.MaskBuffer,a2
	lea.l	.RenderBuffer,a3

	rept	33

	PST_TILELINE_M1	TILE

TILE	set	TILE+1

	endr

	move.l	.HScroll,d1
	clr.l	d2

	move.l	#(32/2)-1,d3
.CopyToRender

	;copy graphics

TILEC	set	0

	rept	7

	move.l	TILEC*TPLANEWIDTH(a3,d2),d0
	lsl.l	d1,d0
	swap	d0
	move.w	d0,TILEC*PLANESIZE(a0,d2)

TILEC	set	TILEC+1

	endr

	;copy mask

	move.l	(a2,d2),d0
	lsl.l	d1,d0
	swap	d0
	move.w	d0,(a1,d2)

	add.l	#2,d2

	dbra	d3,.CopyToRender

	movem.l	(sp)+,d2-d3/a2-a3

	lea.l	PLANEWIDTH(a0),a0	;one line down
	lea.l	PLANEWIDTH(a1),a1

	exg.l	d4,a2
	add.l	a3,d4

	subq.l	#1,d7
	bmi	.EndOfScreen

	subq.l	#1,d3
	bmi	.EndOfTiles

	bra	.RenderYSameTile

.EndOfTiles

	move.l	#8-1,d3
	clr.l	d4

	lea.l	64*2(a4),a4	;one tile row down

	bra	.render_YLoop

.EndOfScreen

	movem.l	(sp)+,d0-a6

	rts

.HScroll	ds.l	1
.RemapTable	ds.l	TPLANEWIDTH
.RenderBuffer	ds.b	TPLANEWIDTH*8
.MaskBuffer	ds.b	TPLANEWIDTH

render_Mode2
	rts

render_Mode3
	rts

render_Mode4
	rts

render_Mode5
	rts

render_Mode6
	rts

render_Mode7	;CHUBBAWUMP! chunky mode!
	rts

	section	bss,bss

prg_ScreenRender
	ds.b	SCR_SIZEOF

prg_PaletteTable
	ds.l	(256*3)+3

prg_FadeTable
	ds.l	(32*16)*4
