Is the VESA graphics working now or not ?
I tested on a LAPTOP (800x600) and no success.
640*480 neither worked.
The only working method was 320*200*8bit using BIOS calls and
DOSMEMPUT.
Is it possible to access the 640*480*4bit mode using BIOS only,
no SCREEN command or graf libraries ?
EDIT: Seems fixed by now [2006/08/01]
[FIXED] VESA & VGA graphics
[FIXED] VESA & VGA graphics
Last edited by DOS386 on Aug 01, 2006 5:34, edited 1 time in total.
Well, the VESA part should be working, but the ISR routines are still broken somehow, so the graphics statements probably won't work on "real" DOS.
If you really need 640x480x4bpp, you can use BIOS mode 0x12 - mjs wrote a driver for it (src/gfxlib2/dos/libfb_gfx_driver_bios.c) if you want to check out how it works. However, it's a pain to code for this mode because it's planar.
If you really need 640x480x4bpp, you can use BIOS mode 0x12 - mjs wrote a driver for it (src/gfxlib2/dos/libfb_gfx_driver_bios.c) if you want to check out how it works. However, it's a pain to code for this mode because it's planar.
Broken graphics
Thanks.
The fact is that VESA does NOT work on my "real" [Free-]DOS.
Is there a chance that it will be fixed one day ?
other modes also (?). Is there a more simple example how to use
this mode "640x480x4bpp, you can use BIOS mode 0x12" ?
The "320x200x8bpp" is so simple :-)
Hmm... what are the "ISR" routines ?Well, the VESA part should be working, but the ISR routines are still broken
somehow, so the graphics statements probably won't work on "real" DOS.
The fact is that VESA does NOT work on my "real" [Free-]DOS.
Is there a chance that it will be fixed one day ?
Hmm... I had a look. It is too complicated and contains support for
If you really need 640x480x4bpp, you can use BIOS mode 0x12 - mjs wrote a driver for it (src/gfxlib2/dos/libfb_gfx_driver_bios.c) if you want to check out how it works.
other modes also (?). Is there a more simple example how to use
this mode "640x480x4bpp, you can use BIOS mode 0x12" ?
The "320x200x8bpp" is so simple :-)
??? Can't imagine how a graph mode can be "planar" ...However, it's a pain to code for this mode because it's planar.
I just dug up my old code for 8-bit VESA. This is horrible, disgusting, dirty code that needs a full rewrite, but it works under real dos, and maybe it will help someone get started.
For 0.15 DOS only
For 0.15 DOS only
Code: Select all
' This code is dirty dirty dirty, it was just cobbled together
' from some old bits and bobs, and needs a FULL checkup. It just demonstrates
' a way to get to 8-bit VESA modes under DOS. I checked it with 0.15 and it
' works for me on DOS, but the compiled exe does not run on windows.
' I can't remember much about how i made it but I remember it came in part from
' some GPL code from FalconsEye, and the VESA (2.0?) Docs.
Option Explicit
#define _BORLAND_DOS_REGS 1 // djgpp specific switch
#include "dos\pc.bi"
#include "dos\dos.bi"
#include "dos\go32.bi"
#include "dos\dpmi.bi"
' No nearptr.bi on 0.15
Declare Function __djgpp_nearptr_enable cdecl Alias "__djgpp_nearptr_enable" () As Integer ' Returns 0 if feature not avail
Declare Sub __djgpp_nearptr_disable cdecl Alias "__djgpp_nearptr_disable" () ' Enables protection
extern __djgpp_selector_limit Alias "__djgpp_selector_" As Integer ' Limit on CS and on DS if prot
extern __djgpp_base_address Alias "__djgpp_base_address" As Integer ' Used in calculation below
' Conflicts with crt.bi
type size_t as uinteger
declare function memcpy cdecl alias "memcpy" (byval as any ptr, byval as any ptr, byval as size_t) as any ptr
#define __djgpp_conventional_base (-__djgpp_base_address)
Type YFVESA_T
w As Integer
h As Integer
vmem As uByte ptr
End Type
Type SVGA_dos_vbe_vgainfo Field = 1
VESASignature(0 To 3) As Byte ' /* VESA 4-byte signature */
VESAVersion As uShort ' /* VBE version number */
OEMStringPtr As uInteger ' /* Pointer to OEM string */
Capabilities(0 To 3) As uByte ' /* Capabilities of video card */
VideoModePtr As uInteger ' /* Pointer to supported modes */
TotalMemory As uShort ' /* Number of 64kb memory blocks */
OEMSoftwareRev As uShort ' /* VBE software revision */
OEMVendorNamePtr As uInteger ' /* Pointer to vendor name string */
OEMProductNamePtr As uInteger ' /* Pointer to product name string */
OEMProductRevPtr As uInteger ' /* Pointer to product revision string */
Reserved(0 To 221) As Byte ' /* Reserved as working space */
OEMData(0 To 255) As Byte ' /* Data area for OEM strings */
End Type
Type SVGA_dos_vbe_modeinfo
ModeAttributes As Short '/* Mode attributes */
WinAAttributes As Byte '/* Window A attributes */
WinBAttributes As Byte '/* Window B attributes */
WinGranularity As Short '/* Window granularity in k */
WinSize As Short '/* Window size in k */
WinASegment As Short '/* Window A segment */
WinBSegment As Short '/* Window B segment */
WinFuncPtr As Any ptr '/* Pointer to window function */
BytesPerScanLine As Short '/* Bytes per scanline */
XResolution As Short '/* Horizontal resolution */
YResolution As Short '/* Vertical resolution */
XCharSize As Byte '/* Character cell width */
YCharSize As Byte '/* Character cell height */
NumberOfPlanes As Byte '/* Number of memory planes */
BitsPerPixel As Byte '/* Bits per pixel */
NumberOfBanks As Byte '/* Number of CGA style banks */
MemoryModel As Byte '/* Memory model type */
BankSize As Byte '/* Size of CGA style banks */
NumberOfImagePages As Byte '/* Number of images pages */
res1 As Byte '/* Reserved */
RedMaskSize As Byte '/* Size of direct color red mask */
RedFieldPosition As Byte '/* Bit posn of lsb of red mask */
GreenMaskSize As Byte '/* Size of direct color green mask */
GreenFieldPosition As Byte '/* Bit posn of lsb of green mask */
BlueMaskSize As Byte '/* Size of direct color blue mask */
BlueFieldPosition As Byte '/* Bit posn of lsb of blue mask */
RsvdMaskSize As Byte '/* Size of direct color res mask */
RsvdFieldPosition As Byte '/* Bit posn of lsb of res mask */
DirectColorModeInfo As Byte '/* Direct color mode attributes */
' VESA 2.0 variables
PhysBasePtr As Long '/* physical address for flat frame buffer */
OffScreenMemOffset As Long '/* pointer to start of off screen memory */
OffScreenMemSize As Short '/* amount of off screen memory in 1k units */
res2(0 To 205) As Byte '/* Pad to 256 byte block size */
End Type
Dim Shared yfvesa As YFVESA_T
Dim Shared SVGA_dos_console As uByte ptr
Dim Shared gran As Short
Dim Shared gran2 As Short
Function SVGA_DOSDetectVBE(vbeinfo As SVGA_dos_vbe_vgainfo ptr) As Integer
Dim regs As __dpmi_regs
Dim sig As String
vbeinfo->VESASignature(0) = Asc("V")
vbeinfo->VESASignature(1) = Asc("B")
vbeinfo->VESASignature(2) = Asc("E")
vbeinfo->VESASignature(3) = Asc("2")
regs.x.ax = &H4F00
regs.x.di = __tb AND &H0F
regs.x.es = (__tb shr 4) AND &HFFFF
dosmemput(vbeinfo, sizeof(SVGA_dos_vbe_vgainfo), __tb)
__dpmi_int(&H10, @regs)
dosmemget(__tb, sizeof(SVGA_dos_vbe_vgainfo), vbeinfo)
sig += chr(vbeinfo->VESASignature(0))
sig += chr(vbeinfo->VESASignature(1))
sig += chr(vbeinfo->VESASignature(2))
sig += chr(vbeinfo->VESASignature(3))
Print sig
return regs.h.ah
End Function
Function SVGA_DOSGetVBEModeInfo(ByVal mode As uShort, modeinfo As SVGA_dos_vbe_modeinfo ptr) As Integer
Dim regs As __dpmi_regs
regs.x.ax = &H4F01
regs.x.cx = mode
regs.x.di= __tb AND &H0F
regs.x.es = (__tb shr 4) AND &HFFFF
__dpmi_int(&H10, @regs)
dosmemget(__tb, sizeof(SVGA_dos_vbe_modeinfo), modeinfo)
Gran = modeinfo->WinGranularity
Gran2 = modeinfo->WinSize
return regs.h.ah
End Function
#define SVGA_MAX_VBEMODES 1000
Function VESA_GetMode(w As Integer, h As Integer, b As Integer) As Integer
Dim vbeinfo As SVGA_dos_vbe_vgainfo
Dim modeinfo As SVGA_dos_vbe_modeinfo
Dim i As Integer
If SVGA_DOSDetectVBE(@vbeinfo) <> 0 Then Return 0
While i < &HFFFF
SVGA_DOSGetVBEModeInfo(i, @modeinfo)
If modeinfo.XResolution = w AND modeinfo.YResolution = h AND modeinfo.BitsPerPixel = b Then Return i
i += 1
Wend
Return 0
End Function
Sub SVGA_DOSSetGDisplayMode(ByVal disp_mode As uInteger)
Dim regs As REGS
regs.x.eax=&H4f02
regs.x.ebx=disp_mode
int86(&H10,@regs,@regs)
End Sub
Sub VESA_Init8(w As Integer, h As Integer)
Dim mode As Integer
yfvesa.vmem = CAllocate(w * h)
yfvesa.w = w
yfvesa.h = h
mode = VESA_GetMode(w, h, 8)
Print Hex$(mode)
If mode <> 0 Then
SVGA_DOSSetGDisplayMode mode
End If
SVGA_dos_console = Cptr(uByte ptr, &HA0000 + __djgpp_conventional_base)
__djgpp_nearptr_enable()
End Sub
Sub VESA_End()
Dim regs As __dpmi_regs
__djgpp_nearptr_disable()
regs.x.ax = 3
__dpmi_int(&H10, @regs)
DeAllocate(yfvesa.vmem)
End Sub
Sub SVGA_DOSSetColor(cindex As uByte, redval As uByte, greenval As uByte, blueval As uByte)
outp(&H03c6, &HFF)
outp(&H03c8, cindex)
outp(&H03c9, redval)
outp(&H03c9, greenval)
outp(&H03c9, blueval)
End Sub
Sub SVGA_pixelput(x As Integer, y As Integer, vari As uByte)
if x < 0 Then x = 0
if y < 0 Then y = 0
if x > yfvesa.w - 1 Then x = yfvesa.w - 1
if y > yfvesa.h - 1 Then y = yfvesa.h - 1
yfvesa.vmem[(y * yfvesa.w) + x] = vari
End Sub
Sub SVGA_DOSSetWindow(ByVal w_num As uInteger)
'Dim regs As REGS
'regs.x.eax=&H4f05
'regs.x.ebx=0
'regs.x.edx=w_num
'int86(&H10,@regs,@regs)
Dim regs As __dpmi_regs
regs.x.ax = &H4f05
regs.x.dx = w_num
__dpmi_int(&H10, @regs)
End Sub
Sub SVGARefresh()
Dim As Integer i, npixels, tempwin
Dim As uByte ptr isource
tempwin = 0
npixels = yfvesa.w * yfvesa.h
isource = yfvesa.vmem
While (npixels > 0)
SVGA_DOSSetWindow(tempwin)
if npixels > 65536 Then
memcpy(SVGA_dos_console,isource,65536)
else
memcpy(SVGA_dos_console,isource,npixels)
End If
npixels -= 65536
isource += 65536
tempwin += 1
Wend
End Sub
Dim As Integer x, y
VESA_Init8(800, 600)
SVGA_DOSSetColor(0, 0, 0, 255)
SVGA_DOSSetColor(1, 255, 0, 0)
SVGA_DOSSetColor(2, 255, 255, 255)
Sleep 2000
For y = 16 To 200
For x = 16 To 200
SVGA_pixelput(x, y, 1)
Next x
Next y
For y = 216 To 400
For x = 216 To 400
SVGA_pixelput(x, y, 2)
Next x
Next y
SVGARefresh()
Sleep 2000
VESA_End()
Print Gran
Print Gran2
Print "OK!"
I made a gui demo that runs on dos using vesa modes here: Binary only: guidemo_dos.zip
It will also run on win98/winxp. This particular demo will allow switching resolutions and color depths.
An explanation of how I did it for the demo is here:
http://www.freebasic.net/forum/viewtopi ... 3600#23600
I have actually tried three different methods:
1) Move the screen update code out of the timer ISR (as in the gui demo) and explicitly call it from the user code
2) Move the screen update code out of the timer ISR and call it from the driver unlock hook. This could be a very real solution to the DOS vesa problem assuming appropriate use of screenlock/unlock'ing in the user code.
3) Leave the screen update code in the timer ISR but only update one bank of video memory per interrupt. (looked horrible, but worked, barely)
I'm not an export on this stuff, I just put together something that worked for me. I certainly was not considering compatibility with QB or that the way the screen gets updated is different from windows and lower res modes.
Of course, making these changes requires recompiling a couple of modules in the dos port of the gfxlib.
It will also run on win98/winxp. This particular demo will allow switching resolutions and color depths.
An explanation of how I did it for the demo is here:
http://www.freebasic.net/forum/viewtopi ... 3600#23600
I have actually tried three different methods:
1) Move the screen update code out of the timer ISR (as in the gui demo) and explicitly call it from the user code
2) Move the screen update code out of the timer ISR and call it from the driver unlock hook. This could be a very real solution to the DOS vesa problem assuming appropriate use of screenlock/unlock'ing in the user code.
3) Leave the screen update code in the timer ISR but only update one bank of video memory per interrupt. (looked horrible, but worked, barely)
I'm not an export on this stuff, I just put together something that worked for me. I certainly was not considering compatibility with QB or that the way the screen gets updated is different from windows and lower res modes.
Of course, making these changes requires recompiling a couple of modules in the dos port of the gfxlib.
VESA graphics
Thanks for 2 previous posts. I'll study them.
Further:
There is Rayer's VESATEST
http://www.volny.cz/rayer/programm/programe.htm
For me it is very reliable - works on every PC, incl. the laptop
mentioned above (up to 800x600x24bits).
Unfortunately it is closed source now, but one could ask the autor if
he could release the source or make it useable from FreeBASIC some
way. By now it is a TEST only.
Further:
There is Rayer's VESATEST
http://www.volny.cz/rayer/programm/programe.htm
For me it is very reliable - works on every PC, incl. the laptop
mentioned above (up to 800x600x24bits).
Unfortunately it is closed source now, but one could ask the autor if
he could release the source or make it useable from FreeBASIC some
way. By now it is a TEST only.
Re: Broken graphics
All VGA modes except 0x13 (320x240x8, chain-4 instead of planar) are planar - for example, in a 4-bit mode, each of the 4 bits for one pixel is split up into a different plane. There are a couple of VGA registers that allow you to pick which plane to read from and which plane(s) to write to. The reason behind this is probably related to the fact that an entire 640x480x4bpp image can't be mapped into a single 64k block.StopTCPA wrote:??? Can't imagine how a graph mode can be "planar" ...
Planar graphics
Thanks.
Does it mean that with 640x480x4bpp there are 4 banks.
every of them 38'400 bytes long (640*480/8), and I have to write
1 bit to every of them to place 1 pixel to the screen ???
The 320x200x8bpp mode has one simple screen buffer :-)
,but low resolution :-(
Hope you catch the BUG in the VESA code soon. :-)
Does it mean that with 640x480x4bpp there are 4 banks.
every of them 38'400 bytes long (640*480/8), and I have to write
1 bit to every of them to place 1 pixel to the screen ???
The 320x200x8bpp mode has one simple screen buffer :-)
,but low resolution :-(
Hope you catch the BUG in the VESA code soon. :-)
Re: Planar graphics
You can too program the latches and other funny things in the VGA hardware to make block reads and writes. Besides it, programming a Soundblaster is a child's game. Better wait for the full SVGA implementation or use a libStopTCPA wrote: Does it mean that with 640x480x4bpp there are 4 banks.
every of them 38'400 bytes long (640*480/8), and I have to write
1 bit to every of them to place 1 pixel to the screen ???