Low Level Computing and Assembly
On this page I’ll keep resources related to the topic above. I have always had a special place in my heart for games that ran directly on “bare metal” hardware like consoles or the Commodore 64 because from some perspectives things were so simple and straightforward and there weren’t enormous layers of operating environment to bog your code down. Of course from other perspectives programming was vastly more complicated back then due to the limitations and quirks of computing and gaming hardware and this page will list some resources about low level things of that nature. I also have a soft spot for classic computing and gaming so there will likely be plenty of that going on here.
Low Level Computing
- This video is about an hour long and explains in detail how your operating system works; for example it explains what happens when your computer boots up and ultimately shows you how to create an extremely bare bones operating system of your own that runs a tiny amount of software that you wrote!
- @35:00 it shows that you have to do some byte skipping to put characters on the screen
- Notes To Self: Other reasons: Wolfenstein 3D had to do some black magic with the VGA screen buffer turning the bitmaps sideways to get texture mapping to be fast enough.
- in the NES video I watched earlier today about programming NES with 6502 assembly it talked about how you had to fill up a background buffer with loops bigger than the processor could handle.
- On this emulator site you can emulate a bunch of old and new operating systems some with assemblers already installed.
- I ran windows version 1 (interesting how much it has progressed) and freebsd.
- This video (called How we fit an NES game into 40kb (~12Min)) has high production values and explains many of the optimizations they used to get their (relatively advanced) NES game to fit in the original NES rom size of 40kb which as you probably know is absolutely freaking tiny by todays standards. It notably does a fantastic job visualizing how their sprites were optimized to fit in the small amount of graphics memory available (8kb) which allowed them to add more actual content to the game.
- Get started by building and running code that does something in assembly in just 20 minutes total. The most straightforward way to start dabbling in assembly programming is probably to watch this 10 minute video and then run the software he gives you to build and run an assembly program for the Sega Genesis. I watched the video and less than 10 minutes later I had built and run my first assembly program!
- Caveats: You need windows, and you need this Sega Genesis Emulator which worked well for me (any other emulator will work too)
- Here is a good high level introduction to Assembly on the NES which shows that even though pong is effectively a very simple game, making a pong game isn’t as easy as it might seem when you are working at the lowest levels.
- It also briefly shows writing to video memory, reading from controller input, interrupts on the NES, etc.
- Here is a good low level introduction to Aseembly on the NES which goes into way more detail about assembly (its about an hour long) but I haven’t tested whether its easy to reproduce his work.
- There are links to the source code and the assembler in the video description so you should be able to reproduce what he did.
- But much of the video is really an exposition of how complicated it was to develop games like this back in the day
- Heres is the code (from the link in the description of the video)
- Instant translation between C and Assembler
How does an ‘if’ statement work at a hardware level
I spent some time preparing an answer to a stack overflow question and although I’m not even sure I answered the question they were asking there is a lot of good information in my answer:
The answer to this has to involve an explanation of what software the hardware is executing.
Background: Each processor has a set of built in codes that tell it what to do (its “machine language” or assembly language) and on modern computers one of those is always a “branch” statement of some sort and I think this wikipedia article) will help answer your question.
More Information: A simple example of this is ‘jeq’ in x86 assembler which stands for ‘jump if equal’ which works like:
JEQ R1,R2,addr // IF R1 == R2 THEN PC addr ELSE PC++
which compares R1 and R2 and if they are equal then the program counter jumps to a location in memory (addr) and starts reading commands from that new location (which would be everything inside the if statements curly brackets). Slide 13 of this presentation has more on this.
A possible explanation of this code:
if (4 < 5)
one instruction would load 4 into register a a second instruction would load 5 into register b a third instruction would compare them and the result would be stored in a ‘condition code’ and a fourth instruction would look at the condition code and either jump the program counter to a new location, or continue executing the next instruction
This page is an easy read and does a good job explaining logic gates and multiplexers which are the building blocks needed to make the circuit you are describing
How some of these instructions are enabled at the circuit level is in these amazing breadboard computer videos
Heres a video that disassembles a simple C program into machine language and although there is technically no if statement, there are related conditional statements which work somewhat similar.
And here is an assembly guide from the university of Virginia.