[comp.sys.ibm.pc.programmer] reading directly from screen

person@plains.UUCP (Brett G. Person) (03/23/90)

How do I make Microsoft C read directly from video memory.  I need to 
access the memory starting from b800.

What does the c code that allows me to do this look like?
-- 
Brett G. Person
North Dakota State University
uunet!plains!person | person@plains.bitnet | person@plains.nodak.edu

everett@hpcvlx.cv.hp.com (Everett Kaser) (03/24/90)

Reading/writing the alpha screen from C is pretty trivial, actually.  Set up
a far pointer with the address 0xb800:0x0000, and then use it like any other
pointer to read/write memory.  NOTE: on the old CGA displays, this will cause
snow (only a visual problem, the code still works).

unsigned char far *disp = 0xb8000000L;
int	i;

/* to clear the display, for instance */

for(i=0; i<25*80*2; i++) {
	*(disp + i++) = '\0';	/* write character byte, null char */
	*(disp + i) = 0x0f;	/* write attribute byte, white on black */
}

I'm sure I've got a mistake in there somewhere, and I'm sure someone will point
it out :-).

Everett Kaser                   Hewlett-Packard Company
...hplabs!hp-pcd!everett        work: (503) 750-3569   Corvallis, Oregon
everett%hpcvlx@hplabs.hp.com    home: (503) 928-5259   Albany, Oregon

shap@bunker.UUCP (Joseph D. Shapiro) (03/24/90)

In article <3850@plains.UUCP> person@plains.UUCP (Brett G. Person) writes:
>How do I make Microsoft C read directly from video memory.  I need to 
>access the memory starting from b800.
>
>What does the c code that allows me to do this look like?

I do it all the time:

	typedef far char farchar;
	farchar *p;
	char c;

	p = (farchar *)(0xb8000000L);
	c = *p;
-- 
__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__
Joe Shapiro					"My other car is a turbo...
ISC-Bunker Ramo     				 ...too."
{decvax,yale,philabs,oliveb}!bunker!shap

zmact61@doc.ic.ac.uk (D Spinellis) (03/24/90)

In article <3850@plains.UUCP> person@plains.UUCP (Brett G. Person) writes:
>
>How do I make Microsoft C read directly from video memory.  I need to 
>access the memory starting from b800.
>
>What does the c code that allows me to do this look like?

It looks like this:

/*
 * Read a byte from video memory starting at b800.
 * Location is the offset in the video RAM.
 */
char
readbyte(int location)
{
	return *(location + (char far *)(0xb8000000l));
}

Diomidis
--
Diomidis Spinellis                  Internet:                 dds@cc.ic.ac.uk
Department of Computing             UUCP:                    ...!ukc!iccc!dds
Imperial College                    JANET:                    dds@uk.ac.ic.cc
London SW7 2BZ                      #include "/dev/tty"

cs4g6ag@maccs.dcss.mcmaster.ca (Stephen M. Dunn) (03/24/90)

In article <3850@plains.UUCP> person@plains.UUCP (Brett G. Person) writes:
$How do I make Microsoft C read directly from video memory.  I need to 
$access the memory starting from b800.
$What does the c code that allows me to do this look like?

   You make a far pointer to an integer and set it to point to 0xb8000000.
The ith word of display memory is then (let's say your pointer is called
foo) *(foo + i), where the high byte is the attribute and the low byte is
the character.

   MSC may have similar functions to Turbo C's gettext () and puttext ()
that allow you to save and restore rectangular chunks of text, if that's
all you need to do.

   Also, please note that code written using your assumption that video
memory starts at b800 will not work on monochrome systems, and also may
not work on the occasional PC whose user has selected a display page
other than the first.  It would be a good idea to find out exactly
where the video memory is before trying to access it.
-- 
Stephen M. Dunn                               cs4g6ag@maccs.dcss.mcmaster.ca
          <std_disclaimer.h> = "\nI'm only an undergraduate!!!\n";
****************************************************************************
    "So sorry, I never meant to break your heart ... but you broke mine."

stever@Octopus.COM (Steve Resnick ) (03/27/90)

