The LIBRARY commands and capability are implemented differently on the retro-computer CGCOLORMAX and CGMMSTICK than they are on the CGMICROBOARD, the CGMICROKIT, and the CGMICROMITE. Library operations for the CGCOLORMAX and CGMMSTICK are based on the SD card storage, where with the CGMICROBOARD, the CGMICROKIT, and the CGMICROMITE the library code is located in internal flash.
LIBRARY LOAD $file
LIBRARY UNLOAD $file
The LIBRARY command will load a library file (‘file$’) into general memory. Any user defined commands and subroutines in the file will then become available to the running program. Up to 8 files can be loaded simultaneously.
A library file is like any other MMBasic program, with the exception that any programming code outside the user defined commands and subroutines will be ignored. The library is not visible to the user (it is not listed by the LIST command) so it should be tested and debugged as a normal basic program first. Normally a library file has the extension “.LIB” and that extension will be automatically added if the file name (‘$file’) does not include the extension.
Libraries can be loaded and unloaded in any order. Libraries can be loaded from within other libraries and nested to an unlimited extent.
Any library file can be unloaded from memory and the memory returned to the general pool by using the LIBRARY UNLOAD command. Library files must not be unloaded from within a library that is currently being used by the program (the results are undefined but it may crash MMBasic).
This command can be used to load specialized libraries to extend the functionality of MMBasic. Examples include device drivers, libraries that provide bit manipulation and libraries of specialized mathematical functions. The library file is only loaded on the first load command encountered so it is acceptable to put the same load command into every part of the program or every subroutine that may need the library.
Another use of the LIBRARY command is to extend the amount of memory available in any program by only loading sections of code as needed and then unloading them when their task is finished so that another function can be loaded.
To prevent fragmentation of memory, functions that use a lot of memory (like COM port buffers and arrays) should be declared first before any libraries are loaded and then unloaded.
The library is a special segment of program memory that can contain program code such as data, subroutines, functions and CFunctions. These routines are not visible to the programmer but are available to any program running on the device and act the same as built in commands and functions in MMBasic.
LIBRARY SAVE will take whatever is in normal program memory, compress it (remove comments, extra spaces, blank lines and the hex codes in CFunctions) and transfer it to the library area (main program memory is then empty). The code in the library will not show in LIST or EDIT and will not be deleted when a new program is loaded or NEW is used.
LIBRARY DELETE will remove the code from the library and recover the memory used as regular code space.
LIBRARY LIST will list the contents of the library.
Any code in the library that is not contained within a subroutine or function will be executed immediately before a program is run. This can be used to initialise constants, set options, etc.
Without using any library capabilities it is easy to think of the program space MMbasic uses as a single empty box. All code put in that box is listed when LIST is executed, runs when RUN is used, and is completely erased with the NEW command.
PRINT "Hello World"
NEW would empty the box above.
Using the library capabilities of MMbasic creates a separate memory space for library routines. If you start with a function in normal program code space:
PRINT "Hello World"
(nothing in this library space)
When you execute a LIBRARY SAVE operation, the Hello subroutine is copied into the library space and removed from the main program space:
PRINT "Hello World"
NEW will clear out anything in the main program space, but will not delete the Hello subroutine in the library space.
If you put code into the main program space, it can call the Hello subroutine as if it existed in that main space. The advantage of the library space is that you can have library routines, perhaps for very specific hardware, that remain in the chip even when the main code is deleted and reloaded. There can be one or more subroutines, functions, and CFunctions in the library.
The mechanism for putting code into the library space is the LIBRARY SAVE command. This command moves all of the code that is in normal code space to the library. You cannot add code to the library space and then later add additional different code. In order to place a second routine into the library space along with Hello, you must first erase using LIBRARY DELETE, load all of the code that you want in the library into the regular code space, and then execute the LIBRARY SAVE command.
Library routines can create and access global variables and are subject to the same rules as the main program – for example, respecting OPTION EXPLICIT if it is set.
The MEMORY command can be used to display the amount of flash memory used by the library.
As an example you could save the following into the library:
00000000 3c02bf81 8c45f000 8c43f000 3c02003d 24420900 7ca51400 70a23002
3c040393 34848700 7c6316c0 00c41021 00621007 3c03029f 24636300 10430005
00402021 00002821 00801021 03e00008 00a01821 3c0402dc 34846c00 00002821
00801021 03e00008 00a01821
This would have the effect of adding a new function (called CPUSpeed) to MMBasic. You could even run it at the command prompt:
> PRINT CPUSpeed()
The library can also include code that is not contained within a subroutine, function or CFunction. This code (if it exists) will be run automatically before a program starts running (ie, via the RUN command). This feature can be used to initialize constants or setup MMBasic in some way. For example, if you wanted to set some constants you could include the following lines in the library code:
CONST TRUE = 1
CONST FALSE = 0
The identifiers TRUE and FALSE will be as if they have been added to the language and will be available to any program that is run.