; zxwister
; a 256byte twister effect by evilpaul^atebit
; compiles with pasmo

		org		32768


ROM_PLOT			equ		0x22dc
ROM_DRAW_LINE		equ		0x24b7
ROM_STACK_A			equ		0x2d28

TWISTER_GFX			equ		32768+512
SINE_TABLE			equ		32768+1024
DRAW_BUFFER			equ		32768+2048

CALC_DELETE          equ	0x02
CALC_MULTIPLY        equ	0x04
CALC_ADDITION        equ	0x0f
CALC_SIN             equ	0x1f
CALC_COS             equ	0x20
CALC_INT             equ	0x27
CALC_DUPLICATE       equ	0x31
CALC_CONST           equ	0x34
CALC_STK_ZERO        equ	0xa0
CALC_ST_MEM_0        equ	0xc0
CALC_END_CALC        equ	0x38


start
		
		; -- make the sin table ( ok, so it's a cosine table.. ) --
		rst		0x28
		db		CALC_STK_ZERO
		db		CALC_END_CALC
		ld		de,SINE_TABLE
sineLoop
		push	de

		rst		0x28
		db		CALC_CONST,0x2b,0x49				;const pi/128
		db		CALC_ADDITION
		db		CALC_DUPLICATE
		db		CALC_COS
		db		CALC_CONST,0x33,0x7f				; const 8
		db		CALC_MULTIPLY
		db		CALC_INT
		db		CALC_ST_MEM_0
		db		CALC_DELETE
		db		CALC_END_CALC
		ld		a,(iy+0x5a)							; third byte of calculator memory 0
		pop		de
		add		a,8
		ld		(de),a

		ld		h,HIGH(16384+2048*3+32*16)			; we've got a bunch of bytes spare, so let's do 
 		ld		a,e									; a mildly extravagant progress bar..
		rrca
		rrca
		rrca
		and		%11111
		ld		l,a
		ld		(hl),%01010000						; bright red

		inc		e
		jr		nz,sineLoop


		; -- set up screen gfx pattern --
		ld		hl,16384
		push	hl
		ld		(hl),%10101010
		ld		de,16384+1
		ld		c,-1								; replacement for:		ld		bc,256-1
		ldir
		ld		(hl),%01010101
		dec		c									; replacement for:		ld		bc,256-1
		ldir
		pop		hl
		inc		de									; replacement for:		ld		de,16384+512
		ld		b,HIGH(2048*3-512)					; replacement for:		ld		bc,2048*3-512
		ldir


		; -- main loop --
mainLoop
		; sync and present
		halt
		ld		hl,DRAW_BUFFER+1
		push	hl
		ld		de,16384+2048*3
		ld		b,3									; replacement for:		ld		bc,768
		ldir

		; clear buffer
		pop		de
		ld		hl,DRAW_BUFFER
		push	hl
		ld		(hl),c								; c = 0
		ld		b,3									; replacement for:		ld		bc,768-1			( we ignore the -1 )
		ldir


		; draw this frame to the buffer
		pop		de									; draw to second screen
		exx
posspd	ld		de,0								; pos and speed
		ld		b,24								; 24 lines of screen
oneRow

		ld		a,e									; advance position per line
		add		a,d
		ld		e,a
		exx

		ld		c,a									; a bit of audio..
		and		%11000
		out		(254),a
		ld		a,c

		bit		7,a									; decide draw order
		jr		nz,order2
order1	ld		hl,colours1
		ld		bc,colours2
		jr		draw
order2	add		a,128
		ld		hl,colours2
		ld		bc,colours1

draw	push	hl
		push	bc
		ld		h,HIGH(SINE_TABLE)
		ld		l,a
		ex		af,af'
		ld		a,(hl)
		pop		hl
		call	drawRow		
		ex		af,af'
		add		a,128
		ld		h,HIGH(SINE_TABLE)
		ld		l,a
		ld		a,(hl)
		pop		hl
		call	drawRow
		ld		hl,32
		add		hl,de
		ex		de,hl

		exx		
		djnz	oneRow
		
		ld		de,posspd+1						; advance position per frame
		ld		a,(de)
		add		a,9
		ld		(de),a
		
speed	ld		hl,SINE_TABLE
		ld		a,(hl)
		inc		de
		ld		(de),a							; speed per line
		ld		a,l
		add		a,2
		ld		(speed+1),a
		
		; -- draw logo --
		ld		de,logoData
		ld		hl,DRAW_BUFFER+32*20+26+1
allLogoSegments
		ld		a,(de)
		or		a
		jr		z,mainLoop
		rlca
		rlca
		and		%11111
		ld		b,a
		ld		a,(de)
		and		%00111000
		jr		z,skipSegment
oneSegment
		ld		(hl),a
		inc		hl
		djnz	oneSegment
endedSegment
		inc		de
		jr		allLogoSegments
skipSegment
		ld		a,l
		add		a,b
		ld		l,a
		jr		endedSegment
		
		
drawRow
		push	de
		add		a,e
		ld		e,a
		ld		bc,11
		ldir
		pop		de
		ret
		

logoSegment macro ?colour, ?length
		db		(?colour<<3)+(?length>>2)+(?length<<6)
	endm
logoData
		logoSegment		%010,2
		logoSegment		%000,1
		logoSegment		%001,2
		logoSegment		%000,26
		logoSegment		%010,3
		logoSegment		%000,1
		logoSegment		%001,3
		logoSegment		%000,25
		logoSegment		%010,1
		logoSegment		%110,1
		logoSegment		%010,1
		logoSegment		%000,1
		logoSegment		%001,3
;		db				0

colours1
		db		%00000000,%01100000,%01100100,%01100100,%01100110,%01110110,%01110111,%01110110,%01100110,%01100100	;,%00000000
colours2
		db		%00000000,%01010000,%01010010,%01010010,%01010011,%01011011,%01011111,%01011011,%01010011,%01010010 ;,%00000000



		end		start

