News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

VESA programming with PowerBASIC 3.5

Started by Gunther, August 13, 2013, 07:49:10 AM

Previous topic - Next topic

Gunther

In the last days I've done a bit retro programming with PB 3.5, the PowerBASIC DOS compiler.

It's a real mode program with a bit 32 bit magic. The application checks during run time which VESA modes are available, lets the user select one of the possible 256 color modes and draws the Mandelbrot set in that mode. For the calculation I've used a kind of integer arithmetics to speed up the calculation time. Since it's a real mode program, I had to use the bank switching approach; that's a bit slow.

The application is tested with DOSBox 0.74, FreeDOS running inside VirtualBox under Windows 7 (64 bit) and native DOS. It's a good tool for checking the capabilities of the installed graphics adaptor. To do this, you should run it under plain DOS. Why? DOSBox emulates a S3 Trio 64 graphics card and VirtualBox has it's own emulated VESA BIOS, too.

I have an AMD Radeon HD 7570 installed; it comes with a lot of VESA modes. Most of these modes are working fine, but there are 4 modes which return with error code 3:

173h = 1600x1200
183h = 1792x1344
1D3h = 1856x1392
1E3h = 1920x1440

That mode numbers could be very different with other cards, because starting with VBE version 2.0, VESA will no longer define new VESA mode numbers and it will no longer be mandatory to support old mode numbers. That's the reason why an application has to check all modes during run time. I think that the not working modes can only be established in the protected mode.

The main program is written in PowerBASIC (svga.bas), but the dirty work is done in assembly language (svga.asm). This source should be assembled with MASM, JWASM or TASM. To re-build the EXE you'll need the PB DOS compiler. There's a well working free trial version of the compiler, which one can find here. It'll do the job.

At the moment I'm writing the protected mode version of the application. That's a challenge, because a part must run under real mode, another part must run under 16 bit protected mode and the third part must run under 32 bit protected mode. That all has to fit together. There are two reasons for doing that:

  • I would like to test the remaining modes.
  • In the protected mode the application can use the linear frame buffer. This will accelerate the pixel set procedure, because bank switching isn't necessary.
It would be nice to test the application under other hardware configurations. Any feedback is welcome.

Gunther
You have to know the facts before you can distort them.

Magnum

Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

Gunther

Thank you Andy. Can you set all available 256 color modes?

Gunther
You have to know the facts before you can distort them.

Magnum

All three modes worked fine.

Do you need the times as well ?

Andy

Older with lower resolution.


;*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*;
;+*+  MANDEL.ASM by Tenie Remmel -- NEW 67-byte version  +*+;
;*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*;

.model tiny
.code

org         100h

start:

               mov bp,sp           ; Save stack pointer
               push 0A000h         ; Point ES to video memory
               pop es
               mov al,13h          ; Change video mode
               int 10h             ; to 320x200
               xor di,di           ; Zero DI
               mov cl,200          ; Height of screen in pixels
CalcRow:      push cx             ; Save the row pointer on the stack
               mov cx,320          ; Width of screen in pixels
CalcPixel:    push cx             ; Save the column counter on stack
               xor bx,bx           ; Zero i coefficient
               xor dx,dx           ; Zero j coefficient
CycleColors:  push dx             ; Save j

               mov ax,bx           ; AX = i
               sub ax,dx           ; AX = i - j
               add dx,bx           ; DX = i + j
               imul dx             ; DX:AX = (i+j)*(i-j) = i*i - j*j
               mov al,dl           ; Save middle bits (i*i - j*j)/100h
               pop dx              ; Restore j
               xchg ah,al          ; Swap hi, lo middle bits
               xchg bx,ax          ; Now swap new i with old i
               sub bx,[bp-4]       ; Subtract vertical line counter
               test bh,bh          ; Is i >= 256 ?
               jg Draw             ; If so, draw this pixel
               imul dx             ; Now DX:AX = old i * j
               mov dh,dl           ; Get middle bits again
               mov dl,ah           ; Put them in DX
               shl dx,1            ; Save middle bits (i * j)/200h
               sub dx,[bp-2]       ; Subtract out horz line counter
               loop CycleColors    ; Loop back
