PARADISE.TXT


                ┌────────────────────────────────────┐
                │ Programming the Paradise SVGA Chip │
                └────────────────────────────────────┘

                 Written for the PC-GPE by Mark Feldman
            e-mail address : u914097@student.canberra.edu.au
                             myndale@cairo.anu.edu.au

                  Please read the file SVGINTRO.TXT
              (Graphics/SVGA/Intro PC-GPE menu option)

            ┌───────────────────────────────────────────┐
            │      THIS FILE MAY NOT BE DISTRIBUTED     │
            │ SEPARATE TO THE ENTIRE PC-GPE COLLECTION. │
            └───────────────────────────────────────────┘


┌────────────┬───────────────────────────────────────────────────────────────
│ Disclaimer │
└────────────┘

I assume no responsibility whatsoever for any effect that this file, the
information contained therein or the use thereof has on you, your sanity,
computer, spouse, children, pets or anything else related to you or your
existance. No warranty is provided nor implied with this information.


┌──────────────┬─────────────────────────────────────────────────────────────
│ Introduction │
└──────────────┘

Western Digital have made a series of Paradise chips, the PVGA1A, WD90C00
and WD90C11. Each chip is fully compatible with it's predecessors. There
is also a WD90C10 which is a stripped down version of the WD90C00 used for
motherboard VGA implementations and does not support 256 color modes higher
that 320x200; this chip will not be discussed here.

┌─────────────────────┬──────────────────────────────────────────────────────
│ Paradise Extensions │
└─────────────────────┘

To modify any of the Paradise extended registers you must enable the
extensions. Disable them once you are done.

To enable extensions:

PortW[$3CE] := $050F; { Extensions on             }
PortW[$3D4] := $8529; { Unlock PR10-PR17          }
PortW[$3C4] := $4806; { Unlock extended sequencer }

To disable extensions :

PortW[$3CE] := $000F; { Extensions off          }
PortW[$3D4] := $0029; { Lock PR10-PR17          }
PortW[$3C4] := $0006; { Lock extended sequencer }

┌────────────────────────────────────┬─────────────────────────────────────────
│ Identifying the Paradise SVGA Chip │
└────────────────────────────────────┘

To identify if a Paradise SVGA chip is present read the 4 bytes at memory
address C000:007D. These bytes should be the string "VGA=".

                ┌──────────────────────────────┐
                │  Memory Address   Value      │
                ├──────────────────────────────┤
                │  C000:007Dh        86d ('V') │
                │  C000:007Eh        71d ('G') │
                │  C000:007Fh        65d ('A') │
                │  C000:0080h        61d ('=') │
                └──────────────────────────────┘

┌────────────────────────────────────────────┬───────────────────────────────
│ Identifying which Paradise Chip is Present │
└────────────────────────────────────────────┘

The Paradise chip present can be determined by trying to access selected
registers. The following pseudo-code will determine the chip id:

var old_value : byte;

Enable Extensions

{ Test for a PVGA1A }
Port[$3D4] := $2B
old_value := Port[$3D5]
Port[$3D5] := $AA
if Port[$3D5] <> $AA then
  begin
    chip is a PVGA1A
    Port[$3D5] := old_value
    return
  end
Port[$3D5] := old_value

{ Distinguish between WD90C00 and WD90C10 }
Port[$3C4] := $12
old_value := Port[$3C5]
Port[$3C5] := old_value and $BF
if (Port[$3C5] and $40) <> 0 then
  begin
    chip is a WD90C00
    return
  end
Port[$3C5] := old_value or $40
if (Port[$3C5] and $40) = 0 then
  begin
    chip is a WD90C00
    Port[$3C5] := old_value
    return
  end
Port[$3C5] := old_value

{ Distinguish between WD90C10 and WD90C11 }
Port[$3C4] := $10
old_value := Port[$3C5]
Port[$3C5] := old_value and $FB
if (Port[$3C5] and $04) <> 0 then
  begin
    chip is a WD90C10
    Port[$3C5] := old_value
    return
  end
Port[$3C5] := old_value or $04
if (Port[$3C5] and $04) = 0 then
  begin
    chip is a WD90C10
    Port[$3C5] := old_value
    return
  end

