Agon512k
Access 512KB RAM from within BASIC on AgonLight (TM)
Install / Use
/learn @TurboVega/Agon512kREADME
agon512k
<b>Access 512KB RAM from within BASIC on AgonLight (TM)</b>
<b>Memory:</b> BASIC (64KB) + CUSTOM (384KB) + MOS (64KB)
This collection of assembler functions provide access to the extended memory (including and beyond the first 64KB) attached to the EZ80 CPU. The entire external RAM resides at addresses &40000 to &BFFFF, with BASIC normally using the lower 64KB (&40000 to &4FFFF), and MOS using the upper 64KB (&B0000 to &BFFFF). Now, you have another 384KB of RAM accessible from BASIC, ranging from &50000 to &AFFFF. You can access any part of the whole 512KB, if you are <i>very</i> careful not to clobber memory that will cause BASIC or MOS to crash.
For example, the empCMBI% procedure, detailed further below, is designed to copy memory blocks, and can be used to copy between RAM in the BASIC area (lower 64KB), and RAM in the extended area (above 64KB). <br> <br> Versions:<br> V0.4 - 30-Apr-2023 - Couple of doc edits; no code changes.<br> V0.3 - 27-Apr-2023 - All tests performed to the extent designated by the "emtests.bas" program.<br> V0.2 - More tests added, but still testing "block" routines.<br> V0.1 - Initial release of code for beta testing of a number of routines. <br> <br> NOTE: The provided routines do not modify or enhance the BASIC language, nor provide an easy way to allow you to write BASIC programs that are larger than would normally fit within the 40+KB available for programs. They provide a way to store <i>data variables</i> and/or blocks of <i>data bytes</i> in the upper RAM. This extends the variable/array capacity greatly. When used with the CHAIN command in BASIC, you could write large programs with lots of data. <br> <br> The assembler functions can read or write the entire memory range, implying that you should be very careful not to clobber any memory used by BASIC, unless you know what effect it will have. It is up to you how to arrange or manage the upper memory. No allocation, deallocation, or garbage collection is provided. You simply call routines that write or read using specific addresses determined by your application. <br> <br> In the following descriptions, the prefix "emp" means "extended memory procedure". The prefix "emf" means "extended memory function". The prefix "emd" means "extended memory data", and refers to a data parameter passed into or out of one of the extended memory procedures. The name "var" is a placeholder for a variable name of your choosing.
Regarding parameters, with the exception of string values, numeric expressions are typically expected, and may be constants, variables, computation results, function results, etc.
Many of the routines work with arrays. When working with 8-, 16-, 24-, or 32-bit array item values, the code automatically assumes the size of an array item to be 1, 2, 3, or 4 bytes, respectively. When working with float values, each item is 5 bytes in size. When working with an array of string values, the maximum item size must be specified manually, because strings have various lengths. The maximum item size in a string array is 256 bytes, meaning that the maximum string length inside an item is 255 bytes, because of the trailing CR character stored with the string.
The maximum array index size for any array is 65535 (&FFFF). This does not prevent you from having larger arrays, because you can arrange two or more arrays in memory such that they are physically together. It only means that you may need to reference the second (or third) array separately from the first array, and be sure to use base zero indexes in each array (i.e., range 0 to 65535).
The code does not presently support storing <i>record-oriented</i> data fields in an obvious manner; however, you can mimic that behavior in a couple of ways: (1) store data fields in subsequent memory locations such that they form a "record" (a set of consecutive data values of various types), and store a series of records in consecutive memory locations, or (2) use multiple arrays, with one array per data field, where each array holds only items of a particular data type. Typically, such arrays would have equal lengths (the same number of array items). Method (1) requires you to manage the memory yourself, but method (2) helps with array indexing, and only requires that the arrays do not overlap in memory. <br> <br>
PROC_empInit - Initialize routine addresses
This BASIC procedure will initialize the variables that are described in the following sections, with the addresses of the various assembler routines that may be called to read and to write extended memory. <i>Call this procedure before calling the others.</i>
Usage: PROC_empInit <br> <br>
emdSA% - Source address parameter
This parameter is a 24-bit source address that is required by some routines, as specified below. To access the first 64KB of memory, the address must be in the range &40000 to &4FFFF, not &00000 to &0FFFF. Any address in the range &40000 to &BFFFF is allowed. <i>Be careful when specifying addresses within the BASIC or MOS areas!</i>
Usage: !emdSA% = <i>sourceaddress</i> <br> <br>
emdDA% - Destination address parameter
This parameter is a 24-bit destination address that is required by some routines, as specified below. To access the first 64KB of memory, the address must be in the range &40000 to &4FFFF, not &00000 to &0FFFF. Any address in the range &40000 to &BFFFF is allowed. <i>Be careful when specifying addresses within the BASIC or MOS areas!</i>
Usage: !emdDA% = <i>destinationaddress</i> <br> <br>
emdAI% - Array index parameter
This parameter is a 16-bit array index that is required by some routines, as specified below. The array index ranges from 0 to 65535 (&FFFF). See comments above about splitting large arrays.
Usage: !emdAI% = <i>arrayindex</i> <br> <br>
emdIS% - Array item size parameter
This parameter is a 16-bit array item size that is required by some routines, as specified below. The item size ranges from 1 to 256 (&100). See comments above about splitting large arrays.
Usage: !emdIS% = <i>itemsize</i> <br> <br>
emdRC% - Repeat count parameter
This parameter is a 24-bit repeat count that is required by some routines, as specified below.
Usage: !emdRC% = <i>repeatcount</i> <br> <br>
emdV8% - Value parameter as 8 bits
This parameter is an 8-bit value that is required by some routines, as specified below.
Usage: ?emdV8% = <i>value</i><br> Or: !emdV8% = <i>value</i> <br> <br>
emdV16% - Value parameter as 16 bits
This parameter is a 16-bit value that is required by some routines, as specified below.
Usage: !emdV16% = <i>value</i> <br> <br>
emdV24% - Value parameter as 24 bits
This parameter is a 24-bit value that is required by some routines, as specified below.
Usage: !emdV24% = <i>value</i> <br> <br>
emdV32% - Value parameter as 32 bits
This parameter is a 32-bit value that is required by some routines, as specified below.
Usage: !emdV32% = <i>value</i> <br> <br>
emdVS% - Value parameter as string
This parameter is a string value that is required by some routines, as specified below. When stored in memory, the string will be terminated by a carriage-return (CR, 0DH) character; therefore, the original string should not contain a carriage-return.
Usage: $emdVS% = <i>stringvalue</i> <br> <br>
empI% - Initialize upper RAM
This procedure clears (to zero) the middle 384KB of memory.
Usage: CALL empI% <br> <br>
emfG8% - Get 8-bit value
This function reads an 8-bit value from memory.
Usage: !emdSA% = <i>sourceaddress</i>: var%=USR(emfG8%) <br> <br>
emfG16% - Get 16-bit value
This function reads a 16-bit value from memory.
Usage: !emdSA% = <i>sourceaddress</i>: var%=USR(emfG16%) <br> <br>
emfG24% - Get 24-bit value
This function reads a 24-bit value from memory.
Usage: !emdSA% = <i>sourceaddress</i>: var%=USR(emfG24%) <br> <br>
emfG32% - Get 32-bit value
This function reads a 32-bit value from memory.
Usage: !emdSA% = <i>sourceaddress</i>: var%=USR(emfG32%) <br> <br>
empGS% - Get String (0..255 characters)
This procedure reads a string value from memory.
Usage: !emdSA% = <i>sourceaddress</i>: CALL empGS%: var$=$emdVS% <br> <br>
empGF% - Get Float (40 bits)
This procedure reads a float value from memory, and copies the value into the specified variable.
Usage: !emdSA% = <i>sourceaddress</i>: CALL empGF%,<i>floatvariable</i> <br> <br>
emfG8AI% - Get 8-bit item from array
This function reads an 8-bit array item from memory.
Usage: !emdSA% = <i>arrayaddress</i>: !emdAI% = <i>array index</i>: var%=USR(emfG8AI%) <br> <br>
emfG16AI% - Get 16-bit item from array
This function reads a 16-bit array item from memory.
Usage: !emdSA% = <i>arrayaddress</i>: !emdAI% = <i>array index</i>: var%=USR(emfG16AI%) <br> <br>
emfG24AI% - Get 24-bit item from array
This function reads a 24-bit array item from memory.
Usage: !emdSA% = <i>arrayaddress</i>: !emdAI% = <i>array index</i>: var%=USR(emfG24AI%) <br> <br>
emfG32AI% - Get 32-bit item from array
This function reads a 32-bit array item from memory.
Usage: !emdSA% = <i>arrayaddress</i>: !emdAI% = <i>array index</i>: var%=USR(emfG32AI%) <br> <br>
empGSAI% - Get String (0..255 characters) item from array
This function reads a string array item from memory. The given start address points to the start of the array (at item #0). The item size tells how big each array item is, which determines the maximum size of the string that can be stored there. For example, using an item size of 21, the maximum string length is 20, because of the trailing CR at the end of the string, while stored.
Usage: !emdSA% = <i>arrayaddress</i>: !emdIS% = <i>itemsize</i>: !emdAI% = <i>array index</i>: CALL empGSAI%: var$ = $emdVS% <br> <br>
empGFAI% - Get Float (40 bits) item from array
This procedure reads a float array item from memory, and copies the value into the specified variable.
Usage: !emdSA% = <i>arrayaddress</i>: !emdAI% = <i>array index</i>: CALL empGFAI%,<i>floatvariable</i> <br> <br>
