1182 lines
37 KiB
Plaintext
1182 lines
37 KiB
Plaintext
# 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 run apps/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 0
|
|
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 02 # dh <- 2 # track 0
|
|
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]
|
|
|
|
# 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
|