Controlling the EGA/VGA/SVGA Blink-Intensity state

If you have questions about any aspect of QBasic programming, or would like to help fellow programmers solve their problems, check out this board!

Moderators: Pete, Mods

Post Reply
RickWesh
Newbie
Posts: 1
Joined: Sat May 29, 2010 9:21 pm

Controlling the EGA/VGA/SVGA Blink-Intensity state

Post 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> 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
Post Reply