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!
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