A program running inside the boot sector, specifically made for playing an ASCII version of Bad Apple. Inspired by the GRUB version, and my urge for low-level programming.
Check out the video showcasing it here!
To build the bootloader in the easiest way, just follow the instructions below.
You can do it the manual way with an assembler, a video to ASCII converter and a virtualization software of your choice too, but then, you're on your own.
For Windows, you can install Scoop and run:
scoop install nasm make mediainfo python
As for Linux, all of the packages should be in your default package manager. Here's an example for Debian-based distros:
sudo apt install nasm make mediainfo python3
If you want to run the bootloader, you need to install QEMU as well, by either using Scoop on Windows (scoop install qemu
) or using your package manager on Linux (sudo apt install qemu
for Debian).
Once you have Python installed, you will also need to install the dependencies for the ASCII converter. Simply do:
python3 -m pip install -r src/converter/requirements.txt
and all of the needed packages will be installed. For Windows, you might need to use py
/python
instead of python3
.
Before building the bootloader, you will need to do a couple of things.
- Download the video you want to be played. It can be anything you like, however grayscale videos work best. You can download the original Bad Apple video from here.
- Open the
Makefile
and edit variables according to your configuration. The one you will most likely need to change isVIDEO_PATH
, which should be set to the path of the video you downloaded in the previous step. - Simply run
make
in the root directory of the project.
This will build the bootloader in the build/bootloader.bin
file.
If you installed QEMU and want to run the bootloader, you can do so by running make run
in the root directory of the project.
By default, the Makefile uses KVM as an accelerator for QEMU. Since KVM is exclusive to Linux, you might need to change it to something else. If you are on Windows or macOS, you can comment the QEMUFLAGS
variable altogether, QEMU should pick the best accelerator by default. If it doesn't work fine (aka. runs really slowly), feel free to experiment with different accelerators (you can find a list of them here).
In the future, I might implement something bigger, like a custom interrupt handler, to get a stable frame rate. After like a month or maybe even more, I finally understood how to set up the PIT and add a handler in the IVT, thus, the framerate is now fully faithful to the original!
If it is still too slow, that means your CPU might not be able to handle the video at the original framerate.
There are two main reasons for this project:
Firstly, I wanted to learn more about low-level programming, more specifically Assembly. I already made an operating system, however, the Assembly side has attracted me the most. I wanted to challenge myself into using it for something bigger, in order to properly learn registers, interrupts and things like that. Perhaps, in the future, I will step into NES development!
Secondly, no one has done this before.
Actually, I was wrong. @redstone_flash5774 made their version and uploaded it to YouTube here. I didn't notice it at all while working on this, just found it out when I was uploading my showcase video on YouTube. Still, our approaches to do it are different, and they have not uploaded the source code, so I guess I can still be proud of it!
The bootloader.bin
file is split into two parts - the first one is the bootloader itself, with all of the code, and the second one is the video data.
The code reads each frame from the video data and displays it on the screen, by iterating over each character and calling an interrupt for each one.
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome, really welcome, in fact! If you want to contribute, whether it's just a simple question or a whole pull request, feel free to do so.