duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit 96c3897cb8e3677a694e4e155f172ef11c86fdfb
parent 4823937d788aee780d28768fec2dcdae6f91d326
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Fri,  6 Jan 2023 20:54:47 -0500

gr/plane: add a layer of indirection

So, my old laptop has VESA 1.2, which means no linear buffer. I gotta do bank
switching. I'm preparing the field by adding new indirections in gr/plane to
make this possible.

Also, make .vesamodes show all modes and document vesa at doc/hw/i386/pc/vesa.

Diffstat:
Mfs/doc/gr/plane.txt | 9+++++++++
Afs/doc/hw/i386/pc/vesa.txt | 32++++++++++++++++++++++++++++++++
Mfs/drv/pc/vesa.fs | 9+++------
Mfs/gr/plane.fs | 37++++++++++++++++++++++---------------
4 files changed, 66 insertions(+), 21 deletions(-)

diff --git a/fs/doc/gr/plane.txt b/fs/doc/gr/plane.txt @@ -34,6 +34,15 @@ Methods: Allocate a new buffer of the proper size (considering height and pitch) and set "buffer" to it. +:addr ( self -- a ) + Yield memory address corresponding to current position. + +:bytes< ( a u self -- ) + Write u bytes from address a at current position. + +:bytes> ( a u self -- ) + Write u bytes from current position at address a. + :pixel! ( self -- ) Set a pixel at tx,ty to the value of field "color". diff --git a/fs/doc/hw/i386/pc/vesa.txt b/fs/doc/hw/i386/pc/vesa.txt @@ -0,0 +1,32 @@ +# VESA + +VESA is the Video Electronics Standard Association and they created VBE, the +VESA BIOS Extension standard. VESA 1.2 was released in 1991 and is the version +that really caught on, so that's our baseline. VESA is much easier to work with +than VGA, so that's why we prefer it. + +The driver lives in drv/pc/vesa.fs + +After you've loaded it, you can get general VESA information with ".vesa" and +you can list available modes with ".vesamodes". The output is +"<id> width/height/bpp". A "*" at the end indicates that this mode is a "linear" +mode. + +There's a big difference between VESA 1.2 and VESA 2.0: the presence of linear +buffer modes. A "regular" mode requires bank switching to access the totality of +the memory for that mode, which comes in 64K banks. It's a hassle to manage. +Linear modes provide a contiguous memory area, which is much nicer. When +available, you always want linear mode, it's much faster. + +TODO: in fact, at this time, only linear mode is supported. bank switching +support incoming... + +This driver provides the VESAScreen struct which you can instantiate and plug +into the "screen" global variable from sys/screen. Example: + + f<< /sys/screen.fs + f<< /drv/pc/vesa.fs + VESAScreen :new ' screen rebind + +The driver also has the "vesamode" variable, which defaults to $112 +(640x480x24), indicating which mode ID will be used on "screen :activate". diff --git a/fs/drv/pc/vesa.fs b/fs/drv/pc/vesa.fs @@ -80,14 +80,11 @@ here VBEModeInfo SZ allot structbind VBEModeInfo _curmode ( cx ) 0 $4f01 int10h ( di bx ax ) $4f = _assert drop ; -\ To make the output a bit lighter, we ignore any mode that is not 24bpp or -\ that don't support a linear frame buffer. : _.mode ( mode -- ) dup >r _modeinfo >r \ V1=modeid V2=modeinfo - r@ VBEModeInfo bpp 24 = r@ VBEModeInfo :linear? and if - r@ VBEModeInfo bpp r@ VBEModeInfo height r> VBEModeInfo width - r> .f" |%w %dx%dx%d " - else rdrop rdrop then ; + r@ VBEModeInfo :linear? + r@ VBEModeInfo bpp r@ VBEModeInfo height r> VBEModeInfo width + r> .f" |%w %dx%dx%d" ( linear ) if '*' emit then spc> ; \ We have to read all mode IDs before we call int10h because that list might be \ overwritten by int10h. diff --git a/fs/gr/plane.fs b/fs/gr/plane.fs @@ -13,27 +13,34 @@ extends Rect struct[ Plane sfield ty sfield color sfield buffer + smethod :addr ( self -- a ) + smethod :bytes< ( a u self -- ) + smethod :bytes> ( a u self -- ) : _colorbytes ( id -- nbytes ) colorbpp >> >> >> ; + : _xyoff ( x y self -- n ) + tuck pitch * rot> encoding _colorbytes * + ; + + : _addr ( self -- a ) + dup buffer swap dup tx over ty rot _xyoff + ; + + : _bytes< ( a u self -- ) _addr swap move ; + : _bytes> ( a u self -- ) _addr rot> move ; + : :new ( width height encoding -- plane ) >r >r >r 0 0 r> r> Rect :new ( rect ) r> ( encoding ) dup , _colorbytes over Rect width * ( pitch ) , - 0 ( tx ) , 0 ( ty ) , 0 ( color ) , 0 ( buffer ) , ; + 0 ( tx ) , 0 ( ty ) , 0 ( color ) , 0 ( buffer ) , + ['] _addr , ['] _bytes< , ['] _bytes> , ; : :allotbuf ( self -- ) >r \ V1=self here r@ pitch r@ height * allot r> to buffer ; - : _xyoff ( x y self -- n ) - tuck pitch * rot> encoding _colorbytes * + ; - : _rectaddr ( rect self -- ) tuck over x rot y ( self self x y ) rot _xyoff swap buffer + ; - : _addr ( self -- a ) - dup buffer swap dup tx over ty rot _xyoff + ; - : :pixel! ( self -- ) >r \ V1=self r@ color r@ _addr 16b !+ r> color 16 rshift swap c! ; @@ -57,14 +64,14 @@ extends Rect struct[ Plane 2drop rdrop ; : :copy< ( rect src self -- ) >r >r >r \ V1=self V2=src V3=rect - V3 V2 _rectaddr V1 _addr V3 height >r begin ( srcaddr dstaddr ) - 2dup V3 width V1 encoding _colorbytes * ( src dst src dst u ) move - V1 pitch + swap V2 pitch + swap next ( src dst ) - 2drop rfree ; + V3 V2 _rectaddr V3 height >r begin ( srcaddr ) + dup V3 width V1 encoding _colorbytes * ( src src u ) V1 :bytes< + 1 V1 :ty+ V2 pitch + next ( src ) + drop rfree ; : :copy> ( rect dst self -- ) >r >r >r \ V1=self V2=dst V3=rect - V1 _addr V3 V2 _rectaddr V3 height >r begin ( srcaddr dstaddr ) - 2dup V3 width V1 encoding _colorbytes * ( src dst src dst u ) move - V2 pitch + swap V1 pitch + swap next ( src dst ) - 2drop rfree ; + V3 V2 _rectaddr V3 height >r begin ( dstaddr ) + dup V3 width V1 encoding _colorbytes * ( dst dst u ) V1 :bytes> + 1 V1 :ty+ V2 pitch + next ( dst ) + drop rfree ; ]struct