Updated: Nov 22, 2022
I am researching options for a video card for my 80286 system.
I will update this page as I learn more.
Related: VGA Add-in Card for My 65816 PC
Potential Address Space
I posted the following to the YouTube video comments.
As I consider the design of this card, the connectivity of the low and high bytes from the processor to the video card RAM could be a challenge.
If I shift the address bits going to the video card RAM (e.g., so BUS_A1 connects to the video RAM pin A0, BUS_A2 to pin A1, etc.), but my video RAM is seen as a single, contiguous address space of bytes (not split between different RAM chips for high and low bytes), that seems to be problematic. This would lead to me only being able to read/write the even addresses of video memory from the processor, correct?
On the other hand, if I don't shift the addresses, and the processor requests an odd address, the processor will use the high byte signals on the data bus, but the video RAM will not be connected to the high byte signals.
How is this typically handled, where the 286 will require accessing even or odd addresses directly, and the byte of data is coming from a single 8-bit RAM? Do I need a pair of transceivers on the video card that both connect to the video card's eight-bit bus, but one transceiver connects to the lower bits on the processor external data bus while the other transceiver connects to the upper bits on the processor external data bus, and then activate one transceiver or the other based on BUS_A0 (only requesting one byte of data at a time from the processor)? This would essentially mux the upper/lower bytes on the processor's external data bus with the single byte memory bus on the video card. Possibly, something like the following? https://imgur.com/a/5YsKxo8
Am I overthinking this? :)
Options I Am Considering
Add a pair of transceivers to the video card, along with some supporting logic gates to place odd and even address data on the processor data bus's low byte. One potential is shown below. Possibly, BHE could also be used in the logic. Upside: this may be the simplest solution (so far). Downside: I would still only be using an 8-bit data bus on a 16-bit capable processor.
Redesign the video card to support paired memory -- high and low bytes -- much like the static RAM on the 286 system itself. This would require some logic on the video card to move away from a sequential read of a single RAM chip to alternating byte reads across the low and high chips. I would essentially have a 64 KB pair and another 64 KB pair, with low/high bytes spread across the pair of ICs in a 64 KB region. Upside: Potentially better performance, taking advantage of the processor's 16-bit data bus. Downside: Possibly, a little more complexity on the video card to read the appropriate high or low chip. Although, this probably isn't any more work than the first option above.
Other Potential Enhancements
Implement a clock buffer. Example: CGS74CT2525N. Currently, I am driving four ICs off of PIXEL_CLK.
Updating to 16-bit
To update the video card to support 16-bit memory access from the processor, I need to update the processor-facing side of the dual-port RAM to take advantage of the full 16-bit processor external data bus. I want to support reading LO byte, HI byte, and full word (i.e., two bytes). I have updated the RAM to use enable signals generated from the following logic.
The above provides video memory access to the processor. As far as the processor is concerned, this is just memory access like any other memory.
For internal video card (output) access to the memory, I only have an 8-bit internal data bus. I updated the logic on the video output side of the RAM with the following enable logic. For the 74138 3-to-8 decoder (U8), I am using VQ8 into C to determine if I should be in the lower or upper 64K of the video memory. I am tying B low and using VA0 into A to split our LO and HI enables. With this, Y0 low has the video output using the first memory chip (U11), Y1 using U13, Y4 using U1, and Y5 using U6.
This, along with RAM_OE# on U8, should provide the appropriate enable signals for the four RAM chips. As the HSYNC and VSYNC count up through the memory locations, the output is read from alternating chips in the lower 64K. At the end of the first 64K, the upper 64K is read from alternating chips.
With the updated enable logic on both sides of the dual-port RAM, the RAM connections look like the following. All addresses (processor side and video output side) have been shifted by one (e.g., BUS_A1 to pin A0L, VA1 to pin A0R, etc.).
This design does not address conflicts when the processor is writing to an address and the video card tries to read the same byte at the same time. This has not been much of an issue on my 65816. Periodically, I will see a pixel that does not get updated. I do not plan to address this at this stage; maybe a future version can improve this.
PCB after the above updates:
The updates I have made leave plenty of room for mistakes. I plan to sleep on this design for a night or two and run back through it, connection by connection to see what I am missing. If you see any issues, please let me know. Thanks!
Data Bus Steering Logic
As I was researching how to access 8-bit memory mapped devices from a 16-bit 80286, I found a helpful section in the book ISA System Architecture, 3rd Ed., Shanely & Anderson. The authors describe the concept of data bus steering logic and describe nine different scenarios, of which four of them require no special intervention by the data bus steering logic. For now, I do not plan to implement such steering logic, and I will try to keep my memory mapped I/O to 16-bit data transfers. However, I expect at some point I will need to implement some form of data bus steering logic.