commit 61a3f7deb2c2daa11fd43d539396b391c6802845
parent 34d5f6375a2a57d6cb5d55fff6fedf235122830c
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Fri, 22 Jul 2022 15:28:37 -0400
pc: we have protected mode, Hi!
Diffstat:
5 files changed, 29 insertions(+), 11 deletions(-)
diff --git a/Makefile b/Makefile
@@ -20,7 +20,7 @@ fatfs: $(ALLSRCS)
mformat -M 512 -d 1 -i $@ ::
mcopy -sQ -i $@ fs/* ::
-pc.bin: dusk
+pc.bin: dusk buildpc.fs
./dusk < buildpc.fs 2> $@
.PHONY: pcrun
diff --git a/buildpc.fs b/buildpc.fs
@@ -1,6 +1,6 @@
: spit ( a u -- ) >r begin c@+ stderr next ;
f<< /asm/i386.fs
f<< /xcomp/pc/mbr.fs
+ORG $200 spit
f<< /xcomp/pc/boot.fs
-
-ORG $400 spit bye
+ORG $200 spit bye
diff --git a/fs/asm/i386.fs b/fs/asm/i386.fs
@@ -158,7 +158,7 @@ ES _ es SS _ ss DS _ ds FS _ fs GS _ gs
\ Inherent
: op ( opcode -- ) doer c, does> ( a -- ) c@ c, asm$ ;
-$c3 op ret, $fa op cli, $fc op cld,
+$c3 op ret, $90 op nop, $fa op cli, $fc op cld,
\ Jumps and relative addresses
\ i386 jumps and calls in their immediate modes are relative. We keep it that
@@ -188,6 +188,9 @@ $0f84 op jz, $0f85 op jnz,
then ;
$04e9 op jmp, $02e8 op call,
+: jmpfar, ( seg16 absaddr ) $ea c, dw, w, ;
+: callfar, ( seg16 absaddr ) $9a c, dw, w, ;
+
\ Single operand
\ opcode format 00000000 00000rrr mmmmmmmm mmmmmmmm
\ r = opreg override
diff --git a/fs/xcomp/pc/boot.fs b/fs/xcomp/pc/boot.fs
@@ -1,6 +1,8 @@
\ This part is called when the bootloader has finished loading the kernel as
-\ well as the Forth boot code following it in memory. We're still in real mode,
-\ SS is uninitialized. This code lives at $8000
-ax $0e59 i) mov,
-$10 int,
+\ well as the Forth boot code following it in memory. We're freshly out of real
+\ mode. SS is uninitialized. This code lives at $8000
+create ORG
+ax 16 i) mov, ds ax mov,
+ax $07690748 i) mov,
+$b8000 m) ax mov,
0 jmp, \ infinite loop
diff --git a/fs/xcomp/pc/mbr.fs b/fs/xcomp/pc/mbr.fs
@@ -1,12 +1,25 @@
\ x86 bootloader
\ Bootsector is loaded at address $7c00
+$7c00 const BINSTART
+BINSTART $1e0 + const GDTADDR
1 to realmode
-create ORG here $200 0 fill
+create ORG here $400 0 fill
$26 jmp, \ bypass BPB
$23 allot
-cli, cld,
+cli, cld, GDTADDR m) lgdt,
+ax $0003 i) mov, $10 int, \ video mode 80x25
\ read sector 2 from boot floppy in memory at address $8000
ax $0201 i) mov, bx $8000 i) mov, cx $0002 i) mov, dx $0000 i) mov, $13 int,
-ax $8000 i) mov, ax jmp,
+ax cr0 mov, ax 1 i) or, cr0 ax mov,
+$08 $8000 jmpfar, 0 to realmode
+
+\ Inspired by GNU grub at grub-core/kern/i386/realmode.S
+ORG $1e0 + to here \ GDT
+\ First entry (the null entry) is a reference to itself
+$17 w, GDTADDR , 0 w,
+\ Code segment. base=0, limit=ffffff*4kb, present, execute/read, DPL=0
+$ffff w, 0 w, 0 c, $9a c, $cf c, 0 c,
+\ Data segment. base=0, limit=ffffff*4kb, present, read/write, DPL=0
+$ffff w, 0 w, 0 c, $92 c, $cf c, 0 c,
ORG $1fe + to here $55 c, $aa c,