		LOCALS @@

		JUMPS

		PUBLIC	diviif, mulfif, mulfff, mattrans, matmul, DrawBuf

CODE		SEGMENT BYTE PUBLIC

		ASSUME	CS:CODE

		EXTRN	PutPixel: NEAR

		INCLUDE	fixedop.asm

	.386

		; div integer (dx:ax) by integer (bx:cx), return fixed (dx.ax)

diviif		PROC NEAR
		sal	ebx, 16
		mov	bx, cx
		movsx	edx, dx
		sal	eax, 16
		idiv	ebx
		mov	edx, eax
		sar	edx, 16
		ret
diviif		ENDP

		; mul fixed (dx.ax) times integer (cx), return fixed (dx.ax)

mulfif		PROC NEAR
		movsx	ecx, cx
		sal	edx, 16
		mov	dx, ax
		mov	eax, edx
		imul	ecx
		mov	edx, eax
		sar	edx, 16
		ret
mulfif		ENDP

		; just the mulf as a procedure (dx.ax * bx.cx =: dx.ax)

mulfff		PROC NEAR
		sal	edx, 16
		mov	dx, ax
		mov	eax, edx
		sal	ebx, 16
		mov	bx, cx
		mulf	ebx
		mov	edx, eax
		sar	edx, 16
		ret
mulfff		ENDP

		; mattrans transforms the integer point passed as
		; dword-aligned param using the matrix at ss:[bx]
		; result is on stack

mattrans	PROC NEAR
		ARG	point: QWORD
		push	bp
		mov	bp, sp
		push	si
		movsx	ecx, WORD PTR point[0]		; x
		movsx	esi, WORD PTR point[4]		; y
		mov	eax, DWORD PTR ss:[bx]
		imul	ecx
		mov	DWORD PTR point[0], eax
		mov	eax, DWORD PTR ss:[bx+4]
		imul	esi
		add	DWORD PTR point[0], eax

		mov	eax, DWORD PTR ss:[bx+8]
		imul	ecx
		mov	DWORD PTR point[4], eax
		mov	eax, DWORD PTR ss:[bx+12]
		imul	esi
		add	DWORD PTR point[4], eax

		pop	si bp
		ret
mattrans	ENDP

matmulrow       MACRO   Row
		mov	ecx, a&Row&1
		mov	eax, ecx
		mul2Dot14 b11
		mov	ebx, eax
		mov	eax, a&Row&2
		mul2Dot14 b21
		add	eax, ebx
		mov	a&Row&1, eax

		mov	eax, ecx
		mul2Dot14 b12
		mov	ebx, eax
		mov	eax, a&Row&2
		mul2Dot14 b22
		add	eax, ebx
		mov	a&Row&2, eax
		ENDM

		; matmul multiplies a 16.16 2x2 matrix with
		; a 2.14 2x2 matrix and stores the result in the
		; 16.16 matrix.

matmul          PROC NEAR
		ARG	Mat2Dot14: DWORD, Mat16Dot16: DWORD = ArgSize
		push	bp
		mov	bp, sp
		push	ds
		les	di, Mat2Dot14
		lds	si, Mat16Dot16

a11		EQU	(DWORD PTR [si])
a12		EQU	(DWORD PTR [si+4])
a21		EQU	(DWORD PTR [si+8])
a22		EQU	(DWORD PTR [si+12])

b11		EQU	(WORD PTR es:[di])
b12		EQU	(WORD PTR es:[di+2])
b21		EQU	(WORD PTR es:[di+4])
b22		EQU	(WORD PTR es:[di+6])

		matmulrow 1
		matmulrow 2

		pop	ds
		pop	bp
		ret	ArgSize
matmul		ENDP

DrawBuf		PROC NEAR
		ARG	Count: WORD, Buffer: DWORD = ArgSize
		push	bp
		mov	bp, sp
		les	di, Buffer
@@1:
		mov	bl, es:[di]
		xor	bh, bh
		mov	eax, es:[di+1]
		mov	ecx, es:[di+5]
		add	di, 9
		roundf	eax
		roundf	ecx
		push	es di
		push	ax cx bx
		call	PutPixel
		pop	di es
		dec	Count
		jnz	@@1
		pop	bp
		ret
DrawBuf		ENDP

CODE		ENDS

		END
