From 7566d80ade1177939bf29345b5b5cbb976765cc5 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Mon, 28 Dec 2020 00:56:25 -0800 Subject: 7438 --- html/baremetal/boot.hex.html | 724 +++++++++++++++++++++++++++++-------------- html/baremetal/ex2.hex.html | 6 +- html/baremetal/ex3.hex.html | 114 +++++++ 3 files changed, 600 insertions(+), 244 deletions(-) create mode 100644 html/baremetal/ex3.hex.html diff --git a/html/baremetal/boot.hex.html b/html/baremetal/boot.hex.html index 0e2909f3..f21c8efc 100644 --- a/html/baremetal/boot.hex.html +++ b/html/baremetal/boot.hex.html @@ -16,7 +16,7 @@ a { color:inherit; } * { font-size:12pt; font-size: 1em; } .subxComment { color: #005faf; } .LineNr { } -.subxH1Comment { color: #005faf; text-decoration: underline; } +.subxS1Comment { color: #0000af; } --> @@ -84,16 +84,16 @@ if ('onhashchange' in window) { 30 # Programs using this initialization: 31 # - can't use any syscalls 32 # - can't print text to video memory (past these boot sectors) - 33 # - must only print raw pixels (256 colors) to video memory (resolution 1280x1024) - 34 # - must store their entry-point at address 0x8000 + 33 # - must only print raw pixels (256 colors) to video memory (resolution 1024x768) + 34 # - must store their entry-point at address 0x8800 35 36 ## 16-bit entry point 37 38 # Upon reset, the IBM PC: - 39 # - loads the first sector (512 bytes) - 40 # from some bootable image (see the boot sector marker at the end of this file) - 41 # to the address range [0x7c00, 0x7e00) - 42 # - starts executing code at address 0x7c00 + 39 # - loads the first sector (512 bytes) + 40 # from some bootable image (see the boot sector marker at the end of this file) + 41 # to the address range [0x7c00, 0x7e00) + 42 # - starts executing code at address 0x7c00 43 44 # offset 00 (address 0x7c00): 45 # disable interrupts for this initialization @@ -118,13 +118,13 @@ if ('onhashchange' in window) { 64 b5 00 # ch <- 0 # cylinder 0 65 b6 00 # dh <- 0 # track 0 66 b1 02 # cl <- 2 # second sector, 1-based - 67 b0 04 # al <- 4 # number of sectors to read + 67 b0 10 # al <- 16 # number of sectors to read; all sectors must be in a single track 68 # address to write sectors to = es:bx = 0x7e00, contiguous with boot segment 69 bb 00 00 # bx <- 0 70 8e c3 # es <- bx - 71 bb 00 7e # bx <- 0x7e00 + 71 bb 00 7e # bx <- 0x7e00 [label] 72 cd 13 # int 13h, BIOS disk service - 73 0f 82 76 00 # jump-if-carry disk-error + 73 0f 82 8a 00 # jump-if-carry disk-error [label] 74 75 # 26: 76 # undo the A20 hack: https://en.wikipedia.org/wiki/A20_line @@ -150,246 +150,488 @@ if ('onhashchange' in window) { 96 # adjust video mode 97 b4 4f # ah <- 4f (VBE) 98 b0 02 # al <- 02 (set video mode) - 99 bb 07 01 # bx <- 0x0107 (graphics 1280x1024x256) -100 # fallback: 0x0101 (640x480x256) -101 # for other choices see http://www.ctyme.com/intr/rb-0069.htm + 99 bb 05 41 # bx <- 0x0105 (graphics 1024x768x256 +100 # 0x4000 bit = configure linear frame buffer in Bochs emulator; hopefully this doesn't hurt anything when running natively) +101 # fallback mode: 0x0101 (640x480x256) 102 cd 10 # int 10h, Vesa BIOS extensions 103 104 # 43: -105 # switch to 32-bit mode -106 0f 01 16 # lgdt 00/mod/indirect 010/subop 110/rm/use-disp16 -107 80 7c # *gdt_descriptor -108 0f 20 c0 # eax <- cr0 -109 66 83 c8 01 # eax <- or 0x1 -110 0f 22 c0 # cr0 <- eax -111 ea c0 7c 08 00 # far jump to initialize_32bit_mode after setting cs to the record at offset 8 in the gdt (gdt_code) +105 # load information for the (hopefully) current video mode +106 # mostly just for the address to the linear frame buffer +107 b4 4f # ah <- 4f (VBE) +108 b0 01 # al <- 01 (get video mode) +109 b9 07 01 # cx <- 0x0107 (mode we requested) +110 bf 00 7f # di <- 0x7f00 (video mode info) [label] +111 cd 10 112 -113 # padding -114 # 57: -115 00 00 00 00 00 00 00 00 00 -116 -117 ## GDT: 3 records of 8 bytes each -118 -119 # 60: -120 # gdt_start: -121 # gdt_null: mandatory null descriptor -122 00 00 00 00 00 00 00 00 -123 # gdt_code: (offset 8 from gdt_start) -124 ff ff # limit[0:16] -125 00 00 00 # base[0:24] -126 9a # 1/present 00/privilege 1/descriptor type = 1001b -127 # 1/code 0/conforming 1/readable 0/accessed = 1010b -128 cf # 1/granularity 1/32-bit 0/64-bit-segment 0/AVL = 1100b -129 # limit[16:20] = 1111b -130 00 # base[24:32] -131 # gdt_data: (offset 16 from gdt_start) -132 ff ff # limit[0:16] -133 00 00 00 # base[0:24] -134 92 # 1/present 00/privilege 1/descriptor type = 1001b -135 # 0/data 0/conforming 1/readable 0/accessed = 0010b -136 cf # same as gdt_code -137 00 # base[24:32] -138 # gdt_end: -139 -140 # padding -141 # 78: -142 00 00 00 00 00 00 00 00 -143 -144 # 80: -145 # gdt_descriptor: -146 17 00 # final index of gdt = gdt_end - gdt_start - 1 -147 60 7c 00 00 # start = gdt_start -148 -149 # padding -150 # 85: -151 00 00 00 00 00 00 00 00 00 00 -152 -153 # 90: -154 # disk_error: -155 # print 'D' to top-left of screen to indicate disk error -156 # *0xb8000 <- 0x0f44 -157 # bx <- 0xb800 -158 bb 00 b8 -159 # ds <- bx -160 8e db # 11b/mod 011b/reg/ds 011b/rm/bx -161 # al <- 'D' -162 b0 44 -163 # ah <- 0x0f # white on black -164 b4 0f -165 # bx <- 0 -166 bb 00 00 -167 # *ds:bx <- ax -168 89 07 # 00b/mod/indirect 000b/reg/ax 111b/rm/bx -169 -170 e9 fb ff # loop forever -171 -172 # padding -173 # a1: -174 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -175 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -176 -177 ## 32-bit code from this point (still some instructions not in SubX) -178 -179 # c0: -180 # initialize_32bit_mode: -181 66 b8 10 00 # ax <- offset 16 from gdt_start -182 8e d8 # ds <- ax -183 8e d0 # ss <- ax -184 8e c0 # es <- ax -185 8e e0 # fs <- ax -186 8e e8 # gs <- ax -187 -188 # load interrupt handlers -189 0f 01 1d # lidt 00/mod/indirect 011/subop 101/rm32/use-disp32 -190 00 7f 00 00 # *idt_descriptor -191 -192 # enable keyboard IRQ -193 b0 fd # al <- 0xfd # enable just IRQ1 -194 e6 21 # port 0x21 <- al -195 -196 # initialization is done; enable interrupts -197 fb -198 e9 21 03 00 00 # jump to 0x8000 -199 -200 # padding -201 # df: -202 00 -203 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -204 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +113 # 4f: +114 # switch to 32-bit mode +115 0f 01 16 # lgdt 00/mod/indirect 010/subop 110/rm/use-disp16 +116 a0 7c # *gdt_descriptor [label] +117 0f 20 c0 # eax <- cr0 +118 66 83 c8 01 # eax <- or 0x1 +119 0f 22 c0 # cr0 <- eax +120 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] +121 +122 # padding +123 # 63: +124 00 00 00 00 00 00 00 00 00 00 00 00 00 +125 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +126 +127 ## GDT: 3 records of 8 bytes each +128 +129 # 80: +130 # gdt_start: +131 # gdt_null: mandatory null descriptor +132 00 00 00 00 00 00 00 00 +133 # gdt_code: (offset 8 from gdt_start) +134 ff ff # limit[0:16] +135 00 00 00 # base[0:24] +136 9a # 1/present 00/privilege 1/descriptor type = 1001b +137 # 1/code 0/conforming 1/readable 0/accessed = 1010b +138 cf # 1/granularity 1/32-bit 0/64-bit-segment 0/AVL = 1100b +139 # limit[16:20] = 1111b +140 00 # base[24:32] +141 # gdt_data: (offset 16 from gdt_start) +142 ff ff # limit[0:16] +143 00 00 00 # base[0:24] +144 92 # 1/present 00/privilege 1/descriptor type = 1001b +145 # 0/data 0/conforming 1/readable 0/accessed = 0010b +146 cf # same as gdt_code +147 00 # base[24:32] +148 # gdt_end: +149 +150 # padding +151 # 98: +152 00 00 00 00 00 00 00 00 +153 +154 # a0: +155 # gdt_descriptor: +156 17 00 # final index of gdt = gdt_end - gdt_start - 1 +157 80 7c 00 00 # start = gdt_start [label] +158 +159 # padding +160 # a5: +161 00 00 00 00 00 00 00 00 00 00 +162 +163 # b0: +164 # disk_error: +165 # print 'D' to top-left of screen to indicate disk error +166 # *0xb8000 <- 0x0f44 +167 # bx <- 0xb800 +168 bb 00 b8 +169 # ds <- bx +170 8e db # 11b/mod 011b/reg/ds 011b/rm/bx +171 # al <- 'D' +172 b0 44 +173 # ah <- 0x0f # white on black +174 b4 0f +175 # bx <- 0 +176 bb 00 00 +177 # *ds:bx <- ax +178 89 07 # 00b/mod/indirect 000b/reg/ax 111b/rm/bx +179 +180 e9 fb ff # loop forever +181 +182 # padding +183 # c1: +184 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +185 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +186 +187 ## 32-bit code from this point (still some instructions not in SubX) +188 +189 # e0: +190 # initialize_32bit_mode: +191 66 b8 10 00 # ax <- offset 16 from gdt_start +192 8e d8 # ds <- ax +193 8e d0 # ss <- ax +194 8e c0 # es <- ax +195 8e e0 # fs <- ax +196 8e e8 # gs <- ax +197 +198 # load interrupt handlers +199 0f 01 1d # lidt 00/mod/indirect 011/subop 101/rm32/use-disp32 +200 f8 7d 00 00 # *idt_descriptor [label] +201 +202 # enable keyboard IRQ +203 b0 fd # al <- 0xfd # enable just IRQ1 +204 e6 21 # port 0x21 <- al 205 -206 # 100: -207 # null interrupt handler: -208 cf # iret +206 # initialization is done; enable interrupts +207 fb +208 e9 01 0b 00 00 # jump to 0x8800 [label] 209 210 # padding -211 # 101: -212 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +211 # ff: +212 00 213 -214 # 110: -215 # keyboard interrupt handler: -216 # prologue -217 fa # disable interrupts -218 60 # push all registers to stack -219 # acknowledge interrupt -220 b0 20 # al <- 0x20 -221 e6 20 # port 0x20 <- al -222 # TODO: perhaps we should check keyboard status -223 # read keycode into eax -224 31 c0 # eax <- xor eax; 11/direct 000/r32/eax 000/rm32/eax -225 e4 60 # al <- port 0x60 -226 # map key '1' to ascii; if eax == 2, eax = 0x31 -227 3d 02 00 00 00 # compare eax with 0x02 -228 75 0b # if not equal, goto epilogue -229 b8 31 0f 00 00 # eax <- 0x0f31 -230 # print eax to top-left of screen (*0xb8000) -231 89 # copy r32 to rm32 -232 05 # 00/mod/indirect 000/r32/eax 101/rm32/use-disp32 -233 # disp32 -234 00 80 0b 00 -235 # epilogue -236 61 # pop all registers -237 fb # enable interrupts -238 cf # iret -239 -240 # padding -241 # 12f -242 00 -243 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -244 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -245 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -246 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -247 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -248 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -249 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -250 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -251 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -252 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -253 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -254 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -255 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -256 -257 # final 2 bytes of boot sector -258 55 aa -259 -260 ## sector 2 -261 # loaded by load_disk, not automatically on boot -262 -263 # offset 200 (address 0x7e00): interrupt descriptor table -264 # 32 entries * 8 bytes each = 256 bytes (0x100) -265 # idt_start: -266 -267 00 00 00 00 00 00 00 00 -268 00 00 00 00 00 00 00 00 -269 00 00 00 00 00 00 00 00 -270 00 00 00 00 00 00 00 00 -271 00 00 00 00 00 00 00 00 -272 00 00 00 00 00 00 00 00 -273 00 00 00 00 00 00 00 00 -274 00 00 00 00 00 00 00 00 -275 -276 # entry 8: clock -277 00 7d # target[0:16] = null interrupt handler -278 08 00 # segment selector (gdt_code) -279 00 # unused -280 8e # 1/p 00/dpl 0 1110/type/32-bit-interrupt-gate -281 00 00 # target[16:32] -282 -283 # entry 9: keyboard -284 10 7d # target[0:16] = keyboard interrupt handler -285 08 00 # segment selector (gdt_code) -286 00 # unused -287 8e # 1/p 00/dpl 0 1110/type/32-bit-interrupt-gate -288 00 00 # target[16:32] -289 -290 00 00 00 00 00 00 00 00 -291 00 00 00 00 00 00 00 00 -292 00 00 00 00 00 00 00 00 -293 00 00 00 00 00 00 00 00 -294 00 00 00 00 00 00 00 00 -295 00 00 00 00 00 00 00 00 -296 00 00 00 00 00 00 00 00 -297 00 00 00 00 00 00 00 00 -298 00 00 00 00 00 00 00 00 -299 00 00 00 00 00 00 00 00 -300 00 00 00 00 00 00 00 00 -301 00 00 00 00 00 00 00 00 +214 # 100: +215 # null interrupt handler: +216 cf # iret +217 +218 # padding +219 # 101: +220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +221 +222 # 110: +223 # keyboard interrupt handler: +224 # prologue +225 fa # disable interrupts +226 60 # push all registers to stack +227 # acknowledge interrupt +228 b0 20 # al <- 0x20 +229 e6 20 # port 0x20 <- al +230 # read status into eax +231 31 c0 # eax <- xor eax; 11/direct 000/r32/eax 000/rm32/eax +232 e4 64 # al <- port 0x64 +233 # if (status & 0x1) == 0, return +234 24 01 # al <- and 0x1 +235 3c 00 # compare al, 0 +236 74 2d # jump to epilogue if = [label] +237 # 120: +238 # if keyboard buffer is full, return +239 31 c9 # ecx <- xor ecx; 11/direct 001/r32/ecx 001/rm32/ecx +240 # . var index/ecx: byte +241 8a # copy m8 at r32 to r8 +242 0d # 00/mod/indirect 001/r8/cl 101/rm32/use-disp32 +243 ce 7d 00 00 # disp32 [label] +244 # . al = *(keyboard buffer + index) +245 8a # copy m8 at r32 to r8 +246 81 # 10/mod/*+disp32 000/r8/al 001/rm32/ecx +247 d0 7d 00 00 # disp32 [label] +248 # . if (al != 0) return +249 3c 00 # compare al, 0 +250 # 130: +251 75 1b # jump to epilogue if != [label] +252 # read keycode into al +253 e4 60 # al <- port 0x60 +254 # al <- *(keyboard normal map + eax) +255 8a # copy m8 at rm32 to r8 +256 80 # 10/mod/*+disp32 000/r8/al 000/rm32/eax +257 00 80 00 00 # disp32 [label] +258 # store al in keyboard buffer +259 88 # copy r8 to m8 at r32 +260 81 # 10/mod/*+disp32 000/r8/al 001/rm32/ecx +261 d0 7d 00 00 # disp32 [label] +262 # 140: +263 # increment index +264 fe # increment byte +265 05 # 00/mod/indirect 000/subop/increment 101/rm32/use-disp32 +266 ce 7d 00 00 # disp32 [label] +267 # clear top nibble of index (keyboard buffer is circular) +268 80 # and byte +269 25 # 00/mod/indirect 100/subop/and 101/rm32/use-disp32 +270 ce 7d 00 00 # disp32 [label] +271 0f # imm8 +272 # 14d: +273 # epilogue +274 61 # pop all registers +275 fb # enable interrupts +276 cf # iret +277 +278 # padding +279 # 150: +280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +281 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +282 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +283 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +284 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +285 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +286 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +287 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +288 +289 # 1ce: +290 # var keyboard circular buffer +291 # write index: nibble +292 00 +293 # 1cf: +294 # read index: nibble +295 00 +296 # circular buffer: byte[16] +297 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +298 +299 # padding +300 # 1e0: +301 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 302 00 00 00 00 00 00 00 00 -303 00 00 00 00 00 00 00 00 -304 00 00 00 00 00 00 00 00 -305 00 00 00 00 00 00 00 00 -306 00 00 00 00 00 00 00 00 -307 00 00 00 00 00 00 00 00 -308 00 00 00 00 00 00 00 00 -309 00 00 00 00 00 00 00 00 -310 00 00 00 00 00 00 00 00 -311 00 00 00 00 00 00 00 00 -312 # idt_end: -313 -314 # offset 300 (address 0x7f00): -315 # idt_descriptor: -316 ff 00 # idt_end - idt_start - 1 -317 00 7e 00 00 # start = idt_start -318 -319 # padding -320 00 00 00 00 00 00 00 00 00 00 -321 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -322 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -323 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -324 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -325 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -326 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -327 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -328 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -329 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -331 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -332 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -333 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -334 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -335 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -336 # offset 400 (address 0x8000) -337 -338 # vim:ft=subx +303 +304 # 1f8: +305 # idt_descriptor: +306 ff 00 # idt_end - idt_start - 1 +307 00 7e 00 00 # start = idt_start [label] +308 +309 # 1fe: +310 # final 2 bytes of boot sector +311 55 aa +312 +313 ## sector 2 +314 # loaded by load_disk, not automatically on boot +315 +316 # offset 200 (address 0x7e00): interrupt descriptor table +317 # 32 entries * 8 bytes each = 256 bytes (0x100) +318 # idt_start: +319 +320 00 00 00 00 00 00 00 00 +321 00 00 00 00 00 00 00 00 +322 00 00 00 00 00 00 00 00 +323 00 00 00 00 00 00 00 00 +324 00 00 00 00 00 00 00 00 +325 00 00 00 00 00 00 00 00 +326 00 00 00 00 00 00 00 00 +327 00 00 00 00 00 00 00 00 +328 +329 # entry 8: clock +330 00 7d # target[0:16] = null interrupt handler [label] +331 08 00 # segment selector (gdt_code) +332 00 # unused +333 8e # 1/p 00/dpl 0 1110/type/32-bit-interrupt-gate +334 00 00 # target[16:32] +335 +336 # entry 9: keyboard +337 10 7d # target[0:16] = keyboard interrupt handler [label] +338 08 00 # segment selector (gdt_code) +339 00 # unused +340 8e # 1/p 00/dpl 0 1110/type/32-bit-interrupt-gate +341 00 00 # target[16:32] +342 +343 00 00 00 00 00 00 00 00 +344 00 00 00 00 00 00 00 00 +345 00 00 00 00 00 00 00 00 +346 00 00 00 00 00 00 00 00 +347 00 00 00 00 00 00 00 00 +348 00 00 00 00 00 00 00 00 +349 00 00 00 00 00 00 00 00 +350 00 00 00 00 00 00 00 00 +351 00 00 00 00 00 00 00 00 +352 00 00 00 00 00 00 00 00 +353 00 00 00 00 00 00 00 00 +354 00 00 00 00 00 00 00 00 +355 00 00 00 00 00 00 00 00 +356 00 00 00 00 00 00 00 00 +357 00 00 00 00 00 00 00 00 +358 00 00 00 00 00 00 00 00 +359 00 00 00 00 00 00 00 00 +360 00 00 00 00 00 00 00 00 +361 00 00 00 00 00 00 00 00 +362 00 00 00 00 00 00 00 00 +363 00 00 00 00 00 00 00 00 +364 00 00 00 00 00 00 00 00 +365 # idt_end: +366 +367 # offset 300 (address 0x7f00): +368 # video mode info: +369 00 00 # attributes +370 00 # winA +371 00 # winB +372 # 304 +373 00 00 # granularity +374 00 00 # winsize +375 # 308 +376 00 00 # segmentA +377 00 00 # segmentB +378 # 30c +379 00 00 00 00 # realFctPtr (who knows) +380 # 310 +381 00 00 # pitch +382 00 00 # Xres +383 # 314 +384 00 00 # Yres +385 00 00 # Wchar Ychar +386 # 318 +387 00 # planes +388 00 # bpp +389 00 # banks +390 00 # memory_model +391 # 31c +392 00 # bank_size +393 00 # image_pages +394 00 # reserved +395 # 31f +396 00 00 # red_mask red_position +397 00 00 # green_mask green_position +398 00 00 # blue_mask blue_position +399 00 00 # rsv_mask rsv_position +400 00 # directcolor_attributes +401 # 328 +402 00 00 00 00 # physbase <== linear frame buffer +403 +404 # 32c +405 # reserved for video mode info +406 00 00 00 00 +407 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +408 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +409 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +410 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +411 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +412 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +413 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +414 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +415 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +416 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +417 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +418 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +419 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +420 +421 # offset 400 (address 0x8000): +422 # keyboard normal map: +423 00 +424 # es +425 1b +426 # |<--- digits -------------->| - = bs +427 31 32 33 34 35 36 37 38 39 30 2d 3d 08 +428 # offset 40f +429 # tb q w e r t y u i o p [ ] +430 09 71 77 65 72 74 79 75 69 6f 70 5b 5d +431 # offset 41c +432 # enter +433 0a 00 +434 # offset 41e +435 # a s d f g h j k l ; ' ` \ +436 61 73 64 66 67 68 6a 6b 6c 3b 27 60 00 5c +437 # offset 42c +438 # z x c v b n m , . / +439 7a 78 63 76 62 6e 6d 2c 2e 2f +440 # offset 436 +441 00 00 00 00 00 00 00 00 00 00 +442 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +443 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +444 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +445 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +446 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +447 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +448 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +449 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +450 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +451 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +452 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +453 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +454 +455 # 500: +456 # keyboard shift map: +457 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +458 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +459 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +460 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +461 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +462 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +463 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +464 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +465 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +466 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +467 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +468 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +469 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +470 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +471 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +472 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +473 +474 # 600: +475 # keyboard ctrl map: +476 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +477 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +478 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +479 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +480 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +481 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +482 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +483 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +484 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +485 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +486 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +487 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +488 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +489 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +490 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +491 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +492 +493 # padding (there might be more keyboard tables) +494 # 700: +495 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +496 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +497 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +498 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +499 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 +501 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +502 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +503 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +504 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +505 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +506 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +507 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +508 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +509 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +511 +512 # 800: +513 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +514 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +515 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +516 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +517 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +518 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +519 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +520 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +521 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +522 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +523 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +524 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +525 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +526 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +527 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +528 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +529 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +531 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +532 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +533 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +534 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +535 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +536 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +537 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +538 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +539 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +540 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +541 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +542 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +543 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +544 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +545 # a00: +546 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +547 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +548 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +549 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +550 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +551 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +552 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +553 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +554 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +555 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +556 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +557 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +558 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +559 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +560 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +561 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +562 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +563 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +564 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +565 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +566 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +567 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +568 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +569 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +570 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +571 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +572 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +573 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +574 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +575 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +576 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +577 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +578 # offset c00 (address 0x8800) +579 +580 # vim:ft=subx diff --git a/html/baremetal/ex2.hex.html b/html/baremetal/ex2.hex.html index 008f2dd3..42eae7b3 100644 --- a/html/baremetal/ex2.hex.html +++ b/html/baremetal/ex2.hex.html @@ -68,7 +68,7 @@ if ('onhashchange' in window) { 15 # ecx <- LFB 16 8b # copy *rm32 to r32 17 0d # 00/mod/indirect 001/r32/ecx 101/rm32/use-disp32 -18 68 7d 00 00 # disp32 +18 28 7f 00 00 # disp32 [label] 19 20 # eax <- LFB + 0xbffff (1024*768 - 1) 21 8d # copy-address rm32 to r32 @@ -79,12 +79,12 @@ if ('onhashchange' in window) { 26 # if (eax < ecx) break 27 39 # compare rm32 with r32 28 c8 # 11/mod/direct 001/r32/ecx 000/rm32/eax -29 7c 05 # break if < +29 7c 05 # break if < [label] 30 # *eax <- al 31 88 # copy r8 to m8 at r32 32 00 # 00/mod/indirect 000/r8/AL 000/rm32/eax 33 48 # decrement eax -34 eb f7 # loop to -9 bytes +34 eb f7 # loop to -9 bytes [label] 35 36 # $break: 37 e9 fb ff ff ff # hang indefinitely diff --git a/html/baremetal/ex3.hex.html b/html/baremetal/ex3.hex.html new file mode 100644 index 00000000..ccb3422c --- /dev/null +++ b/html/baremetal/ex3.hex.html @@ -0,0 +1,114 @@ + + + + +Mu - baremetal/ex3.hex + + + + + + + + + + +https://github.com/akkartik/mu/blob/master/baremetal/ex3.hex +
+ 1 # Draw pixels in response to keyboard events.
+ 2 #
+ 3 # To run, first prepare a realistically sized disk image:
+ 4 #   dd if=/dev/zero of=disk.img count=20160  # 512-byte sectors, so 10MB
+ 5 # Load the program on the disk image:
+ 6 #   cat baremetal/boot.hex baremetal/ex3.hex  |./bootstrap run apps/hex  > a.bin
+ 7 #   dd if=a.bin of=disk.img conv=notrunc
+ 8 # To run:
+ 9 #   qemu-system-i386 disk.img
+10 # Or:
+11 #   bochs -f apps/boot.bochsrc  # boot.bochsrc loads disk.img
+12 
+13 # main:  (address 0x8800)
+14 
+15 # eax <- LFB
+16 8b  # copy *rm32 to r32
+17   05  # 00/mod/indirect 000/r32/eax 101/rm32/use-disp32
+18   28 7f 00 00 # disp32 [label]
+19 
+20 # var read index/ecx: byte = 0
+21 31 c9  # ecx <- xor ecx;  11/direct 001/r32/ecx 001/rm32/ecx
+22 
+23 # $loop:
+24   # CL = *read index
+25   8a  # copy m8 at r32 to r8
+26     0d  # 00/mod/indirect 001/r8/cl 101/rm32/use-disp32
+27     cf 7d 00 00  # disp32 [label]
+28   # CL = *(keyboard buffer + ecx)
+29   8a  # copy m8 at r32 to r8
+30     89  # 10/mod/*+disp32 001/r8/cl 001/rm32/ecx
+31     d0 7d 00 00  # disp32 [label]
+32   # if (CL == 0) loop (spin loop)
+33   80
+34     f9  # 11/mod/direct 111/subop/compare 001/rm8/CL
+35     00  # imm8
+36   74 ef  # loop -17 [label]
+37 # offset 0x19:
+38   # otherwise increment read index
+39   fe  # increment byte
+40     05  # 00/mod/indirect 000/subop/increment 101/rm32/use-disp32
+41     cf 7d 00 00  # disp32 [label]
+42   # clear top nibble of index (keyboard buffer is circular)
+43   80  # and byte
+44     25  # 00/mod/indirect 100/subop/and 101/rm32/use-disp32
+45     cf 7d 00 00  # disp32 [label]
+46     0f  # imm8
+47   # print a pixel in fluorescent green
+48   c6  # copy imm8 to m8 at rm32
+49     00  # 00/mod/indirect 000/subop 000/rm32/eax
+50     31  # imm32
+51   40  # increment eax
+52   eb dc # loop -36 [label]
+53 
+54 # $break:
+55 e9 fb ff ff ff  # hang indefinitely
+56 
+57 # vim:ft=subx
+
+ + + -- cgit 1.4.1-2-gfad0