Returning values from a basic extension function

Anything QL Software or Programming Related.
daniel_baum
Bent Pin Expansion Port
Posts: 90
Joined: Sat Aug 26, 2017 11:58 am

Returning values from a basic extension function

Post by daniel_baum »

Hi all,

I am making (yet) another effort to learn QL assembly language programming. I am attempting to write an basic extension which contains a function and have come up against two questions which I can't find the answers to:

1) How do you return a string from a function? i have found mentions of this in various places but no actual code examples. I have so far managed to return a string of the right length, but not the right characters, so I guess I need some help.

2) How do you return a long integer? I read that you need to convert it to floating point, but I have not yet found any way to do this.

So, could someone point me to some documentation, or explain how it is done?

Thanks,

D


User avatar
NormanDunbar
Forum Moderator
Posts: 2273
Joined: Tue Dec 14, 2010 9:04 am
Location: Leeds, West Yorkshire, UK
Contact:

Re: Returning values from a basic extension function

Post by NormanDunbar »

Here: https://github.com/NormanDunbar/QLAssem ... tober-2020 There's a whole section on extending SuperBasic.

Shout if you need more help.

Cheers,
Norm.


Why do they put lightning conductors on churches?
Author of Arduino Software Internals
Author of Arduino Interrupts

No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
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 »

Hi Norm,

Your excellent book is my main source of information and has got me, as of now, to the stage where I can write some simple programs on my own. I haven't read through the entire book yet, but I intend to keep at it.

However, I couldn't find the answers to my specific questions anywhere in the book. I was unable to find an example of returning a string, and, as for returning a long integer, you say "This is a problem and the usual fix is to convert a long integer to a floating point and return that instead. This will be covered in another thrilling episode !" Does this thrilling episode exist later in the book?

Your book is a tutorial and not a reference manual. I have tried the QDOS/SMS Reference manual, which is available in multiple versions going right back to an original written by Tony Tebby. This is full of useful information, and actually describes what I am looking for, but lacks code examples. I also have "The Sinclair QDOS Companion" by Andrew Pennell, which I bought about 30 years ago. It's literally falling to bits, but does also contain useful information.

Anyway, I really appreciate the work that has obviously gone into your book, and I fully intend to work through it. However, I often get sidetracked into writing programs of my own when learning a new language, and for this I really need a some kind of task-oriented collection of example code. Does anything like this exist anywhere?

Best regards,

D.


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

Re: Returning values from a basic extension function

Post by pjw »

Many of us cut our teeth on Simon Goodwin's DIY Toolkits. His code is well documented and covers all the main aspects of toolkit development - and then some. I believe they can be found on Dilwyn's massive site.

However, you should note that he uses the old Qdos nomenclature, not that currently use by SMSQ/E.

I try not to blow my own trumpet too much, but since you ask: There are plenty of code examples on my website, Knoware.no. Go to the toolkits section and see if anything there interests you..


Per
dont be happy. worry
- ?
User avatar
NormanDunbar
Forum Moderator
Posts: 2273
Joined: Tue Dec 14, 2010 9:04 am
Location: Leeds, West Yorkshire, UK
Contact:

Re: Returning values from a basic extension function

Post by NormanDunbar »

The source code for DJToolkit is on the Sinclair QL github page at https://github.com/SinclairQL/DJToolkit, where you will findvexamples of functions returning justbabout every kind of result, including one which returns a result through its parameters not just the function result itself.

Check out "dev_name".

Thanks for the kind words about the book. Regarding "another thrilling episode" - I better check!

My QDOS Companion is also falling to bits, as are all my "Sunshine" books.


Cheers,
Norm.


Why do they put lightning conductors on churches?
Author of Arduino Software Internals
Author of Arduino Interrupts

No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
User avatar
tofro
Font of All Knowledge
Posts: 2700
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: Returning values from a basic extension function

Post by tofro »

With regards to literature, there's lots of examples in many books.
Unfortunately, there's no such thinks as StackExchange for QDOS where you can simply go and copy code from ;)