In article <3850@plains.UUCP> person@plains.UUCP (Brett G. Person) writes:
>
>How do I make Microsoft C read directly from video memory.  I need to 
>access the memory starting from b800.
>
>What does the c code that allows me to do this look like?
>-- 
>Brett G. Person
>North Dakota State University
>uunet!plains!person | person@plains.bitnet | person@plains.nodak.edu

This routine will read the characters on the video display at Row,Col.
The characters are stored in Buffer up to count characters.

The video ram is organized in char/attr pairs.
The Row/Col paramters are one based to the top left corner is 1,1.

#include <dos.h>
readscreen(char *Buffer, int Row, int Col, int Count)
{
	char far * Video;
	Video = MK_FP(0xB800,(((Row-1)*160)+(Col*2)))
	while(Count--)
	{
		*Buffer++ = *Video;
		*Video += 2;
	}
}
Hope this helps.....
Steve

 

ho@fergvax.unl.edu (Tiny Bubbles...) (04/11/90)

From article <399@techbook.UUCP>, by paulb@techbook.UUCP (Paul Buder):
>>In article <3850@plains.UUCP> person@plains.UUCP (Brett G. Person) writes:
>>>How do I make Microsoft C read directly from video memory.  I need to 
>>>access the memory starting from b800.
> 
> [...] How about the simple solution:
> 
> char (far *screen)[80][2]=(char (far *)[80][2])0xb8000000;
> 
> Then to read the character at the 4th row, 10th column:
> ch=screen[4][10][0];


Trouble with this might be that on EGA systems, if I'm not mistaken, it
is possible to move the "beginning" of display memory, such that it is
no longer at segment 0xb800.

I think it would require a couple of EGA BIOS calls to determine that.
I'm betting the VGA is even more flexible ("confusing"), but as I don't
have access to a VGA card, I can't speculate.
---
        ... Michael Ho, University of Nebraska
Internet: ho@hoss.unl.edu

toma@tekgvs.LABS.TEK.COM (Tom Almy) (04/13/90)

In article <2724@unocss.unomaha.edu> ho@fergvax.unl.edu writes:
>Trouble with this might be that on EGA systems, if I'm not mistaken, it
>is possible to move the "beginning" of display memory, such that it is
>no longer at segment 0xb800.

True! My NNANSI.SYS and FANSI-CONSOLE and perhaps others do just this to
get fast scrolling. I do intercept several BIOS calls and reset the 
offset if I detect that a program probably will be wanting to access the
display directly (FANSI-CONSOLE does the same thing, but different calls).
For instance, enquiring the display mode resets the offset because there is
no reason to check the mode unless you want to display directly.

>I think it would require a couple of EGA BIOS calls to determine that.
>I'm betting the VGA is even more flexible ("confusing"), but as I don't
>have access to a VGA card, I can't speculate.

VGA is the same. And on both you can get the information out of low memory.
You will also want to know the number of columns and lines on the display.

40:4A -- word with number of columns
40:4E -- ofset into segment for start of display
40:84 -- byte with number of rows - 1

Tom Almy
toma@tekgvs.labs.tek.com
Standard Disclaimers Apply

cs4g6ag@maccs.dcss.mcmaster.ca (Stephen M. Dunn) (04/13/90)

In article <2724@unocss.unomaha.edu> ho@fergvax.unl.edu writes:
$Trouble with this might be that on EGA systems, if I'm not mistaken, it
$is possible to move the "beginning" of display memory, such that it is
$no longer at segment 0xb800.

   In fact, on CGA and Hercules systems as well, there is no guarantee
that the current display page starts at segment B800 (CGA) or B000 (Herc).
These cards have the ability to maintain multiple text pages, one of which
is displayed at any time.  I've never met a system that was running with
the text screen anywhere other than B800 or B000, but I'm sure there
are some programs out there that leave the card using a different page.

   The moral of this story is that you should not assume that the
display page is at a given address ... instead, have your program
initially test several likely locations (start with B000 and B800,
and if these fail, try others nearby) by noting their original contents,
printing something, and seeing if they change accordingly.
-- 
               More half-baked ideas from the oven of:
****************************************************************************
Stephen M. Dunn                               cs4g6ag@maccs.dcss.mcmaster.ca
     <std_disclaimer.h> = "\nI'm only an undergraduate ... for now!\n";