Author Topic: Homebrew CPU with discrete 74HC update: Video,Sound,Joystick,Keyboard <-- BIOS  (Read 11456 times)

0 Members and 1 Guest are viewing this topic.

Offline PauloConstantinoTopic starter

  • Regular Contributor
  • *
  • !
  • Posts: 154
  • Country: gb
---->> 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....! |O :scared: 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:


Code: [Select]
; 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 -------------------------------------------------------------------
« Last Edit: July 06, 2017, 06:16:49 pm by PauloConstantino »
 
The following users thanked this post: xrunner, Melt-O-Tronic

Offline albert22

  • Regular Contributor
  • *
  • Posts: 177
 :clap: :clap:
Man. I wish I could have your determination and patience to complete projects as you do.
Congrats.
 

Offline PauloConstantinoTopic starter

  • Regular Contributor
  • *
  • !
  • Posts: 154
  • Country: gb
Thanks Albert! You really need to think about how pleasurable the end result will be. Hooking up wires is not fun, although it feels good when the jumper is going into the breadboards :) But the end result is imagining this mess of wires running a game like prince of persia and asking yourself how on earth, even though you know how :)
 
The following users thanked this post: albert22

Online moffy

  • Super Contributor
  • ***
  • Posts: 1738
  • Country: au
Unbelievable! Remarkable!
 

Offline PauloConstantinoTopic starter

  • Regular Contributor
  • *
  • !
  • Posts: 154
  • Country: gb
Thanks Moffy. I hope someone could let me know of a small, tiny operating system I could install on the machine.
 

Offline dr.diesel

  • Super Contributor
  • ***
  • Posts: 2214
  • Country: us
  • Cramming the magic smoke back in...
Very good Sir,

Offline GK

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
 :-+

Bitmap graphics are nice, but you really ought to add hardware character generation to your video circuitry. Printing strings of text to the screen is a tedious and processor-intensive process if you have to write each individual pixel.
 
« Last Edit: June 29, 2017, 12:15:01 pm by GK »
Bzzzzt. No longer care, over this forum shit.........ZZzzzzzzzzzzzzzzz
 

Offline PauloConstantinoTopic starter

  • Regular Contributor
  • *
  • !
  • Posts: 154
  • Country: gb
Very true. I might do this in the future. I wanted to keep everything as simple as possible. It runs at 5MHz, so it should be fast anyhow.... Thanks for the suggestion!  :-+
 

Offline jiro

  • Contributor
  • Posts: 16
  • Country: mx
  • We are slaves of our own freedom
Boy! Congrats! thie really requires a lot of dedication

 :-+
 

Offline Omega Glory

  • Regular Contributor
  • *
  • Posts: 86
  • Country: us
    • Ezra's Robots
Very very nice! That is really something else. Keep up the good work!

Offline xrunner

  • Super Contributor
  • ***
  • Posts: 7517
  • Country: us
  • hp>Agilent>Keysight>???
Wow! Great work. Now I see the possibilities of having a lot less friends.  :-/O
I told my friends I could teach them to be funny, but they all just laughed at me.
 

Online Fungus

  • Super Contributor
  • ***
  • Posts: 16665
  • Country: 00


You own a lot of breadboard cables.  :o

It's not often I'm left without words but you got me.

I'm not sure whether to offer practical advice or tell you to keep going.

If I was being practical I'd say:

"OK, you've proved you can build a CPU!". The next stage is writing a BIOS and interfacing screens, disk drives, etc., but what do you gain by using all those wires? One bad connection could ruin a whole week. Can you move it to an FPGA or an emulator to do the next part? The advantage is that other people can have a copy of the 'hardware' to work on.

