Using XOR to Improve Graphics Displays
-------------------------------------------------------------------
Abi Wong


   This diskette contains files
      XORPIC.TXT   ;this message file.

      XORPIC.PAS   ;a demo program for the procedure XORPIC.

      FXORPIC.PAS  ;also a demo program, but faster because it uses the
                    external procedure XORPIC.BIN to increase the speed.

      XORPIC.BIN   ;an assembly program performs the same function as the
                   Procedure XORPIC in XORPIC.PAS, but faster. It can be used
                   as an external procedure.

      WXORPIC.PAS  ;same as XORPIC.PAS but also supports GRAPHWINDOW-type
                    calls.


GRAPH.P has a lot of useful procedures that will take us a long time if we
want to duplicate them for our own purposes. So, I decided to make my XORPIC
compatible with it, especially the GETPIC and PUTPIC, instead of making my own
GETPIC and PUTPIC. Although there are a few bugs in the PUTPIC routine, they
are not fatal. So I decided to make my XORPIC compatible with the bugs, since
someone may like to use the PUTPIC to put the picture to the screen and then
use XORPIC to clear it out. I have implemented the XORPIC for Hires mode only.
If anyone wants to change it for 320*200 mode, please be aware that the
formula in the Turbo 3.0 manual (p.173) has some mistakes in its description
of the 320x200 mode: 

     Size = ((Width + 3) div 4) * Height * 2 + 6
     
should be

     Size = ((Width + 3) div 4) * Height + 6

XORPIC does not support windows. I think most applications don't need window
support. The problem with supporting windowing is maintaining the window
corner. In WXORPIC, a GWINDOW procedure is added to replace Turbo Pascal's
GRAPHWINDOW. (Actually GWINDOW just captures the corner coordinates and then
passes control to GRAPHWINDOW.) It may be a better idea to modify GRAPH.P and
replace the procedure GRAPHWINDOW with a procedure similar to GWINDOW; in this
way you need not change all the calls to GRAPHWINDOW in your programs.


Here is a brief explaination of XORPIC:

Before we go into the detail of XORPIC, it is necessary to explain some of the
aspects of the hardware in the Color Graphics Adaptor. When we switch on the graphic mode
the upper left corner address on the screen is $B800:0.

   MSB  6 5 4 3 2 1 0
                       (0,0) 
            $B800:0     ..........................<----80 byte/line 
            $B800:$2000 .                              640 dots for Hires or 
            $B800:$50   .    (X,Y)                     320 of 2bits per pixel for 
            ($50=80)    .                              320x200 
                        . (200 Lines)


The screen can be considered as a map of 80 bytes/line and 200 lines/page.
The addresses of lines are not all in sequence. It is in sequence for all odd
lines and even lines but each odd line is $2000 greater than its previous even
line. So if Y,X is the screen coordinate starting from 0,0 then the address
of that co-ordinate can be calculated by 

     Y := Div 2 * 80;
     If Odd Then Y := Y + $2000 + (X + 7) Div 8;
     
Each line pair occupies 80 bytes, and an odd-numbered line is located $2000
bytes above the previous even-numbered line. Offset to the horizontal position
in byte 7 was added before the Div, since the last byte is not necessarily a
whole byte; the point is then located in the above address and is on the
position of bit 8 - (X Mod 8).

It is quite obvious that when you try to Put the pattern to an address that is
not a multiple of 8 that the pattern will start somewhere in the middle of a
byte. But when you use GetPic, it always aligns the data in so that the
pattern starts at the MSB. It is necessary to calculate how many bits we have
to shift the data before we can put it to the screen. The variable
Bit_To_Shift is used to tell how many times a data point will have to shift. 

Each byte of pattern is shifted and then XOR'd with the data on the screen. 
However, after the shift some bits will be shifted out of the byte. These 
bits are the beginning bytes of next pixel, and they are stored in the
variable Remain and are OR'd with the shifted pattern in the next byte. 

Often the size of the pattern is also not a multiple of 8, but the pixel data
has to occupy a whole byte anyway.  As the result, the last byte from  GetPic
contains more than enough bits, and it is necessary to mask it off before
writing it to the screen. The Last_Mask is the mask for this purpose.
