I have a machine code routine that is CALLed from Basic. It pushes A6 onto the stack at the start of the program, alters it, and then and Pops it off the stack before returning.
This is all works fine, but what if S*BASIC moves while the routine is being processed?
Will this crash the system? Or is S*Basic prevented from moving while doing a CALL command?
A6 and the CALL command
Re: A6 and the CALL command
I would guess that as long as your code doesn't call any SBASIC traps and vectors (the ones that use a6 as argument), you should be safe. Your SBASIC program as such is halted during CALL, so if your code doesn't give SBASIC a reason to move, no one else will.
Tobias
Tobias
ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
-
- Aurora
- Posts: 970
- Joined: Tue Dec 17, 2013 1:17 pm
Re: A6 and the CALL command
I don't know about SMSQ/E. But I thought that in QDOS, when a job is started, SuperBASIC moves down in memory, and the new job goes above it. Likewise if the job above SuperBASIC ends, SuperBASIC moves up.
Or have I got this all wrong?
Or have I got this all wrong?
- janbredenbeek
- Super Gold Card
- Posts: 673
- Joined: Wed Jan 21, 2015 4:54 pm
- Location: Hilversum, The Netherlands
- Contact:
Re: A6 and the CALL command
No, you're right at least with QDOS/Minerva. Under SMSQ/E and SBASIC, A6 doesn't move anymore as it points to a different memory area (I read this from a discussion that's now going on in the mailing list).Martin_Head wrote:I don't know about SMSQ/E. But I thought that in QDOS, when a job is started, SuperBASIC moves down in memory, and the new job goes above it. Likewise if the job above SuperBASIC ends, SuperBASIC moves up.
Or have I got this all wrong?
Jan.
Re: A6 and the CALL command
My first answer applied to SMSQ/E, sorry for not pointing this out.
This somehow allows you to write programs for SMSQ/E that would crash on an original QL. Whether that's acceptable or not, depends on what your program intends to do - If it cannot do the same thing on a real QL, (like high colors or other hardware), I see no point to achieve QDOS compatibility at any cost.
On a real QL, however, SBASIC tends to move all the time, as soon as the Transient Program Area needs to expand (like what happens when a new job is EXECuted) - Actually, moves appear to happen less frequently the more memory you have - So you can achieve some nice, tricky to find bugs by doing something forbidden. Thus, on a real QL, storing a6 somewhere in a SuperBASIC context or doing something like
To obtain a single register pointer to the RI stack, for example, is a no-no.
What actually happens when the system moves SuperBASIC is, in principle
Tobias
I think this says the SBASIC **job** doesn't move - The various areas that pointers from the SBASIC job into areas on the common heap point to may change, however, their value when something moves.SMSQ/E Reference Manual wrote: Note that, under SMSQ/E, the SBasic area doesn't move. If you write an extension, references thus needn't be relative to A6 during the entire processing. However, doing so will make your extension incompatible with QDOS.
This somehow allows you to write programs for SMSQ/E that would crash on an original QL. Whether that's acceptable or not, depends on what your program intends to do - If it cannot do the same thing on a real QL, (like high colors or other hardware), I see no point to achieve QDOS compatibility at any cost.
On a real QL, however, SBASIC tends to move all the time, as soon as the Transient Program Area needs to expand (like what happens when a new job is EXECuted) - Actually, moves appear to happen less frequently the more memory you have - So you can achieve some nice, tricky to find bugs by doing something forbidden. Thus, on a real QL, storing a6 somewhere in a SuperBASIC context or doing something like
Code: Select all
add.l a1, a6
What actually happens when the system moves SuperBASIC is, in principle
- the SuperBASIC job is halted, dumping the current registers (including a6) to the job header area
- SuperBASIC is moved down in memory (to lower addresses) to expand it
- the saved value of a6 is adjusted by the system
- the SuperBASIC job comes back to "run" state and has its registers restored from the job header, with a "magically changed" a6
Tobias
ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
Re: A6 and the CALL command
In SuperBASIC this is a no-no, as external circumstances may cause the area to move even as your routine is executing. Your restored a6 will then be wrong.Martin_Head wrote:I have a machine code routine that is CALLed from Basic. It pushes A6 onto the stack at the start of the program, alters it, and then and Pops it off the stack before returning.
This is all works fine, but what if S*BASIC moves while the routine is being processed?
Will this crash the system? Or is S*Basic prevented from moving while doing a CALL command?
In SBASIC (and compiled obj/tasks) no external events will move it around. However, certain calls you make within a m/c routine could cause areas within the SBASIC to move. But you initiate those calls yourself, so you will know when not to fiddle a6. Basically, you can consider a6 fixed - except around calls to a number of vectored utilities (NOT restricted to the fetching of parameters, or expanding the ri stack) when a6 should be correct on entry, and may have changed after the call.
Per
I love long walks, especially when they are taken by people who annoy me.
- Fred Allen
I love long walks, especially when they are taken by people who annoy me.
- Fred Allen
Re: A6 and the CALL command
Is a6 cached in the job header at start?
If so, you could either load it from there before ending your routine, there would be no need to stack it then either.
or could you use another address register?
If so, you could either load it from there before ending your routine, there would be no need to stack it then either.
or could you use another address register?
Re: A6 and the CALL command
In QDOS, this doesn't help. a6 can change between any two instructions (Even worse, QDOS might assume SuperBASIC is where you make a6 point to). You simply cannot use for anything else but the SuperBASIC base pointer unless you go into supervisor mode.Pr0f wrote:Is a6 cached in the job header at start?
If so, you could either load it from there before ending your routine, there would be no need to stack it then either.
Tobias
ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
-
- Aurora
- Posts: 970
- Joined: Tue Dec 17, 2013 1:17 pm
Re: A6 and the CALL command
Thanks for the replies. In the context of the routine I am referring to, I am only interested in SMSQ/E. So its not going to be a problem.
Just out of interest, Is there a good reason why A6 needs to be preserved on return from the CALL command? Why cant BASIC just insert the correct value for A6 on return from CALL?
Just out of interest, Is there a good reason why A6 needs to be preserved on return from the CALL command? Why cant BASIC just insert the correct value for A6 on return from CALL?