program Scroller;
var  
   	i,j,k,scrollx,x,y,scroll,l,time: byte = 0; 

	@define charPos $1C00
	@define orgChar $58

	@define charCopyPos 64

	tp,h1,h2,zp : pointer;
@export "resources/charsets/charset.flf" "resources/charsets/charset.bin" 256
	charset:incbin("resources/charsets/charset.bin", @charPos);

	chars: array[16] of byte = (0,1,2, 0,   3,4,5,0);

	text : string = ("SMOOTH SEXY SCROLLING ON THE VIC 20     ");
	
	@define ScrollerY 12



procedure PrintText();
begin
	h1:=@charPos+8;//$05D0;
	k:=tp[0];
	if (k<>$20) then begin
	k:=k-65;
	if (k<>0) then begin
		if (k>31) then begin
//			inczp(h1,31*8);
			zp:=zp+(31*8);
			k:=k-31;
		end;
		end;
	h1:=h1+k*8;

	moveto(21,@ScrollerY,$30);
//	fill(screenmemory,2,40);
	for i:=0 to 8 do begin
		j:=getbit(h1[i],7-scroll);
		k:=0;//$20;
		if (j=1) then k:=1;//@charCopyPos;
		screenmemory[0]:=k;
		screenmemory:=screenmemory+22;
//		inczp(screenmemory,22);
	end;
	end;
	inc(scroll);

	if (scroll=8) then begin
		tp:=tp+1;
		scroll:=0;
		if (tp[0]=0) then tp:=#text;
	end;
end;


procedure CopyToScreen();
begin
	moveto(0,@ScrollerY,$30);
	zp:=screenmemory;
	moveto(0,@ScrollerY,$10);

	for y:=0 to 8 do begin
		for x:=2 to 20 do begin
			i:=zp[x]*2 + zp[x+1];
			k:=$20;
			if (i<>0) then k:=@charCopyPos+i;
			screenmemory[x]:=k;

		end;
		zp := zp + screen_width;;
		screenmemory := screenmemory + screen_width;
	end;
	

end;


procedure Clear();
begin
	fill(^$1000,$20,0);
	fill(^$1100,$20,0);
	fill(^$3000,$0,0);
	fill(^$3100,$00,0);

	zp:=$9400;
	for i:=0 to 23 do begin
		j:=i+1;
		if (j&3=0) then
		fill(zp,YELLOW,22)
		else
		fill(zp,YELLOW,22);
		zp:=zp+screen_width;
	end;

	SCREEN_BG_COLOR:=BLACK + BLACK*16;
end;


procedure UpdateChars();
begin

	
	k:=(8-scrollx);

	i:=sine[time*6]/48;

	zp:=@charPos+$47*8;
	zp:=zp+i*8;
	h1:=@charPos+@orgChar*8;
	
	memcpy(zp,0,h1,8);

	CopyBytesShift(^@charPos+^@orgChar*^8,^@charPos+^@charCopyPos*^8+^8,8,k,1);
	CopyBytesShift(^@charPos+^@orgChar*^8,^@charPos+^@charCopyPos*^8+^16,8,scrollx,0);
	CopyBytesShift(^@charPos+^@orgChar*^8,^@charPos+^@charCopyPos*^8+^24,8,scrollx,2);


end;


interrupt RasterInterrupt();
begin
	startirq(0);
	
	VSCROLL_REGISTER:=sine[time*2]/32+30;


	closeirq();
end;


begin
	setcharsetlocation(@charPos);

	tp:=#text;

	disablevic20irq();
	Clear();
	scroll:=0;

	VIAIRQ(RasterInterrupt(), $86, $56);
	
//	poke(^@charPos+^@orgChar*^8,0,0);
//	poke(^@charPos+^@charCopyPos*^8+^16+^8,0,0);
	while (true) do begin
		waitforraster(0);
		SCREEN_BG_COLOR:=BLACK;
		inc(time);
		

		if (scrollx=1) then begin	
			screenmemory:=$3000+@ScrollerY*22;
			h2:=screenmemory+1;
			for i:=0 to 8 do begin
				memcpy(h2,0,screenmemory,21);
				h2 := h2 + screen_width;
				screenmemory := screenmemory + screen_width;
			end;

		end;
		if (scrollx=2) then PrintText();

		inc(scrollx);
		if (scrollx=8) then scrollx:=0;
		UpdateChars();
		if (scrollx=0) then begin
			CopyToScreen();
		end;


	end;


end.
