	TITLE	egacopybits

	.286p

X	EQU	4

IBM_TEXT	SEGMENT  WORD PUBLIC 'CODE'
IBM_TEXT	ENDS

_DATA	SEGMENT
EXTRN	_GXtoEGA:BYTE
_DATA	ENDS

; vgaSetScanline(psrc, pdst, soff, doff, n, alu)
; char *psrc, *pdst
; [bp+4]	psrc
; [bp+8]	pdst
; [bp+12]	soff
; [bp+14]	doff
; [bp+16]	n
; [bp+18]	alu

IBM_TEXT	SEGMENT
	ASSUME	CS: IBM_TEXT
	ASSUME	DS: _DATA
	public	_vgaSetScanline
_vgaSetScanline	PROC NEAR
	push	bp
	mov	bp,sp
	push	si
	push	di
	push	ds
	; load alu
	mov	bx,WORD PTR [bp+18]	;alu
	mov	bl,BYTE PTR _GXtoEGA[bx]
	cmp	bl,0
	jge	$L1
	mov	ax,-1		; return -1 if we can't do it.
	jmp	$L0
$L1:
	mov	ah,bl
	and	ah,03h		; get op
	shl	ah,3
	mov	al,3		; shift register
	mov	dx,03ceh
	out	dx,ax		; set op part of shift register
	mov	ax,0f01h	; enable set/reset register
	out	dx,ax
	and	bl,0ch		; get pre-op part of GXtoEGA
	shr	bl,2
	les	di,8[bp]
	cmp	bl,2		; one
	ja	$L2		; jmp if invert
	mov	bh,0fh
	je	$L3		; jmp if one
	cmp	bl,1		; zero
	jl	$L2		; jmp if copy
	sub	bh,bh		; set to 0
$L3:
	mov	ax,5
	; code used for 1/0.  We don't even need to look at psrc
	out	dx,ax		; just in case
	sub	al,al		; register 0: set/reset register
	mov	ah,bh
	out	dx,ax
	mov	ah,080h
	mov	cl,14[bp]
	shr	ah,cl		; ah = 0x80 >> doff
	mov	al,8		; register 8: mask register
	mov	cx,16[bp]	; n
$P4:
	out	dx,ax
	mov	bl,es:[di]	; preload
	mov	es:[di],bl	; set/reset register: don't care what we store
	shr	ah,1
	jne	$L5
	mov	ah,080h
	inc	di
$L5:
	loop	$P4
	jmp	$L0
$L2:
	; We know soff is either 4 or 0.  Let that bit be the "soff"
	; bit and bit 0 be the "invert" flag.
	mov	bh,12[bp]	; soff
	and	bl,1
	or	bl,bh
	lds	si,4[bp]	; psrc
	mov	bh,080h
	mov	cl,14[bp]	; doff
	shr	bh,cl		; bh = 0x80 >> doff

	mov	cx,16[bp]	; n
	; start of loop
$P2:
	mov	ah,ds:[si]
	test	bl,1
	je	$L6		; copy
	not	ah		; invert
$L6:
	test	bl,4
	je	$L7
	and	ah,0fh
	and	bl,not 4
	inc	si
	jmp	short $L8
$L7:
	shr	ah,4
	or	bl,4
$L8:
	sub	al,al		; register 0: set/reset
	out	dx,ax
	mov	al,8		; register 8: mask register
	mov	ah,bh
	out	dx,ax
	mov	ah,es:[di]	; preload
	mov	es:[di],ah	; set/reset register: don't care what we store
	shr	bh,1		; mask >>= 1
	jne	$L9
	mov	bh,080h
	inc	di
$L9:
	loop	$P2

$L0:
	mov	ax,3		; set op back to copy
	out	dx,ax
	mov	ax,1		; set select set/reset register to 0
	out	dx,ax
	mov	ax,0ff08h	; set mask register to 0xff
	out	dx,ax

	pop	ds
	pop	di
	pop	si
	pop	bp
	ret
_vgaSetScanline	ENDP
IBM_TEXT	ENDS
	END
