7559 - reorganize sectors built in raw hex

This was tedious for three reasons beyond the usual one of having to
track and update offsets several time while I debug:
  - The Bochs troubles of the previous commit kept polluting my brain
    even though they were irrelevant.
  - I had to keep some changes locally to allow myself to use Bochs,
    which polluted my working directory.
  - I had to travel the long way to the realization that I'm not
    actually initializing the stack anywhere. BIOS was starting my stack
    off at 0x10000, which was promptly clobbered by my second read from
    disk.

The good news: while I'm here I grow the interrupt descriptor table. So
I don't have to go through this exercise when I get back to supporting
the mouse.
This commit is contained in:
Kartik Agaram 2021-01-24 19:38:10 -08:00
parent 1c77be68d7
commit 3844651e49
10 changed files with 273 additions and 148 deletions

Binary file not shown.

View File

@ -7,7 +7,7 @@
#
# The expected input is a stream of bytes and some interspersed labels.
# Comments and '==' segment headers are allowed, but ignored. The emitted code
# will all lie in a single header, and start at address 0x9000.
# will all lie in a single header, and start at address 0x9400.
# $ cat x
# == code
# l1:
@ -197,7 +197,7 @@ test-subx-survey-computes-addresses:
# 01
#
# trace contains (in any order):
# label x is at address 0x9005
# label x is at address 0x9405
#
# . prologue
55/push-ebp
@ -315,10 +315,10 @@ test-subx-survey-computes-addresses:
#? # . . discard args
#? 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
#? # }}}
# . check-trace-contains("label 'x' is at address 0x00009005.", msg)
# . check-trace-contains("label 'x' is at address 0x00009405.", msg)
# . . push args
68/push "F - test-subx-survey-computes-addresses/0"/imm32
68/push "label 'x' is at address 0x00009005."/imm32
68/push "label 'x' is at address 0x00009405."/imm32
# . . call
e8/call check-trace-contains/disp32
# . . discard args
@ -330,7 +330,7 @@ test-subx-survey-computes-addresses:
compute-offsets: # in: (addr stream byte), labels: (addr stream {(handle array byte), address})
# pseudocode:
# var current-address = 0x9000
# var current-address = 0x9400
# var line: (stream byte 512)
# while true # line loop
# clear-stream(line)
@ -362,8 +362,8 @@ compute-offsets: # in: (addr stream byte), labels: (addr stream {(handle array
53/push-ebx
56/push-esi
57/push-edi
# var current-address/esi: int = 0x9000
be/copy-to-esi 0x9000/imm32
# var current-address/esi: int = 0x9400
be/copy-to-esi 0x9400/imm32
# var line/ecx: (stream byte 512)
81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x200/imm32 # subtract from esp
68/push 0x200/imm32/size
@ -595,7 +595,7 @@ test-compute-offsets:
# 34
#
# trace contains (in any order):
# label 'x' is at address 0x9006.
# label 'x' is at address 0x9406.
#
# . prologue
55/push-ebp
@ -697,10 +697,10 @@ test-compute-offsets:
#? # . . discard args
#? 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
#? # }}}
# . check-trace-contains("label 'x' is at address 0x00009006.", msg)
# . check-trace-contains("label 'x' is at address 0x00009406.", msg)
# . . push args
68/push "F - test-compute-offsets"/imm32
68/push "label 'x' is at address 0x00009006."/imm32
68/push "label 'x' is at address 0x00009406."/imm32
# . . call
e8/call check-trace-contains/disp32
# . . discard args
@ -732,7 +732,7 @@ emit-output:datum: # slice
emit-output: # in: (addr stream byte), out: (addr buffered-file), labels: (addr stream {(handle array byte), address})
# pseudocode:
# var address-of-next-instruction = 0x9000
# var address-of-next-instruction = 0x9400
# var line: (stream byte 512)
# line-loop:
# while true
@ -803,8 +803,8 @@ emit-output: # in: (addr stream byte), out: (addr buffered-file), labels: (addr
68/push 0/imm32/end
68/push 0/imm32/start
89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx
# var address-of-next-instruction/ebx = 0x9000
bb/copy-to-ebx 0x9000/imm32
# var address-of-next-instruction/ebx = 0x9400
bb/copy-to-ebx 0x9400/imm32
$emit-output:line-loop:
# clear-stream(line)
# . . push args
@ -1491,12 +1491,12 @@ test-emit-output-code-label:
# ef gh
# e8 l1/disp32
# labels:
# - 'l1': 0x9010
# - 'l1': 0x9410
#
# output:
# ab cd
# ef gh
# e8 07 00 00 00 # 0x9010 - 0x9009 = 7
# e8 07 00 00 00 # 0x9410 - 0x9409 = 7
#
# . prologue
55/push-ebp
@ -1566,8 +1566,8 @@ test-emit-output-code-label:
e8/call write/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
# . stream-add2(labels, "l1", 0x9010)
68/push 0x9010/imm32/label-address
# . stream-add2(labels, "l1", 0x9410)
68/push 0x9410/imm32/label-address
# . . push handle for "l1"
53/push-ebx
68/push "l1"/imm32