The most important difference between returning strings and returning scalar variables is: There is none - it works exactly the same way for both. But, while scalar variables are small and will typically let you get away with a bit of an untidy stack or re-use of stack (and it might even work), strings are typically much larger and will definitely require you handle the A1 stack properly.

Some things I did wrong with my first string functions:
  • Not enough A1 stack allocated, or A1 stack on an odd address: Once you now how long your string to return will be, make sure you call BV.CHRIX with the amount of memory you need for that string, including the string length word and rounded up to an even value (the string length (a1,a6) is going to point at on return needs to be on an even address). Then don't forget to actually copy your string there!
  • Once you called BV.CHRIX and extended the stack, you need to store a1 to BV.RIP(a6). It's not enough to return a1 from your S*BASIC function!
  • When you return from your function, D4 must be 1 to signal "I'm returning a string".


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
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 »

DIY Toolkit is an excellent suggestion! I knew I was forgetting something...

I remember typing some of these in from QL World, when the world was young :)

Thanks again,

D.


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 »

tofro wrote:With regards to literature, there's lots of examples in many books.
Unfortunately, there's no such thinks as StackExchange for QDOS where you can simply go and copy code from ;)

The most important difference between returning strings and returning scalar variables is: There is none - it works exactly the same way for both. But, while scalar variables are small and will typically let you get away with a bit of an untidy stack or re-use of stack (and it might even work), strings are typically much larger and will definitely require you handle the A1 stack properly.

Some things I did wrong with my first string functions:
  • Not enough A1 stack allocated, or A1 stack on an odd address: Once you now how long your string to return will be, make sure you call BV.CHRIX with the amount of memory you need for that string, including the string length word and rounded up to an even value (the string length (a1,a6) is going to point at on return needs to be on an even address). Then don't forget to actually copy your string there!
  • Once you called BV.CHRIX and extended the stack, you need to store a1 to BV.RIP(a6). It's not enough to return a1 from your S*BASIC function!
  • When you return from your function, D4 must be 1 to signal "I'm returning a string".
Thanks, I think this just about sums up what I was doing wrong...

D.


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

Re: Returning values from a basic extension function

Post by tofro »

With regards to "return a long as a QL floating point", the following might be of interest (shamelessly stolen from DIY Toolkit):

Code: Select all

* Convert D1.L into a floating point value (see December QLW)
*
return_fp move.w   d1,d4           ;D4 will be exponent
          move.l   d1,d5           ;D5 will be mantissa
          beq.s    normalised      ;Zero is a trivial case
          move.w   #2079,d4        ;First guess at exponent
          add.l    d1,d1           ;Already normalised?
          bvs.s    normalised
          subq.w   #1,d4           ;No, halve exponent weight
          move.l   d1,d5           ;Double mantissa to match
          moveq    #16,d0          ;Try a 16 bit shift
*
normalise move.l   d5,d1           ;Take copy of mantissa
          asl.l    d0,d1           ;Shift mantissa D0 places
          bvs.s    too_far         ;Overflow; must shift less
          sub.w    d0,d4           ;Correct exponent for shift
          move.l   d1,d5           ;New mantissa is more normal
too_far   asr.w    #1,d0           ;Halve shift distance
          bne.s    normalise       ;Try shift of 8, 4, 2 and 1
*
* Check there's enough space for the result: 6 bytes
*
normalised 
          moveq    #6,d1                ; No. of bytes needed
          move.w   BV.CHRIX,a0 
          jsr      (a0)
          movea.l  $58(a6),a1           ; Get safe A1 value
          subq.l   #6,a1
          move.l   a1,$58(a6)           ; Grab 6 more bytes safely
*
          move.l   d5,2(a1,a6.l)        ; Stack mantissa
          move.w   d4,0(a1,a6.l)        ; Stack exponent
          moveq    #2,d4                ; Floating point result
          bra.s    job_done
          
The code at "normalised" also shows how you properly handle extension of the a1 stack.


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
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!

D.


Post Reply