; Coloumn Cache, 256 colors, Copr. 1994 Matthias K”ppe

		INCLUDE ccachdef.asm
		INCLUDE grserv.asm

CODE		SEGMENT BYTE PUBLIC

		PUBLIC	Flush_256o, Flush_256t, Setup_256

Cache		EQU	es:[bx].TCacheHeader

	Def_Mapping
	Def_SegToLinear

Setup_256	PROC NEAR
		push	ax
		mov	ax, BytesPerLine
		mul	dx
		pop	cx
		cmp	cx, ClipRect.A.x
		jl	SHORT @@1
		push	cx
		jmp	SHORT @@2
@@1:            push	ClipRect.A.x
@@2:		sar	cx, 3
		mov	Cache.chStartCol, cx

		sal	cx, 3
		add	ax, cx
		adc	dx, 0
		push	dx ax
		mov	ax, ActiveSeg
		call    SegToLinear
		pop	cx
		add	ax, cx
		pop	cx
		adc	dx, cx
		call	MapLinear
		mov	WORD PTR Cache.chDest[0], ax
		mov	WORD PTR Cache.chDest[2], dx
		pop	cx
		push	cx
		and	cl, 7
		mov	al, 0FFh
		shr	al, cl
		mov	Cache.chLeftMask, al
		mov	cx, ClipRect.B.x
		and	cl, 7
		mov	ax, 0FF00h
		shr	ax, cl
		mov	Cache.chRightMask, al
		pop	cx
		sar	cx, 3
		mov	Cache.chLeftCol, cx
		mov	ax, ClipRect.B.x
		sar	ax, 3
		mov	Cache.chRightCol, ax
		mov	ax, WindowSize
		mov	Cache.chWindowSize, ax
		mov	Cache.chTemp1, ds
		retn
Setup_256	ENDP

	; Get the byte mask
	;
	; In:	ax	coloumn number
	;
	; Out:	ah	mask

GetMask		PROC NEAR
		mov	dh, Cache.chMask
		cmp	ax, Cache.chLeftCol
		jl	SHORT @@0
		jg	SHORT @@1
		and	dh, Cache.chLeftMask
@@1:		cmp	ax, Cache.chRightCol
		jg	SHORT @@0
		jl	SHORT @@2
		and	dh, Cache.chRightMask
@@2:		mov	ah, dh
		retn
@@0:            add	sp, 2
		add	si, 8
		MapNext	si, Cache.chWindowSize, SetDS
		retn				; back to caller
GetMask		ENDP

Flush_256o	PROC NEAR
		call	GetMask			; ah 	Mask

		push	ax
		mov	dx, 03ceh		; GC
		mov	ax, 0ff08h		; Bit mask
		out	dx, ax
		mov	ax, 4005h		; Write mode 0
		out	dx, ax
		pop	ax

		mov	Cache.chTemp2, ds

		PushMapping Cache.chTemp1, Cache.chTemp2
		push	di si
@@o:
		mov	dl, BYTE PTR Cache.chColor
		mov	dh, BYTE PTR Cache.chBkColor
		mov	cx, Cache.chColHeight
@@o0:
		push	si ax
		PushMapping Cache.chTemp1, Cache.chTemp2
		mov	al, es:[di]		; Get bits
		inc	di
@@o1:
		shl	ah, 1			; next bit in mask
		jc	SHORT @@o4
		jz	@@o5
		shl	al, 1
		;inc	si
		add	si, 1
		MapNext	si, Cache.chWindowSize, SetDS
		jmp	@@o1
@@o4:
		test	BYTE PTR [si], 0

		shl	al, 1			; next bit in map
		jnc	SHORT @@o2

		mov	BYTE PTR [si], dl
		;inc	si
		add	si, 1
		MapNext	si, Cache.chWindowSize, SetDS
		or	ah, ah
		jnz	@@o1

		jmp	SHORT @@o5
@@o2:
		mov	BYTE PTR [si], dh
@@o3:
		;inc	si
		add	si, 1
		MapNext	si, Cache.chWindowSize, SetDS
		or	ah, ah
		jnz	@@o1
@@o5:
		PopMapping Cache.chTemp1, Cache.chTemp2, ax
		pop	ax si
		add	si, Cache.chBPL
		MapNext	si, Cache.chWindowSize, SetDS
		loop	@@o0

		pop	si di
		PopMapping Cache.chTemp1, Cache.chTemp2, ax
		add	si, 8
		MapNext	si, Cache.chWindowSize, SetDS

		retn
Flush_256o	ENDP

Flush_256t	PROC NEAR
		call	GetMask			; ah 	Mask

		push	ax
		mov	dx, 03ceh		; GC
		mov	ax, 0ff08h		; Bit mask
		out	dx, ax
		mov	ax, 4005h		; Write mode 0
		out	dx, ax
		pop	ax

		mov	Cache.chTemp2, ds

		PushMapping Cache.chTemp1, Cache.chTemp2
		push	di si
@@t:
		mov	ch, BYTE PTR Cache.chColor
		mov	cl, BYTE PTR Cache.chColHeight
		mov	dx, si
@@t0:
		PushMapping Cache.chTemp1, Cache.chTemp2
		mov	al, es:[di]		; Get bits
		inc	di
		and	al, ah			; Mask 'em
@@t1:
		shl	al, 1
		jz	SHORT @@t3
		jnc	SHORT @@t2
		test	BYTE PTR [si], 0
		mov	BYTE PTR [si], ch
@@t2:
		;inc	si
		add	si, 1
		MapNext	si, Cache.chWindowSize, SetDS
		jmp	@@t1
@@t3:
		jnc	SHORT @@t4
		test	BYTE PTR [si], 0
		mov	BYTE PTR [si], ch
@@t4:
		PopMapping Cache.chTemp1, Cache.chTemp2, si
		add	dx, Cache.chBPL
		MapNext	dx, Cache.chWindowSize, SetDS
		mov	si, dx
		dec	cl
		jnz	@@t0

		pop	si di
		PopMapping Cache.chTemp1, Cache.chTemp2, ax
		add	si, 8
		MapNext	si, Cache.chWindowSize, SetDS

		retn
Flush_256t	ENDP

CODE		ENDS

		END
