Well, here is the first release of my color graphics video card.  The card 
currently functions as a CGA subset.

Unless otherwise specified, everything in this package is the creation of I, 
Brad O'Dell.

The software and firmware items in this package are released under the terms 
of the General Public License Version 3.0 or any later version of the license.

All other files in the package are released under the Creative Commons version 
3.0 Attribution-ShareAlike license.

The project does not yet support a hardware text mode, or CGA-compatible 
control registers.  It does, however, support some things CGA does not. It 
supports the assignment of any of the 16 colors to the four color indexes in 
the 320*200 mode and any of those colors to the two indexes in the 640*200 
mode.  It directly supports a 160*200 16 color mode.  There is also a 213*200 
8-color mode existing as kind of an artifact.  It can also theoretically 
connect to a controllerless black-and-white LCD panel.

The VRAM is mapped the same way as a CGA card for all modes, but the control 
registers are not.  Here are the current control registers:
address:	7	6	5	4   |	3	2	1	0
		proposed border color reg:	color index 0:
0x21B0		I	R	G	B   |	I	R	G	B
		proposed cursor color reg:	color index 1:
0x21B1		I	R	G	B   |	I	R	G	B
		0=color	0=80col text page:	color index 2:
0x21B2		1=B&W	1=40col	1	0   |	I	R	G	B
		0=graph 213*200 graph mode:	color index 3:
0x21B3		1=text	I bit	1	0   |	I	R	G	B
		74ACT715 manual address:
0x21B4		-	-	-	D4	D3	D2	D1	D0
		74ACT715 auto-increment address:		
0x21B5		-	-	-	D4	D3	D2	D1	D0
		74ACT715 low-order data:
0x21B6		D7	D6	D5	D4	D3	D2	D1	D0
		74ACT715 high-order data:
0x21B7		-	-	-	-	D3	D2	D1	D0


The border color, cursor color, 21B2 bits 7~4 and 21B3 bit 7 are not currently 
implemented.

Making room for the VRAM and BIOS in the UMBs:
Set the DIP switches to available addresses in UMB for the BIOS and VRAM.  
Make sure that shadowing control of these locations is disabled in the BIOS, 
if these settings exist.  If using DOS, make sure these regions are also 
excluded from usage by upper memory managers(EMM386,JEMM,JEMMEX,UMBPCI,UMBM).

Boot ROM socket host interface:
As an alternative to the ISA interface, which is no longer included on modern 
PCs, I have proposed the use of the boot ROM socket on a PCI network card.  
32-pin boot ROM sockets have a signal going to the /WE pin on a Flash chip to 
allow in-circuit reprogramming.  Theoretically, one should be able to hook any 
peripheral up to the socket like it was a miniature expansion bus to allow 
both reading AND writing.

DB-25 Output connector pinout:

1-NC		14-NC
2-RED		15-GND
3-GND		16-PIXEL
4-NC		17-GND
5-HSYNC		18-ODD/#EVEN
6-INT		19-NC
7-BLUE		20-GREEN
8-GND		21-VSYNC
9-CURSOR	22-#VSYNC
10-CBLANK	23-CSYNC
11-NC		24-NC
12-NC		25-NC
13-NC

In the future, I may move CSYNC to pin 4, and add 5V power outputs to power an 
LCD.

LCD interface:
This has not been tested, and requires a single-scan display.  It should 
support shifting four bits(IRGB) at a time.  LCD usage would be activated by
setting the graphics card to 160*200 mode, but writing to it as one would in 
640*200 mode.  These are the proposed LCD interface connections:
graphics card:	LCD module:
I		D3
R		D2
G		D1
B		D0
PIXEL		CP or XSCL
HSYNC		LP or YSCL
VSYNC		FLM or DIN
ODD/#EVEN	M or FR

The negative bias supply for the LCD will have to be supplied externally.
Timings may need to be tweaked in the demonstration program to get the LCD to 
work right.  Even better, new video modes could be created in the software to 
do this.

CGA interface:
Interfacing to a CGA-compatible display would only require a standard 25-to-9 
pin RS-232 cable to go from the video card to the monitor.

Video Modes:
0: 640*200, 1bpp.  Use color indexes 0 and 1 to set the background and 
foreground, respectively.
1: 320*200, 2bpp.  Uses all four color indexes.
2: 213*200, 3bpp.  Does not use the palette chip. R, G, and B are specified 
seperately per pixel, with the I bit set for the whole screen in configuration 
byte 0x21B3, bit 6.
3: 160*200, 4bpp.  16 colors per pixel, independently selectable.

The Circuit:

The circuit is based around a Cypress CY7C006 16k*8 dual-port RAM chip and a 
Fairchild 74ACT715 programmable sync generator.  

There are two GALs for bus address decoding.  I used OpalJr to compile the 
logic formulas into a JEDEC fuse map.  I used the GALBlast program and 
circuit, available on the web, to burn the fuse maps into the chips.

