A0 - Getting started (From scratch!)
Thanks for taking an interest in developing for the VO-EM virtual console! This first article is a for-beginners introduction to the basic workings of the device, and computers in general. If you already have a basic knowledge or feel like you'd rather wing it, go ahead to the next tutorial.
This page only refers to one variety of computer; I am aware there are other kinds, but this information is as-relevant to the VO-EM console.
This tutorial doesn't require any specialist knowledge or prior experience, but you do need to know some terms and basic math to be able to get anywhere. I am not going to reinvent the wheel here by defining them all. Instead, I'm going to go ahead and say: Google words you don't understand. Google is a lifesaver. Nothing I say on this page is unable to be defined by Google.
Loosely speaking, a computer is a collection of individual devices that are able to communicate and be programmed to perform tasks. By that definition, nearly every device, from a wristwatch to a jumbo jet is a form of computer. For example, a microwave: most likely, it has buttons, a little screen, a bell, the motor that turns the food around, the doohickey that actually heats the food, and a processor of some kind.
The processor, or CPU, is the part of the computer that actually tells the components what to do. So, when you press "5", it puts the digit "5" on the screen. When you press "start", it turns on the cooking device, turns on the motor, and then counts down from 5, after which it turns them all off again and tells the bell to sound.
However, the CPU doesn't actually know that it's doing any of these things. All it does is kick numbers around.
If you've found your way here, you probably have an understanding of the concept of RAM. It's a whole bunch of blank space inside your computer that can be used to store data temporarily. Each small block of data is one byte, and each byte has an address.
So, say you have a tiny computer with four bytes of RAM.
byte value #0 3 #1 5 #2 0 #3 0
The processor could perform an operation such as "read byte #0 and byte #1, add them together, and store the result in byte #2". Resulting in:
byte value #0 3 #1 5 #2 8 #3 0
But actually, bytes of RAM aren't the only things that have addresses within your computer. Devices within the computer can be mapped to memory addresses, meaning that data written to them actually changes how they function, and that data read from them can actually be indications of the status of the device.
In the case of the previous example, what if byte #1 was actually a microwave's button pad in memory, meaning '5' is only there because that's what the user pressed last? And what if byte #3 was actually the temperature controller for the cooking device?
If the CPU performed the operation "read byte #1 and store it in byte #3", you'd get this:
#0 3 #1 5 <---- this byte contains whatever button was last pressed on the keypad #2 0 #3 5 <---- this byte controls the heat of the cooking device
The CPU has no idea what it has done - it just performed an instruction on the bytes at the given addresses. But the result is that the microwave is now pumping out heat at setting "5", because the user pressed "5" on the button pad.
It's the programmer's job to know where to tell the CPU to read from and write to in order to make the computer do what we want it to do.
On the VO-EM console, things like the controller pad, screen, and timer have addresses in memory allowing us to access them. Writing a number to a byte, for example, can change the position, colour, etc, of a character on the screen. This is exactly how old-fashioned consoles like the SNES and Gameboy worked.
Instructions and Operations
In the last section, I mentioned "operations", such as reading memory, adding numbers, and saving memory, but I glossed over how the processor actually knows how to do these things. It's actually quite simple.
The "instructions" that tell the CPU what to do exist in addressed bytes of memory as well. Maybe they get loaded into RAM from a floppy disk, or maybe they exist on a read-only data storage chip somewhere in the bowels of the computer.
The CPU has a counter, usually called "PC", or "Program Counter", which keeps track of where it's currently up to. Every time it cycles (the average cpu cycles many times per second), it will load up the data contained in the byte that is at the address that PC is pointing to, perform the instruction, and increment PC so that it's pointing at the next instruction.
What this means is that our program - the instructions that we write to control the CPU - exists in the same memory address space as all the other devices, RAM, and the like. How does the CPU know that the address PC is pointing to contains an instruction, and not, for example, the current heat of the microwave device? It doesn't!
The CPU just obediently goes through memory, trying to execute every byte of data it comes across as an instruction. It's part of the programmer's job to ensure that PC doesn't end up somewhere it shouldn't be.
The VO-EM virtual console's DLX-based CPU has 32 bit instructions, meaning that it loads 4 byte long instructions to decide what operations to perform. As such, PC is always a multiple of 4. For more information on how instructions are formatted for our console, see Instructions.
Registers, loading and saving
Reading to and writing from RAM and other devices is quite slow. It would be inefficient to have the CPU constantly reading and writing. Instead, the CPU has some memory of its own, which can be used to perform arithmetic and other operations. These blocks of memory are called "registers". When we read data from memory, it is stored in a register. We can then perform some number kicking on it, and save the result back into memory.
Have a look at our original example of the very small computer - now, we'll give it 2 registers (r1 and r2), each 1 byte long. The instructions to add byte #0 to byte #1 and store it in byte #2 would actually look something like this:
load r1 with the contents of byte #0 (r1 = 3, r2 = 0) load r2 with the contents of byte #1 (r1 = 3, r2 = 5) add r1 to r2 and store the result in r1 (r1 = 8, r2 = 5) save r1 to byte #2 (r1 = 8, r2 = 5, byte #2 = 8)
The VO-EM's CPU has 32 registers, numbered r0 to r31, with each register being 4 bytes long. However, r0 is always equal to zero. Having 32 registers is very luxurious - the Gameboy, for example, only had 8 - and you could only use one of them to do arithmetic!
If you are familiar with other programming languages, it may be useful to consider registers like you would consider variables. The "i" that's typically used in a "while" loop, for example, or the x and y speed of your character on the screen in a game.
The next step
That's probably a lot to digest! I'll be adding to this article and making it easier to understand over time, but don't let any confusion get in the way of you jumping right in to the next tutorial!