Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Reading display of MSDOS program from Delphi app

76 views
Skip to first unread message

Paul E. Schoen

unread,
Aug 8, 2007, 9:47:24 PM8/8/07
to
I have figured out how to read the display memory of a separate MSDOS
program that may be running full-screen or in a DOS window in WinXP. Not
that there is usually much need for this, but I'll post the code for
comment and possible reference. I found that the display buffer is actually
located at $B8000 for a color display, and $B0000 for monochrome (MDA).
This differs from what I found in my PC Handbook (Choisser and Foster),
which showed the buffer to be $A0000 for VGA and EGA. It does show $B8000
for CGA, however.

Set up the Memo for Terminal font to display line characters properly.

Paul


Here's the working code (not optimized):

var
FmTCCtest: TFmTCCtest;
WndHandle: HWND; //HANDLE
WindowName: pchar;

implementation

{$R *.DFM}

procedure TFmTCCtest.Button1Click(Sender: TObject);
begin
WindowName := pchar(Edit1.Text);
WndHandle := FindWindow(Nil,WindowName);
if WndHandle = 0 then begin
MessageBox(0, 'Window does not exist', 'Warning', MB_ICONERROR);
Exit;
end;
end;

procedure TFmTCCtest.Button2Click(Sender: TObject);
var
hProcess: HWND; //HANDLE
lpBaseAddress: Pointer; //LPCVOID
lpBuffer: Pointer; //LPVOID
nSize: Cardinal; //DWORD
lpNumBytesRead: Cardinal; //LPDWORD
Buffer: Array[0..3999] of char;
RowStr: Array[0..81] of char;
Row, Col: Integer;

ProcID : DWord;
begin
GetWindowThreadProcessID(WndHandle,@ProcID);
hProcess := OpenProcess(PROCESS_ALL_ACCESS,False,ProcId);
try
if hProcess<>0 then begin
lpBaseAddress := Ptr($B8000);
lpBuffer := @Buffer;
nSize := SizeOf(Buffer);
ReadProcessMemory( hProcess, lpBaseAddress, lpBuffer, nSize,
lpNumBytesRead );
For Row := 1 to 25 do begin
For Col := 1 to 80 do begin
RowStr[Col-1] := Buffer[ 2*( (Row-1)*80 + (Col-1) )];
end;
RowStr[80] := chr(0);
RowStr[81] := chr(0);
Memo1.Lines.Append(RowStr);
end;
end;
finally
closehandle(hProcess);
end;
end;

procedure TFmTCCtest.FormCreate(Sender: TObject);
begin
WindowName := 'C:\DOCUME~1\ALLUSE~1\DOCUME~1\MYDOCU~1\TCC\TCC.EXE';
fmTCCtest.Edit1.Text := WindowName;
end;


Andreas Koch

unread,
Aug 9, 2007, 12:58:20 PM8/9/07
to
Paul E. Schoen wrote:
> I found that the display buffer is actually
> located at $B8000 for a color display, and $B0000 for monochrome (MDA).
> This differs from what I found in my PC Handbook (Choisser and Foster),
> which showed the buffer to be $A0000 for VGA and EGA. It does show $B8000
> for CGA, however.

Now that you mention it, i remember ;)

$A000:0 is the address for VGA GRAPHICS e.g. the pixels, not the text
characters.

Text mode uses $B800:0, on VGA and EGA.


Dr J R Stockton

unread,
Aug 9, 2007, 6:29:02 PM8/9/07
to
In comp.lang.pascal.delphi.misc message <46ba7260$0$20374$ecde5a14@news.
coretel.net>, Wed, 8 Aug 2007 21:47:24, Paul E. Schoen
<pst...@smart.net> posted:

>I have figured out how to read the display memory of a separate MSDOS
>program that may be running full-screen or in a DOS window in WinXP.

But only partially, it seems.

I'm sure the visible window can be more than 25 lines.
I'd like to think it can be more than 80 columns ... yes, it can.
I'm sure there are several possible pages.
I don't know whether mono windows remain possible.