Draw:         xchg ax,cx          ; Swap color into AL and clear AH
               stosb               ; Write pixel
               pop cx              ; Restore column counter
               loop CalcPixel      ; Loop back
               pop cx              ; Restore row counter
               loop CalcRow        ; Loop back
               mov        al,3     ; return to video mode 3
               int        10h
               mov        ah,4ch
               int        21h

end          start

Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

dedndave

i tried the first 2 (about 6 listed, as i recall)

my adapter seems to be ok, but my monitor doesn't seem to like the resulting refresh rates
so - i see nothing - and have to reboot
i didn't try any more after the first 2 - lol

it would make it a little easier if you gave instructions before the mode switch
then - a simple key-press to try each mode

if the video doesn't show, i can't read the text   :biggrin:

japheth

Quote from: Gunther on August 13, 2013, 07:49:10 AM
In the protected mode the application can use the linear frame buffer. This will accelerate the pixel set procedure, because bank switching isn't necessary.

Actually, the linear frame buffer can also be accessed from real-mode. There's a BIOS function, Int 15h, AH=87h ( copy extended memory ) that will do the job.

hutch--


sinsi

A couple of other ways to access the linear frame buffer from "real" mode
- v86 with paging
- unreal mode / flat real mode
I would be interested to see if you can get vesa's protected mode interface working.

Siekmanski

OS        : Windows XP v5.1.2600 Service Pack 3
Processor : (4x) Intel(R) Core(TM)2 Quad CPU Q6600  @ 2.40GHz
Graphics  : NVIDIA GeForce 9600 GT

Available 256 color modes:

100h 101h 103h 105h 107h 130h 131h 134h 160h 162h 168h

They all work fine.
Creative coders use backward thinking techniques as a strategy.

FORTRANS

Hi,

   Tested on four computers.  If it supports VESA in a DOS like
environment, your program works nicely.  One laptop had
a corrupted desktop after leaving the NTVDM with Windows XP.
The other Windows XP laptop had no such problem, but I invoked
your program a bit differently.  I can test again if you want.
Two old OS/2 VDM's worked well.  Windows 2000 (dual boot)
does not support VESA for DOS programs.

Regards,

Steve N.

Antariy

Hi Gunther :t

Here are the textual results:


Possible 256 color VESA Modes:
==============================

Mode Nr.:   X resoltion    Y resolution     Number
101h        640            480              1
103h        800            600              4
105h        1024           768              7
179h        1280           768              10
107h        1280           1024             13
120h        1600           1200             16
199h        1920           1440             19
22Eh        800            480              22


The program works fine :t

Gunther

Thank you all for testing the application. It broght very interesting results.
Andy,

Quote from: Magnum on August 13, 2013, 08:00:00 AM
All three modes worked fine.

Do you need the times as well ?

no, timings are very individual depending on the installed hardware. Furthermore, the bank switching makes things very slow.

Dave,

Quote from: dedndave on August 13, 2013, 11:10:28 AM
i tried the first 2 (about 6 listed, as i recall)

my adapter seems to be ok, but my monitor doesn't seem to like the resulting refresh rates
so - i see nothing - and have to reboot

The application doesn't manipulate any refresh rate; that's all done by your VESA BIOS. You should look for a resonable monitor.

Andreas,

Quote from: japheth on August 13, 2013, 02:50:37 PM
Actually, the linear frame buffer can also be accessed from real-mode. There's a BIOS function, Int 15h, AH=87h ( copy extended memory ) that will do the job.

