10 REMark Get pointer to System Variables
20 IF VER$ = 'JSL' OR VER$ = 'HBA' THEN
30 SYSV = VER$(-2): REMark Minerva/SMSQ/E
40 ELSE
50 REMark QDOS
60 SYSV = 163840: REMark $28000
70 END IF
80 :
90 :
100 PRINT FindKey("scr_xlim")
..
..
1000 DEFine FuNction FindKey(k$)
1010 LOCal i, n, o, a6, c, s
1020 LOCal l%, k%
1030 REMark GLOBal SYSV
1040 :
1050 REMark Get job#0's JCB
1060 s = PEEK_L(PEEK_L(SYSV + 104)): REMark $68
1070 REMark Get job#0's a6
1080 a6 = PEEK_L(s + 88): REMark $58
1090 :
1100 REMark Some GLOBal definitions
1110 sb_nmtbb = a6 + 24: REMark $18
1120 sb_nmtbp = a6 + 28: REMark $1C
1130 sb_nmlsb = a6 + 32: REMark $20
1140 :
1150 REMark Size of Name Table
1160 c = PEEK_L(sb_nmtbp) - PEEK_L(sb_nmtbb)
1170 :
1180 k% = LEN(k$)
1190 REMark Go through list
1200 FOR n = 0 TO c STEP 8
1210 :
1220 REMark Weed out non-keywords: REMark $800
1230 IF PEEK_W(PEEK_L(sb_nmtbb) + a6 + n) < 2048: NEXT n: EXIT n
1240 :
1250 REMark Get offset in Name List
1260 o = PEEK_W(PEEK_L(sb_nmtbb) + a6 + n + 2)
1270 :
1280 REMark Skip no names
1290 IF o < 0: NEXT n: EXIT n
1300 :
1310 REMark Get Name length
1320 l% = PEEK(PEEK_L(sb_nmlsb) + a6 + o)
1330 :
1340 REMark For slow QLs
1350 IF l% <> k%: NEXT n: EXIT n
1360 REMark Compare strings
1370 FOR i = 1 TO l%
1380 IF NOT CHR$(PEEK(PEEK_L(sb_nmlsb) + a6 + o + i)) == k$(i): l% = 0: EXIT i
1390 END FOR i
1400 IF l% > 0: RETurn 1: REMark Bingo!
1410 END FOR n
1420 RETurn 0
1430 END DEFine FindKey
1440 :
Yes, Im aware that it is a bit nasty, but if used in the right context it should be quite safe. I wrote up my research on this in a short article for the Quantum Technology website (http://www.hunggartorino.it/ql/language/en/) some weeks ago, but it hasnt appeared yet, as its awaiting translation into Italian..
Per
I love long walks, especially when they are taken by people who annoy me.
- Fred Allen
Per,
don't see a lot of nasties in your code except that you seem to be ignoring the fact that a6 can change at any time, and will on memory-restricted machines. One of the downsides of BASIC is that you cannot go into supervisor mode
wide% = 512 : high% = 256
IF CHECK("SCR_XLIM") = 1 THEN
wide% = SCR_XLIM : high% = SCR_YLIM
END IF
I seem to recall that early Sinclair ROMs have a bug/feature (call it a feature if Tony Tebby is listening!) whereby the stack isn't tidied up after use of VER$ in an expression, so for AH/JM (not sure about JS) it might be better to do something like this if the program is likely to be used on early rom versions. It's all explained in Simon Goodwin and Mark Knight's articles on ROM bugs.
tofro wrote:Per,
don't see a lot of nasties in your code except that you seem to be ignoring the fact that a6 can change at any time, and will on memory-restricted machines. One of the downsides of BASIC is that you cannot go into supervisor mode
Well, that IS the nasty bit However, as I mentioned, if it is used in the right context it should be ok. The worst that can happen is that one gets a wrong answer once in a blue moon. The nitty-gritty is explained in the mentioned article, which is expected to appear one day (in Italian AND English).
Per
I love long walks, especially when they are taken by people who annoy me.
- Fred Allen
wide% = 512 : high% = 256
IF CHECK("SCR_XLIM") = 1 THEN
wide% = SCR_XLIM : high% = SCR_YLIM
END IF
But Dilwyn, how to CHECK if the CHECK keyword is loaded? After Id written a tiny m/c toolkit to do the job in the proper fashion, this chicken/egg conundrum struck me. And my solution was the function I submitted above. It was designed to go into a QDOS boot file. At that point not much else is going on in the machine that is likely to shift SuperBASIC around, and if the boot script itself loads stuff that causes that to happen, it wont be running the FindKey function at the same time..
I seem to recall that early Sinclair ROMs have a bug/feature (call it a feature if Tony Tebby is listening!) whereby the stack isn't tidied up after use of VER$ in an expression, so for AH/JM (not sure about JS) it might be better to do something like this if the program is likely to be used on early rom versions. It's all explained in Simon Goodwin and Mark Knight's articles on ROM bugs.
If I ever was aware of that, I have forgotten. I shall put your workaround in any next version. Thanks.
However, for reasons of sanity, I consider JS to be a baseline, below which I dont loose any sleep over.
BTW, line 20 of Per's example, is Minerva a VER$ of "JSL1"? (unsure from memory)
Yup.
Per
I love long walks, especially when they are taken by people who annoy me.
- Fred Allen
pjw wrote:
But Dilwyn, how to CHECK if the CHECK keyword is loaded? After Id written a tiny m/c toolkit to do the job in the proper fashion, this chicken/egg conundrum struck me. And my solution was the function I submitted above. It was designed to go into a QDOS boot file. At that point not much else is going on in the machine that is likely to shift SuperBASIC around, and if the boot script itself loads stuff that causes that to happen, it wont be running the FindKey function at the same time..
That's why I said "As an alternative, for anyone using DJToolkit" as I do in virtually all my released programs.