Returning values from a basic extension function

Anything QL Software or Programming Related.
User avatar
dilwyn
Mr QL
Posts: 2761
Joined: Wed Dec 01, 2010 10:39 pm

Re: Returning values from a basic extension function

Post by dilwyn »

Several of the toolkits on my Toolkits page include assembler sources which can be used as examples.

DIY toolkit has already been mentioned and I learned a lot from Simon's articles.

To extract system information, I'd suggest looking at my own Display Code extensions set, which is heavily commented. And Norman's DJTK. Norman's is more comprehensive, while mine may be easier to start with as the assembler is shorter.

www.dilwyn.me.uk/tk/


martyn_hill
Aurora
Posts: 932
Joined: Sat Oct 25, 2014 9:53 am

Re: Returning values from a basic extension function

Post by martyn_hill »

Hi Daniel!

As well as those terrific examples already cited, getting a good grasp of how the QDOS Maths-stack (usually referred to as the 'RI' stack) needs to be cared-for is well worth the study.

Of all the references I've trawled in the past, I found Mr Dunbar's essay on the Maths stack to be the most comprehensible - you can find it here:

http://www.dilwyn.me.uk/docs/articles/stack.zip

Once you've written a couple of functions, you'll end up copying and pasting your own subroutines in future projects and soon forget all the details...

In the end it's all about 'balance'. :-)


User avatar
mk79
QL Wafer Drive
Posts: 1349
Joined: Sun Feb 02, 2014 10:54 am
Location: Esslingen/Germany
Contact:

Re: Returning values from a basic extension function

Post by mk79 »

The whole SMSQ/E source code is open, included are the sources of TK2 and, most of all, Tony Tebby's SBASIC assembler libraries (sbsext_utq_lib). Then the "return long as FP" problem reduces itself to

Code: Select all

	move.l #$12345678,d1
	jmp	 ut_rtint
Or returning a string (when it's in A1) becomes

Code: Select all

	jmp	ut_rtstr
For every other case just think of an existing basic command that does what you want to do and look up its source code.

To do this you must be able to link to the library. The easiest way is to write a link file and give that to QLink, that does the rest. A relatively easy example on how to do that is my channel toolkit from https://www.kilgus.net/smsqe/sbasic-toolkits/. Edit the link file to adjust the paths and then give it to QLink, it will assembly and link everything together.

Cheers, Marcel


daniel_baum
Bent Pin Expansion Port
Posts: 90
Joined: Sat Aug 26, 2017 11:58 am

Re: Returning values from a basic extension function

Post by daniel_baum »

Thanks everyone for the suggestions. Following them, I have actually been able to write an (as yet small and useless) basic extension that returns a string :)
martyn_hill wrote:
Once you've written a couple of functions, you'll end up copying and pasting your own subroutines in future projects and soon forget all the details...
Absolutely, I am actually trying to write each one of the problems that I solve into a reusable subroutine, so that I don't have to solve it again...

mk79 wrote:The whole SMSQ/E source code is open, included are the sources of TK2 and, most of all, Tony Tebby's SBASIC assembler libraries (sbsext_utq_lib). Then the "return long as FP" problem reduces itself to

Code: Select all

	move.l #$12345678,d1
	jmp	 ut_rtint
Or returning a string (when it's in A1) becomes

Code: Select all

	jmp	ut_rtstr
For every other case just think of an existing basic command that does what you want to do and look up its source code.

To do this you must be able to link to the library. The easiest way is to write a link file and give that to QLink, that does the rest. A relatively easy example on how to do that is my channel toolkit from https://www.kilgus.net/smsqe/sbasic-toolkits/. Edit the link file to adjust the paths and then give it to QLink, it will assembly and link everything together.

Cheers, Marcel
I like this idea a lot; I definitely will be looking into it.

Thanks again to everyone for the help,

D.


User avatar
pjw
QL Wafer Drive
Posts: 1315
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: Returning values from a basic extension function

Post by pjw »

[quote="tofro"]<>

Code: Select all

normalised 
          moveq    #6,d1                ; No. of bytes needed
          move.w   BV.CHRIX,a0 
          jsr      (a0)
<>
A point though: There appears to be some confusion over the BV.CHRIX/qa.resri call. Some versions of the Qdos - SMSQ/E Reference state that the call must be made with a1 -> RI stack (rel a6). There is no mention of it in the original QL Technical Guide AFAICS. Im pretty sure I investigated the matter once and found it to be unnecessary, ie a documentation error, which I reported to the Registrar. Yet the most recent version of the guide has been corrected to say that yes, a1 must point to the RI stack but this only applies to Qdos, not SMSQ/E.

IF that is the case, the routine above is potentially unsafe under Qdos. I suspect,
however, that the documentation is at fault. Does anyone know for sure?


Per
dont be happy. worry
- ?
User avatar
tofro
Font of All Knowledge
Posts: 2702
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Returning values from a basic extension function

Post by tofro »

pjw wrote:
tofro wrote:<>

Code: Select all

normalised 
          moveq    #6,d1                ; No. of bytes needed
          move.w   BV.CHRIX,a0 
          jsr      (a0)
<>
A point though: There appears to be some confusion over the BV.CHRIX/qa.resri call. Some versions of the Qdos - SMSQ/E Reference state that the call must be made with a1 -> RI stack (rel a6). There is no mention of it in the original QL Technical Guide AFAICS. Im pretty sure I investigated the matter once and found it to be unnecessary, ie a documentation error, which I reported to the Registrar. Yet the most recent version of the guide has been corrected to say that yes, a1 must point to the RI stack but this only applies to Qdos, not SMSQ/E.

IF that is the case, the routine above is potentially unsafe under Qdos. I suspect,
however, that the documentation is at fault. Does anyone know for sure?
Per,
The Technical Guide indeed doesn't say (a6,a1) needs to point to the RI stack when this call is made. I once had a very quick look at the JS disassembly, and there (didn't check other ROM versions), this call doesn't seem to need this condition (pretty early in the call, it smashes a1 anyways and uses BV.RIP to retrieve the RI pointer). I'd say it doesn't hurt to have a1 point to RI, but isn't necessary on QDOS as well (at least for JS). Minerva doesn't seem to care about the value of a1 as well.

