This is the verilog source for a very simple 6502 based computer with the following hardware:
- 6502 CPU, using Arlet Ottens core.
- A reloadable 16 bit timer module, at address $FE00.
- An UART at fixed 115200 baud rate, at address $FE20.
- An RGB led controller (with PWM, ramps and On/Off times), at address $FE40.
- PS/2 keyboard interface, see the key code list here.
- VGA video controller, registers at address $FE60.
- 64k bytes of VGA memory, 640x480 video with 4 graphics modes:
- 16 color, 320x480 (or 320x240, 320x160, etc.) pixels, two pixels per byte.
- 2 color, 640x480 (or 640x240, etc.) pixels, 8 pixels per two bytes, one byte bitmap data and one byte fore/back color.
- 2 color, 320x480 (or 320x240, 320x160, etc.), 8 pixels per two bytes, one byte bitmap data and one byte fore/back color.
- 2 color text mode, 80 characters of arbitrary height from 8x2 to 8x32, one byte character, one byte fore/back color, font in RAM.
- A simple SPI controller capable of reading and writing to the configuration FLASH, used as non-volatile storage. Currently the SPI clock is half the CPU clock, the code is capable of reading one byte from FLASH each 19 CPU cycles, about 660Kbyte/sec.
- All graphics modes support arbitrary memory start and height, font can be at any location.
- 256 bytes of boot ROM at address $FF00 to $FFFF.
- 63.5k bytes of RAM, at address $0000 to $FDFF.
The video controller runs at 25.13MHz to generate the video signal, the 6502 CPU runs at half that (12.56MHz), so the video controller access the VRAM in even cycles and the CPU at odd cycles, this allows sharing the bus without conflicts.
The implementation was tested with an Upduino board, this is a cheap (US$10) board with an ice40-up5k FPGA chip.
You need to supply a 12MHz clock to pin 35, the on-chip PLL is used to raise this to 25.13MHz.
See the file rtl/upduino.pcf for the current pinout.
The PS/2 keyboard interface assumes a 3.3V supply to the keyboard, most keyboards will work with that voltage. The I/O is configured for 3.3Kohms internal pull-up and open-collector output, and the CLOCK line is driven low to stop the keyboard from sending packets.
To generate the VGA levels, a simple 8 resistor divider is used:
FPGA MONITOR
(42)--RED-----------[470]--,------ R
|
.--[680]--'
|
(36)--GREEN------)--[470]--,------ G
| |
+--[680]--'
|
(36)--BLUE-------)--[470]--,------ B
| |
+--[680]--'
|
(34)--INTENSITY--'
The above circuit approximates the 16 CGA colors, by generating 0.28V, 0.41V and 0.7V, this is 40%, 60% and 100% of each component. The following table shows the approximate colors: