QBasic For All! > Tutorials > PEEK, POKE, Memory Management and I/O Ports
This tutorial is about writing to/reading from the computer's memory,
and I/O ports.
Use the BSAVE statement to save a part or all of the active memory segment into a file. This is how BSAVE is used:
BSAVE file name, memory address, size
The file name is the path and file name of
the file the information is stored in.
The memory address is the address in the
memory segment from which point the
information is read and saved.
The size is the number of bytes read
from the memory segment and saved.
The size can range from 0 to 65535 bytes.
BSAVE saves the part of the memory segment
literally into the file except for the 7
byte header that is added.
The header of the file is 7 bytes, this means that
the files are the size specified with 7 bytes added.
Use BLOAD to load a file created by BSAVE
into the active memory segment.
This is how BLOAD is used:
BLOAD file name, address.
The file name is the path and file name of the
file that is loaded into a memory segment.
The address is the point in memory from which
the program starts to write the information
in the file into the memory.
- Example 1:
DEF SEG = 0 BSAVE "\memory.dat", 0, 65535
- Example 2:
SCREEN 13: CLS LINE (0, 0)-(100, 200), 1, BF LINE (50, 50)-(150, 250), 2, BF DEF SEG = 40960 BSAVE "\Scrnsht.dat", 0, 65535 CLS BLOAD "\Scrnsht.dat", 0
Use the CLEAR statement to free stackspace,
close all files, erase arrays and erase all
variables. Constants are not erased.
CLS CLEAR 'Sets stackspace to standard amount of stackspace. PRINT FRE(-2) 'Display amount of free stackspace. CLEAR , , 2500 'Creates a stackspace of 2500 bytes. PRINT FRE(-2) 'Show new amount of stackspace, the number 'should be a number close to 2500.
Use the DEF SEG statement to
select a memory segment.
This is how DEF SEG is used:
DEF SEG = segment address.
Each segment is 16 bytes in size.
The segment addresses can
range from 0 to 65535.
- Example: DEF SEG = 40960
Use the FRE statement to get the amount of
free memory for strings, stack space or space
for an array in bytes.
This is how FRE is used:
Here is a list of numbers:
-1 free space for an array that is not an array for numbers.
-2 free stack space in bytes.
Any other number free memory in bytes.
CLS PRINT FRE(0) 'Display amount of free memory in bytes.
How Numbers Are Stored in Memory:
If a number is stored in memory, for example:
999 the number is not stored as a string holding
999 as value but as string of either a 2, 4 or 8
byte string. CVI, CVD, CVS and CVL can be used
to convert these strings to numbers.
CLS n = 10049Address = VARSEG(n) 'Get n's memory location.'Read two ASCII values from memory location '(PEEK does not return bytes but their ASCII values.) 'Convert the two ASCII values to a two byte string. 'Convert the two byte string to an integer and display result. PRINT CVI(CHR$(PEEK(Address)) + CHR$(PEEK(Address + 1)))
Use the INP statement to read a byte from a port.
Use the OUT statement to send a byte to a port.
See "Faster Way of Changing Palette" and
"Using INP(96) instead of INKEY$"
for other examples.
'The result of this example should be a red background. 'This example changes the color with color index '0 (=black by default) to bright red. OUT 968, 0 OUT 969, 63 OUT 969, 0 OUT 969, 0
Use the PEEK function to
get the ASCII value of a
byte in a memory segment.
This is how PEEK is used:PEEK(address)
Use the POKE statement to change
a byte in a memory segment.
This is how POKE is used:
POKE address, ASCII value of new byte
The address specified for PEEK and POKE
is the number of bytes away from the
start (=offset) of the memory segment
set using DEF SEG. The maximum range
for PEEK and POKE is 65535 bytes.
Test$ = "This is a test." 'Set the string Test$. Address = SADD(Test$) 'Store the string's address in Address. CLS PRINT PEEK(Address) 'Get and show the value at the memory address 'stored in Address,this value should be 84 '(ASCII character 84 is "T"). POKE Address, 65 'Writes value 65 to the memory location of the 'string's first letter, changing the 'letter into an "A". ASCII character 64 is "A". PRINT Test$ 'Display what is stored in Test$ 'it should be: "Ahis is a test."
Use the SADD function to get the memory
address of a string's first letter.
CLS Example$ = "This is a test." 'Create a string. PRINT SADD(Example$) 'The location of the string depends 'on things such as whether or not the SADD statement is 'used in an .EXE file. 'See the PEEK and POKE example for another example using SADD.
Use the SETMEM statement to change the size of the
far heap (=memory Quick Basic has left under the 64
kb limit where dynamic arrays are stored) or to get
the size of the far heap. SETMEM(0) returns the size
of the far heap. Any value other than zero changes
the far heap's size.
The VARPTR function returns the address
where a variable's information is stored
in memory. The first two bytes at the
address returned by VARPTR are the variable's
length, the second two bytes are the address
at which the information stored in the variable
is stored in memory.
The VARPTR$ function returns a string version of
the number VARPTR and the variable's data type.
The first byte in the string indicates the variable's
data type. The following two bytes are the address
at which the variable's information is stored.
Here is list of value's for the first
byte in the string returned by VARPTR$:ASCII value of byte: Data type indicated: 2 integer 20 long integer 4 single 8 double 3 string
To turn a number returned by VARPTR into what
would be returned by VARPTR$ use this code:CHR$(ASCII value) + MKI$(VARPTR(variable))
The VARSEG function returns the segment's
address in which a variable is stored.
- Example 1:
Example$ = "This is part of an example." CLS PRINT VARPTR(Example$) 'Display Example$'s offset. PRINT VARSEG(Example$)
- Example 2:
CLS Strng$ = "This is an example." Address = VARPTR(Strng$) Length = CVI(CHR$(PEEK(Address)) + CHR$(PEEK(Address + 1))) Address2 = CVI(CHR$(PEEK(Address + 2)) + CHR$(PEEK(Address + 3))) PRINT Length PRINT Address2 PRINT SADD(Strng$) FOR c = Address2 TO Address2 + Length - 1 PRINT CHR$(PEEK(c)); NEXT c
The WAIT statement performs some operations
on one or two numbers and a number read from a
specified port. WAIT keeps repeating this until
the result is a number with a true (non zero) value.
This is what the WAIT statement does:WAIT Port, Number1does the same as:DO PortData = INP(Port) Result = Number1 AND PortData LOOP UNTIL ResultWAIT Port, Number1, Number2does the same as:DO PortData = INP(Port) Result = PortData XOR Number2 Result = Number1 AND Result LOOP UNTIL Result
The XOR operator is only used
when the second number is specified.
The only difference between WAIT and the code
above is that the loop in the code simulating
WAIT can be left even though the Result variable
is still false. While the WAIT statement
is waiting for the operations to return a true
value the computer will not respond to any input
from the user.
This is how the WAIT statement is used:WAIT Port, Number1 or: WAIT Port, Number1, Number2
'Wait until a key is pressed. WAIT 96, 128, 128
Use the $DYNAMIC meta command to make arrays in a program dynamic,
this means that ERASE can be used to free memory and clearing arrays.
Use the $STATIC meta command to make arrays in a program static,
this means that ERASE cannot be used to free memory,
only for clearing arrays.
An apostrophe or a REM statement must be
added to the left the meta commands.
$DYNAMIC does not have to be used for small arrays.
- Example 1:
'$STATIC DIM Array(1000) CLS PRINT FRE(-1) 'Display free space for array. ERASE Array 'Clear array. PRINT FRE(-1) 'Display free space for array, this number should be 'the same as the first time FRE(-1) was used.
If you click on the link below you will find some books we have selected from amazon.com
- Example 2:
'$DYNAMIC DIM Array(1000) CLS PRINT FRE(-1) 'Display free space for array. ERASE Array 'Clear array and free memory. PRINT FRE(-1) 'Display free space for array, this number should be 'larger than the first time FRE(-1) was used.
Recommended QBasic Books
Copyright QBasic For All!
Created on 16 September 2000