>I've been trying to use SET out of a compiled QBasic routine that increments a counter each time the sytem boots (or the .exe runs) but that doesn't seem to be possible when the OS is WinXP.
I don't think it would work in DOS either. Each program gets its own environment block. Using SET within the qbasic program modifies its own environment block, which is lost when it terminates.
>Can I get errorlevels out of a compiled QBasic program?
I don't know of any "correct" way of getting a qbasic program to return a return code.
The way for a C program to do so is by returning an int value from the main function.
The way for a DOS program to do so is with a call to Int 0x21, function 0x4c.
The way for a Windows program to do so is with a call to ExitProcess.
The following demonstrates a way of getting an error code out of qbasic, but it is *not the correct way*:
'This successfully returns a return code, but is likely to crash the next
'DOS program that runs.
DIM code AS STRING * 5
DIM returncode AS INTEGER
returncode = 5 'must be in range of 0 to 255
code = CHR$(&HB8) + MKL$(&H21CD4C00 OR returncode)
DEF SEG = VARSEG(code)
That successfully returns a return code by terminating qbasic with a call to Int 0x21, function 0x4c. The problem, I think, is that qbasic has probably installed its own interrupt handler for the keyboard, or something, so the NTVDM instance is left in an unstable condition. Perhaps someone with more low level qbasic knowledge (Artelius, perhaps?) could figure out a way of restoring the correct interrupt handlers before terminating.
If you really need to use return codes, I think it would be better to dispense with qbasic, and use assembly or C.
Why do you need return codes? Are you acting on the value within a batch file? If so, perhaps you could use a setup like this:
qbasic /run retcode2
In case you don't want to download Nasm:
---------- retcode2.com (12 bytes) hex values:
BA 00 B8 8E DA B4 4C A0 00 00 CD 21
This works by the qbasic program clearing the screen, and storing the return value in the first byte of VGA text mode memory. The .com program retrieves it from there, and uses it as a return code when it terminates.
I might take a stab at writing an assembly program that will do the file I/O itself, but no guarantees (I am inexperienced with file I/O in assembly).