From 98feca922e46c82d1efdb44b99021b771bdac44d Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Sun, 14 Mar 2021 21:41:47 -0700 Subject: rename boot.hex to boot.subx --- boot.bochsrc | 2 +- boot.hex | 1181 ----------------------------------------------- boot.subx | 1176 ++++++++++++++++++++++++++++++++++++++++++++++ boot0.hex | 4 +- ex1.hex | 19 - ex1.subx | 2 +- ex2.hex | 39 -- ex2.subx | 2 +- ex3.hex | 58 --- translate | 2 +- translate_emulated | 2 +- translate_subx | 2 +- translate_subx_emulated | 2 +- 13 files changed, 1185 insertions(+), 1306 deletions(-) delete mode 100644 boot.hex create mode 100644 boot.subx delete mode 100644 ex1.hex delete mode 100644 ex2.hex delete mode 100644 ex3.hex diff --git a/boot.bochsrc b/boot.bochsrc index 9a02d67c..a1c8a4bc 100644 --- a/boot.bochsrc +++ b/boot.bochsrc @@ -1,5 +1,5 @@ # Configuration for the Bochs x86 CPU emulator to run baremetal Mu programs -# See baremetal/boot.hex for more details. +# See boot.subx for more details. # # Installing Bochs: # On Mac OS: diff --git a/boot.hex b/boot.hex deleted file mode 100644 index f0fe88c7..00000000 --- a/boot.hex +++ /dev/null @@ -1,1181 +0,0 @@ -# Code for the first few disk sectors that all programs in this directory need: -# - load sectors past the first (using BIOS primitives) since only the first is available by default -# - if this fails, print 'D' at top-left of screen and halt -# - initialize a minimal graphics mode -# - switch to 32-bit mode (giving up access to BIOS primitives) -# - set up a handler for keyboard events -# - jump to start of program -# -# To convert to a disk image, first prepare a realistically sized disk image: -# dd if=/dev/zero of=disk.img count=20160 # 512-byte sectors, so 10MB -# Create initial sectors from this file: -# bootstrap/bootstrap run hex < baremetal/boot.hex > boot.bin -# Translate other sectors into a file called a.img -# Load all sectors into the disk image: -# cat boot.bin a.img > disk.bin -# dd if=disk.bin of=disk.img conv=notrunc -# To run: -# qemu-system-i386 disk.img -# Or: -# bochs -f baremetal/boot.bochsrc # boot.bochsrc loads disk.img -# -# Since we start out in 16-bit mode, we need instructions SubX doesn't -# support. -# This file contains just lowercase hex bytes and comments. Programming it -# requires liberal use of: -# - comments documenting expected offsets -# - size checks on the emitted file (currently: 6144 bytes) -# - xxd to spot-check contents of specific offsets in the generated output -# -# Programs using this initialization: -# - can't use any syscalls -# - can't print text to video memory (past these boot sectors) -# - must only print raw pixels (256 colors) to video memory (resolution 1024x768) -# - must start executing immediately after this file (see outline below) -# -# Don't panic! This file doesn't contain any loops or function calls. 80% of -# it is data. One pass through less than 1KB of code (there's lots of -# padding), and then we jump into a better notation. The rest of the stack -# (really only in a couple of slightly higher-level places) needs to know just -# a few magic constants: -# Video memory: start is stored at 0x8128 -# Keyboard buffer: starts at 0x8028 -# -# No mouse support. _That_ would require panicking. - -# Outline of this file with offsets and the addresses they map to at run-time: -# -- 16-bit mode code -# offset 0 (address 7c00): boot code -# -- 16-bit mode data -# e0 (address 7c80) global descriptor table -# f8 (address 7ca0) <== gdt_descriptor -# -- 32-bit mode code -# offset 100 (address 7d00): boot code -# 1fe (address 7dfe) boot sector marker (2 bytes) -# offset 200 (address 7e00): interrupt handler code -# -- 32-bit mode data -# offset 400 (address 8000): handler data -# 410 (address 8010): keyboard handler data -# 428 (address 8028) <== keyboard buffer -# offset 500 (address 8100): video mode data (256 bytes) -# 528 (address 8128) <== start of video RAM stored here -# offset 600 (address 8200): interrupt descriptor table (1KB) -# offset a00 (address 8600): keyboard mappings (1.5KB) -# offset 1000 (address 8c00): bitmap font (2KB) -# offset 1800 (address 9400): entrypoint for applications (don't forget to adjust survey_baremetal if this changes) - -# Other details of the current memory map: -# code: 4 tracks of disk to [0x00007c00, 0x00027400) -# stack grows down from 0x00070000 -# see below -# heap: [0x01000000, 0x02000000) -# see baremetal/120allocate.subx -# Consult https://wiki.osdev.org/Memory_Map_(x86) before modifying any of this. - -## 16-bit entry point - -# Upon reset, the IBM PC: -# - loads the first sector (512 bytes) -# from some bootable image (see the boot sector marker at the end of this file) -# to the address range [0x7c00, 0x7e00) -# - starts executing code at address 0x7c00 - -# offset 00 (address 0x7c00): - # disable interrupts for this initialization - fa # cli - - # initialize segment registers - # this isn't always needed, but the recommendation is to not make assumptions - b8 00 00 # ax <- 0 - 8e d8 # ds <- ax - 8e c0 # es <- ax - 8e e0 # fs <- ax - 8e e8 # gs <- ax - - # initialize stack to 0x00070000 - # We don't read or write the stack before we get to 32-bit mode, but BIOS - # calls do. We need to move the stack in case BIOS initializes it to some - # low address that we want to write code into. - b8 00 70 # ax <- 0x7000 - 8e d0 # ss <- ax - bc 00 00 # sp <- 0x0000 - - # undo the A20 hack: https://en.wikipedia.org/wiki/A20_line - # this is from https://github.com/mit-pdos/xv6-public/blob/master/bootasm.S - # seta20.1: - e4 64 # al <- port 0x64 - a8 02 # set zf if bit 1 (second-least significant) is not set - 75 fa # if zf not set, goto seta20.1 (-6) - b0 d1 # al <- 0xd1 - e6 64 # port 0x64 <- al - # seta20.2: - e4 64 # al <- port 0x64 - a8 02 # set zf if bit 1 (second-least significant) is not set - 75 fa # if zf not set, goto seta20.2 (-6) - b0 df # al <- 0xdf - e6 64 # port 0x64 <- al - - # load remaining sectors from first two tracks of disk into addresses [0x7e00, 0x17800) - b4 02 # ah <- 2 # read sectors from disk - # dl comes conveniently initialized at boot time with the index of the device being booted - b5 00 # ch <- 0 # cylinder 0 - b6 00 # dh <- 0 # track 0 - b1 02 # cl <- 2 # second sector, 1-based - b0 7d # al <- 125 # number of sectors to read = 2*63 - 1 - # address to write sectors to = es:bx = 0x7e00, contiguous with boot segment - bb 00 00 # bx <- 0 - 8e c3 # es <- bx - bb 00 7e # bx <- 0x7e00 [label] - cd 13 # int 13h, BIOS disk service - 0f 82 a3 00 # jump-if-carry disk_error [label] - - # load two more tracks of disk into addresses [0x17800, 0x27400) - b4 02 # ah <- 2 # read sectors from disk - # dl comes conveniently initialized at boot time with the index of the device being booted - b5 00 # ch <- 0 # cylinder 0 - b6 02 # dh <- 2 # track 2 - b1 01 # cl <- 1 # first sector, 1-based - b0 7e # al <- 126 # number of sectors to read = 2*63 - # address to write sectors to = es:bx = 0x17800 - bb 80 17 # bx <- 0x1780 [label] - 8e c3 # es <- bx - bb 00 00 # bx <- 0 - cd 13 # int 13h, BIOS disk service - 0f 82 9b 00 # jump-if-carry disk_error [label] - - # load two more tracks of disk into addresses [0x27400, 0x37000) - b4 02 # ah <- 2 # read sectors from disk - # dl comes conveniently initialized at boot time with the index of the device being booted - b5 00 # ch <- 0 # cylinder 0 - b6 04 # dh <- 2 # track 4 - b1 01 # cl <- 1 # first sector, 1-based - b0 7e # al <- 126 # number of sectors to read = 2*63 - # address to write sectors to = es:bx = 0x17800 - bb 40 27 # bx <- 0x2740 [label] - 8e c3 # es <- bx - bb 00 00 # bx <- 0 - cd 13 # int 13h, BIOS disk service - 0f 82 9b 00 # jump-if-carry disk_error [label] - - # reset es - bb 00 00 # bx <- 0 - 8e c3 # es <- bx - - # adjust video mode - b4 4f # ah <- 4f (VBE) - b0 02 # al <- 02 (set video mode) - bb 05 41 # bx <- 0x0105 (graphics 1024x768x256 - # 0x4000 bit = configure linear frame buffer in Bochs emulator; hopefully this doesn't hurt anything when running natively) - # fallback mode: 0x0101 (640x480x256) - cd 10 # int 10h, Vesa BIOS extensions - - # load information for the (hopefully) current video mode - # mostly just for the address to the linear frame buffer - b4 4f # ah <- 4f (VBE) - b0 01 # al <- 01 (get video mode info) - b9 07 01 # cx <- 0x0107 (mode we requested) - bf 00 81 # di <- 0x8100 (video mode info) [label] - cd 10 - - # switch to 32-bit mode - 0f 01 16 # lgdt 00/mod/indirect 010/subop 110/rm/use-disp16 - f8 7c # *gdt_descriptor [label] - 0f 20 c0 # eax <- cr0 - 66 83 c8 01 # eax <- or 0x1 - 0f 22 c0 # cr0 <- eax - ea 00 7d 08 00 # far jump to initialize_32bit_mode after setting cs to the record at offset 8 in the gdt (gdt_code) [label] - -# padding -# 8e: - 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -# cf: -# disk_error: - # print 'D' to top-left of screen to indicate disk error - # *0xb8000 <- 0x0f44 - # bx <- 0xb800 - bb 00 b8 - # ds <- bx - 8e db # 11b/mod 011b/reg/ds 011b/rm/bx - # al <- 'D' - b0 44 - # ah <- 0x0f # white on black - b4 0f - # bx <- 0 - bb 00 00 - # *ds:bx <- ax - 89 07 # 00b/mod/indirect 000b/reg/ax 111b/rm/bx - -e9 fd ff # loop forever - -## GDT: 3 records of 8 bytes each - -# e0: -# gdt_start: -# gdt_null: mandatory null descriptor - 00 00 00 00 00 00 00 00 -# gdt_code: (offset 8 from gdt_start) - ff ff # limit[0:16] - 00 00 00 # base[0:24] - 9a # 1/present 00/privilege 1/descriptor type = 1001b - # 1/code 0/conforming 1/readable 0/accessed = 1010b - cf # 1/granularity 1/32-bit 0/64-bit-segment 0/AVL = 1100b - # limit[16:20] = 1111b - 00 # base[24:32] -# gdt_data: (offset 16 from gdt_start) - ff ff # limit[0:16] - 00 00 00 # base[0:24] - 92 # 1/present 00/privilege 1/descriptor type = 1001b - # 0/data 0/conforming 1/readable 0/accessed = 0010b - cf # same as gdt_code - 00 # base[24:32] -# gdt_end: - -# f8: -# gdt_descriptor: - 17 00 # final index of gdt = gdt_end - gdt_start - 1 - e0 7c 00 00 # start = gdt_start [label] - -# padding -# fe: - 00 00 - -## 32-bit code from this point (still some instructions not in SubX) - -# offset 100 (address 0x7d00): -# initialize_32bit_mode: - 66 b8 10 00 # ax <- offset 16 from gdt_start - 8e d8 # ds <- ax - 8e d0 # ss <- ax - 8e c0 # es <- ax - 8e e0 # fs <- ax - 8e e8 # gs <- ax - -# 10e: - bc 00 00 07 00 # esp <- 0x00070000 - -# 113: - # load interrupt handlers - 0f 01 1d # lidt 00/mod/indirect 011/subop 101/rm32/use-disp32 - 00 80 00 00 # *idt_descriptor [label] - - # For now, not bothering reprogramming the IRQ to not conflict with software - # exceptions. - # https://wiki.osdev.org/index.php?title=8259_PIC&oldid=24650#Protected_Mode - # - # Interrupt 1 (keyboard) conflicts with debugger faults. We don't use a - # debugger. - # Reference: - # https://wiki.osdev.org/Exceptions - -# 11a: - # enable keyboard IRQ (1) - b0 fd # al <- 0xfd # disable mask for IRQ1 - e6 21 # port 0x21 <- al - -# 11e: - fb # enable interrupts - db e3 # initialize FPU - # eax <- cr4 - 0f 20 # copy cr4 to rm32 - e0 # 11/mod/direct 100/r32/CR4 000/rm32/eax - # eax <- or bit 9 - 0f ba - e8 # 11/mod/direct 101/subop/bit-test-and-set 000/rm32/eax - 09 # imm8 - # cr4 <- eax - 0f 22 # copy rm32 to cr4 - e0 # 11/mod/direct 100/r32/CR4 000/rm32/eax - e9 d0 16 00 00 # jump to 0x9400 [label] - -# padding -# 130: -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -# 1fe: -# final 2 bytes of boot sector -55 aa - -## sector 2 onwards loaded by load_disk, not automatically on boot - -# offset 200 (address 0x7e00): -# null interrupt handler: - cf # iret - -# padding -# 201: - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -# 210: -# keyboard interrupt handler: - # prologue - fa # disable interrupts - 60 # push all registers to stack - # acknowledge interrupt - b0 20 # al <- 0x20 - e6 20 # port 0x20 <- al - 31 c0 # eax <- xor eax; 11/direct 000/r32/eax 000/rm32/eax - # check output buffer of 8042 keyboard controller (https://web.archive.org/web/20040604041507/http://panda.cs.ndsu.nodak.edu/~achapwes/PICmicro/keyboard/atkeyboard.html) - e4 64 # al <- port 0x64 - a8 01 # set zf if bit 0 (least significant) is not set - 74 bb # jump to epilogue if 0 bit is not set [label] -# 21e: - # - if keyboard buffer is full, return - 31 c9 # ecx <- xor ecx; 11/direct 001/r32/ecx 001/rm32/ecx - # var index/ecx: byte - 8a # copy m8 at r32 to r8 - 0d # 00/mod/indirect 001/r8/cl 101/rm32/use-disp32 - 28 80 00 00 # disp32 [label] - # al = *(keyboard buffer + index) - 8a # copy m8 at r32 to r8 - 81 # 10/mod/*+disp32 000/r8/al 001/rm32/ecx - 30 80 00 00 # disp32 [label] - # if (al != 0) return - 3c 00 # compare al, 0 - 75 a9 # jump to epilogue if != [label] -# 230: - # - read keycode - e4 60 # al <- port 0x60 - # - key released - # if (al == 0xaa) shift = false # left shift is being lifted - 3c aa # compare al, 0xaa - 75 0a # jump to $1 if != [label] - # *shift = 0 - c7 # copy imm32 to rm32 - 05 # 00/mod/indirect 000/subop/copy 101/rm32/use-disp32 - 10 80 00 00 # disp32 [label] - 00 00 00 00 # imm32 -# 240: -# $1: - # if (al == 0xb6) shift = false # right shift is being lifted - 3c b6 # compare al, 0xb6 - 75 0a # jump to $2 if != [label] - # *shift = 0 - c7 # copy imm32 to rm32 - 05 # 00/mod/indirect 000/subop/copy 101/rm32/use-disp32 - 10 80 00 00 # disp32 [label] - 00 00 00 00 # imm32 -# 24e: -# $2: - # if (al == 0x9d) ctrl = false # ctrl is being lifted - 3c 9d # compare al, 0x9d - 75 0a # jump to $3 if != [label] - # *ctrl = 0 - c7 # copy imm32 to rm32 - 05 # 00/mod/indirect 000/subop/copy 101/rm32/use-disp32 - 14 80 00 00 # disp32 [label] - 00 00 00 00 # imm32 -# 25c: -# $3: - # if (al & 0x80) a key is being lifted; return - 50 # push eax - 24 80 # al <- and 0x80 - 3c 00 # compare al, 0 - 58 # pop to eax (without touching flags) - 75 75 # jump to epilogue if != [label] -# 264: - # - key pressed - # if (al == 0x2a) shift = true, return # left shift pressed - 3c 2a # compare al, 0x2a - 75 0c # jump to $4 if != [label] - # *shift = 1 - c7 # copy imm32 to rm32 - 05 # 00/mod/indirect 000/subop/copy 101/rm32/use-disp32 - 10 80 00 00 # disp32 [label] - 01 00 00 00 # imm32 - eb 65 # jump to epilogue [label] -# 274: -# $4: - # if (al == 0x36) shift = true, return # right shift pressed - 3c 36 # compare al, 0x36 - 75 0c # jump to $5 if != [label] - # *shift = 1 - c7 # copy imm32 to rm32 - 05 # 00/mod/indirect 000/subop/copy 101/rm32/use-disp32 - 10 80 00 00 # disp32 [label] - 01 00 00 00 # imm32 - eb 55 # jump to epilogue [label] -# 284: -# $5: - # if (al == 0x1d) ctrl = true, return - 3c 1d # compare al, 0x36 - 75 0c # jump to $6 if != [label] - # *shift = 1 - c7 # copy imm32 to rm32 - 05 # 00/mod/indirect 000/subop/copy 101/rm32/use-disp32 - 14 80 00 00 # disp32 [label] - 01 00 00 00 # imm32 - eb 45 # jump to epilogue [label] -# 294: -# $6: - # - convert key to character - # if (shift) use keyboard shift map - 81 # operate on rm32 and imm32 - 3d # 00/mod/indirect 111/subop/compare 101/rm32/use-disp32 - 10 80 00 00 # disp32 = shift [label] - 00 00 00 00 # imm32 - 74 08 # jump to $7 if = [label] - # al <- *(keyboard shift map + eax) - 8a # copy m8 at rm32 to r8 - 80 # 10/mod/*+disp32 000/r8/al 000/rm32/eax - 00 87 00 00 # disp32 [label] - eb 1a # jump to $8 [label] -# 2a8: -# $7: - # if (ctrl) use keyboard ctrl map - 81 # operate on rm32 and imm32 - 3d # 00/mod/indirect 111/subop/compare 101/rm32/use-disp32 - 14 80 00 00 # disp32 = ctrl [label] - 00 00 00 00 # imm32 - 74 08 # jump to $8 if = [label] - # al <- *(keyboard ctrl map + eax) - 8a # copy m8 at rm32 to r8 - 80 # 10/mod/*+disp32 000/r8/al 000/rm32/eax - 00 88 00 00 # disp32 [label] - eb 06 # jump to $9 [label] -# 2bc: -# $8: - # otherwise use keyboard normal map - # al <- *(keyboard normal map + eax) - 8a # copy m8 at rm32 to r8 - 80 # 10/mod/*+disp32 000/r8/al 000/rm32/eax - 00 86 00 00 # disp32 [label] -# 2c2: -# $9: - # - if there's no character mapping, return - 3c 00 # compare al, 0 - 74 13 # jump to epilogue if = [label] -# 2c6: - # - store al in keyboard buffer - 88 # copy r8 to m8 at r32 - 81 # 10/mod/*+disp32 000/r8/al 001/rm32/ecx - 30 80 00 00 # disp32 [label] - # increment index - fe # increment byte - 05 # 00/mod/indirect 000/subop/increment 101/rm32/use-disp32 - 28 80 00 00 # disp32 [label] - # clear top nibble of index (keyboard buffer is circular) - 80 # and byte - 25 # 00/mod/indirect 100/subop/and 101/rm32/use-disp32 - 28 80 00 00 # disp32 [label] - 0f # imm8 -# 2d9: - # epilogue - 61 # pop all registers - fb # enable interrupts - cf # iret - -# padding -# 2dc: - 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -# 300: -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -# offset 400 (address 0x8000): interrupt handler data -# idt_descriptor: - ff 03 # idt_end - idt_start - 1 - 00 82 00 00 # start = idt_start [label] - -# padding -# 406: - 00 00 00 00 00 00 00 00 00 00 - -# 410: -# var shift: boolean - 00 00 00 00 - -# 414: -# var ctrl: boolean - 00 00 00 00 - -# padding -# 418: - 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 - -# 428: -# var keyboard circular buffer -# write index: nibble -# still take up 4 bytes so SubX can handle it - 00 00 00 00 -# 42c: -# read index: nibble -# still take up 4 bytes so SubX can handle it - 00 00 00 00 -# 430: -# circular buffer: byte[16] - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -# padding -# 440: -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -# offset 500 (address 0x8100): -# video mode info {{{ - 00 00 # attributes - 00 # winA - 00 # winB -# 04 - 00 00 # granularity - 00 00 # winsize -# 08 - 00 00 # segmentA - 00 00 # segmentB -# 0c - 00 00 00 00 # realFctPtr (who knows) -# 10 - 00 00 # pitch - 00 00 # Xres -# 14 - 00 00 # Yres - 00 00 # Wchar Ychar -# 18 - 00 # planes - 00 # bpp - 00 # banks - 00 # memory_model -# 1c - 00 # bank_size - 00 # image_pages - 00 # reserved -# 1f - 00 00 # red_mask red_position - 00 00 # green_mask green_position - 00 00 # blue_mask blue_position - 00 00 # rsv_mask rsv_position - 00 # directcolor_attributes -# 28 - 00 00 00 00 # physbase <== linear frame buffer - -# 2c -# reserved for video mode info - 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -# }}} - -# offset 600 (address 0x8200): -# interrupt descriptor table {{{ -# 128 entries * 8 bytes each = 1024 bytes (0x400) -# idt_start: - -# entry 0 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 - -# By default, BIOS maps IRQ0-7 to interrupt vectors 8-15. -# https://wiki.osdev.org/index.php?title=Interrupts&oldid=25102#Default_PC_Interrupt_Vector_Assignment - -# entry 8: clock - 00 7e # target[0:16] = null interrupt handler [label] - 08 00 # segment selector (gdt_code) - 00 # unused - 8e # 1/p 00/dpl 0 1110/type/32-bit-interrupt-gate - 00 00 # target[16:32] - -# entry 9: keyboard - 10 7e # target[0:16] = keyboard interrupt handler [label] - 08 00 # segment selector (gdt_code) - 00 # unused - 8e # 1/p 00/dpl 0 1110/type/32-bit-interrupt-gate - 00 00 # target[16:32] - -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 - -# 500: -# entry 0x20 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 - -# 600: -# entry 0x40 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 - -# 700: -# entry 0x60 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -# entry 0x70 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 -# idt_end: -# }}} - -## the rest of this file has data - -# offset a00 (address 0x8600): -# translating keys to ASCII {{{ -# keyboard normal map: -00 -# es - 1b -# |<--- digits -------------->| - = backspace - 31 32 33 34 35 36 37 38 39 30 2d 3d 08 -# 0f -# tab q w e r t y u i o p [ ] - 09 71 77 65 72 74 79 75 69 6f 70 5b 5d -# 1c -# enter (newline) - 0a 00 -# 1e -# a s d f g h j k l ; ' ` \ - 61 73 64 66 67 68 6a 6b 6c 3b 27 60 00 5c - # ^ left shift -# 2c -# z x c v b n m , . / * - 7a 78 63 76 62 6e 6d 2c 2e 2f 00 2a - # ^ right shift -# 38 -# space - 00 20 -# 3a - 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -# numeric keypad would start here, but isn't implemented - 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -# offset b00: -# keyboard shift map: -00 -# es - 1b -# ! @ # $ % ^ & * ( ) _ + backspace - 21 40 23 24 25 53 26 2a 28 29 5f 2b 08 -# 0f -# tab Q W E R T Y U I O P { } - 09 51 57 45 52 54 59 55 49 5f 50 7b 7d -# 1c -# enter (newline) - 0a 00 -# 1e -# A S D F G H J K L : " ~ | - 41 53 44 46 47 48 4a 4b 4c 3a 22 7e 00 7c -# 2c -# Z X C V B N M < > ? * - 5a 58 43 56 42 4e 4d 3c 3e 3f 00 2a -# 38 -# space - 00 20 -# 3a - 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -# numeric keypad would start here, but isn't implemented - 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -# c00: -# keyboard ctrl map: -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -# 10 -# ^q ^w ^e ^r ^t ^y ^u tb ^o ^p - 11 17 05 12 14 19 15 09 1f 10 00 00 -# 1c -# carriage-return - 0d 00 -# 1e -# ^a ^s ^d ^f ^g ^h ^j ^j ^l ^\ - 01 13 04 06 07 08 0a 0b 0c 00 00 00 00 1c -# 2c -# ^z ^x ^c ^v ^b ^n ^m ^/ - 1a 18 03 16 02 0e 0d 00 00 1f 00 00 -# 38 - 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - -# padding (there might be more keyboard tables) -# d00: -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -# e00: -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -# f00: -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -# }}} - -# offset 1000 (address 0x8c00) -# Bitmaps for some ASCII characters (soon Unicode) {{{ -# Part of GNU Unifont -# 8px wide, 16px tall -# Based on http://unifoundry.com/pub/unifont/unifont-13.0.05/font-builds/unifont-13.0.05.hex.gz -# See https://en.wikipedia.org/wiki/GNU_Unifont#The_.hex_font_format -# Website: http://unifoundry.com/unifont/index.html -# License: http://unifoundry.com/LICENSE.txt (GPL v2) -# Each line below is a bitmap for a single character. -# Each byte is a bitmap for a single row of 8 pixels. - -# some unprintable ASCII chars - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -# 0x20 = space - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -# ! - 00 00 00 00 08 08 08 08 08 08 08 00 08 08 00 00 -# " - 00 00 22 22 22 22 00 00 00 00 00 00 00 00 00 00 -# 0x23 = '#' - 00 00 00 00 12 12 12 7e 24 24 7e 48 48 48 00 00 -# $ - 00 00 00 00 08 3e 49 48 38 0e 09 49 3e 08 00 00 -# % - 00 00 00 00 31 4a 4a 34 08 08 16 29 29 46 00 00 -# & - 00 00 00 00 1c 22 22 14 18 29 45 42 46 39 00 00 -# ' - 00 00 08 08 08 08 00 00 00 00 00 00 00 00 00 00 -# ( - 00 00 00 04 08 08 10 10 10 10 10 10 08 08 04 00 -# ) - 00 00 00 20 10 10 08 08 08 08 08 08 10 10 20 00 -# * - 00 00 00 00 00 00 08 49 2a 1c 2a 49 08 00 00 00 -# + - 00 00 00 00 00 00 08 08 08 7f 08 08 08 00 00 00 -# , - 00 00 00 00 00 00 00 00 00 00 00 00 18 08 08 10 -# - - 00 00 00 00 00 00 00 00 00 3c 00 00 00 00 00 00 -# . - 00 00 00 00 00 00 00 00 00 00 00 00 18 18 00 00 -# / - 00 00 00 00 02 02 04 08 08 10 10 20 40 40 00 00 -# 0x30 = '0' - 00 00 00 00 18 24 42 46 4a 52 62 42 24 18 00 00 -# 1 - 00 00 00 00 08 18 28 08 08 08 08 08 08 3e 00 00 -# 2 - 00 00 00 00 3c 42 42 02 0c 10 20 40 40 7e 00 00 -# 3 - 00 00 00 00 3c 42 42 02 1c 02 02 42 42 3c 00 00 -# 4 - 00 00 00 00 04 0c 14 24 44 44 7e 04 04 04 00 00 -# 5 - 00 00 00 00 7e 40 40 40 7c 02 02 02 42 3c 00 00 -# 6 - 00 00 00 00 1c 20 40 40 7c 42 42 42 42 3c 00 00 -# 7 - 00 00 00 00 7e 02 02 04 04 04 08 08 08 08 00 00 -# 8 - 00 00 00 00 3c 42 42 42 3c 42 42 42 42 3c 00 00 -# 9 - 00 00 00 00 3c 42 42 42 3e 02 02 02 04 38 00 00 -# : - 00 00 00 00 00 00 18 18 00 00 00 18 18 00 00 00 -# ; - 00 00 00 00 00 00 18 18 00 00 00 18 08 08 10 00 -# < - 00 00 00 00 00 02 04 08 10 20 10 08 04 02 00 00 -# = - 00 00 00 00 00 00 00 7e 00 00 00 7e 00 00 00 00 -# > - 00 00 00 00 00 40 20 10 08 04 08 10 20 40 00 00 -# ? - 00 00 00 00 3c 42 42 02 04 08 08 00 08 08 00 00 -# 0x40 = @ - 00 00 00 00 1c 22 4a 56 52 52 52 4e 20 1e 00 00 -# A - 00 00 00 00 18 24 24 42 42 7e 42 42 42 42 00 00 -# B - 00 00 00 00 7c 42 42 42 7c 42 42 42 42 7c 00 00 -# C - 00 00 00 00 3c 42 42 40 40 40 40 42 42 3c 00 00 -# D - 00 00 00 00 78 44 42 42 42 42 42 42 44 78 00 00 -# E - 00 00 00 00 7e 40 40 40 7c 40 40 40 40 7e 00 00 -# F - 00 00 00 00 7e 40 40 40 7c 40 40 40 40 40 00 00 -# G - 00 00 00 00 3c 42 42 40 40 4e 42 42 46 3a 00 00 -# H - 00 00 00 00 42 42 42 42 7e 42 42 42 42 42 00 00 -# I - 00 00 00 00 3e 08 08 08 08 08 08 08 08 3e 00 00 -# J - 00 00 00 00 1f 04 04 04 04 04 04 44 44 38 00 00 -# K - 00 00 00 00 42 44 48 50 60 60 50 48 44 42 00 00 -# L - 00 00 00 00 40 40 40 40 40 40 40 40 40 7e 00 00 -# M - 00 00 00 00 42 42 66 66 5a 5a 42 42 42 42 00 00 -# N - 00 00 00 00 42 62 62 52 52 4a 4a 46 46 42 00 00 -# O - 00 00 00 00 3c 42 42 42 42 42 42 42 42 3c 00 00 -# 0x50 = P - 00 00 00 00 7c 42 42 42 7c 40 40 40 40 40 00 00 -# Q - 00 00 00 00 3c 42 42 42 42 42 42 5a 66 3c 03 00 -# R - 00 00 00 00 7c 42 42 42 7c 48 44 44 42 42 00 00 -# S - 00 00 00 00 3c 42 42 40 30 0c 02 42 42 3c 00 00 -# T - 00 00 00 00 7f 08 08 08 08 08 08 08 08 08 00 00 -# U - 00 00 00 00 42 42 42 42 42 42 42 42 42 3c 00 00 -# V - 00 00 00 00 41 41 41 22 22 22 14 14 08 08 00 00 -# W - 00 00 00 00 42 42 42 42 5a 5a 66 66 42 42 00 00 -# X - 00 00 00 00 42 42 24 24 18 18 24 24 42 42 00 00 -# Y - 00 00 00 00 41 41 22 22 14 08 08 08 08 08 00 00 -# Z - 00 00 00 00 7e 02 02 04 08 10 20 40 40 7e 00 00 -# [ - 00 00 00 0e 08 08 08 08 08 08 08 08 08 08 0e 00 -# \ - 00 00 00 00 40 40 20 10 10 08 08 04 02 02 00 00 -# ] - 00 00 00 70 10 10 10 10 10 10 10 10 10 10 70 00 -# ^ - 00 00 18 24 42 00 00 00 00 00 00 00 00 00 00 00 -# _ - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7f 00 -# 0x60 = backtick - 00 20 10 08 00 00 00 00 00 00 00 00 00 00 00 00 -# a - 00 00 00 00 00 00 3c 42 02 3e 42 42 46 3a 00 00 -# b - 00 00 00 40 40 40 5c 62 42 42 42 42 62 5c 00 00 -# c - 00 00 00 00 00 00 3c 42 40 40 40 40 42 3c 00 00 -# d - 00 00 00 02 02 02 3a 46 42 42 42 42 46 3a 00 00 -# e - 00 00 00 00 00 00 3c 42 42 7e 40 40 42 3c 00 00 -# f - 00 00 00 0c 10 10 10 7c 10 10 10 10 10 10 00 00 -# g - 00 00 00 00 00 02 3a 44 44 44 38 20 3c 42 42 3c -# h - 00 00 00 40 40 40 5c 62 42 42 42 42 42 42 00 00 -# i - 00 00 00 08 08 00 18 08 08 08 08 08 08 3e 00 00 -# j - 00 00 00 04 04 00 0c 04 04 04 04 04 04 04 48 30 -# k - 00 00 00 40 40 40 44 48 50 60 50 48 44 42 00 00 -# l - 00 00 00 18 08 08 08 08 08 08 08 08 08 3e 00 00 -# m - 00 00 00 00 00 00 76 49 49 49 49 49 49 49 00 00 -# n - 00 00 00 00 00 00 5c 62 42 42 42 42 42 42 00 00 -# o - 00 00 00 00 00 00 3c 42 42 42 42 42 42 3c 00 00 -# 0x70 = p - 00 00 00 00 00 00 5c 62 42 42 42 42 62 5c 40 40 -# q - 00 00 00 00 00 00 3a 46 42 42 42 42 46 3a 02 02 -# r - 00 00 00 00 00 00 5c 62 42 40 40 40 40 40 00 00 -# s - 00 00 00 00 00 00 3c 42 40 30 0c 02 42 3c 00 00 -# t - 00 00 00 00 10 10 10 7c 10 10 10 10 10 0c 00 00 -# u - 00 00 00 00 00 00 42 42 42 42 42 42 46 3a 00 00 -# v - 00 00 00 00 00 00 42 42 42 24 24 24 18 18 00 00 -# w - 00 00 00 00 00 00 41 49 49 49 49 49 49 36 00 00 -# x - 00 00 00 00 00 00 42 42 24 18 18 24 42 42 00 00 -# y - 00 00 00 00 00 00 42 42 42 42 42 26 1a 02 02 3c -# z - 00 00 00 00 00 00 7e 02 04 08 10 20 40 7e 00 00 -# { - 00 00 00 0c 10 10 08 08 10 20 10 08 08 10 10 0c -# | - 00 00 08 08 08 08 08 08 08 08 08 08 08 08 08 08 -# } - 00 00 00 30 08 08 10 10 08 04 08 10 10 08 08 30 -# ~ - 00 00 00 31 49 46 00 00 00 00 00 00 00 00 00 00 -# 0x7f = del (unused) - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -# }}} - -# offset 1800 (address 0x9400) - -# vim:ft=subx diff --git a/boot.subx b/boot.subx new file mode 100644 index 00000000..7e2290a8 --- /dev/null +++ b/boot.subx @@ -0,0 +1,1176 @@ +# Code for the first few disk sectors that all programs in this directory need: +# - load sectors past the first (using BIOS primitives) since only the first is available by default +# - if this fails, print 'D' at top-left of screen and halt +# - initialize a minimal graphics mode +# - switch to 32-bit mode (giving up access to BIOS primitives) +# - set up a handler for keyboard events +# - jump to start of program +# +# When translating, put this file first, followed by any other SubX files: +# ./translate_subx boot.subx ... +# +# To run: +# qemu-system-i386 disk.img +# Or: +# bochs -f boot.bochsrc # boot.bochsrc loads disk.img +# +# Since we start out in 16-bit mode, we need instructions SubX doesn't +# support. +# This file contains just lowercase hex bytes and comments. Programming it +# requires liberal use of: +# - comments documenting expected offsets +# - size checks on the emitted file (currently: 6144 bytes) +# - xxd to spot-check contents of specific offsets in the generated output +# +# Programs using this initialization: +# - can't use any syscalls +# - can't print text to video memory (past these boot sectors) +# - must only print raw pixels (256 colors) to video memory (resolution 1024x768) +# - must start executing immediately after this file (see outline below) +# +# Don't panic! This file doesn't contain any loops or function calls. 80% of +# it is data. One pass through less than 1KB of code (there's lots of +# padding), and then we jump into a better notation. The rest of the stack +# (really only in a couple of slightly higher-level places) needs to know just +# a few magic constants: +# Video memory: start is stored at 0x8128 +# Keyboard buffer: starts at 0x8028 +# +# No mouse support. _That_ would require panicking. + +# Outline of this file with offsets and the addresses they map to at run-time: +# -- 16-bit mode code +# offset 0 (address 7c00): boot code +# -- 16-bit mode data +# e0 (address 7c80) global descriptor table +# f8 (address 7ca0) <== gdt_descriptor +# -- 32-bit mode code +# offset 100 (address 7d00): boot code +# 1fe (address 7dfe) boot sector marker (2 bytes) +# offset 200 (address 7e00): interrupt handler code +# -- 32-bit mode data +# offset 400 (address 8000): handler data +# 410 (address 8010): keyboard handler data +# 428 (address 8028) <== keyboard buffer +# offset 500 (address 8100): video mode data (256 bytes) +# 528 (address 8128) <== start of video RAM stored here +# offset 600 (address 8200): interrupt descriptor table (1KB) +# offset a00 (address 8600): keyboard mappings (1.5KB) +# offset 1000 (address 8c00): bitmap font (2KB) +# offset 1800 (address 9400): entrypoint for applications (don't forget to adjust survey_baremetal if this changes) + +# Other details of the current memory map: +# code: 4 tracks of disk to [0x00007c00, 0x00027400) +# stack grows down from 0x00070000 +# see below +# heap: [0x01000000, 0x02000000) +# see 120allocate.subx +# Consult https://wiki.osdev.org/Memory_Map_(x86) before modifying any of this. + +## 16-bit entry point + +# Upon reset, the IBM PC: +# - loads the first sector (512 bytes) +# from some bootable image (see the boot sector marker at the end of this file) +# to the address range [0x7c00, 0x7e00) +# - starts executing code at address 0x7c00 + +# offset 00 (address 0x7c00): + # disable interrupts for this initialization + fa # cli + + # initialize segment registers + # this isn't always needed, but the recommendation is to not make assumptions + b8 00 00 # ax <- 0 + 8e d8 # ds <- ax + 8e c0 # es <- ax + 8e e0 # fs <- ax + 8e e8 # gs <- ax + + # initialize stack to 0x00070000 + # We don't read or write the stack before we get to 32-bit mode, but BIOS + # calls do. We need to move the stack in case BIOS initializes it to some + # low address that we want to write code into. + b8 00 70 # ax <- 0x7000 + 8e d0 # ss <- ax + bc 00 00 # sp <- 0x0000 + + # undo the A20 hack: https://en.wikipedia.org/wiki/A20_line + # this is from https://github.com/mit-pdos/xv6-public/blob/master/bootasm.S + # seta20.1: + e4 64 # al <- port 0x64 + a8 02 # set zf if bit 1 (second-least significant) is not set + 75 fa # if zf not set, goto seta20.1 (-6) + b0 d1 # al <- 0xd1 + e6 64 # port 0x64 <- al + # seta20.2: + e4 64 # al <- port 0x64 + a8 02 # set zf if bit 1 (second-least significant) is not set + 75 fa # if zf not set, goto seta20.2 (-6) + b0 df # al <- 0xdf + e6 64 # port 0x64 <- al + + # load remaining sectors from first two tracks of disk into addresses [0x7e00, 0x17800) + b4 02 # ah <- 2 # read sectors from disk + # dl comes conveniently initialized at boot time with the index of the device being booted + b5 00 # ch <- 0 # cylinder 0 + b6 00 # dh <- 0 # track 0 + b1 02 # cl <- 2 # second sector, 1-based + b0 7d # al <- 125 # number of sectors to read = 2*63 - 1 + # address to write sectors to = es:bx = 0x7e00, contiguous with boot segment + bb 00 00 # bx <- 0 + 8e c3 # es <- bx + bb 00 7e # bx <- 0x7e00 [label] + cd 13 # int 13h, BIOS disk service + 0f 82 a3 00 # jump-if-carry disk_error [label] + + # load two more tracks of disk into addresses [0x17800, 0x27400) + b4 02 # ah <- 2 # read sectors from disk + # dl comes conveniently initialized at boot time with the index of the device being booted + b5 00 # ch <- 0 # cylinder 0 + b6 02 # dh <- 2 # track 2 + b1 01 # cl <- 1 # first sector, 1-based + b0 7e # al <- 126 # number of sectors to read = 2*63 + # address to write sectors to = es:bx = 0x17800 + bb 80 17 # bx <- 0x1780 [label] + 8e c3 # es <- bx + bb 00 00 # bx <- 0 + cd 13 # int 13h, BIOS disk service + 0f 82 9b 00 # jump-if-carry disk_error [label] + + # load two more tracks of disk into addresses [0x27400, 0x37000) + b4 02 # ah <- 2 # read sectors from disk + # dl comes conveniently initialized at boot time with the index of the device being booted + b5 00 # ch <- 0 # cylinder 0 + b6 04 # dh <- 2 # track 4 + b1 01 # cl <- 1 # first sector, 1-based + b0 7e # al <- 126 # number of sectors to read = 2*63 + # address to write sectors to = es:bx = 0x17800 + bb 40 27 # bx <- 0x2740 [label] + 8e c3 # es <- bx + bb 00 00 # bx <- 0 + cd 13 # int 13h, BIOS disk service + 0f 82 9b 00 # jump-if-carry disk_error [label] + + # reset es + bb 00 00 # bx <- 0 + 8e c3 # es <- bx + + # adjust video mode + b4 4f # ah <- 4f (VBE) + b0 02 # al <- 02 (set video mode) + bb 05 41 # bx <- 0x0105 (graphics 1024x768x256 + # 0x4000 bit = configure linear frame buffer in Bochs emulator; hopefully this doesn't hurt anything when running natively) + # fallback mode: 0x0101 (640x480x256) + cd 10 # int 10h, Vesa BIOS extensions + + # load information for the (hopefully) current video mode + # mostly just for the address to the linear frame buffer + b4 4f # ah <- 4f (VBE) + b0 01 # al <- 01 (get video mode info) + b9 07 01 # cx <- 0x0107 (mode we requested) + bf 00 81 # di <- 0x8100 (video mode info) [label] + cd 10 + + # switch to 32-bit mode + 0f 01 16 # lgdt 00/mod/indirect 010/subop 110/rm/use-disp16 + f8 7c # *gdt_descriptor [label] + 0f 20 c0 # eax <- cr0 + 66 83 c8 01 # eax <- or 0x1 + 0f 22 c0 # cr0 <- eax + ea 00 7d 08 00 # far jump to initialize_32bit_mode after setting cs to the record at offset 8 in the gdt (gdt_code) [label] + +# padding +# 8e: + 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +# cf: +# disk_error: + # print 'D' to top-left of screen to indicate disk error + # *0xb8000 <- 0x0f44 + # bx <- 0xb800 + bb 00 b8 + # ds <- bx + 8e db # 11b/mod 011b/reg/ds 011b/rm/bx + # al <- 'D' + b0 44 + # ah <- 0x0f # white on black + b4 0f + # bx <- 0 + bb 00 00 + # *ds:bx <- ax + 89 07 # 00b/mod/indirect 000b/reg/ax 111b/rm/bx + +e9 fd ff # loop forever + +## GDT: 3 records of 8 bytes each + +# e0: +# gdt_start: +# gdt_null: mandatory null descriptor + 00 00 00 00 00 00 00 00 +# gdt_code: (offset 8 from gdt_start) + ff ff # limit[0:16] + 00 00 00 # base[0:24] + 9a # 1/present 00/privilege 1/descriptor type = 1001b + # 1/code 0/conforming 1/readable 0/accessed = 1010b + cf # 1/granularity 1/32-bit 0/64-bit-segment 0/AVL = 1100b + # limit[16:20] = 1111b + 00 # base[24:32] +# gdt_data: (offset 16 from gdt_start) + ff ff # limit[0:16] + 00 00 00 # base[0:24] + 92 # 1/present 00/privilege 1/descriptor type = 1001b + # 0/data 0/conforming 1/readable 0/accessed = 0010b + cf # same as gdt_code + 00 # base[24:32] +# gdt_end: + +# f8: +# gdt_descriptor: + 17 00 # final index of gdt = gdt_end - gdt_start - 1 + e0 7c 00 00 # start = gdt_start [label] + +# padding +# fe: + 00 00 + +## 32-bit code from this point (still some instructions not in SubX) + +# offset 100 (address 0x7d00): +# initialize_32bit_mode: + 66 b8 10 00 # ax <- offset 16 from gdt_start + 8e d8 # ds <- ax + 8e d0 # ss <- ax + 8e c0 # es <- ax + 8e e0 # fs <- ax + 8e e8 # gs <- ax + +# 10e: + bc 00 00 07 00 # esp <- 0x00070000 + +# 113: + # load interrupt handlers + 0f 01 1d # lidt 00/mod/indirect 011/subop 101/rm32/use-disp32 + 00 80 00 00 # *idt_descriptor [label] + + # For now, not bothering reprogramming the IRQ to not conflict with software + # exceptions. + # https://wiki.osdev.org/index.php?title=8259_PIC&oldid=24650#Protected_Mode + # + # Interrupt 1 (keyboard) conflicts with debugger faults. We don't use a + # debugger. + # Reference: + # https://wiki.osdev.org/Exceptions + +# 11a: + # enable keyboard IRQ (1) + b0 fd # al <- 0xfd # disable mask for IRQ1 + e6 21 # port 0x21 <- al + +# 11e: + fb # enable interrupts + db e3 # initialize FPU + # eax <- cr4 + 0f 20 # copy cr4 to rm32 + e0 # 11/mod/direct 100/r32/CR4 000/rm32/eax + # eax <- or bit 9 + 0f ba + e8 # 11/mod/direct 101/subop/bit-test-and-set 000/rm32/eax + 09 # imm8 + # cr4 <- eax + 0f 22 # copy rm32 to cr4 + e0 # 11/mod/direct 100/r32/CR4 000/rm32/eax + e9 d0 16 00 00 # jump to 0x9400 [label] + +# padding +# 130: +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +# 1fe: +# final 2 bytes of boot sector +55 aa + +## sector 2 onwards loaded by load_disk, not automatically on boot + +# offset 200 (address 0x7e00): +# null interrupt handler: + cf # iret + +# padding +# 201: + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +# 210: +# keyboard interrupt handler: + # prologue + fa # disable interrupts + 60 # push all registers to stack + # acknowledge interrupt + b0 20 # al <- 0x20 + e6 20 # port 0x20 <- al + 31 c0 # eax <- xor eax; 11/direct 000/r32/eax 000/rm32/eax + # check output buffer of 8042 keyboard controller (https://web.archive.org/web/20040604041507/http://panda.cs.ndsu.nodak.edu/~achapwes/PICmicro/keyboard/atkeyboard.html) + e4 64 # al <- port 0x64 + a8 01 # set zf if bit 0 (least significant) is not set + 74 bb # jump to epilogue if 0 bit is not set [label] +# 21e: + # - if keyboard buffer is full, return + 31 c9 # ecx <- xor ecx; 11/direct 001/r32/ecx 001/rm32/ecx + # var index/ecx: byte + 8a # copy m8 at r32 to r8 + 0d # 00/mod/indirect 001/r8/cl 101/rm32/use-disp32 + 28 80 00 00 # disp32 [label] + # al = *(keyboard buffer + index) + 8a # copy m8 at r32 to r8 + 81 # 10/mod/*+disp32 000/r8/al 001/rm32/ecx + 30 80 00 00 # disp32 [label] + # if (al != 0) return + 3c 00 # compare al, 0 + 75 a9 # jump to epilogue if != [label] +# 230: + # - read keycode + e4 60 # al <- port 0x60 + # - key released + # if (al == 0xaa) shift = false # left shift is being lifted + 3c aa # compare al, 0xaa + 75 0a # jump to $1 if != [label] + # *shift = 0 + c7 # copy imm32 to rm32 + 05 # 00/mod/indirect 000/subop/copy 101/rm32/use-disp32 + 10 80 00 00 # disp32 [label] + 00 00 00 00 # imm32 +# 240: +# $1: + # if (al == 0xb6) shift = false # right shift is being lifted + 3c b6 # compare al, 0xb6 + 75 0a # jump to $2 if != [label] + # *shift = 0 + c7 # copy imm32 to rm32 + 05 # 00/mod/indirect 000/subop/copy 101/rm32/use-disp32 + 10 80 00 00 # disp32 [label] + 00 00 00 00 # imm32 +# 24e: +# $2: + # if (al == 0x9d) ctrl = false # ctrl is being lifted + 3c 9d # compare al, 0x9d + 75 0a # jump to $3 if != [label] + # *ctrl = 0 + c7 # copy imm32 to rm32 + 05 # 00/mod/indirect 000/subop/copy 101/rm32/use-disp32 + 14 80 00 00 # disp32 [label] + 00 00 00 00 # imm32 +# 25c: +# $3: + # if (al & 0x80) a key is being lifted; return + 50 # push eax + 24 80 # al <- and 0x80 + 3c 00 # compare al, 0 + 58 # pop to eax (without touching flags) + 75 75 # jump to epilogue if != [label] +# 264: + # - key pressed + # if (al == 0x2a) shift = true, return # left shift pressed + 3c 2a # compare al, 0x2a + 75 0c # jump to $4 if != [label] + # *shift = 1 + c7 # copy imm32 to rm32 + 05 # 00/mod/indirect 000/subop/copy 101/rm32/use-disp32 + 10 80 00 00 # disp32 [label] + 01 00 00 00 # imm32 + eb 65 # jump to epilogue [label] +# 274: +# $4: + # if (al == 0x36) shift = true, return # right shift pressed + 3c 36 # compare al, 0x36 + 75 0c # jump to $5 if != [label] + # *shift = 1 + c7 # copy imm32 to rm32 + 05 # 00/mod/indirect 000/subop/copy 101/rm32/use-disp32 + 10 80 00 00 # disp32 [label] + 01 00 00 00 # imm32 + eb 55 # jump to epilogue [label] +# 284: +# $5: + # if (al == 0x1d) ctrl = true, return + 3c 1d # compare al, 0x36 + 75 0c # jump to $6 if != [label] + # *shift = 1 + c7 # copy imm32 to rm32 + 05 # 00/mod/indirect 000/subop/copy 101/rm32/use-disp32 + 14 80 00 00 # disp32 [label] + 01 00 00 00 # imm32 + eb 45 # jump to epilogue [label] +# 294: +# $6: + # - convert key to character + # if (shift) use keyboard shift map + 81 # operate on rm32 and imm32 + 3d # 00/mod/indirect 111/subop/compare 101/rm32/use-disp32 + 10 80 00 00 # disp32 = shift [label] + 00 00 00 00 # imm32 + 74 08 # jump to $7 if = [label] + # al <- *(keyboard shift map + eax) + 8a # copy m8 at rm32 to r8 + 80 # 10/mod/*+disp32 000/r8/al 000/rm32/eax + 00 87 00 00 # disp32 [label] + eb 1a # jump to $8 [label] +# 2a8: +# $7: + # if (ctrl) use keyboard ctrl map + 81 # operate on rm32 and imm32 + 3d # 00/mod/indirect 111/subop/compare 101/rm32/use-disp32 + 14 80 00 00 # disp32 = ctrl [label] + 00 00 00 00 # imm32 + 74 08 # jump to $8 if = [label] + # al <- *(keyboard ctrl map + eax) + 8a # copy m8 at rm32 to r8 + 80 # 10/mod/*+disp32 000/r8/al 000/rm32/eax + 00 88 00 00 # disp32 [label] + eb 06 # jump to $9 [label] +# 2bc: +# $8: + # otherwise use keyboard normal map + # al <- *(keyboard normal map + eax) + 8a # copy m8 at rm32 to r8 + 80 # 10/mod/*+disp32 000/r8/al 000/rm32/eax + 00 86 00 00 # disp32 [label] +# 2c2: +# $9: + # - if there's no character mapping, return + 3c 00 # compare al, 0 + 74 13 # jump to epilogue if = [label] +# 2c6: + # - store al in keyboard buffer + 88 # copy r8 to m8 at r32 + 81 # 10/mod/*+disp32 000/r8/al 001/rm32/ecx + 30 80 00 00 # disp32 [label] + # increment index + fe # increment byte + 05 # 00/mod/indirect 000/subop/increment 101/rm32/use-disp32 + 28 80 00 00 # disp32 [label] + # clear top nibble of index (keyboard buffer is circular) + 80 # and byte + 25 # 00/mod/indirect 100/subop/and 101/rm32/use-disp32 + 28 80 00 00 # disp32 [label] + 0f # imm8 +# 2d9: + # epilogue + 61 # pop all registers + fb # enable interrupts + cf # iret + +# padding +# 2dc: + 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# 300: +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +# offset 400 (address 0x8000): interrupt handler data +# idt_descriptor: + ff 03 # idt_end - idt_start - 1 + 00 82 00 00 # start = idt_start [label] + +# padding +# 406: + 00 00 00 00 00 00 00 00 00 00 + +# 410: +# var shift: boolean + 00 00 00 00 + +# 414: +# var ctrl: boolean + 00 00 00 00 + +# padding +# 418: + 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 + +# 428: +# var keyboard circular buffer +# write index: nibble +# still take up 4 bytes so SubX can handle it + 00 00 00 00 +# 42c: +# read index: nibble +# still take up 4 bytes so SubX can handle it + 00 00 00 00 +# 430: +# circular buffer: byte[16] + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +# padding +# 440: +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +# offset 500 (address 0x8100): +# video mode info {{{ + 00 00 # attributes + 00 # winA + 00 # winB +# 04 + 00 00 # granularity + 00 00 # winsize +# 08 + 00 00 # segmentA + 00 00 # segmentB +# 0c + 00 00 00 00 # realFctPtr (who knows) +# 10 + 00 00 # pitch + 00 00 # Xres +# 14 + 00 00 # Yres + 00 00 # Wchar Ychar +# 18 + 00 # planes + 00 # bpp + 00 # banks + 00 # memory_model +# 1c + 00 # bank_size + 00 # image_pages + 00 # reserved +# 1f + 00 00 # red_mask red_position + 00 00 # green_mask green_position + 00 00 # blue_mask blue_position + 00 00 # rsv_mask rsv_position + 00 # directcolor_attributes +# 28 + 00 00 00 00 # physbase <== linear frame buffer + +# 2c +# reserved for video mode info + 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# }}} + +# offset 600 (address 0x8200): +# interrupt descriptor table {{{ +# 128 entries * 8 bytes each = 1024 bytes (0x400) +# idt_start: + +# entry 0 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 + +# By default, BIOS maps IRQ0-7 to interrupt vectors 8-15. +# https://wiki.osdev.org/index.php?title=Interrupts&oldid=25102#Default_PC_Interrupt_Vector_Assignment + +# entry 8: clock + 00 7e # target[0:16] = null interrupt handler [label] + 08 00 # segment selector (gdt_code) + 00 # unused + 8e # 1/p 00/dpl 0 1110/type/32-bit-interrupt-gate + 00 00 # target[16:32] + +# entry 9: keyboard + 10 7e # target[0:16] = keyboard interrupt handler [label] + 08 00 # segment selector (gdt_code) + 00 # unused + 8e # 1/p 00/dpl 0 1110/type/32-bit-interrupt-gate + 00 00 # target[16:32] + +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 + +# 500: +# entry 0x20 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 + +# 600: +# entry 0x40 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 + +# 700: +# entry 0x60 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +# entry 0x70 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 +# idt_end: +# }}} + +## the rest of this file has data + +# offset a00 (address 0x8600): +# translating keys to ASCII {{{ +# keyboard normal map: +00 +# es + 1b +# |<--- digits -------------->| - = backspace + 31 32 33 34 35 36 37 38 39 30 2d 3d 08 +# 0f +# tab q w e r t y u i o p [ ] + 09 71 77 65 72 74 79 75 69 6f 70 5b 5d +# 1c +# enter (newline) + 0a 00 +# 1e +# a s d f g h j k l ; ' ` \ + 61 73 64 66 67 68 6a 6b 6c 3b 27 60 00 5c + # ^ left shift +# 2c +# z x c v b n m , . / * + 7a 78 63 76 62 6e 6d 2c 2e 2f 00 2a + # ^ right shift +# 38 +# space + 00 20 +# 3a + 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# numeric keypad would start here, but isn't implemented + 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +# offset b00: +# keyboard shift map: +00 +# es + 1b +# ! @ # $ % ^ & * ( ) _ + backspace + 21 40 23 24 25 53 26 2a 28 29 5f 2b 08 +# 0f +# tab Q W E R T Y U I O P { } + 09 51 57 45 52 54 59 55 49 5f 50 7b 7d +# 1c +# enter (newline) + 0a 00 +# 1e +# A S D F G H J K L : " ~ | + 41 53 44 46 47 48 4a 4b 4c 3a 22 7e 00 7c +# 2c +# Z X C V B N M < > ? * + 5a 58 43 56 42 4e 4d 3c 3e 3f 00 2a +# 38 +# space + 00 20 +# 3a + 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# numeric keypad would start here, but isn't implemented + 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +# c00: +# keyboard ctrl map: +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# 10 +# ^q ^w ^e ^r ^t ^y ^u tb ^o ^p + 11 17 05 12 14 19 15 09 1f 10 00 00 +# 1c +# carriage-return + 0d 00 +# 1e +# ^a ^s ^d ^f ^g ^h ^j ^j ^l ^\ + 01 13 04 06 07 08 0a 0b 0c 00 00 00 00 1c +# 2c +# ^z ^x ^c ^v ^b ^n ^m ^/ + 1a 18 03 16 02 0e 0d 00 00 1f 00 00 +# 38 + 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +# padding (there might be more keyboard tables) +# d00: +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# e00: +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# f00: +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# }}} + +# offset 1000 (address 0x8c00) +# Bitmaps for some ASCII characters (soon Unicode) {{{ +# Part of GNU Unifont +# 8px wide, 16px tall +# Based on http://unifoundry.com/pub/unifont/unifont-13.0.05/font-builds/unifont-13.0.05.hex.gz +# See https://en.wikipedia.org/wiki/GNU_Unifont#The_.hex_font_format +# Website: http://unifoundry.com/unifont/index.html +# License: http://unifoundry.com/LICENSE.txt (GPL v2) +# Each line below is a bitmap for a single character. +# Each byte is a bitmap for a single row of 8 pixels. + +# some unprintable ASCII chars + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# 0x20 = space + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# ! + 00 00 00 00 08 08 08 08 08 08 08 00 08 08 00 00 +# " + 00 00 22 22 22 22 00 00 00 00 00 00 00 00 00 00 +# 0x23 = '#' + 00 00 00 00 12 12 12 7e 24 24 7e 48 48 48 00 00 +# $ + 00 00 00 00 08 3e 49 48 38 0e 09 49 3e 08 00 00 +# % + 00 00 00 00 31 4a 4a 34 08 08 16 29 29 46 00 00 +# & + 00 00 00 00 1c 22 22 14 18 29 45 42 46 39 00 00 +# ' + 00 00 08 08 08 08 00 00 00 00 00 00 00 00 00 00 +# ( + 00 00 00 04 08 08 10 10 10 10 10 10 08 08 04 00 +# ) + 00 00 00 20 10 10 08 08 08 08 08 08 10 10 20 00 +# * + 00 00 00 00 00 00 08 49 2a 1c 2a 49 08 00 00 00 +# + + 00 00 00 00 00 00 08 08 08 7f 08 08 08 00 00 00 +# , + 00 00 00 00 00 00 00 00 00 00 00 00 18 08 08 10 +# - + 00 00 00 00 00 00 00 00 00 3c 00 00 00 00 00 00 +# . + 00 00 00 00 00 00 00 00 00 00 00 00 18 18 00 00 +# / + 00 00 00 00 02 02 04 08 08 10 10 20 40 40 00 00 +# 0x30 = '0' + 00 00 00 00 18 24 42 46 4a 52 62 42 24 18 00 00 +# 1 + 00 00 00 00 08 18 28 08 08 08 08 08 08 3e 00 00 +# 2 + 00 00 00 00 3c 42 42 02 0c 10 20 40 40 7e 00 00 +# 3 + 00 00 00 00 3c 42 42 02 1c 02 02 42 42 3c 00 00 +# 4 + 00 00 00 00 04 0c 14 24 44 44 7e 04 04 04 00 00 +# 5 + 00 00 00 00 7e 40 40 40 7c 02 02 02 42 3c 00 00 +# 6 + 00 00 00 00 1c 20 40 40 7c 42 42 42 42 3c 00 00 +# 7 + 00 00 00 00 7e 02 02 04 04 04 08 08 08 08 00 00 +# 8 + 00 00 00 00 3c 42 42 42 3c 42 42 42 42 3c 00 00 +# 9 + 00 00 00 00 3c 42 42 42 3e 02 02 02 04 38 00 00 +# : + 00 00 00 00 00 00 18 18 00 00 00 18 18 00 00 00 +# ; + 00 00 00 00 00 00 18 18 00 00 00 18 08 08 10 00 +# < + 00 00 00 00 00 02 04 08 10 20 10 08 04 02 00 00 +# = + 00 00 00 00 00 00 00 7e 00 00 00 7e 00 00 00 00 +# > + 00 00 00 00 00 40 20 10 08 04 08 10 20 40 00 00 +# ? + 00 00 00 00 3c 42 42 02 04 08 08 00 08 08 00 00 +# 0x40 = @ + 00 00 00 00 1c 22 4a 56 52 52 52 4e 20 1e 00 00 +# A + 00 00 00 00 18 24 24 42 42 7e 42 42 42 42 00 00 +# B + 00 00 00 00 7c 42 42 42 7c 42 42 42 42 7c 00 00 +# C + 00 00 00 00 3c 42 42 40 40 40 40 42 42 3c 00 00 +# D + 00 00 00 00 78 44 42 42 42 42 42 42 44 78 00 00 +# E + 00 00 00 00 7e 40 40 40 7c 40 40 40 40 7e 00 00 +# F + 00 00 00 00 7e 40 40 40 7c 40 40 40 40 40 00 00 +# G + 00 00 00 00 3c 42 42 40 40 4e 42 42 46 3a 00 00 +# H + 00 00 00 00 42 42 42 42 7e 42 42 42 42 42 00 00 +# I + 00 00 00 00 3e 08 08 08 08 08 08 08 08 3e 00 00 +# J + 00 00 00 00 1f 04 04 04 04 04 04 44 44 38 00 00 +# K + 00 00 00 00 42 44 48 50 60 60 50 48 44 42 00 00 +# L + 00 00 00 00 40 40 40 40 40 40 40 40 40 7e 00 00 +# M + 00 00 00 00 42 42 66 66 5a 5a 42 42 42 42 00 00 +# N + 00 00 00 00 42 62 62 52 52 4a 4a 46 46 42 00 00 +# O + 00 00 00 00 3c 42 42 42 42 42 42 42 42 3c 00 00 +# 0x50 = P + 00 00 00 00 7c 42 42 42 7c 40 40 40 40 40 00 00 +# Q + 00 00 00 00 3c 42 42 42 42 42 42 5a 66 3c 03 00 +# R + 00 00 00 00 7c 42 42 42 7c 48 44 44 42 42 00 00 +# S + 00 00 00 00 3c 42 42 40 30 0c 02 42 42 3c 00 00 +# T + 00 00 00 00 7f 08 08 08 08 08 08 08 08 08 00 00 +# U + 00 00 00 00 42 42 42 42 42 42 42 42 42 3c 00 00 +# V + 00 00 00 00 41 41 41 22 22 22 14 14 08 08 00 00 +# W + 00 00 00 00 42 42 42 42 5a 5a 66 66 42 42 00 00 +# X + 00 00 00 00 42 42 24 24 18 18 24 24 42 42 00 00 +# Y + 00 00 00 00 41 41 22 22 14 08 08 08 08 08 00 00 +# Z + 00 00 00 00 7e 02 02 04 08 10 20 40 40 7e 00 00 +# [ + 00 00 00 0e 08 08 08 08 08 08 08 08 08 08 0e 00 +# \ + 00 00 00 00 40 40 20 10 10 08 08 04 02 02 00 00 +# ] + 00 00 00 70 10 10 10 10 10 10 10 10 10 10 70 00 +# ^ + 00 00 18 24 42 00 00 00 00 00 00 00 00 00 00 00 +# _ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7f 00 +# 0x60 = backtick + 00 20 10 08 00 00 00 00 00 00 00 00 00 00 00 00 +# a + 00 00 00 00 00 00 3c 42 02 3e 42 42 46 3a 00 00 +# b + 00 00 00 40 40 40 5c 62 42 42 42 42 62 5c 00 00 +# c + 00 00 00 00 00 00 3c 42 40 40 40 40 42 3c 00 00 +# d + 00 00 00 02 02 02 3a 46 42 42 42 42 46 3a 00 00 +# e + 00 00 00 00 00 00 3c 42 42 7e 40 40 42 3c 00 00 +# f + 00 00 00 0c 10 10 10 7c 10 10 10 10 10 10 00 00 +# g + 00 00 00 00 00 02 3a 44 44 44 38 20 3c 42 42 3c +# h + 00 00 00 40 40 40 5c 62 42 42 42 42 42 42 00 00 +# i + 00 00 00 08 08 00 18 08 08 08 08 08 08 3e 00 00 +# j + 00 00 00 04 04 00 0c 04 04 04 04 04 04 04 48 30 +# k + 00 00 00 40 40 40 44 48 50 60 50 48 44 42 00 00 +# l + 00 00 00 18 08 08 08 08 08 08 08 08 08 3e 00 00 +# m + 00 00 00 00 00 00 76 49 49 49 49 49 49 49 00 00 +# n + 00 00 00 00 00 00 5c 62 42 42 42 42 42 42 00 00 +# o + 00 00 00 00 00 00 3c 42 42 42 42 42 42 3c 00 00 +# 0x70 = p + 00 00 00 00 00 00 5c 62 42 42 42 42 62 5c 40 40 +# q + 00 00 00 00 00 00 3a 46 42 42 42 42 46 3a 02 02 +# r + 00 00 00 00 00 00 5c 62 42 40 40 40 40 40 00 00 +# s + 00 00 00 00 00 00 3c 42 40 30 0c 02 42 3c 00 00 +# t + 00 00 00 00 10 10 10 7c 10 10 10 10 10 0c 00 00 +# u + 00 00 00 00 00 00 42 42 42 42 42 42 46 3a 00 00 +# v + 00 00 00 00 00 00 42 42 42 24 24 24 18 18 00 00 +# w + 00 00 00 00 00 00 41 49 49 49 49 49 49 36 00 00 +# x + 00 00 00 00 00 00 42 42 24 18 18 24 42 42 00 00 +# y + 00 00 00 00 00 00 42 42 42 42 42 26 1a 02 02 3c +# z + 00 00 00 00 00 00 7e 02 04 08 10 20 40 7e 00 00 +# { + 00 00 00 0c 10 10 08 08 10 20 10 08 08 10 10 0c +# | + 00 00 08 08 08 08 08 08 08 08 08 08 08 08 08 08 +# } + 00 00 00 30 08 08 10 10 08 04 08 10 10 08 08 30 +# ~ + 00 00 00 31 49 46 00 00 00 00 00 00 00 00 00 00 +# 0x7f = del (unused) + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +# }}} + +# offset 1800 (address 0x9400) + +# vim:ft=subx diff --git a/boot0.hex b/boot0.hex index 197be1e7..01cc9c56 100644 --- a/boot0.hex +++ b/boot0.hex @@ -11,12 +11,12 @@ # To convert to a disk image, first prepare a realistically sized disk image: # dd if=/dev/zero of=disk.img count=20160 # 512-byte sectors, so 10MB # Now fill in sectors: -# bootstrap/bootstrap run hex < baremetal/boot0.hex > boot.bin +# bootstrap/bootstrap run hex < boot0.hex > boot.bin # dd if=boot.bin of=disk.img conv=notrunc # To run: # qemu-system-i386 disk.img # Or: -# bochs -f baremetal/boot.bochsrc # boot.bochsrc loads disk.img +# bochs -f boot.bochsrc # boot.bochsrc loads disk.img # # Since we start out in 16-bit mode, we need instructions SubX doesn't # support. diff --git a/ex1.hex b/ex1.hex deleted file mode 100644 index cb5f7e25..00000000 --- a/ex1.hex +++ /dev/null @@ -1,19 +0,0 @@ -# The simplest possible program: just an infinite loop. -# All is well if your computer clears screen and hangs without restarting. -# On an emulator the window may get bigger to accomodate the higher-resolution -# graphics mode. -# -# To convert to a disk image, first prepare a realistically sized disk image: -# dd if=/dev/zero of=disk.img count=20160 # 512-byte sectors, so 10MB -# Load the program on the disk image: -# cat baremetal/boot.hex baremetal/ex1.hex |bootstrap/bootstrap run hex > a.bin -# dd if=a.bin of=disk.img conv=notrunc -# To run: -# qemu-system-i386 disk.img -# Or: -# bochs -f baremetal/boot.bochsrc # boot.bochsrc loads disk.img - -# main: (address 0x9400) -e9 fb ff ff ff # jump to main, hanging indefinitely - -# vim:ft=subx diff --git a/ex1.subx b/ex1.subx index 0cd024fe..9ff2113f 100644 --- a/ex1.subx +++ b/ex1.subx @@ -4,7 +4,7 @@ # graphics mode. # # To build a disk image: -# ./translate_subx boot.hex ex2.subx # emits disk.img +# ./translate_subx boot.subx ex2.subx # emits disk.img # To run: # qemu-system-i386 disk.img # Or: diff --git a/ex2.hex b/ex2.hex deleted file mode 100644 index 6447b462..00000000 --- a/ex2.hex +++ /dev/null @@ -1,39 +0,0 @@ -# Test out the video mode by filling in the screen with pixels. -# -# To run, first prepare a realistically sized disk image: -# dd if=/dev/zero of=disk.img count=20160 # 512-byte sectors, so 10MB -# Load the program on the disk image: -# cat baremetal/boot.hex baremetal/ex2.hex |bootstrap/bootstrap run hex > a.bin -# dd if=a.bin of=disk.img conv=notrunc -# To run: -# qemu-system-i386 disk.img -# Or: -# bochs -f baremetal/boot.bochsrc # boot.bochsrc loads disk.img - -# main: (address 0x9400) - -# ecx <- LFB -8b # copy *rm32 to r32 - 0d # 00/mod/indirect 001/r32/ecx 101/rm32/use-disp32 - 28 81 00 00 # disp32 [label] - -# eax <- LFB + 0xbffff (1024*768 - 1) -8d # copy-address rm32 to r32 - 81 # 10/mod/*+disp32 000/r32/eax 001/rm32/ecx - ff ff 0b 00 # disp32 - -# $loop: -# if (eax < ecx) break -39 # compare rm32 with r32 - c8 # 11/mod/direct 001/r32/ecx 000/rm32/eax -7c 05 # break if < [label] -# *eax <- al -88 # copy r8 to m8 at r32 - 00 # 00/mod/indirect 000/r8/AL 000/rm32/eax -48 # decrement eax -eb f7 # loop to -9 bytes [label] - -# $break: -e9 fb ff ff ff # hang indefinitely - -# vim:ft=subx diff --git a/ex2.subx b/ex2.subx index cb75211c..d7809d36 100644 --- a/ex2.subx +++ b/ex2.subx @@ -1,7 +1,7 @@ # Test out the video mode by filling in the screen with pixels. # # To build a disk image: -# ./translate_subx boot.hex ex2.subx # emits disk.img +# ./translate_subx boot.subx ex2.subx # emits disk.img # To run: # qemu-system-i386 disk.img # Or: diff --git a/ex3.hex b/ex3.hex deleted file mode 100644 index 58ccbffa..00000000 --- a/ex3.hex +++ /dev/null @@ -1,58 +0,0 @@ -# Draw pixels in response to keyboard events, starting from the top-left -# and in raster order. -# -# To run, first prepare a realistically sized disk image: -# dd if=/dev/zero of=disk.img count=20160 # 512-byte sectors, so 10MB -# Load the program on the disk image: -# cat baremetal/boot.hex baremetal/ex3.hex |bootstrap/bootstrap run hex > a.bin -# dd if=a.bin of=disk.img conv=notrunc -# To run: -# qemu-system-i386 disk.img -# Or: -# bochs -f baremetal/boot.bochsrc # boot.bochsrc loads disk.img - -# main: (address 0x9000) - -# eax <- LFB -8b # copy *rm32 to r32 - 05 # 00/mod/indirect 000/r32/eax 101/rm32/use-disp32 - 28 81 00 00 # disp32 [label] - -# var read index/ecx: byte = 0 -31 c9 # ecx <- xor ecx; 11/direct 001/r32/ecx 001/rm32/ecx - -# $loop: - # CL = *read index - 8a # copy m8 at r32 to r8 - 0d # 00/mod/indirect 001/r8/cl 101/rm32/use-disp32 - cc 7d 00 00 # disp32 [label] - # CL = *(keyboard buffer + ecx) - 8a # copy m8 at r32 to r8 - 89 # 10/mod/*+disp32 001/r8/cl 001/rm32/ecx - d0 7d 00 00 # disp32 [label] - # if (CL == 0) loop (spin loop) - 80 - f9 # 11/mod/direct 111/subop/compare 001/rm8/CL - 00 # imm8 - 74 ef # loop -17 [label] -# offset 0x19: - # otherwise increment read index - fe # increment byte - 05 # 00/mod/indirect 000/subop/increment 101/rm32/use-disp32 - cc 7d 00 00 # disp32 [label] - # clear top nibble of index (keyboard buffer is circular) - 80 # and byte - 25 # 00/mod/indirect 100/subop/and 101/rm32/use-disp32 - cc 7d 00 00 # disp32 [label] - 0f # imm8 - # print a pixel in fluorescent green - c6 # copy imm8 to m8 at rm32 - 00 # 00/mod/indirect 000/subop 000/rm32/eax - 31 # imm32 - 40 # increment eax - eb dc # loop -36 [label] - -# $break: -e9 fb ff ff ff # hang indefinitely - -# vim:ft=subx diff --git a/translate b/translate index 25a1b7f9..7cc1be12 100755 --- a/translate +++ b/translate @@ -5,4 +5,4 @@ set -e cat $* [0-9]*.mu |linux/mu > a.subx -./translate_subx boot.hex mu-init.subx [0-9]*.subx a.subx +./translate_subx boot.subx mu-init.subx [0-9]*.subx a.subx diff --git a/translate_emulated b/translate_emulated index 06786821..a9c1e05d 100755 --- a/translate_emulated +++ b/translate_emulated @@ -9,4 +9,4 @@ set -v cat $* [0-9]*.mu |linux/bootstrap/bootstrap run linux/mu > a.subx -./translate_subx_emulated boot.hex mu-init.subx [0-9]*.subx a.subx +./translate_subx_emulated boot.subx mu-init.subx [0-9]*.subx a.subx diff --git a/translate_subx b/translate_subx index 43323f6a..08519d9f 100755 --- a/translate_subx +++ b/translate_subx @@ -34,7 +34,7 @@ cat a.survey |linux/hex > a.bin dd if=/dev/zero of=disk.img count=20160 # 512-byte sectors, so 10MB dd if=a.bin of=disk.img conv=notrunc -if [ `stat --printf="%s" a.bin` -ge 193536 ] # 6 tracks * 63 sectors per track * 512 bytes per sector (keep this sync'd with boot.hex) +if [ `stat --printf="%s" a.bin` -ge 193536 ] # 6 tracks * 63 sectors per track * 512 bytes per sector (keep this sync'd with boot.subx) then echo "a.bin won't all be loaded on boot" exit 1 diff --git a/translate_subx_emulated b/translate_subx_emulated index 787be559..d5120f48 100755 --- a/translate_subx_emulated +++ b/translate_subx_emulated @@ -29,7 +29,7 @@ cat a.survey |linux/bootstrap/bootstrap run linux/hex > a.bi dd if=/dev/zero of=disk.img count=20160 # 512-byte sectors, so 10MB dd if=a.bin of=disk.img conv=notrunc -if [ `stat --printf="%s" a.bin` -ge 193536 ] # 6 tracks * 63 sectors per track * 512 bytes per sector (keep this sync'd with boot.hex) +if [ `stat --printf="%s" a.bin` -ge 193536 ] # 6 tracks * 63 sectors per track * 512 bytes per sector (keep this sync'd with boot.subx) then echo "a.bin won't all be loaded on boot" exit 1 -- cgit 1.4.1-2-gfad0