I am looking for a way to write directly to the screen. It needs to work in graphics mode not text mode and in windows. If anyone can help me with this that would be great. Thanks.
Posted on 2001-09-06 16:22:18 by kbd
You could use DirectX. Which resolution do you want in the app?
Posted on 2001-09-07 00:57:14 by gliptic
Write directly to hDC (I've seen it done) or blit using GDI. Both will work but thr first is the fastest solution.
Posted on 2001-09-07 10:12:01 by Kenny
Hey Kenny, where did you see this. I've seen many others ask that question here, but never saw a satisfactory reply.

But here hopeing........;)
Posted on 2001-09-07 12:30:25 by Eóin
Ok, just for you guys I will start my research, because I kinda know the answer to this too.

I knew the answer to it before my brain surgery, but just like a lot of other things, I've completely forgotten how to do it.

Try and post a reply here asap.
Posted on 2001-09-07 12:33:39 by Kenny

What you think use hdc...
Are you able to write it directly ???
So, give me the example please...
Posted on 2001-09-07 15:10:02 by Marty
I know there is a way because I've seen it done. I think it was a fire demo or something. I have to find it again though.
Posted on 2001-09-07 15:12:10 by Kenny
You can draw directly onto the screen in Windows by passing 0
to the GetDC Function. For example (a down and dirty example):

.elseif uMsg == WM_CREATE
m2m rc.left, 0
m2m rc.top, 0
m2m rc.right, 500
m2m rc.bottom, 500

szText szName, "THIS IS SOME TEXT"
invoke GetDC, 0
push eax
pop ecx

invoke DrawText, ecx, ADDR szName, -1, addr rc, DT_LEFT

return 0

One problem with this sample is how quickly it can be drawn
over. For example if Internet Explorer is maximized it will paint
it's "disabled caption-bar" over the text when this sample runs
(...and has the focus). Normally you would do this in response to
a message of some sort.

To be safe, minimize all windows to view the sample.

Posted on 2001-09-07 15:52:44 by Xtreme
What I am really looking for is a way to write to video memory directly and have it display a pixel on the screen. Because of windows if you try to access video memory you get a protection fault. Maybe you have to be in ring 0 to do it, but this is what I am trying to find out.
Posted on 2001-09-07 16:19:45 by kbd
I think gliptic is right, the simpliest way is to use DirectDraw. It works the same way as real 0xa000 access.

while (lpDDSurf->Lock (NULL, &ddsd, 0, NULL) == DERR_WASSTILLDRAWING)

((BYTE*)ddsd.lpSurface)[y * ddsd.lPitch + x] = color;


Sorry if I don't post asm snippet, but I use C ;)
Posted on 2001-09-07 17:20:13 by LuHa
The only thing is many computer dont support direct draw so its not something I really want to use. I'm also trying to learn something, so if DirectDraw is able to access video memory there has to be a way that I can access it.

Oh and thanks everyone for your help. I really do appreciate it.
Posted on 2001-09-07 23:03:18 by kbd

I know what are you looking for..
Direct write to graphics segment a000 under win.. Thats a hard problem.. You know a000 is 16bit and windows are runing in 32bit. Kernel32.dll is 32bit, krnl386.exe is 16bit.
:alright: Krnl386.exe has many interesting functions. One of them is called _A000H. Try to look there. It is direct way... :grin:

But there is another problem. I said krnl386.exe is 16bit and you must load it. But how ? I m looking for this problem many months. In win95 was functions like as LoadLibrary16, GetProcAddress16 etc..
:mad: It isnt in win98...

So we must use method call THUNKING. Flat thunks used for link 32 - 16. But how ? I know this way only under win95. Win98 is different.

We are looking for hard problem..
So, if here is anybody to answer our problems... JUST DO IT,..

Posted on 2001-09-08 07:14:02 by Marty

I have heard something about DEATH and RESSURECTION GDI..
DisableOEMLayers etc..
This functions provides what we want... but it is in user.exe
(16 bit ..huh.)