I've strong doubts that this would be much faster. Instead of calling the bank switch procedure by drawing each pixel, one had to call INT 15h. Furthermore, here is a short quote form the VBE CORE FUNCTIONS VERSION 3.0, p. 38:
Quote
The PhysBasePtr is a 32-bit physical address of the start of frame buffer memory when the controller is in flat frame buffer memory mode. If this mode is not available, then this field will be zero. Note that the physical address cannot be used directly by the application, but must be translated by an operating system service to a linear address that can be used directly by the application (ie: the OS must create the page tables to map in this memory).
That means: The PhysBasePtr must be maped into the application's address space. Do you know an opportunity to do that with INT 15h?

I think the cleanest way to do that is a 32 bit DPMI client which can map the PhysBasePtr via DPMI function 800h into the program's address space; if that's properly done it has direct access to every location inside the linear frame buffer.

Sinsi,

Quote from: sinsi on August 13, 2013, 03:14:12 PM
A couple of other ways to access the linear frame buffer from "real" mode
- v86 with paging
- unreal mode / flat real mode

Please, check my above answer for Andreas. Moreover, unreal mode will only work under plain DOS, not with emulations or virtual machines. No Host OS can allow any Guest to manipulate CR0 directly. This could compromise the system security.

Quote from: sinsi on August 13, 2013, 03:14:12 PM
I would be interested to see if you can get vesa's protected mode interface working.

That's what I try to do. I think the lowest common denominator should be VBE 2.0. DOSBox and VirtualBox support that.

Marinus,

Quote from: Siekmanski on August 13, 2013, 06:43:58 PM
Available 256 color modes:

100h 101h 103h 105h 107h 130h 131h 134h 160h 162h 168h

They all work fine.
thank you for testing. I wasn't sure if it would work with Nvidia cards, but it seems to do.

Steve,

Quote from: FORTRANS on August 13, 2013, 11:55:10 PM
Hi,

   Tested on four computers.  If it supports VESA in a DOS like
environment, your program works nicely.  One laptop had
a corrupted desktop after leaving the NTVDM with Windows XP.
The other Windows XP laptop had no such problem, but I invoked
your program a bit differently.  I can test again if you want.
Two old OS/2 VDM's worked well.  Windows 2000 (dual boot)
does not support VESA for DOS programs.

Regards,

Steve N.

that would be nice. You have an OS/2 box running?

So, boys and girls: Special thank to all of you for testing and the fast answers. Take care. I've a bit VESA code to write.  :lol:

Gunther



You have to know the facts before you can distort them.

Gunther

Alex,

Quote from: Antariy on August 14, 2013, 02:48:40 AM
Here are the textual results:


Possible 256 color VESA Modes:
==============================

Mode Nr.:   X resoltion    Y resolution     Number
101h        640            480              1
103h        800            600              4
105h        1024           768              7
179h        1280           768              10
107h        1280           1024             13
120h        1600           1200             16
199h        1920           1440             19
22Eh        800            480              22


The program works fine :t

a lot of modes available with your graphics adaptor. Can you set every mode? Thanks for testing.  :t

Gunther
You have to know the facts before you can distort them.

japheth

Quote from: Gunther on August 14, 2013, 03:24:47 AM
That means: The PhysBasePtr must be maped into the application's address space. Do you know an opportunity to do that with INT 15h?

There's no need for "mapping" because Int 15h assumes all addresses to be "physical".

Actually, I didn't recommend to follow the "Int 15h"-path, I just mentioned it to make it clear that the LFB can be accessed from real-mode.




Gunther

Andreas,

Quote from: japheth on August 14, 2013, 04:14:25 AM
There's no need for "mapping" because Int 15h assumes all addresses to be "physical".

interesting, I didn't know that.

Quote from: japheth on August 14, 2013, 04:14:25 AM
Actually, I didn't recommend to follow the "Int 15h"-path, I just mentioned it to make it clear that the LFB can be accessed from real-mode.

I agree with you; DPMI is probably faster.

Gunther
You have to know the facts before you can distort them.