[Back to CHARS SWAG index] [Back to Main SWAG index] [Original]

    program Reverse;

    {
      Sample program demonstrating manipulation of the VGA (EGA?)
      alphanumeric character set using the 80x25 character mode.

      The only thing this program does is to copy the current character
      set from the video adapter, and restore it in such a way that all
      the characters appear upside-down.  To restore the characters,
      simply run the program again.  Not that this is a terribly useful
      thing to do, mind you...

      NOTE: This has not been tested on monochrome monitors or in
            other video modes.

      Written using Borland Pascal 7.0.

      For more information on character sets for other video modes and
      a whole bunch of good stuff on the EGA & VGA in general, you will
      want the following book:

       Title     - "Programmer's Guide to PC & PS/2 Video Systems"
       Author    - Richard Wilton, 1987
       Publisher - Microsoft Press
                   16011 NE 36th Way
                   Box 97017
                   Redmond, Washington  98073-9717
    }

      var
        I, J: integer;
        CBuf: array [0..8191] of byte; { Buffer for original character map }

      procedure CharGenModeOn;

      { I'm sorry that there is no explanation here, but I did this a while
        ago and I don't have the reference with me right now.   }

        begin
          asm
            cli
            mov       dx,03C4h
            mov       ax,0100h
            out       dx,ax
            mov       ax,0402h
            out       dx,ax
            mov       ax,0704h
            out       dx,ax
            mov       ax,0300h
            out       dx,ax
            sti
            mov       dl,0CEh
            mov       ax,0204h
            out       dx,ax
            mov       ax,0005h
            out       dx,ax
            mov       ax,0006h
            out       dx,ax
         end;
       end;

      procedure CharGenModeOff;

        begin
          asm
            cli
            mov       dx,03C4h
            mov       ax,0100h
            out       dx,ax
            mov       ax,0302h
            out       dx,ax
            mov       ax,0304h
            out       dx,ax
            mov       ax,0300h
            out       dx,ax
            sti
            mov       dl,0CEh
            mov       ax,0004h
            out       dx,ax
            mov       ax,1005h
            out       dx,ax
            mov       ax,0E06h
            out       dx,ax
            mov       ah,0Fh
            int       10h
            cmp       al,7
            jne       @skip
            mov       ax,0806h
            out       dx,ax
          @skip:
          end;
        end;

      begin
        CharGenModeOn;  { Get access to character map }

        { Copy the current character map into the buffer }
        move( mem[$A000: 0], CBuf, 8192 );

        { Restore the map, inverting the top 16 scan lines.

          Characters are stored in a 8x32 pixel matrix, allowing
          for characters that are 32 scan lines high.  Each byte
          in the buffer represents one scan line of a single
          character.  In the 80x25 character mode only the first
          16 scan lines are displayed, so we need to be a little
          careful about what bytes are swapped. }

        for I := 0 to 255 do                { Each of the 256 characters }
          for J := 0 to 15 do               { Top 16 scan lines of each }
            mem[$a000:((I*32) + J)] := CBuf[(I*32) + (15 - J)];

        CharGenModeOff; { Restore normal video operations }
      end.

[Back to CHARS SWAG index] [Back to Main SWAG index] [Original]