PS: I hate windows !!!
Posted on 2001-09-08 07:16:56 by Marty
A000 is the vga framebuffer address, at physical memory location
A0000. This is only 64kb large, so clearly it's no good for high resolutions,
unless you use bank switching (which is adapter specific). All modern
cards have framebuffers at the end of the physical address space,
(mine is currently) located at C8000000. I am writing a win2k KMD
(kernel mode driver, ring0 code, similar to win9x VXD) that does
a MmMapIoSpace to map this physical address inside virtual (adressable)
space. And thus I have direct access to my graphics card framebuffer.
Haven't check it with DDraw yet, but I assume I would still have
access there. OpenGL/D3D might be a different matter, as they might
switch the adapter into some "weird" mode where the framebuffer
is interpreted differently.

And yes, this trick can be done under 9x as well.

There's some catches to this. First of all, I have no idea how to
programatically find framebuffer address and length. And you of
course also need to be able to figure out the resolution and color
depth. I also don't know if the pages are mapped in user space as
well (but it should be very well possible).

The next problem would be old crap adapters that don't support
a linear framebuffer and must work in banked mode. But if you're
clever, you can overcome this with some interesting paging and #PF
tricks. I did this in 32bit dos.
Posted on 2001-09-08 07:23:09 by f0dder
IT is VerY interesting,..

Are you able to attach examaple what you think.. source codes etc..
It will be excellent if you can..
Thanks Mr.Programmer
Posted on 2001-09-08 07:39:37 by Marty
Well, my current source is not exactly suitable for general release :).
But it's pretty simple. Open device manager, find your display adapter,
and check it's resources. It will have a some meory ranges listed,
most adapters have three ranges: A0000 - BFFFF, and two others.
For my geforce2, it's the "middle" of the three ranges that is the
framebuffer. Then, code a VXD or KMD that uses pagin to map
this range. In a KMD, it's MmMapIoSpace. Don't know/care about VXDs.
My KMD is a skeleton that does nothing more than this (well, OK,
it does a little doodling, and a MmUnmapIoSpace when it's done).

Now, you don't really want to code KMDs in assembly. It's not great
fun. You'll be dealing with 64bit numbers because of the address
space extensions we've had since the PPro core. And the whole
API that's available when developing KMDs is much more geared
towards C than assembly. And, well, sorry to say it, but assembly
isn't very important in KMDs.

Also, this method of direct screen access probably isn't very suitable
for general use. If you want general use, go for directdraw. If you
run windows, it will be supported, and it's the only clean way to
get direct screen access. Forget about GDI death/resurrection, it
is very dirty - I've only had a very quick glimpse of it and trust me,
you don't want to deal with it. If you want to overwrite the screen
without going fullscreen (ie, DDraw), use GDI. It's slow and you
don't have direct pixel access, but that's the way life is. Paint directly
into a bitmap, and use a bitblt to transfer to screen. This will be
moderately fast.

If you want to write a kernel-mode debugger, go for my approach
of mapping the framebuffer :].
Posted on 2001-09-08 08:16:07 by f0dder
To kbd:

Are you sure that there are many computers they won't served by directdraw ? I know that much work has done to develop a fast gui base for many different video-cards ! So I do not believe that there are clean other ways to do this job.

Windows is a multi-tasking-os and therefore the output of gfx to the screen is not as easy as one thought at first. If you use the gdi-routines painting onto the desktop you have to lock the areas to paint to so other running apps won't destroy this areas and windows gets knowledge about the areas which aren't allowed to draw into.

greetings, CALEB
Posted on 2001-09-08 09:55:37 by Caleb
under win9x, vxd vflatd emulates a flat frame buffer (hence the name) if there is no available. And it exports functions like VFlatD_Query to get the address of this buffer and "Begin_Linear_Access" to access this buffer. It has a device number, so part of the functions are possibly available to ring 3. But I think, nowadays you can take it for granted that directdraw is installed and use that way. There exists no device independent access "below" direct draw. And forget all about functions in krnl386.exe or gdi.exe.

Posted on 2001-09-08 12:52:20 by japheth
f0dder: could u post the source code, please ;)

i had succeed to MmMapIoSpace, but using READ_REGISTER_ULONG to read on that return address yield 0xFFFFFFFF. the doc said it is base address. hmm... what does that mean? trying to inc the addr and got same FF result :(

Posted on 2003-01-04 01:30:58 by dion
Afternoon, dion.

This thread is almost a year and a half old:grin: .

If you really are interested in the topic, and cannot find related info by searching the messageboard, then please feel free to open a new thread.

Posted on 2003-01-04 04:36:30 by Scronty