Tetris-OS: An operating system that only plays Tetris
github.com
github.com
This probably sounds like I'm picking a nit, but I think it matters for the sake of newbies just starting to climb the learning curve and trying to understand what an "operating system" actually is. IMHO, the defining characteristic of an operating system is that it provides an environment in which to run other programs, ones that are not part of the operating system, and which may not even exist at the time that the operating system starts to run.
(You'd have them in userland. Whether you count that as part of the OS or not, is a different question.)
But if you accept that, everything becomes fuzzy. Is the firmware an "operating system" then? The CPU microcode? On systems like the XEROX Alto, the microcode was developed like a sort of OS kernel. I think it's interesting to explore the "lesser meanings" of terms like "operating system" :-)
For example, you can have a Smalltalk-based OS, written in Smalltalk. The OS components are simply Smalltalk classes and methods. Your programs/utilities/applications would also be Smalltalk classes and methods. There needn't be any clear boundary between the classes/methods that belong to the OS and those that belong to programs/applications/utilities.
If you look at library operating systems, the operating system is just a library which you link into your application. Such an operating system can only run one program, and you have to rebuild the operating system whenever you want to change the single program it runs. Still, I think library operating systems count as operating systems. This Tetris implementation isn't using a library operating system, but you could refactor the code into two parts – the Tetris game, and generic OS services, and the later would constitute a library operating system. If you look at its source files, only about seven of them (main.c, music.[ch], sound.[ch], speaker.[ch]) actually implement the game. The other 23 source files are generic OS services. So I'd say that, even if this isn't an operating system as a whole, it contains an OS within itself.
Note that this also makes for example the uppermost part of the JVM an OS by my definition. I’d argue it’s not a completely incorrect characterization.
For too narrow: you might have a security focused OS that includes everything like a TCP/IP stack etc, but perhaps doesn't allow arbitrary binaries by construction. (Eg it might only allow binaries that come with a proof of innocence, or some other restriction that's harsh enough to lose the 'arbitrary' rating.)
For too broad: https://en.wikipedia.org/wiki/Weird_machine would make almost any software that was written sloppily enough into an OS.
Imagine some embedded application, eg in car, that has a network stack, graphics drivers etc, but can only run built-in functionality.
In your example, a real or virtual machine’s load/setregs interface is an operating system. One that can only run a single program at a time in the case of the physical processor’s bootstrap, but you’d be surprised how similar that is to early DOS.
A more hand-waving version is “the lowest level interface over the machine that can run...”. So a processor and a ROM grid can run arbitrary programs, but the lowest common denominator entry point is the ROM flashing spec! A very slow scheduler indeed.
No, every operating system that I know of makes some assumptions about the language that programs are written in. On my amd64/Ubuntu system, the language is largely specified by the processor (and, yes, has a binary format) and the programs are allowed to assume the presence of various devices, formats of various system calls, etc. Other languages are supported through a complicated system of compilers, interpreters and assemblers.
Or, coming at a different tack: does the existence of a C->Smalltalk transpiler turn the Smalltalk-based pseudo-OS into a real OS? What if the pseudo-OS doesn't ship the transpiler, and you need to run that yourself in user-space?
A lot of software was written in this format several decades ago, including many games:
https://en.wikipedia.org/wiki/Self-booting_disk
https://en.wikipedia.org/wiki/List_of_PC_booter_games
I think the boundaries are quite fuzzy; while something like the mask-ROM firmware in a 4-function calculator or microwave would probably not be called an OS by the majority of people, how about a router running Linux, or the RTOS used in a car's ECU? Moving up from there, DOS is clearly in the realm of an actual OS, then we have the locked-down mobile devices, and at the far end are the general-purpose PCs running Windows, Linux, macOS, and such.
Even at the "small end", a microcontroller running a firmware containing a single infinite loop that does stuff with the peripherals seems unlikely to classify as an OS; but what if you start adding dynamic memory allocation, coroutines/cooperative multithreads, filesystem code, etc.?
I do see where you're coming from, though. Personally I would've described it as "bootable Tetris".
We call things BIOS and Boot-loader and Operating System by virtue of history, not necessity. It could even be confusing to a newcomer looking into development closer to the hardware and being told that all these programs are fundamentally different, instead of just being instructions and data getting shoved through a bunch of tubes in the processor and PCB.
Heres a good talk I came across in a HN comment a little while back [1] about how games used to be developed vs how they are today.
(Use qemu-system-i386 -fda btetris.bin if you want to try it out.)
Not really an OS, I just squeezed an implementation of Tetris into a 512-byte boot sector. I remember that a first draft had ~600 bytes and I was cutting away bytes, here replacing mov ax,0 with xor ax,ax, there reusing code as data, until I arrived at that size.
I've lost the source code, but ndisasm should help out.
I remember I encoded tetromino shapes as a 4x4 1bpp bitmaps taking up 2 bytes each, and there's a 56 41 59 41 52 01 56 01 15 48 52 41 59 in the hexdump, which in ASCII reads VAYAR^AV^A^UHRAY. I've been meaning to write a short story featuring a Vayar V. Hray as a protagonist, but never got around to it.
– Casey Muratori in “The Thirty Million Line Problem” https://youtu.be/kZRE7HIO3vk?t=1205
I'd recommend every serious programmer to write their own OS.
There's some decent tutorials available on here that provide a good introduction to the topic.
OTOH the time of jumpers and dip-switches for configuring hardware state is over; I am not sure I want to give any gaming company any chance to persist not only in some management layer of my computer but also in peripherals.
Um, I do extremely well working exclusively with higher level languages like Python and JavaScript. If we're talking about pure salary, a senior web dev will probably make more than the vast majority of embedded engineers.
I'm totally nitpicking here, but I don't like the gatekeeping of saying you need to be able to use a low level language to be a programmer
You may well have very different yardsticks. Programming means different things to different people.
If an intern writes a small Python script to format CSV contacts, that's programming. Programming can be completely visual as well, such as Unreal blueprints. I don't suggest going that route because it doesn't open up many career opportunities, but it still is programming.
Personally I've never been able to use a lower level language to get anything done. And I still have a fantastic career.
Most bootdisk-based games did not have any kind of "customized version of an operating system". They were running on bare metal. For 99% of the games, there was no abstraction/management layer between the application (the game) and the hardware nor any kind of framework that would impose a certain structure on your application. Of course, game code was structured and you could often find subroutines for recurring tasks (clear screen, wait 100ms, read track from floppy,...) but even those were sometimes directly inlined in higher-level code (e.g. game AI) where it gave a performance advantage.
Only complex games had some kind of very thin abstraction/management layer that you could call an OS (often MUCH thinner than embedded micro-OS like RIOT or Contiki). As an example, Carrier Command had a quite general GUI system.
The newer machines use APIs to abstract. Where companies used to conform to particular HW standards (VGA,EGA,etc) with extensions. Now HW companies see their drivers as a differentiator. While the programmer writes to the abstraction API. Technically you could still write bare metal but few companies want to say what their real API looks like. So you are stuck with the OS or if you are lucky what someone else has noodled out.
At the core of it, the AmigaOS exec was tiny and helpful, and things like device drivers were just separate processes that you sent messages to, so it would make sense to make use of them, but just not bother loading all the other stuff that makes up an OS.
Boot-loaded Games disposed of the GUI (Workbench) and some other things, but the OS was not included in them.
I haven’t watched chess in a while, but your comment certainly sparked something. I may give it another go.
For a less nerd-y class of content, I have also enjoyed boxing videos - especially those focused on coaches illustrating technique.
[*] https://www.youtube.com/channel/UCguWV1bZg1QiWbY32vGnOLw
This brings back memories for those wretched days when you needed floppy drivers for the most casual of peripherals. Life was simpler back then (and also much more complex)
(It seems for certain problems it is NP-complete!) https://liacs.leidenuniv.nl/~kosterswa/tetris/tot.pdf
(I also read the paper: to clarify, they are referring to different problems you can build on top of Tetris, and prove some of them NP-complete and some Turing complete.
(They don't mention Turing completeness directly, but they do a reduction to Post's correspondence problem.))
So for it to be turing complete you first need to define a language based on tetris. For NP-completeness, it might just be solving the game.
QEMU works on WSL and WSL2 now, that would be one way.
Edit: Thinking about it, I'm pretty sure QEMU comes with an SDL frontend by default, which should wrap at least audio output even on Windows.
I'm sure someone could figure it out for Windows as well.
Love the brutal honesty.
boot tetris.bin -l a
Or, if you have the source, change the org loading
address to 100h, then compile it as usual, as DOS will
see it as a COM file and thus you could run it under DOS.Genuinely curious, trying to visualize what you mean
Deleting a file would be similar to any current GUI file manager, but with more blocks - drag file block to delete block. Opening a file with a particular program would be similar. Chaining a series of operations would be where it gets interesting. The shape of the pieces would control what can be chained together.
Edit: having read the readme, it looks like performance is locked at 60fps.
The tetrominos themselves are not protected but the shapes+colours are protected in some way (as original art), as is the official set of gameplay rules, the argument being that the overall combination of these is the "Tetris IP"... although the enforceability of that more often seem to hinge into "I don't have the money to fight an army of lawyers to prove that a gameplay idea isn't protected in yet another jurisdiction".
https://arstechnica.com/gaming/2012/06/defining-tetris-how-c...
?! So this is just a stand-alone binary with an awkward loader then.
The real trick (and challenge) comes when you want to run your stuff on actual bare metal.
Also the author refers to the (raw/MBR-format) disk image twice as an "iso" which makes me shudder.
But has it actually run on bare metal or just qemu I wonder. Anyway good music.
> - It's Tetris.
Not sure what I was expecting.
Somewhat like VESA graphics modes which are at least there if you have no vendor-specific VGA drivers.
The SB16 also features FM synthesis, though this program doesn't appear to use it; it rolls its own wave table method.
However, that would be a particular reason to target it specifically, rather than some more modern card that lacks FM synthesis. FM synthesis produces the signature sounds heard in 80's pop music and video games.
The real reason is that SB16 is the lowest common denominator for DOS stereo compatibility with higher models. You might think SBPRo also supports stereo playback, but SB16, SB32, SB64, and SB128 do not support SBPro Stereo mode playback. SB16 DSP 4.x removed support for DSP 2.x 3.x "High Speed" modes. Anything using SBPro Stereo mode will not work in SB16 an newer at all.