bootsector.txt

What is a bootsector?

A boot sector is the sector of a persistent data storage device (e.g., hard disk, floppy disk, optical disc, etc.) which contains machine code to be loaded into random-access memory (RAM) and then executed by a computer system's built-in firmware (e.g., the BIOS).

Usually, the first sector of the hard disk is the boot sector, regardless of sector size (512 or 4096 bytes) and partitioning flavor (MBR or GPT).

The fun part about writing code that would run in a bootsector for a intel compatible processor that runs on the IMB PC and compatibles is that it only provides a 16bit real mode for the processor and 512bytes for the code itself

On an IBM PC compatible machine, the BIOS selects a boot device, then copies the first sector from the device (which may be a MBR, VBR or any executable code), into physical memory at memory address 0x7C00. On other systems, the process may be quite different.

We are however only concerned with the "default" which is the one that loads code at 0x7c00 and provides 512 bytes of data

stupidity.txt

Why bootsector?

There is something fun about trying to challenge yourself to make something with limited resources. This idea was born out of just interest in making things not for any os, but for hardware itself, but since i had no access to any old console and didn't want to deal with setting up emulators and such I chose the desktop PC as the target.

Thanks to what bootloaders are meant for this created a situation where i essentially used the modern desktop PC hardware as a makeshift game console. Although this would be far more limiting than any real console, at least one that people think of when they think "retro" console

technical.ld

What do you even get?

Code

Generally most programming for modern hardware is done in a very high level language. That can be C++, C#, Kotlin, Python etc. which provide lots of helpful tools and built-in things. However in this case, none of them can be used with a good result. This code has to be very specific and you require very precise control over the final binary. This is where assembly comes in! Using assembly is about as close as you can get to just writing out machine code bytes yourself, at least in a sane way. This does come with a downside of the code generally being far more complex for even simplest things

Assembly vs C

Take this C-like code for a example int b = 4; int a = b + 3; It's written in a way that can be easily understood by human writing it and is fairly consistent with how we write expressions. Assembly on the other hand is not meant to be easy for humans to read, but instead map closely to the machine code, so similar(exact will depend on what we are doing) code could be something like this

mov bx, 4 ; let's presume that value for 'b' was stored in register bx
add bx, 3 ; perform 'b + 3'
mov ax, bx ; store result of 'b + 3' inside register 'ax' which we will assume is where the 'a' will be stored

As can be seen each operation has to be performed separately. It's also important to note that assembly does not have a concept of a variable, it just has processor registers.

  • General purpose registers: ax, bx, cx, dx
  • Special registers:
    • si - used offsets into data space, being second part of address formed with DS
    • di - used offsets into data space, being second part of address formed with ES
    • bp - stack pointer, refers to the current position of data in program stack
    • sp - base pointer, used in addressing subroutine call arguments
  • Segment registers:
    • cs - code segment, points to the code itself
    • ds - data segment, points the part of the program where data stores(for example using DB operation)
    • es - extra segment, can be generally used as needed and has special instructions related to writing bytes
    • ss - stack segment, base position of the stack, used in conjunction with stack pointer

Memory

Tools