IC14 is a horizontal pixel counter.  Gated with the clock, IC12A generates an 
active low parallel load pulse to shift register IC7 when the lowest three 
count stages are high.  The next seven stages count from 0 to 79 to address a 
column of video data on the current row.

IC13 is a vertical row counter.  The lowest eight stages count from 0 to 199.  
The lowest bit goes to the highest order VRAM address input, because in the 
CGA addressing scheme, the odd numbered rows are 8k above the even numbered 
ones.  The upper seven bits go through IC9, IC21, and IC16A.  This logic is 
wired to multiply the vertical address by 80, because video data rows start 
every eighty bytes.  This is broken down into multiplying by 16 and by five.  
Multiplying by sixteen is accomplished by simply shifting the result over four 
bits.  Multiplying by five results from multiplying by four and adding the 
input (5n=4n+n).  IC15, IC22 and IC16B add the *80 vertical product to the 
current address, resulting in the full address.  The XOR gates were added to 
provide one more bit to each addition stage.  All of this addition circuitry 
is needed because of the non-integer-of-two number (80) used for the number of 
columns and also to support the seperation of the odd and even numbered lines 
on the video RAM.  IC19A and B form an R/S latch which drives the reset line 
on the vertical counter active high when VSYNC is active, and resets it again 
when the active field starts again (CBLANK goes low).

IC7 is the primary shift register.  It breaks each byte down into individual 
bits.  IC8 is the secondary register which reassembles the bits into pixels as 
needed by the currently selected video mode.  IC11 generates latch pulses to 
the secondary shift register.  The reload inputs of it set the video mode by 
changing the divide ratio of clocks to pixels.  This in turn selects the 
tradeoff between horizontal resolution and color depth.  IC10 holds the 
reassembling shift register outputs off of the IRGB outputs.  In this case, 
the shift register outputs go to the dual-port RAM address inputs and the 
outputs then go out to IRGB.

IC5 allows the arbitrary assignment of the 16 available colors to the two or 
four indexes  available in modes 0 and 1.  This chip is circumvented in modes 
2 and 3.

IC6 is a latch that holds some mode configuration bits.

IC16C, and D provide a composite sync output built from VSYNC and HSYNC.

Bugs:
There is a problem when some color other than black is selected for the 
border.  When any of the I, R, G, or B bits are set, those bits become 
excluded from pixels on the screen.  Apparently, the state of these signals 
at some point in the horizontal blanking interval is used as a reference for 
the whole scan line instead of ground.  Right now, I work around this by 
assigning color index 0 to black.  Hopefully, using HSYNC to force the IRGB 
outputs low will work.

Forthcoming Graphics Card v2:
* A text mode, using graphics2.sch.  This design has not been tested.
* cursor color and border registers using two 74HCT173s.  The peripheral chip 
  selects are already built into the GAL20V8.  These will be gated on by the 
  CURSOR and CBLANK signals, and these will force the IC5 and IC10 outputs off.
* fix the v1 bug
* test the boot ROM socket interface concept
* test an LCD

Roadmap to v3: adding attributes. composite color encoder.
* add color and black-and-white attributes.  Use a double-buffered latch setup 
  consisting of a 74HCT574 and a 74HC574.  Reassign IC12B to have the inputs 
  go to the same places as the IC12A inputs, but with pin 13 inverted.  Use 
  the output from IC12B to strobe the first latch.  Use the output of IC12A to 
  strobe the second latch, in sync with the primary video shift register.
* composite color encoder, interfacing the IRGB outputs to an NTSC composite 
  video output.  The simplest solution might just be to use an AD725 with 
  high-speed open-collector output comparators on the R, G, and B inputs.  The 
  I signal could select between two reference levels for the pullups.

Roadmap to v4: 
At this stage, I would supporting original CGA register functionality by using 
a microcontroller to translate between the CGA register map, and the intrinsic 
configuration functionality of the graphics card.  Some latches will be used 
to store the data and three-bit port address.  When this register bank is 
strobed, an interrupt will be sent to a microcontroller.  The ISA bus will 
also be held.  The MCU will then read the latches and react to the input.  The 
ISA bus will then be released.  The problem might be that the bus will be 
realeased automatically after a timeout, not allowing enough time for a 
translation.  If the selected MCU has at least four timer outputs, the 
74ACT715 chip may not be needed.

Roadmap to v5: 
The final step would be to port the bus end of the circuit to the PCI bus.  
A Cypress CY7C09449 plus a 24Cxx serial EEPROM would replace the CY7C006 and 
the GALs.  The boot ROM socket would be eliminated at this point.  The serial 
EEPROM stores thing like the Vendor/Product ID, and a selection of base 
addresses for the PCI configurator to assign to the I/O and the memory.