What the TG indeed says is that BV.RIP must be the current value of the RI pointer when the call is made - So, if you've been messing with the RI stack and a1 is different from BV.RIP when the call is made for some reason (which is a perfectly valid situation), first update BV.RIP from a1.

All in all: Basic extensions should leave a6 (special care on this) and a1 alone, if possible and only modify a1 if you know what you're doing. There's quite a number of pitfalls to be avoided here.


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
User avatar
pjw
QL Wafer Drive
Posts: 1315
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: Returning values from a basic extension function

Post by pjw »

Hi Tobias,
My point was that the current manual (Qdos / SMS Reference Manual V 4.5) appears to be wrong. I pointed out the matter to Wolfgang and he corrected it in that rather specific way, ie applies to Qdos only. I believe I only looked at SMSQ/E and JS, possibly Minerva. Perhaps he knows something about this that we dont. I guess I should take it up with him rather than litigate it here, its just that Im rather distracted with other things right now (like Linux and SMSQ effing keyboard tables!).


Per
dont be happy. worry
- ?
User avatar
tofro
Font of All Knowledge
Posts: 2702
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Returning values from a basic extension function

Post by tofro »

Per,

well, a1 pointing to the RI stack when calling BV.CHRIX definitely doesn't hurt. So I'm really not sure any further discussion is worth the hassle, (or, is rather academic). In my own S*BASIC extensions, I have a1 always pointing there - Not because I think it's necessary under all conditions, but because it's convenient.

Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
User avatar
mk79
QL Wafer Drive
Posts: 1349
Joined: Sun Feb 02, 2014 10:54 am
Location: Esslingen/Germany
Contact:

Re: Returning values from a basic extension function

Post by mk79 »

pjw wrote:Hi Tobias,
My point was that the current manual (Qdos / SMS Reference Manual V 4.5) appears to be wrong. I pointed out the matter to Wolfgang and he corrected it in that rather specific way, ie applies to Qdos only. I believe I only looked at SMSQ/E and JS, possibly Minerva. Perhaps he knows something about this that we dont. I guess I should take it up with him rather than litigate it here, its just that Im rather distracted with other things right now (like Linux and SMSQ effing keyboard tables!).
This is how TT calls it (ut_chkri):

Code: Select all

        move.w  bv..chrix,a1
        jsr     (a1)
I think it's save to say that A1 is not needed on calling it or TK2 wouldn't work...


User avatar
tofro
Font of All Knowledge
Posts: 2702
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Returning values from a basic extension function

Post by tofro »

mk79 wrote:
pjw wrote:Hi Tobias,
My point was that the current manual (Qdos / SMS Reference Manual V 4.5) appears to be wrong. I pointed out the matter to Wolfgang and he corrected it in that rather specific way, ie applies to Qdos only. I believe I only looked at SMSQ/E and JS, possibly Minerva. Perhaps he knows something about this that we dont. I guess I should take it up with him rather than litigate it here, its just that Im rather distracted with other things right now (like Linux and SMSQ effing keyboard tables!).
This is how TT calls it (ut_chkri):

Code: Select all

        move.w  bv..chrix,a1
        jsr     (a1)
I think it's save to say that A1 is not needed on calling it or TK2 wouldn't work...
Well, here it is needed on calling it. :D

But it's save to say it doesn't need to point to the RI stack. Thanks, that is probably a definite proof.


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
Post Reply