6 ms·
Simple 4-bit/1 Hz virtual computer for learning purposes
- userbinator 11y agoComputer has one 8 bit register. That would be enough to classify it as an 8-bit machine, despite the fact that instructions are only 4 bits wide. A real 4-bit CPU, like the 4004, has 4-bit registers.
- tr352 11y agoI'd say, more importantly, it has an 8-bit data bus. It is the 4 bit address bus which cripples it. By comparison, the 4004 has a 4 bit data bus and 4 bit registers, but a 12 bit (4KByte) address bus.
- kosma 11y agoHow about implementing some sort of paging on top of it, Intel-style?
- tr352 11y agoIt seems like it can also easily be extended to an architecture with 12 bit address bus. Simply extend the size of every instruction to two bytes, and use the extra byte to refer to a 12 bit instead of 4 bit address.
- userbinator 11y agoThe Pentium has a 64-bit databus, yet its general-purpose registers are only 32 bits and it is classified as a 32-bit machine. This gets even muddier with the Pentium MMX, which has a set of 64-bit MMX registers. Of course there's also 80-bit-wide registers in the FPU of everything back to the 8087... Bitness is a surprisingly subtle thing to define, but I think an 8-bit-wide GPR is enough for this one to be called 8-bit.
- dspillett 11y agoYeah, it is a pretty muddy area when you actually look at the details, but it is generally accepted that the bit-ness of a CPU is related to its general purpose register size. The general purpose registers can be thought of as the processing unit's native size (sometimes called the word size). Anything else (data buses, address buses, special purpose registers for floating point or vector operations, and so forth) can and will vary. Take the 80386SX for another somewhat convoluted example: 32-bit general purpose registers so considered a 32-bit CPU, but some of those registers are effectively composed of chunks that can be used independently to work with 8 or 16 bits at a time, it has a 24-bit address bus, and a 16-bit data bus (which uses multiple requests when asked to bring or push a 32-bit value - this was the primary difference between the 386 (later dubbed 386DX) and 386SX models).
- tr352 11y ago> The Pentium has a 64-bit databus Didn't realize that, and you're right. Other examples of CPU's that I'm aware of with a different "bitness"/databus width are the 68008 and 8808, but in both cases the data bus is smaller than the "bitness".
- cmrdporcupine 11y agoSure, or the 68k itself which has a 16bit physical data bus but 32bit registers, spawning 30+ years of pointless arguing over whether to classify it as 32 bit or 16 bit.
- deleted 11y ago[deleted]
- kozak 11y agoWould be great if someone reimplemented it for the web.
- cosarara97 11y agoWhy?
- allan_s 11y agoespecially as a learning plateform for not-yet computer savy people, it's easier to give them a link and hop everybody can start playing. Don't underestimate the time it takes as a professor for "deploying" a tool on a 40 students class
- Zardoz84 11y agoIf you not have problem with a more complex RISC like CPU : - https://github.com/trillek-team/trillek-computer/blob/master/cpu/TR3200.md https://github.com/trillek-team/trillek-computer/blob/master... - https://github.com/trillek-team/trillek-vcomputer-module https://github.com/trillek-team/trillek-vcomputer-module - https://github.com/trillek-team/computer-toolkit https://github.com/trillek-team/computer-toolkit The official implementation it's a standlone library, and has been tested running at same time around 1000 VM's (on a single thread). So if some one implements a server and a web-client with it, could be very nice for this kind of stuff. And there is a macro assembler (VASM), linker (VLINK) and SmallerC compiler for it.
- dspillett 11y agoMaybe it would run in something like https://s-macke.github.io/jor1k/demos/main.html https://s-macke.github.io/jor1k/demos/main.html - I might have to give it a try when I'm at home and have some play time...
- nsxwolf 11y agoUh wow, this is awesome.
- vadiml 11y agoI wonder why RAM_SIZE = ADDR_SIZE * ADDR_SIZE - 1? I mean why -1?
- bendykstra 11y agoOne address is used for memory-mapped I/O. (Writes go to the printer. Reading from this address produces a random value.)
- unwind 11y agoAnd why ADDR_SIZE squared? That just seems to work "by accident", since ADDR_SIZE is 4 it evaluates to 15. What is really meant is probably (1 << ADDR_SIZE), i.e. 2 raised to ADDR_SIZE. Of course for the value 4 it evaluates to the same thing. For 5 it would become 24 rather than 31 which I would expect, assuming it's a size in bits of course ... Now I'm confused. The file in question: https://github.com/gto76/comp-cpp/blob/e800d121e40f8acca6b9d0c4f2fe299fce012eee/src/const.hpp https://github.com/gto76/comp-cpp/blob/e800d121e40f8acca6b9d.... And the -1 seems to be explained by how the author wants to use it, it's "last valid address", i.e. not the size at all. Something I'd complain about if this were open for review, for sure. :)
- circa 11y ago"my CPU is a neural net processor a learning computer" I can't be the only one who thought this, right?!
- nsxwolf 11y agoHumor is not allowed on HN, but your comment reminded me of how the original Terminator apparently runs on an 8-bit MOS 6502 if you look at some of the code flying across the screen in those red-tinted POV scenes.
- CatsoCatsoCatso 11y agoWhich in turn reminds me of this BBC Radio 4 clip which made me chuckle: http://www.bbc.co.uk/programmes/p02n9txt http://www.bbc.co.uk/programmes/p02n9txt "The Terminator is an accounting programme run amok"
- ataylor284_ 11y agoThis reminds me of my Gakken GMC-4. It's a 4-bit computer like this, but a physical piece of hardware. It has 7 LEDs, one 7-segment LED, a 20-key keypad and a tone generator. You have to key in the programs manually on the keypad, but you've only got about 100 4-bit words into which to fit your code and data. It's further constrained by the fact you can only directly address 16 of them for data. Even so, it's surprisingly fun and challenging to write little assembly programs for.
- daveloyall 11y agoRAM ADDR ________ ---- |----***-| ---* |---*****| --*- |--*-*--*| --** |---****-| -*-- |-*------| -*-* |--------| -**- |--------| -*** |--------| *--- |--------| *--* |-------*| *-*- |--------| *-** |--------| **-- |--------| **-* |--------| ***- |--------|
- deleted 11y ago[deleted]
- deleted 11y ago[deleted]
- nsajko 11y agoRAM ADDR ________ ---- |----***-| ---* |---*****| --*- |--*-**-*| --** |---****-| -*-- |-*-*-**-| -*-* |-*------| -**- |----**--| -*** |---****-| *--- |--------| *--* |--------| *-*- |--------| *-** |--------| **-- |--------| **-* |-------*| ***- |--------| This should get the counter back to 0 after it gets to 255 :)
- daveloyall 11y agohah! I just implemented that locally. Here's what I came up with... ________ |----***-| |-*-*-**-| |---*****| |--*-*--*| |---****-| |-*------| |----**--| |---****-| |-*------| |-------*| As you can see, it's pretty much the same, except in mine, the conditional is earlier, and I moved the initial 1 further up... Which required an additional jump?? ...I'd dig deeper but I'm eager to review this other comment, too!
- ketralnis 11y agoYou need the additional jump because he forgot his jump :) His doesn't actually reset on 255. It prints 254 and then stops. Here is his program commented: RAM AD PC ADDR ________ _ _ ---- |----***-|-|*| ; read in SCRATCH (starts at 0) ---* |---*****|-|-| ; write it to OUTPUT --*- |--*-**-*|-|-| ; add ONE --** |---****-|-|-| ; write to SCRATCH -*-- |-*-*-**-|-|-| ; IF MAX, GOTO LBL_RESET -*-* |-*------|-|-| ; ELSE, start over -**- |----**--|-|-| ; LBL_RESET: read in ZERO -*** |---****-|-|-| ; write the ZERO to SCRATCH *--- |--------|-|-| ; fall off the world (I think this is where is missing jump is) *--* |--------|-|-| *-*- |--------|-|-| *-** |--------|-|-| **-- |--------|-|-| ; ZERO (r/o literal) **-* |-------*|-|-| ; ONE (r/o literal) ***- |--------|-|-| ; SCRATCH (r/w) **** | OUTPUT |-|-| If I change his "fall off the world" to a "start over" instruction (-*------) then it works fine
- ketralnis 11y agoI wrote a little fibonacci: RAM AD PC ADDR ________ _ _ ---- |---****-|-|*| ---* |----**-*|-|-| --*- |---***--|-|-| --** |--*-***-|-|-| -*-- |---***-*|-|-| -*-* |----**--|-|-| -**- |---*****|-|-| -*** |-*------|-|-| *--- |--------|-|-| *--* |--------|-|-| *-*- |--------|-|-| *-** |--------|-|-| **-- |--------|-|-| **-* |-------*|-|-| ***- |--------|-|-| **** | OUTPUT |-|-| But due to the saturating arithmetic, it gets to 255 and then just prints 255 over and over. I tried to write one that would reset itself when that happens, but I can't seem to do it in 15 bytes (I have a 14 instruction+3 variable version but of course 17 bytes won't fit in RAM) Edit: I can save one of the variables with a set-immediate instruction :) https://github.com/gto76/comp-cpp/pull/7 https://github.com/gto76/comp-cpp/pull/7
- fbonetti 11y agoCan anyone give me a super dumbed-down explanation of how to operate this machine? If I understand the README correctly, it looks like the left 4 bits are the instruction, and the right 4 bits are the address. So the line ---1--1- would mean "READ the value from address 0010 into the register". Is the correct interpretation? If so, how do I put a value onto the register in the first place? How I do I set the value at an address? Let's say I wanted to add 0001 + 0001 and show the output as 0010 on the printer. How would I do that?