#include "screendefs.h"

.text
.align 4

.globl _moveblock
_moveblock:
	pushl %ebp
	movl %esp,%ebp
	
	pushl %esi
	pushl %edi

	pushl %eax
	pushl %ebx
	pushl %ecx
	pushl %edx
		
	movl 8(%ebp),%esi	!source
	movl 12(%ebp),%edi	!dest
	movl 16(%ebp),%ecx	
	movl %ecx,%eax		

	shrl $3,%ecx		/* shift right byte 3 bits same as div by 8 */
	movl %ecx,16(%ebp)	/* save result on stack */	
	movl $SCREENWIDTH,%edx  /* calulate line adjustment */
	subl %eax,%edx
	movl %edx,%eax
	movl 20(%ebp),%edx		
moveline:
	movl 16(%ebp),%ecx
linemove:
	movsl
	movsl
	loop linemove
	movl %esi,%ebx	/* move to start of next line */
	addl %eax,%ebx
	movl %ebx,%esi
	movl %edi,%ebx
	addl %eax,%ebx
	movl %ebx,%edi

	decl %edx	/*decrement y counter*/
	jne moveline	

	popl %edx
	popl %ecx
	popl %ebx
	popl %eax

	popl %edi
	popl %esi
		
	movl %ebp,%esp
	popl %ebp
	ret

.globl _cutblock
_cutblock:
	pushl %ebp
	movl %esp,%ebp
	
	pushl %esi
	pushl %edi

	pushl %eax
	pushl %ebx
	pushl %ecx
	pushl %edx
		
	movl 8(%ebp),%esi	!source
	movl 12(%ebp),%edi	!dest
	movl 16(%ebp),%ecx	
	movl %ecx,%eax		

	shrl $3,%ecx		/* shift right byte 3 bits same as div by 8 */
	movl %ecx,16(%ebp)	/* save result on stack */	
	movl $SCREENWIDTH,%edx  /* calulate line adjustment */
	subl %eax,%edx
	movl %edx,%eax
	movl 20(%ebp),%edx		
copyline:
	movl 16(%ebp),%ecx
linecopy:
	movsl
	movsl
	loop linecopy
	movl %esi,%ebx
	addl %eax,%ebx
	movl %ebx,%esi

	decl %edx	/*decrement y counter*/
	jne copyline	

	popl %edx
	popl %ecx
	popl %ebx
	popl %eax

	popl %edi
	popl %esi
		
	movl %ebp,%esp
	popl %ebp
	ret

.align 4
.globl _pasteblock
_pasteblock:
	pushl %ebp
	movl %esp,%ebp
	
	pushl %esi
	pushl %edi

	pushl %eax
	pushl %ebx
	pushl %ecx
	pushl %edx
		
	movl 8(%ebp),%esi	!source
	movl 12(%ebp),%edi	!dest
	movl 16(%ebp),%ecx	!x width
	movl %ecx,%eax	
	shrl $3,%ecx		/*adjust for a 48bit width*/
	movl %ecx,16(%ebp)	/*write back new value*/
	movl $SCREENWIDTH,%edx
	subl %eax,%edx		/*calulate line adjustment*/
	movl %edx,%eax
	movl 20(%ebp),%edx	/*height*/	
copyline2:
	movl 16(%ebp),%ecx
linecopy2:
	movsl
	movsl
	loop linecopy2
	movl %edi,%ebx
	addl %eax,%ebx
	movl %ebx,%edi

	decl %edx	/*decrement y counter*/
	jne copyline2	

	popl %edx
	popl %ecx
	popl %ebx
	popl %eax

	popl %edi
	popl %esi
		
	movl %ebp,%esp
	popl %ebp
	ret

.align 4
.globl _andpasteblock
_andpasteblock:
	pushl %ebp
	movl %esp,%ebp

	pushl %esi
	pushl %edi

	pushl %eax
	pushl %ebx
	pushl %ecx
	pushl %edx
		
	movl 8(%ebp),%esi	!source (mask)
	movl 12(%ebp),%edi	!dest
	movl 16(%ebp),%ecx	!x width
	movl %ecx,%eax	
	shrl $3,%ecx		/*adjust for a 32bit width*/
	movl %ecx,16(%ebp)	/*write back new value*/
	movl $SCREENWIDTH,%edx
	subl %eax,%edx		/*calulate line adjustment*/

copyline3:
	movl 16(%ebp),%ecx
linecopy3:
	lodsl 			/* load si into eax and increment si */
	andl %eax,(%edi)	/* AND block uint32 into destination */ 
	incl %edi		/* increment destination address */
	incl %edi		/* increment destination address */
	incl %edi		/* increment destination address */
	incl %edi		/* increment destination address */

	lodsl 			/* load si into eax and increment si */
	andl %eax,(%edi)	/* AND block uint32 into destination */ 
	incl %edi		/* increment destination address */
	incl %edi		/* increment destination address */
	incl %edi		/* increment destination address */
	incl %edi		/* increment destination address */
	loop linecopy3

	movl %edi,%ebx
	addl %edx,%ebx
	movl %ebx,%edi

	decl 20(%ebp)	/*decrement y counter*/
	jne copyline3	

	popl %edx
	popl %ecx
	popl %ebx
	popl %eax

	popl %edi
	popl %esi
		
	movl %ebp,%esp
	popl %ebp
	ret

.align 4
.globl _xorpasteblock
_xorpasteblock:
	pushl %ebp
	movl %esp,%ebp

	pushl %esi
	pushl %edi

	pushl %eax
	pushl %ebx
	pushl %ecx
	pushl %edx
		
	movl 8(%ebp),%esi	!source (mask)
	movl 12(%ebp),%edi	!dest
	movl 16(%ebp),%ecx	!x width
	movl %ecx,%eax	
	shrl $3,%ecx		/*adjust for a 32bit width*/
	movl %ecx,16(%ebp)	/*write back new value*/
	movl $SCREENWIDTH,%edx
	subl %eax,%edx		/*calulate line adjustment*/

copyline4:
	movl 16(%ebp),%ecx
linecopy4:
	lodsl 			/* load si into eax and increment si */
	xorl %eax,(%edi)	/* AND block uint32 into destination */ 
	incl %edi		/* increment destination address */
	incl %edi		/* increment destination address */
	incl %edi		/* increment destination address */
	incl %edi		/* increment destination address */

	lodsl 			/* load si into eax and increment si */
	xorl %eax,(%edi)	/* AND block uint32 into destination */ 
	incl %edi		/* increment destination address */
	incl %edi		/* increment destination address */
	incl %edi		/* increment destination address */
	incl %edi		/* increment destination address */
	loop linecopy4

	movl %edi,%ebx
	addl %edx,%ebx
	movl %ebx,%edi

	decl 20(%ebp)	/*decrement y counter*/
	jne copyline4

	popl %edx
	popl %ecx
	popl %ebx
	popl %eax

	popl %edi
	popl %esi
		
	movl %ebp,%esp
	popl %ebp
	ret