SHOWER, SCRCATCH, and maybe others, via sig line 3, are Pascal and
contain some or all of the code to deal with such.

Given the way "DOS" windows can now scroll, you might like to consider
catching what cannot be seen.

--
(c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk DOS 3.3, 6.20; WinXP.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms & links.
PAS EXE TXT ZIP via <URL:http://www.merlyn.demon.co.uk/programs/00index.htm>
My DOS <URL:http://www.merlyn.demon.co.uk/batfiles.htm> - also batprogs.htm.

Jamie

unread,
Aug 9, 2007, 8:14:13 PM8/9/07
to
Paul E. Schoen wrote:

The $A000 was the starting of the old Graphics information.
$B800 was the character base index information where you simply
put the single character values for the Graphics display electronics
to use an on board character rom image base.


--
"I'm never wrong, once i thought i was, but was mistaken"
Real Programmers Do things like this.
http://webpages.charter.net/jamie_5

Paul E. Schoen

unread,
Aug 10, 2007, 12:25:43 AM8/10/07
to

"Andreas Koch" <nos...@kochandreas.com> wrote in message
news:f9fgjj$pa$02$1...@news.t-online.com...

Here is a snip from my old TurboC code that worked in the ancient days of
monochrome monitors and Hercules graphics cards, and at least up to EGA and
VGA. The programs written with this still work in a DOS window on Win95,
Win98, WinMe, and WinXP.

#define MONO_DISP_SEG 0xB000
#define COLOR_DISP_SEG 0xB800

void check_display()
{
int disp_cont_addr; /* Display controller address */

disp_cont_addr = peek( BIOS_DATA_SEG, VIDEO_CONT_OFFSET );

if (disp_cont_addr == 0x03d4 )
screen_seg = COLOR_DISP_SEG;
else
screen_seg = MONO_DISP_SEG;
}

And here is a utility for printing from the VGA graphics buffer. Note that
it prints 8 pixels at a time, in 80 rows, for 640 pixels. The image is
rotated on the paper:

/*****************************************************************************
The vgaprint() function prints the VGA Graphics Screen ( B/W ) on Epson
*****************************************************************************/

void vgaprint()

{
unsigned int printrow, printcol, n, offset;

if( !outprn( 0x1b ) )
return;
if( !outprn( 'A' ) )
return;
if( !outprn( 0x08 ) )
return;

for( printrow = 0; printrow <= 79; printrow++ )
{
if( !outprn( 0x1b ) )
return;
if( !outprn( 'K' ) )
return;
if( !outprn( 0xe0 ) )
return;
if( !outprn( (char)1 ) )
return;

for ( printcol = 0; printcol <= 479; printcol++ )
{
offset = 80*(479-printcol) + printrow;
if( !outprn( peekb( 0xa000, offset ) ) )
return;
}
if( !outprn( 0x0d ) )
return;
if( !outprn( 0x0a ) )
return;
if( kbhit() )
return;
}
if( !outprn( 0x0c) )
return;
}


My program does have a graphics screen, so this might be handy, but it's
not really necessary for what I'm doing.

Thanks for the input, everyone!

Paul

Maarten Wiltink

unread,
Aug 10, 2007, 5:29:49 AM8/10/07
to
"Dr J R Stockton" <j...@merlyn.demon.co.uk> wrote in message
news:v99hFgiu...@invalid.uk.co.demon.merlyn.invalid...

> In comp.lang.pascal.delphi.misc message <46ba7260$0$20374$ecde5a14@news.
> coretel.net>, Wed, 8 Aug 2007 21:47:24, Paul E. Schoen
> <pst...@smart.net> posted:

>> I have figured out how to read the display memory of a separate MSDOS
>> program that may be running full-screen or in a DOS window in WinXP.
>
> But only partially, it seems.
>
> I'm sure the visible window can be more than 25 lines.
> I'd like to think it can be more than 80 columns ... yes, it can.
> I'm sure there are several possible pages.
> I don't know whether mono windows remain possible.
>
> SHOWER, SCRCATCH, and maybe others, via sig line 3, are Pascal and
> contain some or all of the code to deal with such.
>
> Given the way "DOS" windows can now scroll, you might like to consider
> catching what cannot be seen.

I think you're confusing 'Command.com' and 'Cmd.exe' windows, that
being shorthand for executables running in the win16 subsystem emulating
DOS, and the modern character subsystem.

'Real' DOS could have 25, 43, or 50 lines, and 80 columns only. When
displaying 25 lines, a 16 pixels high font was used; displaying 50
lines switched to a half-height font. 43 Lines may have used a font
that was 11 pixels high, with 7 pixels left over, but ISTR it was a
closer fit than that.

Groetjes,
Maarten Wiltink


Hans-Peter Diettrich

unread,
Aug 10, 2007, 5:58:16 AM8/10/07
to
Maarten Wiltink wrote:

> I think you're confusing 'Command.com' and 'Cmd.exe' windows, that
> being shorthand for executables running in the win16 subsystem emulating
> DOS, and the modern character subsystem.

There may exist other kinds of DOS windows, e.g. for PIF's, and of
course the Win32 console windows, which use the conole API.


> 'Real' DOS could have 25, 43, or 50 lines, and 80 columns only.

AFAIR text mode switching was done inside the graphics card. The
available modes and the associated memory areas were depending on the
graphics card (model and mode). You remember the famous Hercules card,
which could be used with a second monitor, e.g. for debugging purposes
or "high" resolution graphics?

I also suspect that in monochrome mode a different layout of the screen
buffer memory is used, not the otherwise used interleave of character
codes and text attribute bytes. In graphics mode no character output was
supported, one had to use e.g. BGI for painting characters. And AFAIR
the lines then were stored interleaved, i.e. in two blocks of odd and
even lines of pixels.

Those were the days...

DoDi

Dr J R Stockton

unread,
Aug 10, 2007, 5:07:40 PM8/10/07
to
In comp.lang.pascal.delphi.misc message <46bc3033$0$231$e4fe...@news.xs
4all.nl>, Fri, 10 Aug 2007 11:29:49, Maarten Wiltink
<maa...@kittensandcats.net> posted:

>I think you're confusing 'Command.com' and 'Cmd.exe' windows, that
>being shorthand for executables running in the win16 subsystem emulating
>DOS, and the modern character subsystem.

It is possible that I was. But I've just checked a command.com window,
and it does what I said, having properties controls like cmd.exe ones.

>'Real' DOS could have 25, 43, or 50 lines, and 80 columns only. When
>displaying 25 lines, a 16 pixels high font was used; displaying 50
>lines switched to a half-height font. 43 Lines may have used a font
>that was 11 pixels high, with 7 pixels left over, but ISTR it was a
>closer fit than that.

It's been a long time; but I think TVTOYS for Borland's Pascal would
give more choice; ISTR 132 columns. Ralf's List, interrup.a, gives many
possibilities for various systems.

It's easy enough to read the dimensions from the $40:xx region, so the
OP might as well do that in case he ever needs it.

Certainly BP7 in any Windows DOS box and with an appropriate font is
much nicer than BP7 in DOS with available sizes.

Thinks : one should be able to have in Windows, several copies of BP7 in
DOS boxes of differing properties, all working on one job - though it
could get confusing.


CAVEAT : watch <http://www.wikicodia.com/wiki/Main_Page> in case the
originators of the current pages start on Pascal/Delphi.

--
(c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/&c., FAQqy topics & links;
<URL:http://www.merlyn.demon.co.uk/clpb-faq.txt> RAH Prins : c.l.p.b mFAQ;
<URL:ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip> Timo Salmi's Turbo Pascal FAQ.

Maarten Wiltink

unread,
Aug 11, 2007, 4:55:41 AM8/11/07
to
"Dr J R Stockton" <j...@merlyn.demon.co.uk> wrote in message
news:IrAIQXpc...@invalid.uk.co.demon.merlyn.invalid...

> In comp.lang.pascal.delphi.misc message <46bc3033$0$231$e4fe...@news.xs
> 4all.nl>, Fri, 10 Aug 2007 11:29:49, Maarten Wiltink
> <maa...@kittensandcats.net> posted:
[...]
>> 'Real' DOS could have 25, 43, or 50 lines, and 80 columns only. ...

>
> It's been a long time; but I think TVTOYS for Borland's Pascal would
> give more choice; ISTR 132 columns. Ralf's List, interrup.a, gives
> many possibilities for various systems.

Oh yes. DOS had more limitations than the hardware. I've never used
it on DOS, but when my playing with Linux happened on consoles instead
of through X when it stabilised more, I was a big fan of SVGATextMode.

Groetjes,
Maarten Wiltink


Marco van de Voort

unread,
Aug 11, 2007, 9:08:00 AM8/11/07
to
On 2007-08-10, Maarten Wiltink <maa...@kittensandcats.net> wrote:

> 'Real' DOS could have 25, 43, or 50 lines, and 80 columns only.

BAD dos programs. E.g. some trident cards had 132x60 modes, based on a 8x8
font.


Rudy Velthuis

unread,
Aug 15, 2007, 1:38:34 PM8/15/07
to
Dr J R Stockton wrote:

> I'm sure the visible window can be more than 25 lines.
> I'd like to think it can be more than 80 columns ... yes, it can.
> I'm sure there are several possible pages.
> I don't know whether mono windows remain possible.
>
> SHOWER, SCRCATCH, and maybe others, via sig line 3, are Pascal and
> contain some or all of the code to deal with such.
>
> Given the way "DOS" windows can now scroll, you might like to consider
> catching what cannot be seen.

He might consider using the Console functions in Windows. It can't be
too hard to get a handle on the current console window. Once he has
that, all Console functions should work, also the ones that can read
the console buffer.

--
Rudy Velthuis http://rvelthuis.de

"Humor is just another defense against the universe."
-- Mel Brooks (1926- )

Rudy Velthuis

unread,
Aug 15, 2007, 1:39:20 PM8/15/07
to
Maarten Wiltink wrote:

> I think you're confusing 'Command.com' and 'Cmd.exe' windows, that
> being shorthand for executables running in the win16 subsystem
> emulating DOS, and the modern character subsystem.
>
> 'Real' DOS could have 25, 43, or 50 lines, and 80 columns only.

There is no real DOS under WinXP, though.


--
Rudy Velthuis http://rvelthuis.de

"Distrust any enterprise that requires new clothes."
-- Henry David Thoreau (1817-1862)

Paul E. Schoen

unread,
Aug 15, 2007, 2:35:32 PM8/15/07
to

"Rudy Velthuis" <newsg...@rvelthuis.de> wrote in message
news:xn0f9zljh...@news.online.de...

> Dr J R Stockton wrote:
>
>> I'm sure the visible window can be more than 25 lines.
>> I'd like to think it can be more than 80 columns ... yes, it can.
>> I'm sure there are several possible pages.
>> I don't know whether mono windows remain possible.
>>
>> SHOWER, SCRCATCH, and maybe others, via sig line 3, are Pascal and
>> contain some or all of the code to deal with such.
>>
>> Given the way "DOS" windows can now scroll, you might like to consider
>> catching what cannot be seen.
>
> He might consider using the Console functions in Windows. It can't be
> too hard to get a handle on the current console window. Once he has
> that, all Console functions should work, also the ones that can read
> the console buffer.
>

The code I posted seems to work OK, and I have not needed to go any further
at this point. However, sometimes the program fails to find the window as
expressed in the edit box, and it seems to be when I have set some of the
properties for the window (such as full-screen vs window). This seems to
create a shortcut which may be another handle. If I delete the shortcut it
seems to work better. In any case, when the handle is found, the display
buffer read shows the entire text, and the program from which I may need to
get data does not have any abnormal display modes, and it would not be
resized so as to scroll. Even so, I don't think the display buffer will
change.

Thanks,

Paul


0 new messages