;*************************************************
;*       Odo of ExMachina Design Present :       * 
;*         The >> RotationZoom Writer <<         *
;*   Code and Design (c) 1993 ExMachina Design   *
;*************************************************

	heap	O=256k
	smc+

	Rs=	$1300
M7A_copy	Rs.w	0
M7B_copy	Rs.w	0
M7C_copy	Rs.w	0
M7D_copy	Rs.w	0
Mulu_T_Val	Rs.t	0
Zoom_Val	Rs.b	0
Scroll_X	Rs.w	0
Scroll_Y	Rs.w	0
Counter	Rs.w	0
MoveTable	Rs.w	0
ZoomIn	Rs.b	0
ZoomOut	Rs.b	0
RotateLeft	Rs.b	0
RotateRight	Rs.b	0
BrightNES	Rs.b	0
M7PrintLine	Rs.w	0
M7CharName	Rs.b	0
M7TextAddr	Rs.w	0
M7LineCounter	Rs.b	0

	.include	snes:include/SuperInclude.i

	CLC
	XCE			;set 16 bit native mode
	SEI			;set interrupt flag(NO INTS)
	REP	#$10		;X&Y 16 Bit
	SEP	#$20		;Acc  8 Bit
	Jsr	InitRegs
	jmp	Mode7Main

WaitVblank	PHP
	SEP	#$20
wait1	LDA	rRdNMI
	BIT	#$80
	BNE	wait1
wait2	LDA	rRdNMI
	BIT	#$80
	BEQ	wait2
	PLP
	RTS

Mode7Setup:	JSR	WaitVblank
	LDX	#$2200		;register $2122 -Colour data
	STX	PmDMA0Tr
	LDX	#Mod7Palette	;address for data
	STX	TaDMA0L
	LDA	#^Mod7Palette	;bank for data
	STA	TaDMA0B
	LDX	#64		;number of bytes to DMA
	STX	DMA0DaSL
	LDA	#$00		;Select Colour 0
	STA	CgAdd
	LDA	#$01		;start DMA
	STA	mDMAen
	LDA	#$80
	STA	VmaInc
	LDX	#$0000		;set VRAM addr to $0
	STX	VmAddL
	LDX	#$1801		;register $2118 -Vram data
	STX	PmDMA2Tr           
	LDX	#gfxdata		;address of data
	STX	TaDMA2L
	LDA	#^gfxdata		;bank for data
	STA	TaDMA2B
	LDX	#$8000		;number of bytes to DMA      
	STX	DMA2DaSL
	LDA	#$04		;Start DMA
	STA	mDMAen
	lda	#7
	sta	BGmode
	lda	#1
	sta	TM
	lda	#0
	sta	M7Sel
	jsr	Mode7Clear
	Ldx	#TestText
	Stx	M7TextAddr
	Ldx	#$0000
	Stx	M7PrintLine
	Jsr	Mode7Print
	RTS

Mode7Clear:	Jsr	WaitVblank		;Wait for VBlank
	Lda	#$00		;Set Vram
	Sta	VmAddL		;addr 
	Lda	#$00		;to
	Sta	VmAddH		;$0000
	Ldx	#$0000		;Set ClearCounter
.Loop	Lda	#$0		;get Character Name
	Sta	VmDataL		;Store character in VRAM
	LDA	rVmDataH		;Increment Vram by 2
	Inx			;Increment X
	Inx			;Twice
	Cpx	#$8000		;compare with end CharNames
	Bne	.Loop		;Continue Clear
	Rts

Mode7Print:	Ldx	M7TextAddr
	Lda	$0,x
	cmp	#0
	beq	M7LineExit
	cmp	#$ff
	beq	M7PrintExit
	SBC	#$1f
	Sta	M7CharName
	Inx	
	Stx	M7TextAddr
	Ldy	M7PrintLine		;Set Vram
	Sty	VmAddL		;addr 
	Lda	M7CharName		;get Character Name
	Sta	VmDataL		;Store character in VRAM
	Ldx	M7PrintLine
	Inx
	Stx	M7PrintLine
	Jmp	Mode7Print

M7PrintExit:	Ldx	#$0000
	Stx	M7TextAddr
	Stx	M7LineCounter
	rts

M7LineExit:	Ldx	M7PrintLine
.Loop	Inx
	Lda	M7LineCounter
	Adc	#1
	Sta	M7LineCounter
	cmp	#$61
	bne	.Loop
	Lda	#$00
	Sta	M7LineCounter
	Stx	M7PrintLine
	ldx	M7TextAddr
	inx
	Stx	M7TextAddr
	jmp	Mode7Print


Mode7Sinus:	.include	ExM:ExM-Zoom.Snes/ExM-ZoomSinusTable.s
	.include	ExM:ExM-Zoom.Snes/ExM-ZoomSinusTable.s


VBI:	rti

