Coder's Guild Mailing List

Re: Mode 13

Posted by Weasel on 1999-03-22

Will wrote:
> 
> Could anyone please explain more of the mode 13 issue and mode z to me? I don't quite understand the Hardware accessing portion.
> Will

in Mode 13 the vga-memory is accessable in segment 0a000h and has a very
simple structure: every pixel is assigned one byte. (something you need
not to know: the value in this byte points to one color-register of the
DAC). addressing starts top left (like always).

to set a pixel you can use the following pascal procedure:

CONST
  ScrSeg = $0a000;


PROCEDURE PutPixel(x,y : word; c : byte);
var
  PxlOfs : word;
BEGIN
  PxlOfs := y * 320  +  x;
  Mem[ScrSeg:PxlOfs] := c;
END;

or to make it a bit simplier:

VAR
  SCREEN : array[0..199, 0..319] of byte ABSOLUTE $a000:0000;

screen[x,y]:=c;



background:
-----------
In Mode 13 the video adapter hides its 4 planes and fakes this linear
structure. Internal the vga card converts this address and spreds the
data to its 4 planes by using the 2 least significant bits to select the
plane. for purposes of address generation these two bits are then set to
zero.
so it looks like this:

/-- Address
|

      Plane 0     Plane 1     Plane 2     Plane 3
0    Pixel 0/0       1/0         2/0         3/0
1       -           -           -           -
2       -           -           -           -
3       -           -           -           -
4        4/0         5/0         6/0         7/0
5       -           -           -           -
6       -           -           -           -
7       -           -           -           -

distribution of pixels(x/y) in the video ram




ModeX
=====
=====


One big disadvantage of Mode 13 is that it offers only one page. To get
4 pages you just need to do a few things:

* switch of chain-4
* ensure odd/even mode is not active
* switch CRTC to bytemode


PROCEDURE EnterModeX;
BEGIN
  { switch to Mode13 first}
  ASM
    mov ax,13h
    int 10h
  END;

 {chain-4 , odd/even}
  Port[$3c4]:= 4;
  Port[$3c5]:= (Port[$3c5] and (not 8)) or 4;

 {doubleword addressing OFF, byte addressing ON}
  Port[$3d4]:= $14;
  Port[$3d5]:= Port[$3d5] and (not 64);
  Port[$3d4]:= $17;
  Port[$3d5]:= Port[$3d5] or 64;
END;

after switching to ModeX you should clean the videoRAM since there is
still bit-rubbish at places wich where not visible before. (see later)

Accessing gets a little more complicated now since you have to select
the right planes yourself now.

Addressing:
offset = Y * 80 + X div 4
plane = X mod 4;

VAR
  ScreenWidth : word ABSOLUTE $0040:$004a; {BIOS variable}
  {should be 80 IIRC}

PROCEDURE PutPixel(x, y: word; c: byte; PageOffset : word);
VAR
  ScrOfs : word;
BEGIN
  ScrOfs:=ScreenWidth * 2 * y  +  x div 4  + PageOffset;
  Port[$3c4]:= 2;
  Port[$3c5]:= 1 SHL (x and 3); { set pitplane mask}
  mem[ScrSeg:ScrOfs] := c;
END;
  
with PageOffset you can select the page you want to edit.
You see that this value is simply added up to the ofset value, so
setting it to 0 shows you the zero-th page, setting it to
2*200*ScreenWidth = 32000 shows you the first page, 64000 the second and
9600 the third page.

To read a pixel we need to use the Read Plane Select Register:

FUNCTION GetPixel(x, y : word; PageOffset : word)  : byte;
VAR
  ScrOfs : word;
BEGIN
  ScrOfs:=ScreenWidth * 2 * y  +  x div 4  + PageOffset;
  Port[$3ce]:= 4;
  Port[$3cf]:= x and 3; { set read-plane select}
  mem[ScrSeg:ScrOfs] := c;
END;





To display page 1 instead of page 0 do the following:

SetLinearStartingAddress(PageOffset : word);

with the same PageOffsets like above. (It may be that you have to double
these values of divide them by two. I simply cannot remember)



VAR
  CRTCPort : word ABSOLUTE $0040:$0063; {BIOS variable}
  { this  should be 3d4 IIRC in Mode13 but is different for other modes
}

PROCEDURE SetLinearStartingAddress(LSA : word);
BEGIN
  Port[CRTCPort  ]:= $0c;
  Port[CRTCPort+1]:= hi(LSA);
  Port[CRTCPort  ]:= $0d;
  Port[CRTCPort+1]:= lo(LSA);
END;





Don't hestitate to ask if you have any questions.



-- 
Weasel                          mailto:palfrader@xxxxxxx.xxx
Peter                   http://www.cosy.sbg.ac.at/~ppalfrad/
------------------------------------------------------------
     We have full klingon console support just in case.
                         -- Alan Cox on linux-kernel