Miscellaneous Video Cards
Notes on various vintage video cards, where I don't have enough information for a full writeup (perhaps because I don't have the card, or I don't have the right monitor).
Orchid Graphics Adapter
A very early monochrome graphics card for the PC. This information is derived from the GSX-86 1.1 driver for the card.
- The card appears to be installed alongside an MDA or CGA, rather than replacing it, possibly driving a second monitor.
- There is no code to initialise the card or select a particular video mode.
- Resolution: 720 × 334
- Graphical framebuffer is at segment E000.
- May suffer from 'snow'. When writing to the screen, GSX does this:
- Wait for bit 0 of port 202h to be high (not in retrace?)
- Wait for bit 0 of port 202h to go low (in retrace?)
- Write 0 to port 200h (disable output?)
- Write to video RAM.
- Write 20h to port 200h (enable output?)
Tecmar Graphics Master
The Graphics Master is a card that attempts to combine CGA and MDA functionality. It can either be installed as the only card in a system, or alongside an existing CGA or MDA card (or both).
DIP switch settings are:
Configuration | JP7 | JP1/A | JP1/B | JP1/C | JP1/D | JP1/E | JP1/F | SW1 |
---|---|---|---|---|---|---|---|---|
Graphics Master is primary / only display, CGA monitor | Open | Closed | Closed | Closed | Open | Open | Open | Down |
Graphics Master is primary / only display, MDA monitor | Closed | Closed | Closed | Closed | Open | Open | Open | Up |
CGA is primary display, Graphics Master uses MDA monitor | Closed | Open | Closed | Closed | Open | Open | Open | Up |
MDA is primary display, Graphics Master uses CGA monitor | Open | Closed | Open | Closed | Open | Open | Open | Down |
Graphics Master (using CGA monitor) installed alongside CGA and MDA | Closed | Open | Open | Closed | Open | Open | Open | Down |
Graphics Master (using MDA monitor) installed alongside CGA and MDA | Closed | Open | Open | Closed | Open | Open | Open | Up |
Writing to port 03DAh controls the card's extra features:
Bit 7: Reverse the meaning of the 'bright' bit (in text & graphics modes) Bit 6: Unknown Bit 5: Set for 400-scanline modes? Bit 4: Moves screen left (used for modes that are 720 rather than 640 pixels wide?) Bit 3: Enable 128k framebuffer, 4-way interleave (eg: With framebuffer at 0xA000, first line comes from 0xA000, second from 0xA800, third from 0xB000, fourth from 0xB800). Done in text mode, this gets you something resembling the 160x100x16 mode, except it's 160x200. Bits 2-0: Framebuffer base address. In text modes bit 0 appears to be ignored. 111 => 0xA4000 110 => 0xA0000 101 => 0xAC000 100 => 0xA8000 011 => 0xB4000 010 => 0xB0000 001 => 0xBC000 000 => 0xB8000
The file tecmar.cfg at ftp://ftp.ucl.ac.uk/pub/users/ucklddc/dcprogs/hgraph/ gives the register values to write to the card for a 16-colour 640×400 video mode.
Vermont Microsystems IM-1024
The IM-1024 operates in the same way as the IBM PGC, but with a 1024×800 resolution and an extended command set. What makes it, as far as I know, almost unique is that there is a Windows 1.0x driver for it that supports 256 colours — see V1DSK.ZIP.
There appears to be an alternative method of sending data to the card, selected by setting the byte at 0xC6330 is set to 1. In this mode, the host calculates the maximum number of bytes it can write as (0xFF - [byte at 0xC6331]). It then writes up to that number of bytes to 0xC6000.
The IM-1024 is able to draw polygons with more than 255 vertices. The Windows driver does this by creating a command list containing two POLY commands in succession. When the command list is executed, the two lists are combined and a single polygon is drawn.
The Windows driver uses some standard PGC commands (such as MOVE, COLOR and DRAW) but coordinates are passed as 2-byte integers rather than the PGC's usual 4-byte fixed-point fractions. It also sends a number of commands not in the PGC's repertoire. The extended command set includes:
Command (ASCII mode) | Command byte (HEX mode) | Parameters | Notes |
---|---|---|---|
BLKMOV (BK) | DF | (6 words) | A screen-to-screen blit. The first four words define the rectangle to copy; the last two give its new location. |
BKVMOV (BKV) | DD | ||
BLINK (BL) | E5 | ||
BLKRD (BKR) | DA | (4 words) | Screen-to-memory blit. The four words give the opposite corners of a rectangle; all bytes in that rectangle are returned to the caller. Unlike IMAGER, the result is not RLE-compressed. |
BLKWR (BKW) | DB | ||
BUTRD (BRD) | 54 | ||
BUTTBL (BTB) | 79 | ||
BUTTON (BUT) | 78 | ||
CONVPV (CPV) | AD | ||
CONVVP (CVP) | AE | ||
COPROC (CP) | 6B | ||
DSPSIZ (DSP) | 4D | ||
IMGSIZ (IS) | 4E | width,height, unknown (3 words) | Sent at initialisation. Followed by two words and two bytes. The first two look like they define the framebuffer width and height, but I don't know what the other two are for. |
IPREC (IP) | E4 | ||
LINFUN (LF) | EB | mode (1 byte) | LINFUN is present on the PGC but only supports modes 0 (paint) or 1 (invert). The IM-1024 also accepts 2 (XOR) and 3 (AND). |
LUT8 (L8) | E6 | ink, r, g, b (4 bytes) | Define an ink in the palette using 8-bit RGB (the PGC uses 4-bit RGB). This is quite a common extension among PGC clones. |
LUT8RD (L8RD) | 53 | ink (1 byte) | Read back a palette register and return its 8-bit R/G/B values. |
LOCCUR (LC) | 1E | ||
LOCMAP (LM) | B4 | ||
LOCXH (LX) | 6C | ||
MPOLY (MP) | 23 | ||
MPOLYR (MPR) | 24 | ||
NULL | 00 | ||
OCOLOR (OC) | D4 | ||
PAN (PA) | B7 | x,y (words) | Sets the origin of the viewable part of the screen. For a 1024×800 display with a 1024×1024 framebuffer, the values passed are (0,-112). This seems to cause the bottom 800 lines to be displayed; that is, -112 corresponds to an offset of 224 lines. |
PICK (PK) | 56 | ||
PLINE (PL) | 36 | 1 byte count, then 2 * count words | Draw a polyline linking the specified points. |
PLINER (PLR) | 37 | Presumably as PLINE, but with coordinates relative to the current drawing position. | |
PVEC (PV) | 25 | ||
PVECR (PVR) | 26 | ||
RBAND (RB) | E1 | ||
READP (RP) | 55 | none | Read the pixel at the current location. Returns a single byte giving the colour. |
TIMER | F2 | ||
TESTER | F3 | ||
X2CUR | 1E | ||
XHAIR (XH) | E2 | ||
XMOVE (XM) | E3 | ||
XVMOVE (XV) | 1D |
There is a similar card, the IM-640, which does not appear to have a Windows 1.x driver.
Everex EV-235
The EV-235 is a high-resolution mono card. In normal operation it behaves like a Hercules Plus, but it also has a 1664×1200 mode. There is a Windows 3.0 driver for this mode at mpoli.fi; a GEM driver also existed, but I haven't been able to track down a copy.
The Windows driver creates a selector pointing at C800:0000 which may well be where the high-resolution framebuffer lives. The high-resolution framebuffer is pageable in 4k chunks, allowing different areas of memory to be selected into a 16k window.
The memory and I/O port ranges used by the card are configurable using jumpers; this allows multiple EV-235 cards to coexist.
The video mode is selected using the usual INT 10h function. The EV-235 supports two modes: 60h for high-resolution text, and 61h for high-resolution graphics.
There are further INT 10h functions:
AX = 6000h: Check for EV-235. If EV-235 is present returns: AL = 60h BX = segment of framebuffer DX = I/O base address AX = 6001h: Toggle between normal and reverse video modes AX = 6002h: Screen-to-screen memory copy. BL=source page, SI=source address BH=destination page, DI=destination address CX=length in bytes AX = 6003h: Set framebuffer segment (BX=segment) AX = 6004h: Toggle display on/off AX = 6005h: Load font. DS:DX=font address, CX=length, BL=character width, BH = character height. AX = 6006h: Switch character size. BL=0 for normal, 1 for double width. AX = 6007h: Return address of default 8×16 font in BX:DX AX = 6008h: Enable / disable timer interrupt handler (used to simulate a blinking cursor). Enter with BL=1 to enable, 0 to disable.
On closing down, the Windows driver calls INT 10h with AX=6000h, BX=1 and CH=1. I'm not sure of the reason for this, since the BIOS ROM doesn't seem to check BX or CH in this handler. Possibly the intention was to use AX=6008h to reinitialise the timer interrupt handler.
John Elliott 13 October 2025