November 24th, 1999



Secret ASM tricks for QB

Hello people!

Since I am about to totally retire from the QB scene, 4 years of QB is about enough for me, I thought I should pass this knowledge on to the who ever wants to follow my footsteps. This is "secret" information that I've gathered through trial and error, disassembly and a little bit of common sense. But first allow me:

If you...
1. dont know asm
2. dont know what the hell I am talking about
3. dont know how to apply this info
4. ever need help with this
5. intend to use this information to produce yet another bad product
6. wont put my name in the credits (yes I can tell!)
...then scroll down to the next article!

I assume you use MASM, the commercial version, not the free one, and you know your way around rarely used meta commands. And I assume that you have all basic info on parameter passing etc.

Some of these functions doesnt necessarily work in a .QLB, some may require linking while compiling. I assume you know how to do that.

RETRIEVE DEF SEG SEGMENT

First trick is how to retrieve the DEF SEG'ed segment. A version can be found in the excellent ABC packets, that i submitted ages ago.

Note: I have found this to work in quick libraries!

First, declare the global (DGROUP) segment that QB uses. This is common to use in all functions to use that retrieves this info. Without it the linker wouldnt know what you are talking about.

CODE  SEGMENT WORD PUBLIC USE16 'CODE'
CODE  ENDS

_BSS  SEGMENT WORD PUBLIC USE16 'DATA'
_BSS  ENDS

_DATA SEGMENT WORD PUBLIC USE16 'DATA'
_DATA ENDS


DGROUP  GROUP _BSS

EXTRN   b$seg:WORD	; Tell linker we want to use this variable.
PUBLIC	MyRoutine	; Tell linker here is our routine

CODE SEGMENT
MyRoutine:
	mov ax, b$seg
	retf
CODE ENDS
END

Now declare in a basic file

DECLARE FUNCTION MyRoutine AS INTEGER

DEF SEG = &HA000
a% = MyRoutine
PRINT HEX$(a%)

a% should now be &HA000. It worked for me!

RETRIEVE VARIOUS SCREEN INFO

Second trick, how to retrieve the current screen mode information. This one is basically like the above, except a different variable.

* Warning * This does not work in a Quick library!

[ same as above ]

EXTRN b$ScreenMode:BYTE			; Current screen mode  (0,..,13)
EXTRN b$HorzRes:WORD			; Horizontal resolution (320,..,640)
EXTRN b$VertRes:WORD			; Vertical resolution (200,..,480)
EXTRN b$CharColor:BYTE			; Character color
EXTRN b$BFColors:WORD			; Character colors e.x:
					; AH = Background, AL = Foreground
EXTRN b$ForeColor:BYTE			; Character foreground color
EXTRN b$BackColor:BYTE			; Character background color

b$CharColor is a "special" case compared to the others above. The highnibble is the background color, the lownibble is foreground. The funny thing is, b$BackColor has the background color too, but no extra twiddling is necessary, and b$ForeColor has the foreground color. The use of b$CharColor is primarily assembly usage, as it requires shifting etc. To convert Foreground, Background colors to b$CharColor do this:

(Background*2^4)+ForeGround

Or in assembly terms:

mov al, Background
shl al, 4
xor al, Foreground

That is all for now, time prohibits me from writing more, but if I get any positive feedback or time, I will write about more, and only for QB on Acid!

This article is copyrighted by Sten Daniel Sørsdal, 1999.
You may not publish or copy this without my expressed written permission!