mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-31 16:11:33 +01: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. | 