View File

@ -28,7 +28,7 @@ pixel-on-real-screen: # x: int, y: int, color: int
c1/shift 4/subop/left %eax 0xa/imm8
03/add-> *(ebp+8) 0/r32/eax
# eax += location of frame buffer
03/add-> *0x7e28 0/r32/eax # unsafe
03/add-> *0x7f28 0/r32/eax # unsafe
# *eax = color
8b/-> *(ebp+0x10) 1/r32/ecx
88/byte<- *eax 1/r32/CL

View File

@ -20,19 +20,19 @@ read-key: # kbd: (addr keyboard) -> result/eax: byte
{
75/jump-if-!= break/disp8
# var read/ecx: byte = keyboard buffer's read index
8b/-> *0x7dcc 1/r32/CL # keyboard-buffer-read
8b/-> *0x7ee4 1/r32/CL # keyboard-buffer-read
# var next-key/eax: byte = *(keyboard buffer + ecx)
8a/byte-> *(ecx+0x7dd0) 0/r32/AL # keyboard-buffer-data
# if (next-key != 0) lock and remove from keyboard-buffer
8a/byte-> *(ecx+0x7ee8) 0/r32/AL # keyboard-buffer-data
# if (next-key != 0) lock and remove from keyboard buffer
81 7/subop/compare %eax 0/imm32
{
74/jump-if-= break/disp8
# TODO: add some instructions in this block to SubX if we ever want to
# use bootstrap on baremetal programs
fa/disable-interrupts
c6 0/subop/copy-byte *(ecx+0x7dd0) 0/imm8
ff 0/subop/increment *0x7dcc # keyboard-buffer-read
81 4/subop/and *0x7dcc 0xf/imm32 # keyboard-buffer-read
c6 0/subop/copy-byte *(ecx+0x7ee8) 0/imm8 # keyboard-buffer-data
ff 0/subop/increment *0x7ee4 # keyboard-buffer-read
81 4/subop/and *0x7ee4 0xf/imm32 # keyboard-buffer-read
fb/enable-interrupts
}
# return

View File

@ -25,9 +25,9 @@ draw-grapheme-on-real-screen: # g: grapheme, x: int, y: int, color: int, backgr
# var letter-bitmap/esi = font[g]
8b/-> *(ebp+8) 6/r32/esi
c1 4/subop/shift-left %esi 4/imm8
8d/copy-address *(esi+0x8800) 6/r32/esi # font-start
# if (letter-bitmap >= 0x9000) return # characters beyond ASCII currently not supported
81 7/subop/compare %esi 0x9000/imm32
8d/copy-address *(esi+0x8c00) 6/r32/esi # font-start
# if (letter-bitmap >= 0x9400) return # characters beyond ASCII currently not supported
81 7/subop/compare %esi 0x9400/imm32
7d/jump-if->= $draw-grapheme-on-real-screen:end/disp8
# var ycurr/edx: int = y*16
8b/-> *(ebp+0x10) 2/r32/edx

View File

@ -30,7 +30,7 @@ operating systems. There's also currently no code/data segment separation,
just labels and bytes. I promise not to write self-modifying code. Security
and sandboxing is still an open question.
Programs start executing at address 0x9000. See baremetal/boot.hex for
Programs start executing at address 0x9400. See baremetal/boot.hex for
details.
Mu programs always run all their automated tests first. `main` only runs if

View File

@ -24,7 +24,7 @@
# This file contains just lowercase hex bytes and comments. Zero
# error-checking. Make liberal use of:
# - comments documenting expected offsets
# - size checks on the emitted file (currently: 5120 bytes)
# - size checks on the emitted file (currently: 6144 bytes)
# - xxd to eyeball that offsets contain expected bytes
#
# Programs using this initialization:
@ -34,20 +34,24 @@
# - must start executing immediately after this file (see outline below)
# Outline of this file with offsets and the addresses they map to at run-time:
# offset 0 (address 7c00): boot code, 16-bit mode
# 80 (address 7c80) global descriptor table
# a0 (address 7ca0) <== gdt_descriptor
# offset e0 (address 7ce0): boot code
# offset 100 (address 7d00): interrupt handler code
# 1c8 (address 7dc8) <== keyboard buffer
# 1f8 (address 7df8) <== idt_descriptor
# -- 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): video mode data (256 bytes)
# 228 (address 7e28) <== start of video RAM stored here
# offset 300 (address 7f00): interrupt descriptor table (256 bytes)
# offset 400 (address 8000): keyboard mappings (2KB)
# offset c00 (address 8800): bitmap font (2KB)
# offset 1400 (address 9000): entrypoint for applications (don't forget to adjust survey_baremetal if this changes)
# offset 200 (address 7e00): interrupt handler code
# -- 32-bit mode data
# 2e0 (address 7ee0) <== keyboard buffer
# 2f8 (address 7ef8) <== idt_descriptor
# offset 300 (address 7f00): video mode data (256 bytes)
# 328 (address 7f28) <== start of video RAM stored here
# offset 400 (address 8000): interrupt descriptor table (1KB)
# offset 800 (address 8400): keyboard mappings (2KB)
# offset 1000 (address 8c00): bitmap font (2KB)
# offset 1800 (address 9400): entrypoint for applications (don't forget to adjust survey_baremetal if this changes)
## 16-bit entry point
@ -90,7 +94,7 @@
cd 13 # int 13h, BIOS disk service
0f 82 8a 00 # jump-if-carry disk_error [label]
# 26:
# load 63 sectors from disk into addresses [0xfa00, 0x17800)
# load second track from disk into addresses [0xfa00, 0x17800)
b4 02 # ah <- 2 # read sectors from disk
b5 00 # ch <- 0 # cylinder 0
b6 01 # dh <- 1 # track 1
@ -145,21 +149,48 @@
b4 4f # ah <- 4f (VBE)
b0 01 # al <- 01 (get video mode)
b9 07 01 # cx <- 0x0107 (mode we requested)
bf 00 7e # di <- 0x7e00 (video mode info) [label]
bf 00 7f # di <- 0x7f00 (video mode info) [label]
cd 10
# 6c:
# switch to 32-bit mode
0f 01 16 # lgdt 00/mod/indirect 010/subop 110/rm/use-disp16
a0 7c # *gdt_descriptor [label]
f8 7c # *gdt_descriptor [label]
0f 20 c0 # eax <- cr0
66 83 c8 01 # eax <- or 0x1
0f 22 c0 # cr0 <- eax
ea e0 7c 08 00 # far jump to initialize_32bit_mode after setting cs to the record at offset 8 in the gdt (gdt_code) [label]
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
# 80:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 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
# 80:
# e0:
# gdt_start:
# gdt_null: mandatory null descriptor
00 00 00 00 00 00 00 00
@ -180,46 +211,18 @@
00 # base[24:32]
# gdt_end:
# padding
# 98:
00 00 00 00 00 00 00 00
# a0:
# f8:
# gdt_descriptor:
17 00 # final index of gdt = gdt_end - gdt_start - 1
80 7c 00 00 # start = gdt_start [label]
e0 7c 00 00 # start = gdt_start [label]
# padding
# a5:
00 00 00 00 00 00 00 00 00 00
# b0:
# 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
# padding
# c1:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
# fe:
00 00
## 32-bit code from this point (still some instructions not in SubX)
# e0:
# offset 100 (address 0x7d00):
# initialize_32bit_mode:
66 b8 10 00 # ax <- offset 16 from gdt_start
8e d8 # ds <- ax
@ -228,9 +231,10 @@ e9 fd ff # loop forever
8e e0 # fs <- ax
8e e8 # gs <- ax
# 10e:
# load interrupt handlers
0f 01 1d # lidt 00/mod/indirect 011/subop 101/rm32/use-disp32
f8 7d 00 00 # *idt_descriptor [label]
f8 7e 00 00 # *idt_descriptor [label]
# For now, not bothering reprogramming the IRQ to not conflict with software
# exceptions.
@ -241,27 +245,49 @@ e9 fd ff # loop forever
# Reference:
# https://wiki.osdev.org/Exceptions
# 115:
# enable keyboard IRQ (1)
b0 fd # al <- 0xfd # disable mask for IRQ1
e6 21 # port 0x21 <- al
# 119:
# initialization is done; enable interrupts
fb
e9 01 13 00 00 # jump to 0x9000 [label]
e9 e1 16 00 00 # jump to 0x9400 [label]
# padding
# ff:
# 11f:
00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00
# 100:
# 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
# 101:
# 201:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
# 110:
# 210:
# keyboard interrupt handler:
# prologue
fa # disable interrupts
@ -276,20 +302,20 @@ e9 fd ff # loop forever
24 01 # al <- and 0x1
3c 00 # compare al, 0
74 39 # jump to epilogue if = [label]
# 120:
# 220:
# 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
c8 7d 00 00 # disp32 [label]
e0 7e 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
d0 7d 00 00 # disp32 [label]
e8 7e 00 00 # disp32 [label]
# . if (al != 0) return
3c 00 # compare al, 0
# 130:
# 230:
75 27 # jump to epilogue if != [label]
# read keycode into al
e4 60 # al <- port 0x60
@ -299,37 +325,37 @@ e9 fd ff # loop forever
3c 00 # compare al, 0
58 # pop to eax (without touching flags)
75 1d # jump to epilogue if != [label]
# 13c:
# 23c:
# al <- *(keyboard normal map + eax)
8a # copy m8 at rm32 to r8
80 # 10/mod/*+disp32 000/r8/al 000/rm32/eax
00 80 00 00 # disp32 [label]
00 84 00 00 # disp32 [label]
# if there's no character mapping, return
3c 00 # compare al, 0
74 13 # jump to epilogue if = [label]
# 146:
# 246:
# store al in keyboard buffer
88 # copy r8 to m8 at r32
81 # 10/mod/*+disp32 000/r8/al 001/rm32/ecx
d0 7d 00 00 # disp32 [label]
# 14c:
e8 7e 00 00 # disp32 [label]
# 24c:
# increment index
fe # increment byte
05 # 00/mod/indirect 000/subop/increment 101/rm32/use-disp32
c8 7d 00 00 # disp32 [label]
e0 7e 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
c8 7d 00 00 # disp32 [label]
e0 7e 00 00 # disp32 [label]
0f # imm8
# 159:
# 259:
# epilogue
61 # pop all registers
fb # enable interrupts
cf # iret
# padding
# 15c:
# 25c:
00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
@ -337,76 +363,69 @@ e9 fd ff # loop forever
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
# 1c8:
# 2e0:
# var keyboard circular buffer
# write index: nibble
# still take up 4 bytes so SubX can handle it
00 00 00 00
# 1cc:
# 2e4:
# read index: nibble
# still take up 4 bytes so SubX can handle it
00 00 00 00
# 1d0:
# 2e8:
# circular buffer: byte[16]
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
# padding
# 1e0:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
# 1f8:
# 2f8:
# idt_descriptor:
ff 00 # idt_end - idt_start - 1
00 7f 00 00 # start = idt_start [label]
00 80 00 00 # start = idt_start [label]
# 1fe:
# final 2 bytes of boot sector
55 aa
# padding
# 2fe:
00 00
## sector 2
# loaded by load_disk, not automatically on boot
# offset 200 (address 0x7e00):
# offset 300 (address 0x7f00):
# video mode info:
00 00 # attributes
00 # winA
00 # winB
# 204
# 304
00 00 # granularity
00 00 # winsize
# 208
# 308
00 00 # segmentA
00 00 # segmentB
# 20c
# 30c
00 00 00 00 # realFctPtr (who knows)
# 210
# 310
00 00 # pitch
00 00 # Xres
# 214
# 314
00 00 # Yres
00 00 # Wchar Ychar
# 218
# 318
00 # planes
00 # bpp
00 # banks
00 # memory_model
# 21c
# 31c
00 # bank_size
00 # image_pages
00 # reserved
# 21f
# 31f
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
# 228
# 328
00 00 00 00 # physbase <== linear frame buffer
# 22c
# 32c
# 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
@ -423,8 +442,9 @@ e9 fd ff # loop forever
00 00 00 00 00 00 00 00 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 300 (address 0x7f00): interrupt descriptor table
# 32 entries * 8 bytes each = 256 bytes (0x100)
# offset 400 (address 0x8000):
# interrupt descriptor table {{{
# 128 entries * 8 bytes each = 1024 bytes (0x400)
# idt_start:
00 00 00 00 00 00 00 00
@ -440,14 +460,14 @@ e9 fd ff # loop forever
# https://wiki.osdev.org/index.php?title=Interrupts&oldid=25102#Default_PC_Interrupt_Vector_Assignment
# entry 8: clock
00 7d # target[0:16] = null interrupt handler [label]
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 7d # target[0:16] = keyboard interrupt handler [label]
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
@ -475,11 +495,114 @@ e9 fd ff # loop forever
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:
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
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:
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
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:
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
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 400 (address 0x8000):
# offset 800 (address 0x8400):
# translating keys to ASCII {{{
# keyboard normal map:
00
@ -487,22 +610,22 @@ e9 fd ff # loop forever
1b
# |<--- digits -------------->| - = bs
31 32 33 34 35 36 37 38 39 30 2d 3d 08
# offset 40f
# offset 80f
# tb q w e r t y u i o p [ ]
09 71 77 65 72 74 79 75 69 6f 70 5b 5d
# offset 41c
# offset 81c
# enter
0a 00
# offset 41e
# offset 81e
# a s d f g h j k l ; ' ` \
61 73 64 66 67 68 6a 6b 6c 3b 27 60 00 5c
# offset 42c
# offset 82c
# z x c v b n m , . / *
7a 78 63 76 62 6e 6d 2c 2e 2f 00 2a
# offset 438
# offset 838
# space
00 20
# offset 43a
# offset 83a
00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
@ -517,7 +640,7 @@ e9 fd ff # loop forever
00 00 00 00 00 00 00 00 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:
# 900:
# keyboard shift map:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
@ -536,7 +659,7 @@ e9 fd ff # loop forever
00 00 00 00 00 00 00 00 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:
# a00:
# keyboard ctrl map:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
@ -556,7 +679,7 @@ e9 fd ff # loop forever
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
# padding (there might be more keyboard tables)
# 700:
# b00:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
@ -573,8 +696,7 @@ e9 fd ff # loop forever
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
# 800:
# c00:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
@ -591,6 +713,7 @@ e9 fd ff # loop forever
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
# 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
@ -607,7 +730,7 @@ e9 fd ff # loop forever
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
# a00:
# 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
@ -624,6 +747,7 @@ e9 fd ff # loop forever
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 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
@ -642,7 +766,7 @@ e9 fd ff # loop forever
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
# }}}
# offset c00 (address 0x8800)
# offset 1000 (address 0x8c00)
# Bitmaps for some ASCII characters (soon Unicode) {{{
# Part of GNU Unifont
# 8px wide, 16px tall
@ -880,6 +1004,6 @@ e9 fd ff # loop forever
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
# }}}
# offset 1400 (address 0x9000)
# offset 1800 (address 0x9400)
# vim:ft=subx

View File

@ -18,7 +18,7 @@
# ecx <- LFB
8b # copy *rm32 to r32
0d # 00/mod/indirect 001/r32/ecx 101/rm32/use-disp32
28 7e 00 00 # disp32 [label]
28 7f 00 00 # disp32 [label]
# eax <- LFB + 0xbffff (1024*768 - 1)
8d # copy-address rm32 to r32

View File

@ -14,7 +14,7 @@
main:
# ecx <- start of video memory
8b/-> *0x7e28 1/r32/ecx
8b/-> *0x7f28 1/r32/ecx
# eax <- final pixel of video memory
8d/copy-address *(ecx + 0x0bffff) 0/r32/eax # 0xbffff = 1024*768 - 1

View File

@ -8,6 +8,7 @@
# initialize stack
bd/copy-to-ebp 0/imm32
bc/copy-to-esp 0x00070000/imm32 # consult https://wiki.osdev.org/Memory_Map_(x86) when modifying this
# always first run tests
(run-tests)
(num-test-failures) # => eax