MS BASIC Machine Monitor for RC2014

There has been quite bit of interest in assembly or machine monitors for the RC2014 lately, so I’ve taken the opportunity to write one in MS (NASCOM) BASIC which will work for RC2014 Mini / Micro / Classic ][ machines, but equally well for any machine running a version of MS Basic 4.7 or later.

RC2014 Cylon

The functional goal was to provide the same user tools as the NASBUG monitor, but to be maintainable and easily customisable by the user. As the monitor is written in BASIC it works equally well for both Z80 based machines and 8085 based RC2014 machines using my 8085 CPU Module (for example).

The code is published in the RC2014 BASIC Programs Monitor repository.

A key issue for me was that it needed to fit completely into the BASIC program memory found below the default z88dk assembly loading address of 0x9000 for the RC2014 target.

By using BASIC language for the monitor it enabled me to focus on the functionality, as BASIC provided the command line support via INPUT(), string tokenisation via MID$(), ASC(), and VAL(), and mathematical functions.

Program Development

The trickiest piece of code is producing a signed integer address from the 4 digit hexadecimal ascii string. Unsurprisingly, I didn’t write this very nice code segment. I found it provided as an example in the back of the NASCOM BASIC User Manual (Appendix I). Kudos to the NASCOM team there for their 40 years of foresight.

However, Fred has provided a better simpler solution for getting an integer from a hexadecimal string and now that solution has been implemented.

With that key function done, then the MID$() function was used to tokenise the command string into 4 (or less) digit strings to convert into hexadecimal. Depending on the function required either signed integers were then produced to be an address or where a length was needed an unsigned integer was provided.

Finally an IF THEN tree was made to process the command string, found using the very convenient ASC() function. Since the commands are sparse, I thought that a simple decision tree would be best.

As noted, a key goal for me was that it needed to fit completely into the BASIC program memory found below the default assembly loading address 0x9000. The program fits with over 100 Bytes free, currently. But the stripped version has still over 1200 Bytes free, so there is quite a lot more code that could be added if needed.

Program Usage

The BASIC monitor is useful to casually poke around in the RAM or ROM of a running MS BASIC RC2014 machine to get a feeling of how variables and strings are stored, for example.

It can be used to enter assembled binary code into the RAM, and then run it. The assembly code can use the facilities (serial I/O, RST table, and MS Basic functions) as needed. Some further information on Assembly can be found here.

Further, it can be used together with the Zen Editor/Assembler to write and then assemble larger programs for the RC2014. When the monitor is used together with Zen, the monitor can be loaded (copy / pasted) into the BASIC Command Line, then using the BASIC HLOAD command Zen can be loaded (cat) into the RAM at 0x9000, and launched either from the monitor or directly using ?USR(0). Once editing and assembly is finished, Zen can be exited with Q and then the newly assembled program can be run from its origin by entering the monitor with run, and then E xxxx yy, where yy is a signed integer input parameter.

Using this combination of Zen and the BASIC monitor it is possible to develop, examine, and modify complex Z80 and 8085 assembly code in a very comfortable environment.

Commands for a BASIC Monitor (Syntax borrowed from NASBUG)

A – hexadecimal arithmetic

A xxxx yyyy – Responds with: SSSS DDDD JR JJ. SSSS is sum of xxxx and yyyy. Values in Hexadecimal. DDDD is difference of xxxx and yyyy, yyyy-xxxx. Values in Hexadecimal. JJ is displacement required in a Jump Relative instruction which starts at xxxx, to cause a jump to yyyy. Value in Decimal.

C – copy

C xxxx yyyy zzzz Copy a block of length zzzz from xxxx to yyyy. One byte is copied at a time, starting with the first byte, so if there is an overlap in the two areas data may be destroyed. This command is useful for filling a block with a single value. Make yyyy one greater than xxxx and put the required value into address xxxx using M. Set zzzz to the number of bytes required. Values in Hexadecimal.

E – execute

E xxxx yy – Execute program at xxxx, supplying integer input parameter yy. The USRLOC location depends on the specific MS BASIC ROM implemented. The value can be easily adjusted in the monitor source code. Values in Hexadecimal.

I – intelligent copy

I xxxx yyyy zzzz – Like the Copy command but copies to ensure it will not cause data corruption in an overlapping section. Values in Hexadecimal.

M – modify store

M xxxx – Modify memory starting at address xxxx. The address is displayed followed by the current data. The data value may then be changed. Continuous entry of new data values is supported. Values in Hexadecimal.

Q – quit

Q – Quit to BASIC Immediate Mode (Command Line).

T – tabulate

T xxxx yy – Tabulate (display) a block of memory starting at xxxx and continuing to yy-1. Values in Hexadecimal.

Further Development

As the monitor is written in BASIC it is easy to maintain for all hardware or CPU types wherever MS BASIC is found, and to further develop to support new functions. As there are about 1200 Bytes free below the default origin (in the stripped version), there is space for the user to add their own preferred functions or modifications to existing functions.