commit 586b5f0749027310004a32d65f90790297bbbfb9
parent 6ed422509bc46b0f7781b650ca46440fbb05b5c7
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Sun, 11 Dec 2022 14:10:04 -0500
drv/pc/vesa: first steps
Diffstat:
5 files changed, 81 insertions(+), 7 deletions(-)
diff --git a/fs/asm/label.fs b/fs/asm/label.fs
@@ -2,6 +2,11 @@
0 value org
0 value binstart
+\ Short-lived labels that we need from time to time
+0 value L1
+0 value L2
+0 value L3
+0 value L4
: pc here org - binstart + ;
: pc>addr ( pc -- a ) org + binstart - ;
diff --git a/fs/drv/pc/vesa.fs b/fs/drv/pc/vesa.fs
@@ -0,0 +1,40 @@
+\ VESA driver
+?f<< /lib/fmt.fs
+
+struct[ VBEInfo
+ sfield sig
+ sfieldw version
+ sfield oem
+ sfield capabilities
+ sfield videomodes
+ sfieldw videomem
+ sfieldw softwarerev
+ sfield vendor
+ sfield productname
+ sfield productrev
+
+ : :new ( -- self ) here SZ allot ;
+]struct
+
+VBEInfo :new structbind VBEInfo _info
+
+: _err abort" VESA error" ;
+: _assert not if _err then ;
+
+\ Transform a segment+offset into a 32-bit address
+: seg>32 ( n -- n )
+ dup 12 rshift $ffff0 and swap $ffff and + ;
+
+: vesa$
+ 0 0 $4f00 int10h ( di bx ax )
+ $4f = _assert drop _info :self VBEInfo SZ move ( )
+ _info sig $41534556 ( "VESA" ) = _assert ;
+
+: .vesa
+ _info version .f" Version: %w\n"
+ _info capabilities .f" Capabilities: %x\n"
+ _info videomem .f" Video memory (*64K): %w\n"
+ _info videomem .f" Software rev: %w\n"
+ _info vendor seg>32 .f" Vendor: %z\n"
+ _info productname seg>32 .f" Product name: %z\n"
+ _info productrev seg>32 .f" Product rev: %z\n" ;
diff --git a/fs/xcomp/i386/kernel.fs b/fs/xcomp/i386/kernel.fs
@@ -25,7 +25,7 @@
\ Constants and labels
0 to realmode
: values ( n -- ) >r begin 0 value next ;
-26 values L1 L2 lblmainalias lblbootptr lblin< lblabort lblnextword
+24 values lblmainalias lblbootptr lblin< lblabort lblnextword
lblcurword lblnextmeta lblret lblsysdict lblemit lblparsec lblparseh
lblparseud lblerrmsg lblrtype lblhere lbl[rcnt] lblmovewrite lblwrite
lblcwrite lblfind lblcompiling lblidt lblwoff
diff --git a/fs/xcomp/i386/pc/init.fs b/fs/xcomp/i386/pc/init.fs
@@ -45,3 +45,4 @@ f<< /sys/ps2.fs
f<< /drv/pc/a20.fs
a20$
+f<< /drv/pc/vesa.fs
diff --git a/fs/xcomp/i386/pc/kernel.fs b/fs/xcomp/i386/pc/kernel.fs
@@ -7,19 +7,19 @@ pc to L1 \ back to protected mode!
lblidt m) lidt, sti,
ret,
-pc $3ff w, 0 , \ real mode IVT
+pc to L2 $3ff w, 0 , \ real mode IVT
-pc to L2 1 to realmode \ we're in realmode
- ax ax xor, es ax mov, ds ax mov, ss ax mov, ( pc ) m) lidt, sti,
+pc to L3 1 to realmode \ we're in realmode
+ ax ax xor, es ax mov, ds ax mov, ss ax mov, L2 m) lidt, sti,
ax $0201 i) mov, $13 int,
\ we've done what we came for, let's go back to 32bit
cli, ax cr0 mov, ax 1 i) or, cr0 ax mov,
$08 L1 jmpfar,
-pc to L1 \ segment with ffff limits
+pc to L4 \ segment with ffff limits
ax $20 i) mov, ds ax mov, ss ax mov, es ax mov, gs ax mov, fs ax mov,
ax cr0 mov, ax $fffffffe i) and, cr0 ax mov,
- 0 L2 jmpfar,
+ 0 L3 jmpfar,
0 to realmode
xcode int13h ( drv head cyl sec dst -- )
@@ -28,7 +28,35 @@ xcode int13h ( drv head cyl sec dst -- )
AX pspop, ch al mov, \ cyl
AX pspop, dh al mov, \ head
AX pspop, dl al mov, \ drive
- cli, $18 L1 jmpfar,
+ cli, $18 L4 jmpfar,
+
+pc to L1 \ back to protected mode!
+ \ we still need to push di, bx and ax
+ dx $10 i) mov, ds dx mov, ss dx mov, es dx mov, gs dx mov, fs dx mov,
+ DI pspush, BX pspush, AX pspush,
+ lblidt m) lidt, sti,
+ ret,
+
+pc to L3 1 to realmode \ we're in realmode
+ dx dx xor, es dx mov, ds dx mov, ss dx mov, L2 m) lidt, sti,
+ \ VESA calls need a 512b buffer that can be accessed by real mode. SP is
+ \ always in the 64K range, so let's use it along with a little security buf.
+ di sp mov, di $300 i) sub,
+ \ Write "VBE2" at DI
+ di 0 d) $4256 i) mov, ( VB ) di 2 d) $3245 i) mov, ( E2 )
+ $10 int,
+ \ we've done what we came for, let's go back to 32bit
+ cli, dx cr0 mov, dx 1 i) or, cr0 dx mov,
+ $08 L1 jmpfar,
+
+pc to L4 \ segment with ffff limits
+ dx $20 i) mov, ds dx mov, ss dx mov, es dx mov, gs dx mov, fs dx mov,
+ dx cr0 mov, dx $fffffffe i) and, cr0 dx mov,
+ 0 L3 jmpfar,
+0 to realmode
+
+xcode int10h ( cx bx ax -- di bx ax )
+ AX pspop, BX pspop, CX pspop, di di xor, cli, $18 L4 jmpfar,
\ To avoid lockups, we map all PIC IRQs on boot to words that acknowledge those
\ IRQs. The rest of PIC initialization is done in /drv/pc/pic.fs