[comp.lang.pascal] Hercs and Turbo

josh%ILJCT.BITNET@wiscvm.wisc.EDU (Joshua D. Males) (09/15/87)

  I pulled this out of an Info-IBMPC digest a few months ago. Some guy from some
Scandinavian country sent it in. Here it goes:
Since this information was recently asked and I've not seen the answer, I
looked it up. It comes from the manual for a board that claims to be "100%
Hercules compatible", and seems to be just that. I take no responsibility of
its accuracy.

The card has a text mode and a graphics mode. In the text mode, it is just
like IBM monochrome adapter. In graphics mode it has two graphic pages ( 0 and
1 ), resolution 720 x 348. It also has a printer port, which I will not discuss
further.

The board uses the ( Motorola ) 6845 display adapter. ( Look the data sheet
for more information about that. )

The graphics are in memory, page 0 in B0000 - B7FFF and page 1 in B8000 -
BFFFF ( hex ).

The I/O ports are:
        03B4: 6845 index register
        03B5: 6845 data register
        03B8: display mode control port
        03B9: set light pen flip flop
        03BA: display status port
        03BB: reset light pen flip flop
        03B.C.: printer data port
        03BD: printer status port
        03BE: printer control port
        03BF: configuration switch

The display mode control port sets the mode of operation for the card.
        bit 0: not used
        bit 1: 0 = text mode
               1 =  graphics mode ( note: you must reprogram the 6845 if you
                    change this bit! ( otherwise you may blow your monitor))
        bit 2: not used
        bit 3: 0 = blank the screen
               1 = screen active
        bit 4: not used
        bit 5: 0 = text blinker off
               1 = text blinker on ( every character whose attribute bits
                   indicate blinking, will blink )
        bit 6: not used
        bit 7: 0 = page 0
               1 = page 1

The display status port:
        bit 0: 0 = normal character
        bit 3: 0 = dots off
               1 = dots on ( I don't know the meaning of this ... )
        bit 7: 0 = vertical retrace
               1 = active display
      ,all other bits unused.

The configuration switch:
        bit 0: 0 = prevents the setting of graphics mode
               1 = allows it
        bit 1: 0 = masks page 1 out of memory map
               1 = brings it to the memory

In graphics mode the offset (zinto the pagez) of the byte containing the dot
(x,y) is 2000H*(y mod 4) + 90*integer(y/4) + integer (x/8),
    where [ 0 <= x <= 719 and 0 <= y <= 347 ]

The following are example procedures in Turbo Pascal:

const
   indexreg = $03b4;
   datareg = $03b5;
   control = $03b8;
   config_switch = $03bf;
var
   graphic_paramtrs : array [ 0..11] of byte;
   text_paramtrs : array [ 0..11] of byte;
   hgccntrlport_value : byte;

procedure init_graphics;
begin
   graphic_paramtrs [0] := $35;
   graphic_paramtrs [1] := $2d;
   graphic_paramtrs [2] := $2e;
   graphic_paramtrs [3] := 7;
   graphic_paramtrs [4] := $5B;
   graphic_paramtrs [5] := 2;
   graphic_paramtrs [6] := $57;
   graphic_paramtrs [7] := $57;
   graphic_paramtrs [8] := 2;
   graphic_paramtrs [9] := 3;
   graphic_paramtrs [10] := 0;
   graphic_paramtrs [11] := 0;

   text_paramtrs [0] := $61;
   text_paramtrs [1] := $50;
   text_paramtrs [2] := $52;
   text_paramtrs [3] := $0F;
   text_paramtrs [4] := $19;
   text_paramtrs [5] := 6;
   text_paramtrs [6] := $19;
   text_paramtrs [7] := $19;
   text_paramtrs [8] := 2;
   text_paramtrs [9] := $0d;
   text_paramtrs [10] := $0b;
   text_paramtrs [11] := $0c;

   hgccntrlport_value:= $20;
   port[config_switch]:=3;
end;

procedure screen_on;
begin
   hgccntrlport_value := hgccntrlport_value or $08;
   port[control] := hgccntrlport_value;
end;

procedure screen_off;
begin
   hgccntrlport_value := hgccntrlport_value and $f7;
   port[control] := hgccntrlport_value;
end;

procedure textmode;
var
   i: integer;
begin
   screen_off;
   hgccntrlport_value:= (hgccntrlport_value and $fd) or $20;
   port[control] := hgccntrlport_value;
   for i:= 0 to 11 do
   begin
       port[indexreg]:= i;
       port[datareg]:=text_paramtrs [i];
   end;
   clrscr;
   screen_on;
end;

procedure graphicsmode;
var
   i: integer;
begin
   init_graphics;
   screen_off;
   hgccntrlport_value := ( hgccntrlport_value or $02 ) and $df;
   port[control] := hgccntrlport_value;
   for i:= 0 to 11 do
   begin
       port[indexreg]:= i;
       port[datareg]:=graphic_paramtrs [i];
   end;
   screen_on;
end;