If you're asking for collaboration with the BIOS it's going to be difficult because nobody else has the computer to work with (there's only one!) You might have to create an emulator anyway.

 

Offline PauloConstantinoTopic starter

  • Regular Contributor
  • *
  • !
  • Posts: 154
  • Country: gb


You own a lot of breadboard cables.  :o

It's not often I'm left without words but you got me.

I'm not sure whether to offer practical advice or tell you to keep going.

If I was being practical I'd say:

"OK, you've proved you can build a CPU!". The next stage is writing a BIOS and interfacing screens, disk drives, etc., but what do you gain by using all those wires? One bad connection could ruin a whole week. Can you move it to an FPGA or an emulator to do the next part? The advantage is that other people can have a copy of the 'hardware' to work on.

If you're asking for collaboration with the BIOS it's going to be difficult because nobody else has the computer to work with (there's only one!) You might have to create an emulator anyway.


Hehehe thanks for your kind comments.

I gain nothing in the long term by using the jumpers. I only gained a lot of time. I built the bulk of it in one week, and then started improving it and tuning it during the subsequent weeks. I didn't want to use an FPGA because I think it's not as "romantic" as building it like this. I wanted it to be as primitive as possible and still work.

As for the BIOS, I think I'm trying to get others inspired to build their own.

Thanks a lot
 
The following users thanked this post: dr.diesel

Offline GK

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Oh, looks like the reply I just opened this thread again to reply to had disappeared....... I presume that you have figured it out  ;) Incidentally this evening I noticed that IC4D is drawn as a NAND gate when in fact it is an AND gate. Just being pedantic.

 
Bzzzzt. No longer care, over this forum shit.........ZZzzzzzzzzzzzzzzz
 

Offline GK

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Yes, you just have to program to update the video ram only during either the vertical or horizontal blanking intervals or both. If your processor can monitor digital I/O, just feed it the sync/blanking signals. A more sophisticated system/arrangement would be interrupt driven.

Having the video RAM separate from the main RAM is the best performing and most logical way to implement a simple system like this, IMO. If the processor and video circuitry shared a common address and data bus then you wouldn't be able to do any processing at all out side of the video blanking intervals.

« Last Edit: July 02, 2017, 03:50:50 am by GK »
Bzzzzt. No longer care, over this forum shit.........ZZzzzzzzzzzzzzzzz
 

Offline ali_asadzadeh

  • Super Contributor
  • ***
  • Posts: 1905
  • Country: ca
Nice work,  :) I think you should expand the address bus to at least 24 bits, and I think it would be nice if you could do it on the PCB, I have lot's of students, so maybe it would be a great practice for them to design separate PCB's for each part of the computer as an assignment! if you are willing to I can set the assignment for them ;) ;) ;)
ASiDesigner, Stands for Application specific intelligent devices
I'm a Digital Expert from 8-bits to 64-bits
 

Offline PauloConstantinoTopic starter

  • Regular Contributor
  • *
  • !
  • Posts: 154
  • Country: gb
Nice work,  :) I think you should expand the address bus to at least 24 bits, and I think it would be nice if you could do it on the PCB, I have lot's of students, so maybe it would be a great practice for them to design separate PCB's for each part of the computer as an assignment! if you are willing to I can set the assignment for them ;) ;) ;)


Yes definitely if you want to set it I can send you the eagle schematics.......
 

Offline GK

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Yes, you just have to program to update the video ram only during either the vertical or horizontal blanking intervals or both. If your processor can monitor digital I/O, just feed it the sync/blanking signals. A more sophisticated system/arrangement would be interrupt driven.

Having the video RAM separate from the main RAM is the best performing and most logical way to implement a simple system like this, IMO. If the processor and video circuitry shared a common address and data bus then you wouldn't be able to do any processing at all out side of the video blanking intervals.


Was that how you did it? Feeding the blanking signals to the IO ports for the CPU to know when to write? That's not how I intend to do it though.................. snip


That is one of two possible ways I mentioned for doing it. I cloned a Commodore PET. The PET video RAM update was interrupt driven.
 
Bzzzzt. No longer care, over this forum shit.........ZZzzzzzzzzzzzzzzz
 

Offline GK

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Quote from: PauloConstantino
But there is a third way, which is what i described mate. I cloned a Commodore 64. Ok mate? How does the interrupt driven one work lad ?


:-//


What you described is called double buffering, of which there are variations. You also insisted on keeping the video logic as simple as practical, which double-buffered video RAM isn't. Make up your mind.
« Last Edit: July 03, 2017, 07:05:32 am by GK »
Bzzzzt. No longer care, over this forum shit.........ZZzzzzzzzzzzzzzzz
 

Offline ali_asadzadeh

  • Super Contributor
  • ***
  • Posts: 1905
  • Country: ca
Quote
Yes definitely if you want to set it I can send you the eagle schematics.......
Sure...please send them in ;) :)
ASiDesigner, Stands for Application specific intelligent devices
I'm a Digital Expert from 8-bits to 64-bits
 

Offline timb

  • Super Contributor
  • ***
  • Posts: 2536
  • Country: us
  • Pretentiously Posting Polysyllabic Prose
    • timb.us
Yes, you just have to program to update the video ram only during either the vertical or horizontal blanking intervals or both. If your processor can monitor digital I/O, just feed it the sync/blanking signals. A more sophisticated system/arrangement would be interrupt driven.

Having the video RAM separate from the main RAM is the best performing and most logical way to implement a simple system like this, IMO. If the processor and video circuitry shared a common address and data bus then you wouldn't be able to do any processing at all out side of the video blanking intervals.


Was that how you did it? Feeding the blanking signals to the IO ports for the CPU to know when to write? That's not how I intend to do it though.................. snip


That is one of two possible ways I mentioned for doing it. I cloned a Commodore PET. The PET video RAM update was interrupt driven.


But there is a third way, which is what i described mate. I cloned a Commodore 64. Ok mate? How does the interrupt driven one work lad ?

*Facepalm*
Any sufficiently advanced technology is indistinguishable from magic; e.g., Cheez Whiz, Hot Dogs and RF.
 

