//============================================================
//============================================================
//==														==
//==					DissBits Routines					==
//==														==
//============================================================
//============================================================


//========================================================  Includes  

#include "Globals.h"
#include "UnivUtilities.h"
#include "DissBits.h"


//========================================================  DissBitsMed13QD  

void DissBits13QD (Rect *clippedRect)

{
	Rect			transRect;
	RgnHandle		clipRgn;
	register short	value = 1;
	register short	mask = 0x0CA0;
	short			rectH, rectV;
	
	clipRgn = NewRgn();
	RectRgn(clipRgn, clippedRect);
	
	do
	{
		if (value & 1)						// pseudo-random # between 1 and 4095 
			value = (value >> 1) ^ mask;
		else
			value = (value >> 1);
		
		rectH = (value % 80) * 8;			// convert value into screen coords 
		rectV = ((value / 80) * 10) + clippedRect->top;
		SetRect(&transRect, rectH, rectV, rectH + 8, rectV + 10);
		
		if (isColor)						// copy bits within rect to mainWndo 
			CopyBits(&((GrafPtr)offCWorkPtr)->portBits, &(((GrafPtr)mainWndo)->portBits), 
					&transRect, &transRect, srcCopy, clipRgn);
		else
			CopyBits(&offWorkBits, &(mainWndo->portBits), &transRect, &transRect, 
					srcCopy, clipRgn);
	} while (value != 1);
	
	rectH = 0;								// handle special case for zero 
	rectV = clippedRect->top;
	SetRect(&transRect, rectH, rectV, rectH + 8, rectV + 10);
	if (isColor)
		CopyBits(&((GrafPtr)offCWorkPtr)->portBits, &(((GrafPtr)mainWndo)->portBits), 
				&transRect, &transRect, srcCopy, clipRgn);
	else
		CopyBits(&offWorkBits, &(mainWndo->portBits), &transRect, &transRect, 
				srcCopy, clipRgn);
	
	DisposeRgn(clipRgn);
}


//========================================================  DissBits12QD  

void DissBits12QD (Rect *clippedRect)

{
	Rect			transRect;
	RgnHandle		clipRgn;
	register short	value = 1;
	register short	mask = 0x0500;
	short			rectH, rectV;
	
	clipRgn = NewRgn();
	RectRgn(clipRgn, clippedRect);
	
	do
	{
		if (value & 1)						// pseudo-random # between 1 and 2047 
			value = (value >> 1) ^ mask;
		else
			value = (value >> 1);
		
		rectH = (value % 64) * 8;			// convert # into screen coords 
		rectV = ((value / 64) * 12) + clippedRect->top;
		SetRect(&transRect, rectH, rectV, rectH + 8, rectV + 12);
		
		if (isColor)						// copy bits within rect to mainWndo 
			CopyBits(&((GrafPtr)offCWorkPtr)->portBits, &(((GrafPtr)mainWndo)->portBits), 
					&transRect, &transRect, srcCopy, clipRgn);
		else
			CopyBits(&offWorkBits, &(mainWndo->portBits), &transRect, &transRect, 
					srcCopy, clipRgn);
	} while (value != 1);
	
	rectH = 0;								// handle special case for zero 
	rectV = clippedRect->top;
	SetRect(&transRect, rectH, rectV, rectH + 8, rectV + 12);
	if (isColor)
		CopyBits(&((GrafPtr)offCWorkPtr)->portBits, &(((GrafPtr)mainWndo)->portBits), 
				&transRect, &transRect, srcCopy, clipRgn);
	else
		CopyBits(&offWorkBits, &(mainWndo->portBits), &transRect, &transRect, 
				srcCopy, clipRgn);
	
	DisposeRgn(clipRgn);
}


//========================================================  DissBits13Assm4  

void DissBits13Assm4 (Rect *clippedRect)

{
	Point		zeroPt;
	long		screenOffset, workOffset;
	short		mask = 0x3500;
	short		value = 1;
	short		rectH, rectV, rowsThen;
	char		theMode;
	
	SetPt(&zeroPt, 0, 0);
	ShieldCursor(clippedRect, zeroPt);
	theMode = true32b;
	SwapMMUMode(&theMode);
	
	do
	{
		if (value & 1)						// produces # between 1 and 16383 
			value = (value >> 1) ^ mask;
		else
			value = (value >> 1);
		
		rectH = (value % 160) * 4;			// convert to screen coords 
		rectV = ((value / 160) * 5) + clippedRect->top;
		
		if (rectV > (clippedRect->bottom - 5))
		{
			rowsThen = clippedRect->bottom - rectV;
			
			if (rowsThen > 0)
			{
				workOffset = (long)((long)rectH >> 1) + workRowOffsets[rectV] + 
						(long)offWorkPix;
				screenOffset = (long)((long)rectH >> 1) + screenRowAddrs[rectV];
				
				asm 68000
				{
					move.l			workOffset, a0		; source
					move.l			screenOffset, a1	; destination
					move.w			workRowBytes, d0
					move.w			screenRowBytes, d1
					move.w			rowsThen, d2		; how many rows
				@1	move.w			(a0),(a1)			; move a row
					adda.w			d0, a0
					adda.w			d1, a1
					subq.w			#1, d2				; decrement counter
					bne				@1					; branch if not zero
				}
			}
		}
		else
		{
			workOffset = (long)((long)rectH >> 1) + workRowOffsets[rectV] + 
					(long)offWorkPix;
			screenOffset = (long)((long)rectH >> 1) + screenRowAddrs[rectV];
			
			asm 68000
			{
				move.l			workOffset, a0			; source
				move.l			screenOffset, a1		; dest
				move.w			workRowBytes, d0
				move.w			screenRowBytes, d1
				move.w			(a0),(a1)				; move row 1
				adda.w			d0, a0
				adda.w			d1, a1
				move.w			(a0),(a1)				; move row 2
				adda.w			d0, a0
				adda.w			d1, a1
				move.w			(a0),(a1)				; move row 3
				adda.w			d0, a0
				adda.w			d1, a1
				move.w			(a0),(a1)				; move row 4
				adda.w			d0, a0
				adda.w			d1, a1
				move.w			(a0),(a1)				; move row 5
			}
		}
	} while (value != 1);
	
	rectH = 0;								// handle special case for zero 
	rectV = clippedRect->top;
	workOffset = (long)((long)rectH >> 1) + workRowOffsets[rectV] + 
			(long)offWorkPix;
	screenOffset = (long)((long)rectH >> 1) + screenRowAddrs[rectV];
	
	asm 68000
	{
		move.l			workOffset, a0			; source
		move.l			screenOffset, a1		; destination
		move.w			workRowBytes, d0
		move.w			screenRowBytes, d1
		move.w			(a0),(a1)				; move row 1
		adda.w			d0, a0
		adda.w			d1, a1
		move.w			(a0),(a1)				; move row 2
		adda.w			d0, a0
		adda.w			d1, a1
		move.w			(a0),(a1)				; move row 3
		adda.w			d0, a0
		adda.w			d1, a1
		move.w			(a0),(a1)				; move row 4
		adda.w			d0, a0
		adda.w			d1, a1
		move.w			(a0),(a1)				; move row 5
	}
	
	SwapMMUMode(&theMode);
	ShowCursor();
}


//========================================================  DissBits12Assm4  

void DissBits12Assm4 (Rect *clippedRect)

{
	Point		zeroPt;
	long		screenOffset, workOffset;
	short		value = 1;
	short		mask = 0x1B00;
	short		rectH, rectV, rowsThen;
	char		theMode;
	
	SetPt(&zeroPt, 0, 0);
	ShieldCursor(clippedRect, zeroPt);
	theMode = true32b;
	SwapMMUMode(&theMode);
	
	do
	{
		if (value & 1)							// produces value between 1 and 8191 
			value = (value >> 1) ^ mask;
		else
			value = (value >> 1);
		
		rectH = (value % 128) << 2;				// convert to screen coords 
		rectV = ((value / 128) * 6) + clippedRect->top;
		
		if (rectV > clippedRect->bottom - 6)
		{
			rowsThen = clippedRect->bottom - rectV;
			
			if (rowsThen > 0)
			{
				screenOffset = (rectH >> 1) + screenRowAddrs[rectV];
				workOffset = (long)((long)rectH >> 1) + workRowOffsets[rectV] + 
						(long)offWorkPix;
				
				asm 68000
				{
					move.l			screenOffset, a0
					move.l			workOffset, a1
					move.w			screenRowBytes, d0
					move.w			workRowBytes, d1
					move.w			rowsThen, d2
				@1	move.w			(a1),(a0)			; move a row
					adda.w			d0, a0
					adda.w			d1, a1
					subq.w			#1, d2				; decrement counter
					bne				@1					; branch if not zero
				}
			}
		}
		else
		{
			screenOffset = (rectH >> 1) + screenRowAddrs[rectV];
			workOffset = (long)((long)rectH >> 1) + workRowOffsets[rectV] + 
					(long)offWorkPix;
			
			asm 68000
			{
				move.l			screenOffset, a0
				move.l			workOffset, a1
				move.w			screenRowBytes, d0
				move.w			workRowBytes, d1
				move.w			(a1),(a0)				; move row 1
				adda.w			d0, a0
				adda.w			d1, a1
				move.w			(a1),(a0)				; move row 2
				adda.w			d0, a0
				adda.w			d1, a1
				move.w			(a1),(a0)				; move row 3
				adda.w			d0, a0
				adda.w			d1, a1
				move.w			(a1),(a0)				; move row 4
				adda.w			d0, a0
				adda.w			d1, a1
				move.w			(a1),(a0)				; move row 5
				adda.w			d0, a0
				adda.w			d1, a1
				move.w			(a1),(a0)				; move row 6
			}
		}
	} while (value != 1);
	
	rectH = 0;								// handle special case for zero 
	rectV = clippedRect->top;
	
	screenOffset = (rectH >> 1) + screenRowAddrs[rectV];
	workOffset = (long)((long)rectH >> 1) + workRowOffsets[rectV] + 
			(long)offWorkPix;
	
	asm 68000
	{
		move.l			screenOffset, a0
		move.l			workOffset, a1
		move.w			screenRowBytes, d0
		move.w			workRowBytes, d1
		move.w			(a1),(a0)				; move row 1
		adda.w			d0, a0
		adda.w			d1, a1
		move.w			(a1),(a0)				; move row 2
		adda.w			d0, a0
		adda.w			d1, a1
		move.w			(a1),(a0)				; move row 3
		adda.w			d0, a0
		adda.w			d1, a1
		move.w			(a1),(a0)				; move row 4
		adda.w			d0, a0
		adda.w			d1, a1
		move.w			(a1),(a0)				; move row 5
		adda.w			d0, a0
		adda.w			d1, a1
		move.w			(a1),(a0)				; move row 6
	}
	
	SwapMMUMode(&theMode);
	ShowCursor();
}


//========================================================  DissolveWorkToMain  

void DissolveWorkToMain (void)

{
	switch (displayMode)
	{
		case kDisplay9Inch:
		case kDisplay12Inch:
			if (useQD)
				DissBits12QD(&offWorkRect);
			else
			{
				if (isColor)
					DissBits12Assm4(&offWorkRect);
				else
					DissBits12QD(&offWorkRect);
			}
			break;
		case kDisplay13Inch:
			if (useQD)
				DissBits13QD(&offWorkRect);
			else
			{
				if (isColor)
					DissBits13Assm4(&offWorkRect);
				else
					DissBits13QD(&offWorkRect);
			}
			break;
		default:
			break;
	}
	
}

