PROGRAMMING HACKS AND TRICKS - TIPS FOR POWER PERFORMANCE

Trick - Page flipping in 13h

Heh, this is a tricky one. The easiest way to achieve this is to get a library, such as DirectQB, and let it do the work for you. If you are one of those people who doesnt want to give other people any credit in your games then this tip will be of much help to you:

As you probably already know, everything on your screen at any time when in SCREEN 13 is stored in memory. The place in memory where all the pixels on your screen is stored is 64k big. Right, as you may already have guessed, you could make an array with 64000 elements and treat each one as a pixel. That would give you page flipping in 13h right? Wrong! The problem is qbasic wont allow you to make an array that big. What can we do? Well, remember that an integer takes up 2 bytes, and 1 byte equals 1 pixel. So if you create an array of 32000 integers, its 64000 bytes in size, and you can treat each byte as a pixel! However, to access each byte you are going to need to use PEEK and POKE! Here's some code:

DIM VScreen%(32000)  'Create the virtual screen.
DEF SEG = VARSEG(VScreen%(0))  'Change the seg to the seg of VScreen.
POKE (VARPTR(VScreen%(0)) + (y% * 320) + x%), col%  'PSET to it.
col% = PEEK(VARPTR(VScreen(0)) + (y% * 320) + x%)  'POINT from it.

It is not wise to use too many virtual screens as they take up too much memory.

Okay, so now you know how to make a virtual screen in memory and you know how to PSET to it and POINT from it. But how do you make whats on the virtual screen flip over to the real screen? Well, for this we are going to have to use some assembly. Noooooooooo you say? Yes! ASM is great for this sort of thing, and very fast! The following example program includes an asm page flipping routine, and a demonstration of how to use it:

'Example program demonstating page flipping in SCREEN 13. Written by
'Matthew R.Knight of Horizons Interactive Entertainment. Feel free to use
'this code as you wish.
DIM VS1%(32000)  'Create the 1st virtual screen.
DIM VS2%(32000)  'Create the 2nd virtual screen.

'ASM Screen page copying routine.
PageCopy$ = ""
PageCopy$ = PageCopy$ + CHR$(&H1E)                          ' PUSH DS
PageCopy$ = PageCopy$ + CHR$(&H55)                          ' PUSH BP
PageCopy$ = PageCopy$ + CHR$(&H89) + CHR$(&HE5)             ' MOV BP,SP
PageCopy$ = PageCopy$ + CHR$(&H8B) + CHR$(&H46) + CHR$(&HE) ' MOV AX,[BP+0E]
PageCopy$ = PageCopy$ + CHR$(&H8E) + CHR$(&HD8)             ' MOV DS,AX
PageCopy$ = PageCopy$ + CHR$(&H8B) + CHR$(&H76) + CHR$(&HC) ' MOV SI,[BP+0C]
PageCopy$ = PageCopy$ + CHR$(&H8B) + CHR$(&H46) + CHR$(&HA) ' MOV AX,[BP+0A]
PageCopy$ = PageCopy$ + CHR$(&H8E) + CHR$(&HC0)             ' MOV ES,AX
PageCopy$ = PageCopy$ + CHR$(&H8B) + CHR$(&H7E) + CHR$(&H8) ' MOV DI,[BP+08]
PageCopy$ = PageCopy$ + CHR$(&HB9) + CHR$(&H0) + CHR$(&H7D) ' MOV CX,7D00
PageCopy$ = PageCopy$ + CHR$(&HF3)                          ' REPZ
PageCopy$ = PageCopy$ + CHR$(&HA5)                          ' MOVSW
PageCopy$ = PageCopy$ + CHR$(&H5D)                          ' POP BP
PageCopy$ = PageCopy$ + CHR$(&H1F)                          ' POP DS
PageCopy$ = PageCopy$ + CHR$(&HCA) + CHR$(&H8) + CHR$(&H0)  ' RETF 0008

'Fill VS1%
FOR N = 0 TO 32000
VS1%(N) = N
NEXT

CLS
PRINT "VS1% Press any key..."
SLEEP
FOR N = 0 TO 32000
PRINT VS1%(N);
NEXT
PRINT
PRINT "Press any key..."
SLEEP

CLS
PRINT "VS2% Press any key..."
SLEEP
FOR N = 0 TO 32000
PRINT VS2%(N);
NEXT
PRINT
PRINT "Press any key..."
SLEEP

CLS
PRINT "Now we are going to move the contents of VS1% into VS2% via and ASM"
PRINT "routine. This involves copying all the memory allocated to VS1% to"
PRINT "VS2%. This same routine and principle could be used for page flipping"
PRINT "in SCREEN 13!!! as it copies chunks of 64K of memory!!!!  =)"
PRINT
PRINT "Press any key..."
SLEEP

FromSeg% = VARSEG(VS1%(1))
FromOff% = VARPTR(VS1%(1))
ToSeg% = VARSEG(VS2%(1))  'If you wanted to copy an array straight to the 
                          'screen then this would be = &HA000
ToOff% = VARPTR(VS2%(1))  'and this would be = 0

DEF SEG = VARSEG(PageCopy$)
CALL ABSOLUTE(BYVAL FromSeg%, BYVAL FromOff%, BYVAL ToSeg%, BYVAL ToOff%, SADD(PageCopy$))
DEF SEG

CLS
PRINT "Copying complete....Lets now see VS2% Press any key..."
SLEEP
FOR N = 0 TO 32000
PRINT VS2%(N);
NEXT

'additional testing:
PRINT
COLOR 2: PRINT "Just some additional tests:"
COLOR 4
PRINT "VS1%(0)"; VS1%(0)
PRINT "VS1%(287)"; VS1%(287)
PRINT "VS1%(288)"; VS1%(288)
PRINT "VS1%(32000)"; VS1%(32000)
COLOR 5
PRINT "VS2%(0)"; VS2%(0)
PRINT "VS2%(287)"; VS2%(287)
PRINT "VS2%(288)"; VS2%(288)
PRINT "VS2%(32000)"; VS2%(32000)
PRINT
PRINT "Press any key..."
SLEEP

CLS
COLOR 9
PRINT "So this works! Is this cool or what? Page flipping in 13h!  =)"

All you have to do to when using the above asm routine to copy a virtual screen to the actual screen is make ToSeg% = &HA000 and make ToOff% = 0. The example program above using the routine clearly shows how to copy one virtual screen to another.

Well, thats all there is to it. Now you know how to do page flipping in SCREEN 13!

Thats all the tips, hacks and tricks we have for this month. You can be sure that next month we will have twice as many for ya! ^_^

Once again, if you have any tips, hacks or tricks for us then please email them to us at horizonsqb@hotmail.com and we will print them.