Single Code Base

Here are some strategies for managing a single code base for deployment under AMOS and A-Shell.

If you are willing to maintain a single source code base, but generate separate RUN modules for each run-time environment, then you can take advantage of conditional compilation directives to separate out the code that isn't cross-compatible. For example:

++if RUN_VER = "ASHELL"

    INPUT CSV #CH, name$, addr1$, addr2$, comments$

++else

    <some alternative logic not relying on A-Shell specific features like INPUT CSV>

++endif

 

In this case, for the A-Shell compilation, you can, for example use COMPIL /X:2/C:RUN_VER="ASHELL" to compile the A-Shell-specific sections and ignore the AMOS-specific sections. For the AMOS version, use COMPIL /RC (optionally with /C:RUN_VER="AMOS" in place you plan to test for that condition explicitly). If you accidentally include some non-AMOS compatible code outside your ++if RUN_VER = "ASHELL" condition blocks, the compiler will flag these as errors in the version of the compilation without /X:2.

You'll be able to distinguish the different RUN versions using the VERSYS utility.

If, on the other hand, if you would rather maintain just a single set of RUN modules which work in all environments, then you pretty much have to limit yourself to only those features that are supported by /RC (which leaves out, for example, user-defined functions and procedures). The only alternative would be to compile with /X:2, but make sure that you separate out your A-Shell-only or AMOS-only code via run-time IF statements. For example:

<runtime logic to set RUNVER$ to "ASHELL" or "AMOS" - perhaps using GETJTB.SBR>

 

if RUNVER$ = "ASHELL" then

    INPUT CSV #CH, name$, addr1$, addr2$, comments$

else

    <some alternative logic not relying on A-Shell specific features like INPUT CSV>

endif

 

The above technique also requires one further trick in order for AMOS to accept the RUN modules created by the A-Shell compiler when using /X:2: you will need to manually modify the RUN header. The 11th and 12th bytes of the RUN file contain a series of flags which indicate to the run-time system certain attributes of the RUN module, such as whether it was compiled with OCMPIL or COMPIL, /A or not, etc. This allows the run-time interpreter to properly interpret the RUN code, and also to identify RUN modules that are incompatible. Trying to run an invalid RUN module will most likely result in "illegal syntax code" errors (error #34).

To modify the RUN header to make it appear to be AMOS-compatible, write a Basic program to treat the RUN file as a RANDOM file with a record size of 1, allowing you to manipulate the 11th and 12th bytes. To determine what they should be, use VERSYS to look at similar RUN modules compiled under AMOS. In particular, be careful about /A (and /AV), since if the associated header flag bits are not correct, the program will crash. For this reason, you may want to use /A explicitly on all compilations, whether needed or not, so that you can use a fixed RUN header. Otherwise, the A-Shell compiler will invoke /A (and /AV) automatically as needed and your utility to patch the header will have to leave the /A and /AV bits alone.