mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-05-05 21:33:43 +02:00
80 lines
3.0 KiB
ObjectPascal
80 lines
3.0 KiB
ObjectPascal
{ Example for : dosmemmove()
|
|
dosmemfillchar()
|
|
dosmemget()
|
|
DOS memory access
|
|
}
|
|
{ This example copies around some blocks of memory in DOS memory space.
|
|
|
|
In more detail, the program copies a string randomly to the text mode
|
|
screen. Aditionally it messes around a bit with the color attributes of
|
|
the string.
|
|
Before doing this it saves the entire screen contents to the heap and
|
|
restores it afterwards.
|
|
|
|
Some additional background:
|
|
|
|
The text screen of a VGA card has it's address space at $B800:0; screen
|
|
memory is organized in a linear fashion, e.g. the second line comes
|
|
directly after the first, where each cell occupies 2 bytes of memory
|
|
(1 byte character data, 1 byte attributes). It is 32 kb in size.
|
|
|
|
Hence the offset of a single memory cell from its origin is:
|
|
|
|
Y*columns*2 + X*2
|
|
|
|
where X and Y mark the point and columns is the number of character cells
|
|
per line
|
|
}
|
|
|
|
uses crt, { keypressed(), gotoxy(), randomize(), random(), wherex(),
|
|
wherey() }
|
|
go32;
|
|
|
|
const columns = 80; { number of columns on screen }
|
|
rows = 25; { number of rows on screen }
|
|
screensize = rows*columns*2;
|
|
|
|
text = '! Hello world !'; { sample text string }
|
|
|
|
var textofs : Longint;
|
|
save_screen : array[0..screensize-1] of byte; { this variable holds the
|
|
entire screen contents }
|
|
curx, cury : Integer; { These two hold the previous cursor coordinates }
|
|
|
|
begin
|
|
randomize;
|
|
{ save screen contents to save_screen variable }
|
|
dosmemget($B800, 0, save_screen, screensize);
|
|
{ save current cursor coordinates }
|
|
curx := wherex; cury := wherey;
|
|
{ This is our demo text }
|
|
gotoxy(1, 1); Write(text);
|
|
{ calculate the address in offscreen memory (to be sure it won't be over
|
|
written by the copy process later, we don't put it exactly at the end
|
|
of the visible screen area) }
|
|
textofs := screensize + length(text)*2;
|
|
{ copy it to offscreen memory }
|
|
dosmemmove($B800, 0, $B800, textofs, length(text)*2);
|
|
{ clear the screen by writing zeros on the whole visible screen }
|
|
dosmemfillchar($B800, 0, screensize, #0);
|
|
while (not keypressed) do begin
|
|
{ set the attribute field (byte 2 of every cell) of the text in
|
|
offscreen memory to random values }
|
|
dosmemfillchar($B800, textofs + random(length(text))*2 + 1,
|
|
1, char(random(255)));
|
|
{ copy the string from offscreen to visibly screen by calculating
|
|
it's destination address randomly }
|
|
dosmemmove($B800, textofs,
|
|
$B800, random(columns)*2+random(rows)*columns*2,
|
|
length(text)*2);
|
|
{ small delay, else it is too fast (remove it if you want...) }
|
|
delay(1);
|
|
end;
|
|
{ clear the keyboard buffer }
|
|
readkey;
|
|
{ wait for a keypress }
|
|
readkey;
|
|
{ restore old screen contents afterwards }
|
|
dosmemput($B800, 0, save_screen, screensize);
|
|
gotoxy(curx, cury);
|
|
end. |