---->> Howdy my electronics nerdy, geeky and junkie fellows.. After trying 10 times to post this thread, with error after error saying I had already posted it, how frustrating....!
Anyways.
Since I have no friends and I am a lone electronics obsessed person, I thought I would share my work online with like minded people.
This is an update on the 8 bit homebrew breadboard CPU made using only discrete 74HC logic IC's. Before you think about saying it's a birdnest, which it is, bear in mind this is the very point: to make a complete cpu from scratch using breadboards and jumpers very quickly, almost like a piece of art. I WILL however, replace the jumpers with short wires later on. Bear in mind that the circuit works perfectly as it is, with little crosstalk due to the very few edge type signals involved.
There are a couple of things, first I'll show an unupdated schematic, which I will update some time in the future, but the current design is 95% what the schematics show, except for how memory is handled and lack of I/O devices on the schematics.
Secondly, I am now in the BIOS stage, that is, the CPU is finished, with its instruction set exhausted, except that it could be fine tuned for sure, and so now I am looking to write a BIOS from scratch, in order to provide basic I/O support. For example, video handling routines: character writing, line, circle, triangle drawing, cursor moving, screen clearing, etc. IDE Disk handling routines, Floppy handling routines, Serial and parallel port handling routines, sound card handling routines and so forth.
And yes the CPU/Computer has support for all these devices, all I need is drivers at the moment and thats where the bios comes in.
The CPU is 8bits, with an 8bit data bus, an 8bit address bus (my only regret), 2 registers A and B, a stack pointer SP and a base pointer BP. There is currently 32KB of RAM accessible by the CPU, which is handled as 128 banks of 128 bytes each. The CPU is microcoded, with 4 parallel ROMS flowing control bits into the system. The PROMS are programmed with a u-code compiler written by myself which takes strings of 1's and 0's corresponding to control bits and assembled everything in binary files to be programmed into the ROMS with a rom programmer.
There is a video card installed. Also made with breadboards and discrete IC's. It generates monochrome composite video which goes into a TV or monitor. The resolution is 320x280 pixels at 8MHz pixel write frequency. Video memory isn't part of the main memory, but is stored in an external VRAM, which is accessed and written to via IO ports. So if you want to write a byte to VRAM, just send a 2 byte address to port 70h/71h, the data to port 75h, and pulse WE on port 76h. This is of course slower than if it were part of main RAM, but I preferred this as then I don't use 11kB from main memory.
There are 16 I/O ports at the moment, which can be used for anything. 9 of them are currently used for video, bank switching, the sound card, and 2 input ports.
Yes there is a sound circuit, which generates square waves in several octaves, with 12 notes per octave. This circuit will be expanded soon to include sawtooth, triangle and sine, as well as filters to control the desired waveform etc.
So this being said, this is a photo of the current setup, with a green monitor displaying raw random VRAM.
I appreciate comments and questions!
This is a top view photo of the whole set up, with a joystick installed, and a picture being displayed at the TV, having been loaded by the CPU.
This is a picture of the current, latest instruction set. There is only one space left blank at the moment. I am still fine tuning it however.
This is a picture of the CPU displaying raw VRAM to the monitor, just after reset. It shows a nice pattern that some old NEC srams have at reset:
This is a sample assembly code, which I wrote early on before the instruction set was expanded. The memory map showing here however is correct:
; Genesis BIOS Version 1.0
****************************************
************** Memory map **************
****************************************
________________________________
| |
0xFFFF | ROM Banks |
. | |
. | |
0x8090 | ROM Banks |
________|_______________________|
| |
0x808F | Lower 16 |
. | bytes of | -->> These addresses conflict with the lower 16 bytes of common ROM, which are used to boot up the system.
. | ROM |
0x8080 | |
________|_______________________|
| |
0x7FFF | 127 Banks of |
. | 128 Bytes |
. | (RAM) |
0x0180 | |
________|_______________________|
| |
0x00FF | Free RAM |
. | Free RAM |
. | Free RAM |
0x00F0 | Free RAM | -->> These addresses do not conflict with the common area I/O ports because the I/O ports decoder requires A7 to be 0, and here it is 1.
________|_______________________|
| |
0x00EF | Common RAM |
. | Common RAM |
. | Common RAM | -->> Duplicate addresses for common RAM
0x0080 | Common RAM |
________|_______________________|
| |
0xXX7F | I/O: |
0xXX7E | I/O: |
0xXX7D | I/O: |
0xXX7C | I/O: |
0xXX7B | I/O: |
0xXX7A | I/O: |
0xXX79 | I/O: |
0xXX78 | I/O: |
0xXX77 | I/O: |
0xXX76 | I/O: VRAM Control |
0xXX75 | I/O: VRAM DataOut |
0xXX74 | I/O: Bank Reg |
0xXX73 | I/O: Input1 |
0xXX72 | I/O: Input0 |
0xXX71 | I/O: VRAM Addr1 |
0xXX70 | I/O: VRAM Addr0 |
________|_______________________|
| |
0xXX6F | SP |
0xXX6E | BP |
. | Stack Begin |
. | |
0xXX10 | Common RAM |
________|_______________________|
| |
0xXX0F | Lower ROM |
. | |
. | |
. | |
. | 04: Begin BIOS |
. | 03: 6E |
. | 02: 6F |
0xXX00 | 00: JMP 04 |
________|_______________________|
Low << =========== >> High
VRAM write sequence:
write address0 to 70h
write address1 tp 71h
write data to 75h
write 1 to VRAMEn (bit 0 on control byte) while keeping WR bit high (bit1)
write 0 to bit1 on VRAM control byte. (WR) to write data
write 1 to bit1 on VRAM control byte. (WR) to remove WR
then either continue writing: changing addr and data and pulsing WR
or stop writing: send 0 to VRAMEn (bit0)
00:
_boot:
71 04 jmp 04
6F 6f
6E 6e
03 00 mov a, 00 ; reset VRAM controls and tristates it (VRAM WR here is active high, even though its active low in the actual chip)
05 76 mov [76], a ; write 00000000 to VRAM Control to turn off buffers and keep WR high.
03 80 mov a, 80
05 74 mov [74], a ; send 80 to BANK register
71 90 jmp 90 ; jmp to 8090, which is the beginning of the BIOS, after the 16 lower bytes.
8090:
_BIOS:
03 6D mov a, 6d
05 6F mov [6f], a
05 6E mov [6e], a ; initialize SP and BP
03 00 mov a, 0
86 push a ; make space for 1 local variable for keeping VRAM address, starting at BP
71 9B jmp _VRAM_test
_VRAM_test:
03 ff mov a, ff
_count:
23 dec a
75 A2 jz _end1:
71 9D jmp _count ; just a flagging loop so I know where the program is
_end1:
11 FF mov b, ff
03 00 mov a, 0
05 71 mov [71], a ; send address to VRAM, upper byte is 0
03 0F mov a, 0F
05 75 mov [75], a ; send data to VRAM data register (stripped pattern)
03 01 mov a, 01
05 76 mov [76], a ; open VRAM buffers while keeping WR low
_loop:
13 70 mov [70], b ; send lower address to VRAM, which consists of just counter b.
03 03 mov a, 03
05 76 mov [76], a ; pulse WR high and write data
03 01 mov a, 01
05 76 mov [76], a ; pulse WR back low
24 dec b
75 BF jz _end2
71 B0 jmp _loop
_end2:
03 00 mov a, 00
05 76 mov [76], a ; close VRAM buffers so VRAM controller takes control again and displays data
_halt:
71 C3 jmp _halt
I have also attached the complete microcode that the CPU executes. Note that it is the textfile version, which is compiled into binaries.
------------------------------- end -------------------------------------------------------------------