Mode7Main:	REP	#$10		;X&Y 16 Bit
	SEP	#$20		;Acc  8 Bit
	LDX	#$1ff
	TXS			;Set stack pointer to $1ff
	LDA	#$00
	XBA     
	LDA	#$00
	TCD
	ldx	#$0000
	stx	Scroll_X		;-Plane
	stx	Scroll_Y		;-Coordinates
	stx	M7PrintLine
	Stx	M7TextAddr
	Lda	#$00
	Sta	M7CharName
	Sta	M7LineCounter
	ldx	#0
	stx	Counter
	lda	#64
	sta	Zoom_Val
	Ldx	#AutoPilotTable
	Stx	MoveTable
	JSR	Mode7Setup		;copy character & palette data in
	lda	#$81
	stA	NmiTimEn		;enable NMI + PAD
	rep	#$20
	lda	Scroll_X
	clc
	adc	#128
	sep	#$20
	sta	M7X
	xba
	sta	M7X
	rep	#$20
	lda	Scroll_Y
	clc
	adc	#128
	sep	#$20
	sta	M7Y
	xba
	sta	M7Y
	rep	#$20
	lda	Scroll_X
	sep	#$20
	sta	BG1Hofs
	xba
	sta	BG1Hofs
	rep	#$20
	lda	Scroll_Y
	sep	#$20
	sta	BG1Vofs
	xba
	sta	BG1Vofs
loop:	wai			;just same as jsr waitvbi
	rep	#$20
ComputeZoom:	brl	ExecuteZoom
zoom:	sep	#$20		;groesse aendern
	sta	M7A
	xba
	sta	M7A
	lda	Zoom_Val
	sta	M7B
	lda	rMpyL
	sta	Mulu_T_Val
	lda	rMpyM
	sta	Mulu_T_Val+1
	lda	rMpyH
	sta	Mulu_T_Val+2
	and	#$80
	beq	.plus
	sec
	bra	.skip
.plus	clc
.skip	ror	Mulu_T_Val+2
	ror	Mulu_T_Val+1
	ror	Mulu_T_Val
do_2nd:	lda	Mulu_T_Val+2
	and	#$80
	beq	.plus
	sec
	bra	.skip
.plus	clc
.skip	ror	Mulu_T_Val+2
	ror	Mulu_T_Val+1
	ror	Mulu_T_Val
do_2nd2:	lda	Mulu_T_Val+2
	and	#$80
	beq	.plus
	sec
	bra	.skip
.plus	clc
.skip	ror	Mulu_T_Val+2
	ror	Mulu_T_Val+1
	ror	Mulu_T_Val
do_2nd3:	lda	Mulu_T_Val+2
	and	#$80
	beq	.plus
	sec
	bra	.skip
.plus	clc
.skip	ror	Mulu_T_Val+2
	ror	Mulu_T_Val+1
	ror	Mulu_T_Val
	rep	#$20
	lda	Mulu_T_Val+1
	rts

ExecuteZoom:	lda	Counter
	clc
	adc	#1024/4*2
	and	#1023*2
	tax
	lda	Mode7Sinus,x
	jsr	zoom
	sta	M7A_copy
	sta	M7D_copy
	lda	Counter
	clc
	adc	#1024/2*2
	and	#1023*2
	tax
	lda	Mode7Sinus,x
	jsr	zoom
	sta	M7C_copy
	ldx	Counter
	lda	Mode7Sinus,x
	jsr	zoom
	sta	M7B_copy	
	sep	#$20		;copy to hardware regs
	lda	M7A_copy
	sta	M7A
	lda	M7A_copy+1
	sta	M7A
	lda	M7B_copy
	sta	M7B
	lda	M7B_copy+1
	sta	M7B
	lda	M7C_copy
	sta	M7C
	lda	M7C_copy+1
	sta	M7C
	lda	M7D_copy
	sta	M7D
	lda	M7D_copy+1
	sta	M7D
	JSR	AutoPilot

AutoP1:	Lda	ZoomOut
	cmp	#1
	beq	zoomout
AutoP2:	Lda	ZoomIn	
	cmp	#1
	beq	zoomin
AutoP3:	Lda	RotateLeft
	cmp	#1
	beq	rotateleft
AutoP4:	Lda	RotateRight
	cmp	#1
	beq	rotateright
	brl	loop
zoomout	lda	Zoom_Val
	clc
	adc	#2
	sta	Zoom_Val
	brl	AutoP2
zoomin	lda	Zoom_Val
	sec
	sbc	#2
	sta	Zoom_Val
	brl	AutoP3
rotateright	rep	#$20
	lda	Counter
	clc
	adc	#16
	and	#1023*2
	sta	Counter
	sep	#$20
	brl	AutoP4
rotateleft	rep	#$20
	lda	Counter
	sec
	sbc	#16
	and	#1023*2
	sta	Counter
	sep	#$20
	brl	loop

AutoPilot:	Ldx	MoveTable
	Lda	0,x
	cmp	#$ff
	beq	ResetMoves
	Sta	ZoomIn
	Inx
	Lda	0,x
	Sta	ZoomOut
	Inx
	Lda	0,x
	Sta	RotateLeft
	Inx
	Lda	0,x
	Sta	RotateRight
	Inx
	Lda	0,x
	Sta	BrightNES
	Sta	IniDisp
	Inx
	Stx	MoveTable
	rts

