[alt.msdos.programmer] Trident VGA mode 60: write a pixel, .ASM

nelson@IMAGE.SOE.CLARKSON.EDU (Russ Nelson) (01/18/90)

The following code will write a single pixel to a Trident VGA in mode 60,
that's 1024 x 768.  It's a disassembly of the same function from the VGA bios.
It should be usable to write general-purpose access functions.
-russ

comment \

INT 10 - VIDEO - WRITE DOT ON SCREEN
        AH = 0Ch
        AL = color of dot (0/1 in mode 6, 0-3 in modes 4 and 5)
             if bit 7 set, new color will be XORed with current pixel
        BH = display page (ignored if mode only supports one page)
        CX = column
        DX = row
Note:   only valid in graphics modes
SeeAlso: AH=0Dh
---------------------------------------------
\

;write a dot in video mode 60h (Trident)

write_dot_mode_60:

	CALL	l082A			;clear sequencer register b.
	MOV	BL,AL			;get the color.
	CALL	l26BC			;map the color.
	MOV	SI,AX			;save it in si for a while.
	CALL	l2681
	MOV	AL,08			;output the mask register.
	OUT	DX,AX
	XCHG	BX,SI			;get si into bx, and our memory
					;  address into si.
	MOV	AX,0205h		;select write mode 2.
	OUT	DX,AX
	OR	BL,BL			;is the color signed?  (should we
	JNS	25BA			;  xor the existing bit?)  go if not.
	MOV	AX,1803h		;set the function to XOR.
	OUT	DX,AX
25ba:
	MOV	AL,[SI]			;load the latches
	MOV	AL,BL
	MOV	[SI],AL			;store the new pixel's value.
	MOV	AX,0FF08h		;reset graphics controller bit mask
	OUT	DX,AX
	MOV	AX,0005h		;reset to mode zero.
	OUT	DX,AX
	CALL	l2344
	JMP	2525

l2344:
	MOV	AX,0003			;reset function and rotate.
	MOV	DX,03CEh
	OUT	DX,AX
	MOV	AX,0F02h			;store F into CRT controller reg. 2.
	MOV	DL,0C4h
	OUT	DX,AX
	RET

;this video mode puts odd bytes on odd pages, even bytes on even pages.

graphics_addr	dw	0a000h

l2681:
;enter with cx = x, dx = y.
;exit with dx pointing to the graphics controller,
;	ds -> screen memory,
;	ah = bit of byte in memory.
	MOV	BX,CX			;Isolate the X byte.
	SHR	BX,1
	SHR	BX,1
	SHR	BX,1
	SHR	BX,1
	MOV	AX,DX
	MOV	DX,[044Ah]		;get the screen width in bytes.
	SHR	DX,1
	MUL	DX			;multiply the Y by the width.
	ADD	BX,AX			;accumulate the address.

	AND	CL,0Fh			;get the X position
	MOV	AX,8000h		;shift the bit over.
	SHR	AX,CL
	OR	AH,AH			;Did we shift it off?
	MOV	CH,AH			;assume no -- put bit in ch,
	MOV	AH,5			;  and page value.
	JNZ	26AB
	MOV	AH,10			;yes, get page value,
	MOV	CH,AL			;  and put bit in ch.
26ab:
	MOV	DX,3C4h			;set CRT controller register 2.
	MOV	AL,2
	OUT	DX,AX
	MOV	AH,CH			;get the bit into ah.
	MOV	DS,CS:graphics_addr	;get the screen address into ds
	MOV	DX,3CEh			;get the graphics controller into dx.
	RET

l26C0	db	0, 3, 12, 15

;map colors 0 through 3 into 0, 3, 12, and 15.
l26bc:
	PUSH	BX
	AND	BL,3
	XOR	BH,BH
	MOV	AL,CS:l26c0[BX]
	POP	BX
	RET

l082a:
	PUSH	AX	;clear sequencer register b.
	PUSH	DX
	MOV	DX,3C4h
	MOV	AX,000Bh
	OUT	DX,AX
	POP	DX
	POP	AX
	RET
-- 
--russ (nelson@clutx [.bitnet | .clarkson.edu])  Russ.Nelson@$315.268.6667
Violence never solves problems, it just changes them into more subtle problems