A snake game made entirely in the BIOS without any OS or bootloader
Posted by Perfect-Highlight964@reddit | programming | View on Reddit | 119 comments
When I made my original snake game some people argued the only reason it was possible, was that the PC already had the BIOS and OS on it so what I call a "58 bytes snake game" is not only 58 bytes because the BIOS and OS are each thousands upon thousands of bytes.
While it's true that without those wrappers the program wouldn't be that small, I don't think it's a valid argument, but anyways, I made a POC snake game that can work without any BIOS, bootloader, or OS, all the code, including the hardware initialization, fits in 114 bytes (and filler) and runs on QEMU.
I also commented every single line in the code so you can use it to learn about how the BIOS initializes the hardware, although I tried making it very minimal (just like the original snake game), so there is not much to see.
The main problem I encountered when making this was the icount. The icount is an optional QEMU argument that allows you to set a certain speed to the emulated machine.
I wanted to use icount=20, however, someone on the QEMU team limited the icount to 10 max although everything works just fine for icount<=30.
I made a PR to the QEMU project to fix it by raising the max of icount to 30 and doing the necessary adjustments to the code to enable it to work with the higher icount.
However, one of the devs at QEMU noted that icount is deprecated so I should use the ips plugin. The problem now was that my QEMU version (5.2.0) was incompatible with plugins, I tried changing to 9.1.0 and the plugin worked! But now my BIOS didn't output anything to the screen.
I had a hunch the problem had something to do with the changes made to the VGA protocol of QEMU between those versions, so I did a binary search between the versions and found that my program works perfectly fine up until v9.0.0-rc0.
So now all I had to do was skim through the changes made between versions 8.2.6 and 9.0.0-rc0 and find something that could lead to the screen staying empty.
I looked at diffs for a whole hour and finally, I found it, I couldn't believe I missed it all along, someone started to use the byte masking property of the graphics registers.
I quickly added an output of 0xFF08 to port 0x3CE and it indeed fixed the issue and I was able to use ips successfully.
zedkyuu@reddit
Waiting for someone to complain that this doesn’t count because it won’t work on real hardware because you don’t have things in there like DDR memory initialization and the Intel/AMD processor initialization blobs and whatnot, heh.
AgoAndAnon@reddit
"This doesn't run on an abacus so it doesn't count."
raskim7@reddit
”My brother in christ I couldn’t run this in my sundial, are you even trying?”
josluivivgar@reddit
I found a rock, got some jumper cables and a potatoe, I plugged everything together and tried to run your snake game, but it won't even start up
GheorgheGheorghiuBej@reddit
His joke, but worster
Perfect-Highlight964@reddit (OP)
I mean, if I had real hardware I would make something for it, but I don't, so I have to stick to the emulators...
WaitForItTheMongols@reddit
If you're running the emulator, you must be running it on hardware, so clearly you have hardware available!
I don't care if it's your only laptop and you use it for school, you must run snake on it for my enjoyment! :)
Perfect-Highlight964@reddit (OP)
My only hardware is my snapdragon CPU phone, so not really an option 😅
Infamous-Way-416@reddit
What?! That’s awesome. I’m trying to figure out the best way to get a coding setup on my iPhone for when I’m away from my computer and have an idea. My best approach so far is running Linux in UTM but it’s not going great… still trying to figure out the best ways to deal with the screen size. What do you use?
Perfect-Highlight964@reddit (OP)
I'm using proot to "emulate" a Debian machine on the Termux app (https://github.com/donno2048/Debiandroid)
WaitForItTheMongols@reddit
Wait, so you coded this thing on a phone? That makes everything even more impressive.
Perfect-Highlight964@reddit (OP)
Thanks 🤣
pjmlp@reddit
As inspiration, https://tinytapeout.com/competitions/demoscene/
GaboureySidibe@reddit
As inspiration for what?
pjmlp@reddit
Apparently for silly comments.
GaboureySidibe@reddit
You aren't making sense
Perfect-Highlight964@reddit (OP)
When I said I wanted to test it on real hardware I meant using an actual CPU and not on an ASIC, I guess it could be interesting too but it's almost an entirely different field...
Perfect-Highlight964@reddit (OP)
But I guess you're right...
zedkyuu@reddit
Sorry, I’m mocking anyone who would continue to insist that this isn’t “BIOS independent”. I think even the original with its one single mode set call counts as that, too.
sexy-geek@reddit
Well, he IS relying on the hardware clock, soooo. It's not that hardware independent. And also, assuming the standard ports and all..... I'd say this is just a lazy attempt....
( As in, I'm daring you to go even deeper just out of spite and make this run on a toaster and earn even more mad respect from a bunch of nerds )
ovum-vir@reddit
Careful, you’re giving this mad man new ideas
Perfect-Highlight964@reddit (OP)
😅
RegularUser003@reddit
mad lad energy
captain_obvious_here@reddit
Low level programming is more and more of a lost art. This is extremely impressive!
Perfect-Highlight964@reddit (OP)
It is very saddening that it is, I appreciate the work that the FFMPEG foundation does to promote low-level programming for new programmers, the state of current software and the bloat added to almost every single program is very bad imo... Not to say that the over-minimalistic approach I took is good in production but you get my point.
captain_obvious_here@reddit
It's not even about software efficiency (although performance definitely counts!) but about the fact most young developers now have no idea about how a computer works, memory is managed, and such.
I'm very far from having as much knowledge as you seem to have...but I remember a time when a common technical interview question was "how would you write your own malloc?". Nowadays I would never hire anyone if my interviews relied on that question :)
946789987649@reddit
Why is that a problem? There's multiple abstractions even from how memory is managed, where do you stop?
captain_obvious_here@reddit
It's a problem when you hire people to work on stuff that need be work in optimal ways. Not every field of IT has gigabytes of RAM, and not every problem has a "throw more hardware at it" solution.
946789987649@reddit
Absolutely, but we're talking more in the general sense than specific fields. As I said in another comment, the vast majority of us are doing CRUD apps, it's fine not to know how memory is managed.
captain_obvious_here@reddit
We're in a thread about a guy who wrote a game that runs in a PC BIOS...
946789987649@reddit
Yes, which brought us on to talking about developers in general
Perfect-Highlight964@reddit (OP)
If in ten years a need for a CPU architecture will arise and nobody knows anything about bare-metal the developers would have to gather bits and pieces of information online and reinvent the wheel over and over again...
946789987649@reddit
That's a wild if lol, I don't think that's an example at all.
Not to mention that yes some people need to retain that knowledge, but not your average CRUD developer (which let's be honest, the vast majority are)
Perfect-Highlight964@reddit (OP)
Yeah, I didn't mean the example is realistic or probable, I'm just saying that it leads to knowledge lost, and the knowledge can be used...
I do get your point that only some people need to know it, but when years pass by, fewer and fewer people fit into this category.
FeliusSeptimus@reddit
lol, this candidate can't even refine ultrapure silicon from beach sand!
946789987649@reddit
Honestly what is the world coming to? People used to really know what they were working on.
scythus@reddit
Ultimately people know and learn what they need to know to do the job. For 99% of development jobs in 2024 doing your own memory management is a terrible idea.
captain_obvious_here@reddit
It definitely is a terrible idea to DO your own memory management stuff. But understanding how it works makes a world of difference between two developers.
Perfect-Highlight964@reddit (OP)
You don't need to make and use your own malloc to be able to understand how memory is structured and allocated.
Perfect-Highlight964@reddit (OP)
That's a big problem too.
josluivivgar@reddit
it's hard to get started on it, it's hard to find a job that doesn't require years of experience already, so it's basically a very exclusive club, I've been starting to want to get into it, but I can't "learn on the job" because every job requires years of experience.
and there's no very obvious paths, I'm slowly learning, but in the meantime I have to feed myself and my family so I have to find an unrelated job until I learn and gain enough experience
Perfect-Highlight964@reddit (OP)
Makes sense, don't feel bad about it though (I'm currently a secretary basically) and continue learning it, I think it could really help you by expanding the way you think about many things and quite worth it...
josluivivgar@reddit
for sure, just wonder how they'll get people with 5+ years of experience in that in 10 years where to he people right now that don't already have 5+ years of experience don't really have a chance at all
I definitely think it's worth learning even if I never get a job related to it
Perfect-Highlight964@reddit (OP)
Agreed
pickledplumber@reddit
I've always wanted to learn how a thing runs on a processor / computer. It's obvious that we do it everyday but what happens when the computer starts up to get the program you want to run.
Maybe you could explain and I will Investigate your project too?
ShinyHappyREM@reddit
Obviously depends on the architecture; on the 6502 the CPU loads a pointer value stored at the end of the address space and jumps to that address. Related:
Perfect-Highlight964@reddit (OP)
I think that is true for most CPUs
ShinyHappyREM@reddit
Apparently early Intel/Zilog started at zero: https://retrocomputing.stackexchange.com/questions/9448/where-does-the-z80-processor-start-executing-from
sexual--predditor@reddit
From Speccy coding :) Yes Z80 starts at $0... and from some MPU4 Fruit Machine hacking I think the 6809 starts from the end, at $fffe.
ShinyHappyREM@reddit
Makes sense, the both the 6502 and the 6809 were inspired by the 6800 in that regard.
Perfect-Highlight964@reddit (OP)
I didn't mean all CPUs go to the same address 😅
I meant that almost every CPU has a reset vector...
Perfect-Highlight964@reddit (OP)
Well, it's not really as complicated as you might think at first, put simply, the CPU communicates with many types of devices by simply outputting data to the i/o ports and DMA (which simply means that the device uses an intermediate chip to use the mainboard RAM/ROM/... instead of its own) and such. One very common way for I/O port communication used for hardware initialization and settings is writing to the I/O port related to a specific register array the index and then the value of the property to be overwritten.
I don't know how well it explains it, but I think that's all the background you need to view the code.
Somepotato@reddit
Note that io ports on real hardware could do nothing before the bios does some initialization
Perfect-Highlight964@reddit (OP)
I don't think that's true, maybe just for PCI
Somepotato@reddit
There is no real standardization there. In fact, iirc, Intel is planning to kill off both real mode and io ports because of that.
Perfect-Highlight964@reddit (OP)
fr? never heard of it
Somepotato@reddit
Look into x86s. Not sure if it's gone anywhere but the interest is there.
Perfect-Highlight964@reddit (OP)
Looked on the Intel page for x86s
First of all, this is awful imo, but regardless of what I think, it seems as if the I/O port disabling is only applied for ring 3 which does not apply to the BIOS, or am I missing something?
Somepotato@reddit
Well the bios won't exist anymore, it'll just be uefi. There are motherboards that don't support legacy boot and that number will only grow over time. But truth told I thought they were eliminating io ports entirely because they're so legacy and are unstandardized entirely.
DwarfNylon@reddit
Bruh, you slept for 4 hours.
Perfect-Highlight964@reddit (OP)
Yeah, my doctor said I have insomnia, not sure about the insomnia but I do have some sleep problems...
DwarfNylon@reddit
I'm gonna DM you.
Perfect-Highlight964@reddit (OP)
k
aholmes0@reddit
If you really want to get your hands dirty, check out https://www.nand2tetris.org/
MarcusOrlyius@reddit
When the computer boots up after posting, the bios would look for a Master Boot Record file at the start of the primary storage device which is typically 512 bytes. This would basically contain partition data and at the start of the partition there is a Volume Boot Record. The MBR would basically load the VBR from the active partition which would then start loading files to boot an OS.
Detailed info can be found in the links below:
https://en.wikipedia.org/wiki/Master_boot_record
https://en.wikipedia.org/wiki/Volume_boot_record
Ralf Brown's Interrupt List
haqbar@reddit
Just wanted to add Ben Eater on YouTube here, he builds a cpu from scratch on breadboard and does an excellent job of explaining as he goes. Cool series and well made
Perfect-Highlight964@reddit (OP)
I'm going to sleep, it's 4 am here... 😅
Will answer this tomorrow...
GreyHat33@reddit
Meanwhile in other threads people are complaining how hard learning git and c# is
fxfighter@reddit
This is actually the most powerful/well known form of development, i.e. SDD. Spite Driven Development.
unloud@reddit
Ah, yes, the Git, Mozilla, and Signal approach.
happyscrappy@reddit
That's basically what a DOS program was. At least one that didn't read any files. You used BIOS calls for display and DOS calls to access the file system.
You could probably turn it into a .COM file and run it under DOS. Especially if it never exists (you don't have the exit INT call in your code).
Perfect-Highlight964@reddit (OP)
Yeah, the point is that it doesn't use BIOS calls though 😅
happyscrappy@reddit
That's not what the headline says: "entirely in the BIOS".
There's two ways to do it. You either can make BIOS calls (INT 11h? I forget) or you can just put values directly into the video card (frame buffer, ports). Either is the exact same thing DOS programs do.
Perfect-Highlight964@reddit (OP)
You do realize
int 11h
in a DOS program is basically pushing IP, setting CS to [0:0x46], and then setting IP to [0:0x44]? You can't simply doint 11h
in the BIOS (you can but you need to define it first).happyscrappy@reddit
Why are you talking down to me? We both know what an BIOS call is.
You wrote in your title you run only in BIOS, no DOS needed. I'm telling if you do that you can run also under DOS, just package your code as a .COM file. Might be easier to debug that way.
Perfect-Highlight964@reddit (OP)
First of all, sorry if it felt like I was talking down to you, English isn't my first language, when I wrote "you do realize that..." I meant it literally, as if to ask you if you understand that BIOS calls have no inherent meaning when in the context of the BIOS itself other than those defined by the BIOS itself, because I understood you incorrectly.
Secondly, now I get what you're saying (I thought you meant to say that the BIOS I made is equivalent to a COM executable), but there is already a COM file version, that was made as a kind of generalization of sort...
happyscrappy@reddit
I think this is more the communications problem.
When you say "run in BIOS" it's like "runs in Windows". It means you use BIOS. I looked at your code and now I see why you can't make a BIOS call.
What you should be saying is "A snake game made entirely as a BIOS" or "A snake game that runs in place of BIOS".
Again, probably because English isn't your first language, the confusion is very understandable.
And now I see why people say doing it on real hardware will be so much more work. Burning an EPROM or whatever. You might be able to use a machine which has a "dual boot BIOS" but it's still going to be difficult and you better be sure the way to switch back is implemented in hardware so you know you can bring it back to booting normally, if only to update your code later.
Perfect-Highlight964@reddit (OP)
Thanks for the correction...
Worth_Trust_3825@reddit
I aspire to be as petty as you. But as u/zedkyuu says, your next goal is real hardware.
Perfect-Highlight964@reddit (OP)
I wish! I can't afford real hardware (especially not one that is good for bare-metal debugging...)
ovum-vir@reddit
Crowdfund it? I’m sure many people that have watched this journey would love to see how far you can take it. You’ve certainly earned the right to some financial support for the project
Perfect-Highlight964@reddit (OP)
People suggested it before and I always rejected the idea simply because I think not many people are willing to contribute to it
ovum-vir@reddit
I think you’ve put in enough work now that you could definitely get it funded. An exact dollar amount you would need would help. Feels like this is the right ending for the project
Perfect-Highlight964@reddit (OP)
I would need at least: - A machine with i486 or below, a 8042 chip and a VGA card, the best option I could find was pocket386 which will cost 212$ without tax and shipping - SST 39SF512 to flash the BIOS to, which will cost 16$ - EPROM programmer with a PLCC32 adapter - 73$
I'm willing to pay taxes and shipping, so overall it's 300$.
I also need a soldering iron and a soldering rework station but I can buy those myself if they're not very expensive.
b0w3n@reddit
At least you're realistic in your goals, there's something people appreciate about that.
I've seen similar projects with lofty like 10k goals never get funded, but the small ones looking for a few hundred to do something neat like this seem to.
ovum-vir@reddit
I’d be willing to throw in $5, only need another 59 people to do the same. You’d need to advertise this yourself but hopefully people in the community see this and are willing to help this project get to its final form! Good luck
iafs_@reddit
I wonder, what kind of hardware allows you to do bare-metal debugging? Is it some kind of dedicated motherboard-CPU combo? Btw, cool project! I'm always impressed by these low-level marvels.
Perfect-Highlight964@reddit (OP)
I thought of a CPU-breadboard adapter, saw someone make them on YouTube, but I don't have any hardware whatsoever anyways
Worth_Trust_3825@reddit
Intel has jtags, but i think they're behind a lot of legal paperwork.
walking_smoke_cloud@reddit
Oh, what does this spell do?
Emergency-Limit-1238@reddit
Good stuff mate!
Kinglink@reddit
"Yeah but originally it was 58 bytes, and now it's bloated up to 114"
(Guys, let's just keep ragging on this dude, until he creates Snake with atoms)
Zitronenlolli@reddit
SnakeOS incoming
Bob_The_Doggos@reddit
A git bisect could have found that much easier and in at least half the time.
Perfect-Highlight964@reddit (OP)
Building qemu takes a whole hour on my machine and has no file-based caching, so to use git bisect I would have to either improve the caching mechanism of qemu (which would take more than an hour) or wait for at least one compilation which also will take one hour.
So I thought looking at diffs would be the most effective way to find the issue.
Bob_The_Doggos@reddit
I just recently bisected a bad qemu commit on my machine and it took less than a minute to build.
Maybe you're compiling a bunch of unnecessary things like other machine types you're not testing, the docs, tests etc? Or maybe your machine is just that slow, not sure. But it certainly isn't the case for everyone.
Perfect-Highlight964@reddit (OP)
"My machine" is a Debian "container" I run on the Termux app on my 120$ phone so it might be it 😅😕
Maybe I am also compiling too many unnecessary things.
Does qemu use ccache by default?
FeliusSeptimus@reddit
lol, this is awesome.
fromtheether@reddit
Just posting your GitHub for others to find since I didn't have it handy: https://github.com/donno2048/snake-bios
I've followed your smol Snake journey for a while now, but I think this takes the cake (so far!) This is so fucking cool. It might actually make me sit down and try to figure out the ASM. Even after taking a course in uni I have about 0 knowledge, and it's always bugged me that it kicks my ass.
BlauFx@reddit
Wow, that's really impressive!
Perfect-Highlight964@reddit (OP)
Thanks!
jeaanj3443@reddit
waiting for but can it run doompeople always want more
anti-bullsh1t@reddit
Damn. I wish I was this smart.
Korlus@reddit
This is so cool (like your last project). Kudos!
Have you ever looked at the demoscene before? They focus on trying to make aesthetically pleasing music/sound videos, featuring tiny code sizes (although rarely quite as small as you've aimed for). E.g. the code for this video fits in 64kb. While there are different competitions and demoscene standards, Revision is one of the biggest, and it has a 4k competition this year.
May not be your kind of thing, but the demoscene is so far away from most programming subcultures that it's always fun whenever someone gets close.
Perfect-Highlight964@reddit (OP)
Thanks! I've heard about the demoscene but I don't think I have enough creativity to do something of that sort, the video is amazing though.
ezaquarii_com@reddit
Nice. Very nice.
ImAtWorkKillingTime@reddit
Well done!
Perfect-Highlight964@reddit (OP)
Thanks!
IndependentMonth1337@reddit
This is cool. If feel like i know nothing when i see stuff like this. Where do you start if you want to learn and understand stuff like this?
Level-Taste4581@reddit
The osdev website has some good resources i think.
Perfect-Highlight964@reddit (OP)
Félix Cloutier's online x86 references are pretty good for getting knowledge about CPU instructions and their effect. You can read on tutorialspoint about the basics assembly. And although I'm pretty sure it's abandoned osdever has a lot of resources for bare-metal stuff, probably the best ones I've seen.
Those are the only resources I used as far as I can recall because it's pretty hard to find good documentation on those topics and those were excellent, so I highly recommend you check them out if you find the topic interesting.
Also, I guess the best path is to learn C then x86 then bare-metal, not jump to deep water.
s0ulbrother@reddit
I’m literally just like this is some amazingly next level petty shit of “fine you say I could only do this because of this well fuck you I’ll start my own thing, with black jack and hookers”
Perfect-Highlight964@reddit (OP)
Yeah, ig, but it's not really meant to "prove everyone wrong", it's more about the fact that I love giving myself challenges and this was an excuse for one 😅
iamiamwhoami@reddit
Yeah the best way to show someone up is doing it while acting like you couldn't care less.
QuestionableEthics42@reddit
Are you really a programmer if you don't do that for a sadistic form of "fun" though?
GauntletWizard@reddit
You sir, are awesome.
Perfect-Highlight964@reddit (OP)
Thanks
OffbeatDrizzle@reddit
nice
Perfect-Highlight964@reddit (OP)
thanks