Page 1 of 1

Controlling the EGA/VGA/SVGA Blink-Intensity state.

Posted: Tue May 25, 2010 6:39 am
by RickWesh
Description: Controlling the EGA/VGA/SVGA Blink-Intensity state through the Attribute Control Register.

There are several attribute control registers in the EGA/VGA and all compatible hardware.
The register we'll be working with is the Attribute Mode Register.

To access this register is different for the HGC/CGA boards than it is for EGA/VGA boards and all those that followed.

On a EGA/VGA we can program the registers using the CALL INTERRUPT(&H10, regs, regs)
The AX register should be set to &H1003 to access the Attribute Control Register, and the BX register should be set to 0 to disable the blinking state, or to 1 enabling blinking again.

On the CGA the control Attribute Control register is at &H3D8
Bit five of this register controls the blink state on the CGA. Set to 0 it then blinking is enabled. When set to 1 blinking is disabled.

On the HGC display this register is at &H3B8, also using bit 5 of that register.

Since the control registers on both the HGC/CGA cards can both be handled with a simple OUT statement we don't need to call an interrupt for these boards.

The example code still works well with QB45/PDS7 in a COMMAND, CMD shell, and in DOSBOX. The standard QB.QLB/QBX.QLB was used to test this using my HP Pavilion zv6000 laptop with Windows XP.

In case anyone is interested, it also works in FreeBASIC using the QB/QBX library.

'$INCLUDE: 'c:\dosemu\qb45\QB.BI'

This is the edited example I submitted that was published in volume 12#7 of PC-Magazine.

When the code is run it will place columns of color bars on the display using all sixteen colors in a text mode screen on the VGA/SVGA display.
Image

Since the HGC/CGA/EGA boards are no longer in use those portions of code are there simply for reference.

I've edited the original code I wrote simply to test on WinXP and further comment the code for this posting.

Code: Select all

DEFINT A-Z
'$INCLUDE: 'c:\dosemu\qb45\QB.BI'

DECLARE SUB FPrint (Text$, Row, Col, Fg, Bg)    ' Simple Print routine

DECLARE SUB SetBackIntens (Board, Setting)      ' Main routine to change the
												' blinking/intensity bit
												' on Herc/CGA/EGA/VGA boards

DIM SHARED Regs AS RegType                      ' Required by CALL Interrupt

DIM Colors$(0 TO 15)                            ' Used for DATA and color chg
												'
												'=-=-= Data for Color names
												'
DATA Bright White, Yellow, Bright Purple, Bright Red, Bright Cyan
DATA Bright Green, Bright Blue, Grey, White, Brown, Purple, Red
DATA Cyan, Green, Blue, Black

FOR X = 0 TO 15                                 ' Read the Color names in
  READ Colors$(X)
NEXT

MDAHerc = 0: CGA = 1: EgaVga = 2                ' Explicit variables
BlinkOn = 0: BlinkOff = 1

Title$ = "High intensity background colors in QuickBASIC 4.5"

CLS                                             ' Clear the screen and setup
CALL SetBackIntens(EgaVga, BlinkOff)            ' the initial blinking state
												'
												' Display our title
												'
FPrint Title$, 4, 40 - LEN(Title$) \ 2 + 1, 15, 0
												'
												' Now drop down the color
												' bars with opposing
												' foreground/background
FOR Row = 1 TO 15
  FOR PlaceBar = 0 TO 15
	StartPos = ABS(Row - 2) + 1
	Item$ = Colors$(15 - PlaceBar)
	IF Row < 2 OR Row > LEN(Item$) + 1 THEN
	  Text$ = "     "
	ELSE
	  Text$ = "  " + MID$(Item$, StartPos, 1) + "  "
	END IF

	IF PlaceBar > 7 THEN Switch = 1

	IF Switch = 1 THEN
	  Fg = 31 - PlaceBar
	ELSE
	  Fg = 15 - PlaceBar
	END IF

	Bg = PlaceBar
	FPrint Text$, Row + 6, 1 + PlaceBar * 5, Fg, Bg

  NEXT
  Switch = 0
NEXT

COLOR 7, 0                                              ' Normal Fg/Bg colors again
WHILE LEN(INKEY$) = 0: WEND                  ' Wait for a keypress

CALL SetBackIntens(EgaVga, BlinkOn)             ' Then restore the display
												' boards blink state setting

SUB FPrint (Text$, Row, Col, Fg, Bg) STATIC

  LOCATE Row, Col
  COLOR Fg, Bg
  PRINT Text$;

END SUB

SUB SetBackIntens (Board, Setting) Static
  CONST MDAHerc = &H3B8                'the MDA/Hercules port address
  CONST CGA = &H3D8                    'the CGA port address
  IF Setting THEN                      'exchange blinking for high-intensity
	SELECT CASE Board
	  CASE 0                           	'monochrome adapter
		Out MDAHerc, 9
	  CASE 1                            'CGA adapter
		Out CGA, 9
	  CASE 2                            'EGA/VGA adapter
		Regs.ax = &H1003
		Regs.bx = 0
		Call Interrupt(&H10, Regs, Regs)
	END Select
  ELSE                                 'restore blinking (normal setting)
	SELECT CASE Board
	  CASE 0
		Out MDAHerc, &H29
	  CASE 1
		Out CGA, &H29
	  CASE 2
		Regs.ax = &H1003
		Regs.bx = 1
		CALL Interrupt(&H10, Regs, Regs)
	END SELECT
  END If
END SUB
Keep in mind this was during a time when Windows 3.1 was still pretty new and MS-DOS 6 was just coming out.

I hope this helps anyone interested in programming the VGA/SVGA.
Thanks for reading