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.
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.
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
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
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
FOR Row = 1 TO 15
FOR PlaceBar = 0 TO 15
StartPos = ABS(Row - 2) + 1
Item$ = Colors$(15 - PlaceBar)
IF Row <2> LEN(Item$) + 1 THEN
Text$ = " "
Text$ = " " + MID$(Item$, StartPos, 1) + " "
IF PlaceBar > 7 THEN Switch = 1
IF Switch = 1 THEN
Fg = 31 - PlaceBar
Fg = 15 - PlaceBar
Bg = PlaceBar
FPrint Text$, Row + 6, 1 + PlaceBar * 5, Fg, Bg
Switch = 0
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
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)
ELSE 'restore blinking (normal setting)
SELECT CASE Board
Out MDAHerc, &H29
Out CGA, &H29
Regs.ax = &H1003
Regs.bx = 1
CALL Interrupt(&H10, Regs, Regs)
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