Subroutines written in ASB are written and compiled just like normal ASB programs, except for a few differences. The first is that after compiling (which you must do with the /X:2 option), you must change the extension from RUN to SBX; better yet, use the ++PRAGMA SBX which automatically creates an SBX instead of a RUN. The extension "SBX" was chosen, rather than SBR, to eliminate confusion between machine language SBRs or XBRs for AMOS and ASB SBXs for A-Shell, particularly for dealers that distribute their application on both AMOS and non-AMOS platforms. The search path for SBXs is the same as that for RUN programs (i.e. current [p,pn], [p,0], BAS:), unless the system parameter OPTIONS=SBX_RUNDIR is set, in which case the [p,0] part of the search path is replaced with the location whence the current RUN file was loaded.
Because of the SBX extension used by subroutines written in ASB, these routines are often referred to, elsewhere in this document or in other documents, as SBX Modules or SBX Routines or simples SBXes.
The biggest difference has to do with parameter passing. Standard RUN programs do not receive parameters, except via the command line or via some indirect method (such as COMMON or a shared file.) Subroutines, on the other hand, generally receive parameters from the calling program, often updating one or more of them for return to the calling program. Parameter passing to/from SBXs is similar in concept to that to/from Functions and Procedures; see Subroutines vs. Functions/Procedures for a more detailed comparison. From the standpoint of the calling program, there is no difference in the way parameters are passed between a traditional subroutine and one that was written in ASB. But from the standpoint of the subroutine itself, special techniques must be used to retrieve and return parameters. These steps are actually analogous to the procedure used in subroutines written in assembler under AMOS to process the parameters. In this case, however, you use special statements (X-ARGs) or MIAMEX functions rather than system library calls (as with AMOS subroutines) or direct binding (as with many other languages.)
Some other differences between SBXs and programs
| • | SBXs must have a PROGRAM statement. Programs should, but it is optional. |
| • | Files opened within an SBX are not automatically closed at the end of the SBX unless the AS_SBXASRUN flag is set; see Xcall ASFLAG. |
These and other differences and details specific to SBXs are explored in the following sections. But first, let's address the question of whether a single compiled program can act as both a program (RUN) and a subroutine (SBX).
There is no difference in the internal structure of a RUN file versus an SBX, so any differences between the two arise solely from the file extension and the way they are called or executed. It is not possible to XCALL a RUN file (since the extension is not part of the XCALL statement syntax; see Calling External Routines), but it is possible to RUN an SBX directly by specifying the SBX extension on the RUN command line, e.g. :
.RUN FOO.SBX
Alternatively, you can create a simple wrapper command to use in place of RUN.LIT when you want to 'run' an SBX ...
.SBXRUN FOO
... where SBXRUN.LIT essentially consists of VXCALL CMDLIN, although it might include other configuration logic, such as converting command line arguments (CMDLIN) into XCALL parameters. Note that the compiler expects the XCALL statement to specify a literal SBX name; in order to use a single statement to call an SBX whose name is not resolved until runtime we need to use the VXCALL variant.
RUN programs typically input parameters from the keyboard or files, not from the command line, so the SBX would probably use the .ARGCNT system variable to determine whether it should act like a program or a subroutine.
Most programs though are not launched via a command line, rather via CHAIN, which is a bit more finicky about syntax. In order to CHAIN to an SBX, you would need to specify the complete command line, e.g. :
CHAIN "SYS:RUN FOO.SBX"
So the answer the question is yes; an SBX file can act as both a subroutine and a program, depending on how it is called. But except in the simplest cases, it will require some conditional logic to adapt to how it is being run.