{ We made it this far so it's a WD90C11 }
chip is a WD90C11
Port[$3C5] := old_value

┌─────────────────────────────────┬──────────────────────────────────────────
│ Paradise Graphics Display Modes │
└─────────────────────────────────┘

        ┌─────────────────────────────────────────────────────────┐
        │ Mode     Resolution       Colors    Chips               │
        ├─────────────────────────────────────────────────────────┤
        │ 58h      800x600          16        pVGA1, WDC90cxx     │
        │ 59h      800x600          2         pVGA1, WDC90cxx     │
        │ 5Eh      640x400          256       pVGA1, WDC90cxx     │
        │ 5Fh      640x480          256       pVGA1, WD90cxx      │
        │ 5Ah      1024x768         2         WD90cxx             │
        │ 5Bh      1024x768         4         WD90cxx             │
        │ 5Dh      1024x768         16        WD90cxx, c11 (512K) │
        │ 5Ch      800x600          256       WD90c11 (512K)      │
        └─────────────────────────────────────────────────────────┘

┌─────────────────────────┬──────────────────────────────────────────────────
│ Paradise Display Memory │
└─────────────────────────┘

Remember, extensions must be enabled before any of the following procedures
are called.

The Paradise can work in either single-paging mode, duel-paging mode or
read/write mode. There are two registers used to select banks in each of
the Paradise bank selection modes:

          PR0A Address Offset A
          Index : 09h at port 3CEh
          Read/Write at port 3CFh
          ┌───┬───┬───┬───┬───┬───┬───┬───┐
          │ 7 │ 6 │ 5 │ 4 │ 3 │ 2 │ 1 │ 0 │
          └───┴───┴───┴───┴───┴───┴───┴───┘
                └───────────┬───────────┘
                           Bank

          PR0B Address Offset A
          Index : 0Ah at port 3CEh
          Read/Write at port 3CFh
          ┌───┬───┬───┬───┬───┬───┬───┬───┐
          │ 7 │ 6 │ 5 │ 4 │ 3 │ 2 │ 1 │ 0 │
          └───┴───┴───┴───┴───┴───┴───┴───┘
                └───────────┬───────────┘
                           Bank

There are 128 banks and the bank granularity is 4k, so if you want a bank
granularity of 64k you must multiply the bank number by 16.


Single Paging Mode
──────────────────

In single paging mode PR0A is set to map a bank to host memory at
A000:0000-FFFFh. The bank is used for both reading and writing operations.
To set up for single paging mode use the following procedure:

Port[$3C4] := $11;                 { Disable read/write mode }
Port[$3C5] := Port[$3C5] and $7F;
Port[$3CE] := $0B;                 { Disable PR0B            }
Port[$3CF] := Port[$3CF] and $F7;

To set a 64k bank number in single paging mode use the following procedure:

PortW[$3CE] := bank_number Shl 12 + $09;


Duel Paging Mode
────────────────

In duel paging mode PR0A is set to map a bank to host memory at
A000:0000-7FFFh and PR0B is set to map a bank to host memory at
A000:8000-FFFFh. Each bank is used for both reading and writing operations.

To set up for duel paging mode use the following procedure:

Port[$3C4] := $11;                 { Disable read/write mode }
Port[$3C5] := Port[$3C5] and $7F;
Port[$3CE] := $0B;                 { Enable PR0B             }
Port[$3CF] := Port[$3CF] or $80;

To set the lower bank use the same procedure as given for single-paging
mode. The upper bank can be set with the following procedure:

PortW[$3CE] := bank_number Shl 12 + $0A;


Read/Write Paging Mode
──────────────────────

In read/write paging mode PR0A is used to map a bank at A000:0000-FFFFh for
read operations and PR0B is used to map a bank at A000:0000-FFFFh for write
operations. To set up for read/write paging mode use the following procedure:

Port[$3C4] := $11;                 { Enable read/write mode }
Port[$3C5] := Port[$3C5] or $80;
Port[$3CE] := $0B;                 { Enable PR0B             }
Port[$3CF] := Port[$3CF] or $80;

Setting PR0A and PR0B is the same as for duel paging mode.