Offline alexanderbrevig

  • Frequent Contributor
  • **
  • Posts: 700
  • Country: no
  • Musician, developer and EE hobbyist
    • alexanderbrevig.com
Awesome stuff :)
 

Offline GK

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Make up my mind? I have no idea what you're on about buddy.

There's no issue about keeping things simple. What I described I can easily implement. And it's not double buffering. Double buffering is basically having 2 whole RAM areas, one to write to and another to display. What I described is just a few temporary flip flops.

Also, it's you who started this confusion by posting your schematics and saying "there's not a lot to it", as if I was asking for video advice. I already have video, a fact which you missed. I don't need hardware character generation, my characters are simply dealt with by software. It's my choice.

It's you who seem a bit confused here.


Unreal!

No, double buffering need not involve a duplicate of the entire RAM area, though that is how it was typically implemented. A shift register acting as a temporary memory storage for serial pixel shifting while the processor writes to the main video memory is the same operational principle.

All I did was suggest that hardware character generation in addition to your bitmap graphics (really, I missed the fact that you already have video generation?) would be worthwhile addition to your project. Let me remind you of how you replied:

"Very true. I might do this in the future. I wanted to keep everything as simple as possible. It runs at 5MHz, so it should be fast anyhow.... Thanks for the suggestion!  :-+ "

Also, it's you who started this confusion by posting your schematics and saying "there's not a lot to it", as if I was asking for video advice.

I wrote that "there isn't a lot to it" simply because there isn't, as could be seen from the schematics I posted subsequent to your reply. In addition to the pixel/line counters required in any case for addressing the RAM and deriving the line/frame sync and blanking signals there is just a character ROM, a shift register and a small amount of additional logic.

I wasn't suggesting that you were asking for advice and you can implement your video generator however you see fit. I bothered to scan and then post/share my video generator circuit design because I stupidly thought the technical details might be something of mutual interest, being from a project in a similar vein, irrespective of however you choose to build your own unit.

I've deleted my unwelcome post with the schematics from this thread; I didn't post them here to wave my dick.


Bye.
« Last Edit: July 03, 2017, 10:21:04 am by GK »
Bzzzzt. No longer care, over this forum shit.........ZZzzzzzzzzzzzzzzz
 

Offline timb

  • Super Contributor
  • ***
  • Posts: 2536
  • Country: us
  • Pretentiously Posting Polysyllabic Prose
    • timb.us
Make up my mind? I have no idea what you're on about buddy.

There's no issue about keeping things simple. What I described I can easily implement. And it's not double buffering. Double buffering is basically having 2 whole RAM areas, one to write to and another to display. What I described is just a few temporary flip flops.

Also, it's you who started this confusion by posting your schematics and saying "there's not a lot to it", as if I was asking for video advice. I already have video, a fact which you missed. I don't need hardware character generation, my characters are simply dealt with by software. It's my choice.

It's you who seem a bit confused here.


Unreal!

No, double buffering need not involve a duplicate of the entire RAM area, though that is how it was typically implemented. A shift register acting as a temporary memory storage for serial pixel shifting while the processor writes to the main video memory is the same operational principle.

All I did was suggest that hardware character generation in addition to your bitmap graphics (really, I missed the fact that you already have video generation?) would be worthwhile addition to your project. Let me remind you of how you replied:

"Very true. I might do this in the future. I wanted to keep everything as simple as possible. It runs at 5MHz, so it should be fast anyhow.... Thanks for the suggestion!  :-+ "

Also, it's you who started this confusion by posting your schematics and saying "there's not a lot to it", as if I was asking for video advice.

I wrote that "there isn't a lot to it" simply because there isn't, as could be seen from the schematics I posted subsequent to your reply. In addition to the pixel/line counters required in any case for addressing the RAM and deriving the line/frame sync and blanking signals there is just a character ROM, a shift register and a small amount of additional logic.

I wasn't suggesting that you were asking for advice and you can implement your video generator however you see fit. I bothered to scan and then post/share my video generator circuit design because I stupidly thought the technical details might be something of mutual interest, being from a project in a similar vein, irrespective of however you choose to build your own unit.

I've deleted my unwelcome post with the schematics from this thread; I didn't post them here to wave my dick.


Bye.


This is what happens when two people can't tolerate each other's intolerance.

Yeah, uh, you're the one who started that argument, just to let you know. GK did nothing but help.

GK, can you send me those schematics? I didn't have a chance to grab them before you took them down. (I've been collecting stuff on video generation for awhile, for a future project.)
Any sufficiently advanced technology is indistinguishable from magic; e.g., Cheez Whiz, Hot Dogs and RF.
 

Offline PauloConstantinoTopic starter

  • Regular Contributor
  • *
  • !
  • Posts: 154
  • Country: gb
Awesome stuff :)

Thanks buddy. Glad you found it interesting!  :)
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf