Virtual Screens, memory addressing, and more!
What is memory?
foo = 5
you're actually telling the computer to put 5 into the place in memory which has been 'given' ( or more technically, allocated ) to foo.
How do I access them in QBASIC?
DEF SEG = Segment
There, that simple! Now, let me explain in more detail. DEG SEG sets the segment to use when you use commands such as POKE and PEEK. POKE writes the value of Value to the Offset specified, and PEEK reads the value at Offset into Value. At the end we call DEF SEG again ( this time without an = after it ) to return to the default QBASIC segment ( because if we didn't then QBASIC might start writing stuff into the wrong places in memory and your computer might crash - now we wouldn't want that to happen would we? ).
101 ways to trash your PC
How to find a safe place to write to
' Get the segment of foo
Now you can change to the segment using DEF SEG, and read and write to it using PEEK and POKE! Finding the offset of the string however, is a little different. Instead of using VARPTR(), use SADD(). Note: When finding the segment and offset of an array, always tell it to find the address of element 0 eg. VARSEG(foo(0)), VARPTR(foo(0))
Saving your memory to a file -
DEF SEG = Segment
Now why would you want to do this? Well for instance, you draw a sprite for your game and you GET it. However, drawing it and getting it every time you run the program makes for ugly and big code, so you save it to file and load it up at the start of the program instead! The important thing to remember is to create an array that is the size of the sprite to load it into ( remember what I said before - that you have to allocate the memory before you can use it ). Here's an example:
DIM Sprite%(51) ' The Array to store the sprite in
OK, you might have a few questions. First, you don't need to set the segment when you use BLOAD. Usually. Secondly, about the length of memory and the size of the array ( WARNING - this is complicated. Don't read unless you're ready for a challenge ). An integer in QBASIC takes up two bytes, OK? So, as our array is 51 integers long, it takes up 104 bytes in memory. In SCREEN 13 each pixel takes up one byte in memory, so we need 100 bytes ( 10 * 10 ) for that. But what's with the extra 4 bytes? Well that's the space that QB needs to store the sprite's width etc. ( You can visit QBASIC Help for info on getting your array exactly the right size for GET - or, if you use DirectQB, use DQBsize(x1, y1, x2, y2) and divide the result by 2! )
Writing directly to video memory
First thing to warn you about, is that you should only really do this in SCREEN 13 because in other modes it's much more complicated. This is one of the reasons why SCREEN 13 is so popular - because it's easy to use.
OK, you need the segment of where the video memory is. It's at &HA000, so,
DEF SEG = &HA000
Then you need the offset. Thankfully that's 0! Right then, now we just have to write to the memory. Some of you may have recognised a problem though. Memory goes in straight lines ( 1, 2, 3, 4 etc. ), but a SCREEN is two-dimensional! So, we have to work out how to convert 2D into 1D. This is actually easy. The SCREEN info is stored in bytes 0 - 319 for the first line, 320 - 639 for the second etc. The formula to work this out is ( prove this yourself if you want to ):
Offset = (Y * 320) + X
Now you have it! You can write quickly to video memory! Here's a few lines to help you out though...
DEF SEG = &HA000
DEF SEG = &HA000 BSAVE "picture1.bsv", 0, 64000 ... BLOAD "picture1.bsv"
There! You've saved a picture, and then, very quickly loaded it up!
DIM VScreen(32000) ' Create the virtual screen
It's not wise to use too many virtual screens though as they will take up too much memory.
Back to Top