|
Z80 Space-Time Productions Single Board Computer
Technical Support Information - BASIC Programming Language in Rom
Operation of the Space-Time Productions MCB is often a bit harrowing for some people who are not as interested in the hex monitor-level and assembly language hoops one jumps thru to use this board. There are two versions of BASIC being offered here at the moment. Both are port overs from Nascom Z80 Basic produced in 1978 by Microsoft for them. It was one of the only Z80 versions I found that had the better features of BASIC and utilized the Z80 microprocessor. It was also one of the only ones I found that had a well-documented disassembly source file. BASIC1 is designed to run either on a factory-ram-only (2K of HM2114 chips) MCB, or on an MCB that has expanded memory installed starting at $4000 upward. On startup, it scans the onboard ram which it treats as $3800-$3FFF. Then it continues scanning upward from $4000 thru $FF00 to see if additional ram has been added to MCB, and will allow BASIC to utilize any extra ram it finds. It assumes you have ram from at least $3800-$3FFF (which is the MCB's default onboard ram configuration, see HARDWARE page for more information on the memory layout of this board). BASIC2 was actually created before BASIC1, and is hard-coded for unmodified MCB that has only the 2K of HM2114 ram chips on board. This is not enough ram to run anything other than very small BASIC programs [STARTREK.BAS will not load for instance], but is useful for hardware testing and I/O operating routines. Small control programs will work, and it has all the same features of BASIC1.Some people may find using BASIC with their MCB much simpler than the supplied machine language monitor. Does not scan for any expanded memory, uses only ram from $3000-$37FF in its operation. DOWNLOAD BASIC
The BASIC Language This version uses old style line numbers and commands, and is one of the earlier simplified variants of the language, similar in user interface to Tandy Level II Basic is some respects.Command Words
Uses standard BASIC language conventions, including line numbers:
10 FOR A=1 TO 10
Line numbers may run in any increments but are limited from 0 to 65529. Variables:
Communicating with BASIC The MCB in today's environment will most likely find itself running tied to a PC using Hyperterminal as the interface. Originally they were no doubt tied to Video Data Terminals. Since this BASIC operates in ASCII text, it interfaces easily to most RS232 serial accomodating devices. There are three routines which handle the transport of ASCII characters:
The routine CKSIOA loads the Transmit Buffer status bit into the Z flag and the Receive Ready flag into the CY flag. This routine is called several times througout BASIC to test for "ESC/BRK", so you will want to make sure either your routine sets the flags accordingly, or modify the rest of the code so it responds better to your particular UART/SIO device. The small version, which is designed to run on the MCB which has not had any hardware modifications or memory expansion, bypasses any ram detection routines, and establishes the 2K on board as the entire usable ram area. This setting leaves about 1,500 bytes for user programs {not a lot there}.
Some Notes:
CLEAR command In Nascom BASIC, the CLEAR command has some interesting effects and a parameter not mentioned in their Basic User Manual. CLEAR 250 sets the string space to 250 bytes.While evaluating what the code was doing, I noted it can also have a second parameter such as this example: CLEAR 100, 16283 The first parameter create a string space of 100 bytes, the second undocumented parameter sets the LSTRAM internal variable address at 16283 ($3F9B). This gives 100 additional bytes from $3F9C to $3FFF for storing your own machine language routine, for use with USR(x). Then it takes the 100 bytes of String space out below this new ceiling (16283). The second parameter directly sets LSTRAM in the BASIC internal variables, and resets all the other memory pointers for it. The LSTRAM parameter is what BASIC uses to see where the top limits for it's reach into ram are for storing strings. They do not necessarily reflect the actual ram in the machine. Since you can move LSTRAM with the CLEAR command, it is possible to 'clear' memory above BASIC for your own use. Nascom BASIC came with several commands that just didn't make the cut. DOKE and DEEK (a double byte POKE and PEEK) used that same crappy signed 16-bit integer format that required you get out your calculator to figure out the actual address or data. DOKE is replaced with VECTOR nnnnn, which sets the location for the next USR(x) jump. DEEK is one of those buggy problems you will read about in just a moment. SET, RESET, and POINT all dealt directly with the graphic screen of the Nascom computer - I have left those commands intact so they may be used later on with a graphic LCD display, etc. but for now they simply collect the parameters and place them into BASIC's internal variable storage, and returns back to BASIC. A function I added allows the use of hexadecimal values in calcs - Very Handy! If you want to set a VECTOR for the next USR(x) command, you can give it directly in hex (e.g. - VECTOR $0283). Most commands that involve calculations can use this, I have noticed it seems to function without error if you put the hex values in parenthesis for processing [ e.g. - PRINT ($34)+128 , or A=5*($8B) ]. Especially useful for use with the following commands:
Using Assembly Language with BASIC BASIC has a portal through which assembly language routines may be called from with a BASIC program. The VECTOR command allows you to set the starting address of your routine, then the USR(x) command will cause BASIC to suspend and call your routine. When BASIC initializes this jump to the FCERR routine internal to BASIC, so if you execute a USR command without first setting some other VECTOR, you will get an "? Illegal Function Call Error" from BASIC. Machine code executes many times faster than similar code in BASIC, because of all the conversion and processing that has to be done for each character in code, whereas in Machine Code ("assembled assembly language"), each byte IS the instruction or data, this is processessing at its most fundamental level. There are several reasons that you might want to incorporate machine code into BASIC:
The Steps to Use Assembly with BASIC: 1) Load your assembly language program. 2) Set the Vector
It is not necessary to calculate the memory value in decimal, since VECTOR can use hexadecimal, thanks to a routine I added to BASIC. However, if you prefer decimal, one way to calculate addresses over 32767 is to take the decimal equivalent of the desired address, (i.e. 32768) and subtract 65536 from it. Thus 32768-65536=-32768, VECTOR -32768.
The actual USR 'JP' command ($C3) is stored at $3123 ($4203 in the expanded memory version), and the vector right after it at $3124 (LSB) and $3125 (MSB), in the typical Z80 (8080) address format (low address byte, high address byte). A VECTOR 32767 ($7FFF) will be stored as: Executing the USR from BASIC
3) Passing Parameters to/from BASIC
In BASIC, the USR command requires a parameter and returns a passed parameter. This makes it convenient to hand off
a 16-bit signed integer to the machine language program, and to expect a 16-bit signed integer return.
In order to properly pass parameters, your machine code needs to access a couple of BASIC internal functions:
DEINT is an internal routine that takes an Integer number from the Floating Point Register which is where the USR(param) is stored, converts and places this 16 bit value into the register pair DE (hence the name).
ABPASS is an internal BASIC routine that takes a 16-bit signed integer that is in registers A (MSB) and B (LSB).
While not a true 'register pair', this routine treats the number that way.
Both DEINT and ABPASS must be run from within your Assembly program, you cannot call them from BASIC before switching the vector
command around to call your routine. BASIC operations will again alter your registers and parameters before you can get there to intercept them. Optionally, if you are returning only an 8-bit unsigned you may return it to BASIC using the routine PASSA. A jump to PASSA is located at $1FFC. You should call this with your value in A before issuing your final RETurn to BASIC.
The vectors at this table are: An alternate way to you may also pass parameters by placing them into ram and then having BASIC 'PEEK' those locations when you are done. This is a good secondary way to pass ASCII characters and other non-16-bit-integer data back into BASIC. OTHER NOTES: 1) You may call monitor ROM routines with USR, provided VECTOR addresses them correctly. 2) An ? Illegal Function Call Error will result if you try to pass a parameter which is out of the 16-bit signed integer range. 3) When USR is called, BASIC sets up 8 levels (16 bytes) of stack storage area. The Stack area is quite large and should accomodate just about anything you can throw at it. 4) You should always remember that any exit condition to your program should leave the Stack unaltered, in other words you should POP off all the things you PUSHed onto the Stack before finishing up. Otherwise, you may crash BASIC, or some of your program may start acting very strange. Most likely it will crash.
5) You can change memory and registers at will with machine code, so be careful what you change. Memory Locations for Your Code Since there is so little ram available in the BASIC2 version, I recommend starting BASIC and issuing a CLEAR 100, $3700 command. Then load your machine code program into the area from $3700-$37FF. BASIC, following the CLEAR will not attempt to use the area above the defined ceiling (second paramater of the CLEAR command). This is useful, but strongly recommend you keep it as small as possible to allow as much room for BASIC to operate as possible.
If your routine uses only 30 bytes, you should try CLEAR 100, $37FF-31.
Honorable Mentions - Those who threw in and helped me with this: Grant Searle - Who fixed my modified commands which allow the use of Hexadecimal numbers in such commands as OUT(port,data) and fixed the conversion of numbers to Hex from within BASIC. Many thanks. Mike Brearly - Who repaired my poor Intel Hex Save routine and made it less messy. Many thanks.
Click HERE if you do not see a menu frame to the left. This page created September 18, 2004. Modified April 13, 2011. |