ResetMoves:	Ldx	#AutoPilotTable
	Stx	MoveTable
	jmp	AutoPilot

InitRegs:	sep	#$20		;This one is The Initial
	lda	rStat77		;Setting routine For the
	lda	rStat78		;Snes CPU & PPU Regs
	lda	#$80		;(Must Be Started First of all)
	sta	$2100
	stz	$2101
	stz	$2102
	stz	$2103
	stz	$2105
	stz	$2106
	stz	$2107
	stz	$2108
	stz	$2109
	stz	$210a
	stz	$210b
	stz	$210c
	stz	$210d
	stz	$210d
	stz	$210e
	stz	$210e
	stz	$210f
	stz	$210f
	stz	$2110
	stz	$2110
	stz	$2111
	stz	$2111
	stz	$2112
	stz	$2112
	stz	$2113
	stz	$2113
	stz	$2114
	stz	$2114
	lda	#$80
	sta	$2115
	stz	$2116
	stz	$2117
	stz	$211a
	lda	#$01
	stz	$211b
	sta	$211b
	stz	$211c
	stz	$211c
	stz	$211d
	stz	$211d
	stz	$211e
	sta	$211e
	stz	$211f
	stz	$211f
	stz	$2120
	stz	$2120
	stz	$2121
	stz	$2122
	stz	$2122
	stz	$2123
	stz	$2124
	stz	$2125
	stz	$2126
	stz	$2127
	stz	$2128
	stz	$2129
	stz	$212a
	stz	$212b
	stz	$212c
	stz	$212d
	stz	$212e
	lda	#$30
	sta	$2130
	stz	$2131
	lda	#$e0
	sta	$2132
	stz	$2133
	stz	$4200
	lda	#$ff
	sta	$4201
	stz	$4202
	stz	$4203
	stz	$4204
	stz	$4205
	stz	$4206
	stz	$4207
	stz	$4208
	stz	$4209
	stz	$420a
	stz	$420b
	stz	$420c
	stz	$420d
	rts

AutoPilotTable:	;Zo  Zi  Rr  Rl  Br
	.REPEAT 10 {
	dc.b	$01,$00,$00,$00,$0f
	}
	.REPEAT 128 {
	dc.b	$00,$00,$01,$00,$0f
	}
	.REPEAT 40 {
	dc.b	$00,$01,$00,$00,$0f
	}
	.REPEAT 30 {
	dc.b	$01,$00,$00,$00,$0f
	}
	.REPEAT 150 {
	dc.b	$00,$00,$00,$00,$0f
	}
	dc.b	$ff,0,0,0,0

TestText:	dc.b	"{\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\}",0
	dc.b	"^       odo of exmachina       ~",0
	dc.b	"^          PRESENTS :          ~",0
	dc.b	"^tHe MoDe7 rOtAtIoN zOoM wRiTeR~",0
	dc.b	"^   THIS ONE IS ONLY A OTHER   ~",0
	dc.b	"^ PART OF MY SOON COMMING DEMO ~",0
	dc.b	"^                              ~",0
	dc.b	"^ {\\\\\\\\\\\\\\\\\\\\\\\\\\} ~",0
	dc.b	"^ ^   greetings go out to:   ~ ~",0
	dc.b	"^ ^                          ~ ~",0
	dc.b	"^ ^MAVE/CSL, BASELINE, DARYL,~ ~",0
	dc.b	"^ ^ALPHA FLIGHT, MAGICAL, ME,~ ~",0
	dc.b	"^ ^EVH, RED SECTOR, AJAXIANS,~ ~",0
	dc.b	"^ ^ELITENDO, PARADOX, TAIPAN,~ ~",0
	dc.b	"^ ^NESquik, SKID ROW, MYSTIC,~ ~",0
	dc.b	"^ ^FLORIAN W. SAUER,  ARTHUR,~ ~",0
	dc.b	"^ ^KAI UWE SP.,   MICHAEL W.,~ ~",0
	dc.b	"^ ^JEAN-MICHEL-JARRE, X-TREM,~ ~",0
	dc.b	"^ ^PREDATOR, RAY , SYNTH'O'N,~ ~",0
	dc.b	"^ ^                          ~ ~",0
	dc.b	"^ [||||||||||||||||||||||||||] ~",0
	dc.b	"^                              ~",0
	dc.b	"^  THE TEXT ABOVE IN THE BOX,  ~",0
	dc.b	"^  IS ONLY >SHIT< TO TEST THE  ~",0
	dc.b	"^  OUTFIT OF THIS ZOOM WRITER  ~",0
	dc.b	"^  SEE YOU IN A GALAXY.......  ~",0
	dc.b	"^       ODO OF EXMACHINA       ~",0
	dc.b	"[||||||||||||||||||||||||||||||]",0,$ff

Mod7Palette	.bin		ExM:ExM-Zoom.Snes/ExM-Zoom.Col

;vectors
	ORG $ffea
	dcr.w VBI
	ORG $fffc
	dcr.w $8000
	.pad
gfxdata:	.bin		ExM:ExM-Zoom.Snes/ExM-Zoom.Mod7
