• Please review our updated Terms and Rules here

Please recommend a Z80 monitor

Following up with what Dwight, I want to point out one of my favorite "Forth" moments.


This is Frank Sargents "3 instruction Forth". What it really is, is a "forth slave". He's using it to bootstrap 68H11 board, and he has a "master" Forth on another machine to drive it.

The epiphany of this is where this stands out over pretty much any other high level language.

In most any other language, you as a user don't have access to the lowest level of primitives. Notably, assignment.

If you have an expression, like A = 1, many languages give you a lot of flexibility over what shows up on the right hand side, the 1 in this case. Some give you some flexibility on the left hand side, as in what A means and how it handles the 1.

But not many give you the capability to really hack in the the "=" part of the expression.

Consider.

VAR @ 1 + VAR !

This takes the VAR variable, fetches its value, add 1 to it, and stores it back. The @ and ! are the "fetch" and "store" commands. Fetch and Store are first class operations. This is routine, Forth 101.

Now consider this:

VAR X@ 1 + VAR X!

This does the identical thing. The difference is that the data motion is happening on the slave computer, the 68H11 in this case. X@ fetches the value of the memory specified on the stack (from VAR) from the 68H11, and stores it on the local, host, stack. Similarly the X! takes the 2nd item on teh stack and stores it in the address specified on the top of the stack.

This is a pretty profound bit of kit here.

Now, you can drive this 68H11, with essentially NO software on it (the driver to communicate data over the serial line is trivial), and you can use your "full boat" Forth as the monitor. You can use your editor, your mass storage, etc. Just the data is stored on the board.

Rather than having 8K of code on the new board, you have, perhaps, 100 bytes.

It's a pretty neat concept.
 
I should note that unlearning other languages and picking up Forth is not trivial. There are things you you trivially do in Forth that don't even exist in other languages.
One thing Forth is good for is creating working code in a short amount of time. Most processors are not optimized to run a stack based language, so there is a time penalty running Forth on a machine, not intended to handle stack based computing. It is not huge but still there.
As you can tell by reading my post, I make a lot of mistakes. You might ask, how can a person that makes a lot of mistakes do something like create a processor simulator, assembler and emulation of a physical piece of hardware and get it to work in the end.
First, Forth has little boilerplate. What I mean is that when you abstract away from the low level code, your MAIN level of code often has little of low level Forth in it. It usually has mostly the operators that you created, with your words. That means the later part of the code text is denser with the end project than the language you started with.
Second, Forth expects one to make mistakes. Most low level words are easily tested at the instant you've finish writing them. There are always things that take multiple levels before you have a testable piece of code ( that is the hard part of programming ) but most things are tested as you go. As a matter of course, Forth almost requires you to do this. I often have to restart the Forth compiler from the crash I caused. Some versions of Forth have better protection but I find, if there is a simple recovery, that is enough.
Third, A program is to tell a computer what to do and exactly when to do it. This is where RPN comes in. The operation as most people learn it in school, " 1 + 2 ", is actually the operation of taking 1 and 2 then adding them or in Forth " 1 2 + ". Why is this important. What if it were " A + B ". One might assume that A was a value and so was B. What if A and B were operations? What if A effected what B returned. How do you ensure that the order was maintained. The math rules don't ensure this for you. This of course is a simple example and you might say it looks obvious. Still, in a complex system of operation order is important. Forth is read and operated Left to Right. Other languages are almost always a mixture, procedure and math or logical that are always a mix. The only exception to this is the handling of strings. It could be different if you like, see the next thing below.
Fourth, If the compiler doesn't have an optimal way to deal with a problem, you have full control of the compiler. You can modify or add it to match your needs. This is a lot of power and it takes a while to get the power of it. I was writing programs in Forth for about a 2 years before I understood this.
Sorry I strayed so far from the subject.
Dwight
 
Here is an update for improved loading for cassettes.

necmon.raw is still a raw disk image and necmon.d88 is a d88 disk image.

Integrated into one file - easiest to use for emulators - both of these have both the loader and monitor. You might need to rename to .p6:
necmon-32k.cas
necmon-16k.cas

Loader split from the monitor. Will work in the emulators, but you have to load the second part manually. Split versions required for actual hardware.
necmon-loader-32k.cas/wav
necmon-loader-16k.cas/wav
necmon.cas/wav

As an interesting note, I had tried to get the all in one file to load on real hardware, but it never would work. I tried expanding the area between the loader and the main program thinking that was the issue, but the real issue is that the leader part was being "put in" by the emulator and not being put in when I was playing the single wav file from computer to record on my cassette deck. The answer to that issue was two wav files, each with its own leader. I did end up playing all 3 of these wav files to a cassette (loader 16k, then loader 32k, then necmon.wav). Then you can do a CLOAD which will load the first one (16K, or you could use CLOAD "necm16"), or if you have a 32K system, you can do CLOAD "necm32" and it will skip the necm16 and load the necm32. Either way, when you RUN it, it will look for the necmon.wav part and skip the necm32 loader if necessary to get there.

I still plan to make a ROM loadable version of this too, just haven't gotten around to that yet. The extended BASIC cartridge is only taking up 8K of the 16K ROM area, so the second half of it is begging to have the monitor added to it.
 

Attachments

  • necmon.zip
    2 MB · Views: 2
Sorry I strayed so far from the subject.
Dwight
Not at all, as far as I'm concerned. Both you and "whartung" have provided cogent responses to my question :-}! I need to think about how I might go about trying out one or both approaches. Do you have a working example of an 8080- or Z80-based 8K Forth ROM that I might start from to customize to fit whatever HW environment I end up adopting?
 
I appreciate all he ideas and comments in this thread, so keep them coming!
 
Not at all, as far as I'm concerned. Both you and "whartung" have provided cogent responses to my question :-}! I need to think about how I might go about trying out one or both approaches. Do you have a working example of an 8080- or Z80-based 8K Forth ROM that I might start from to customize to fit whatever HW environment I end up adopting?
I'm afraid I've lost most of that stuff over time. ROM based Forths are not real common, most load from disk. It does take moving things like user variables into RAM and initializing them on boot ( not that many variables but it needs to be in RAM as things like the input string pointers and such obviously need to be in RAM ). There are a number of both 8080 and Z80 Forths out there. In the early days, I took an early FIG Forth paper listing from the "West Coast Computer Fair" ( now long gone ) and brought it up on an Intel MSD800 ( a 8080 machine).
While it is a little tedious, I learned a lot about Forth, since much of it is actually written in Forth, with only a few low level code words.
During the 8080 times, ROMs were expensive and only expected to boot the machine to a level that could load from some mass source, like disk, cassette or serial. I had the advantage then that I worked at Intel and had a development system to work on.
I can ask around to see what is out there.
Dwight
 
Here is an old Forth. It looks to have patches for all the things I found broken in the copy I brought up.
It will be quite similar to the Forth described in the book "Starting Forth". One should also look up "Thinking Forth". I believe both are on the web as pdfs.
Here is a pdf of the 8080 fig Forth:
The way I entered my version 1.0 was to enter it into an assembler as exact as one can at the same memory location.
Take a hex dump of the result and do a byte by byte comparison with the listing. Once you are at that point I can help you make it ROMable and then move it to the desired location.
It will need some form of console In/Out, as a minimum. That will be system dependent. Often times the low level monitor will provide something for the console. If you have a disk system you'll want to add that as well.
I can help with these if you have specific hardware.
Dwight
 
Thank you Dwight. I found https://tinymicros.com/wiki/FIG_Forth, which appears to be a transcribed copy of the source code that I presume is "assembler clean" (although which assembler was intended is unspecified in the PDF). So the next step would be to identify where are the ROMable pain-points and how to revise them?

Also I see that Udo Monk has been down a somewhat similar path (https://comp.os.cpm.narkive.com/OXjq69ZT/figforth-for-8080), so perhaps there is something useful in Z80Pack. comp.lang.forth also seems to include useful threads (e.g., discussion in https://groups.google.com/g/comp.lang.forth/c/Ha1hi3bEVvg/m/gS-IXCRcAgAJ ). General search results: https://groups.google.com/g/comp.lang.forth/search?q=ROM-able Z80 ROM-able would be fine too.

Found the The Stackworks SL5 manual at http://oldcomputers.dyndns.org/public/pub/manuals/sl5.pdf Unfortunately I'm not able to access http://www.softsector.aplaholm.se/cpm/sl5/ where source code resided. Apparently it was accessible in 2018 (https://trollheaven.wordpress.com/2021/06/10/the-mark-i-forth-homebrew-cpu-2018-10-22/) but the Wayback Machine has no content either.

eForth gets a positive mention but http://www.forth.org/eforth.html doesn't show any obvious interest in ROM-ability.

Looking around, my best SBC choice seems to be a NS DLC 80/24 (Multibus), which is a work-alike for the iSBC 80/24 (http://www.nj7p.org/Manuals/PDFs/Intel/142927-001.pdf & http://www.bitsavers.org/pdf/intel/iSBC/148437-001_iSBC_80_24A_Hardware_Reference_Manual_Nov85.pdf) that meets the minimum requirements that you've mentioned. Currently has 4K SRAM populated (of 8K possible) and 4x 2716 / 2732 / 2764 UVPROM (4x 2716 currently populated, which I'd replace with a single 2764 for this purpose). 8251 serial interface. 2x 8255 parallel. 8253 interval timer (and baud rate generator, which makes system start-up a bit tricky since there is no on-board strapping to configure the UART; it is possible to strap it to use an externally-supplied clock, however). 8259 PIC. Plenty of goodies. Other than the added complexity during initialization for the PIT in addition to the UART this SBC seems like a good, representative, experimental candidate.
 
You'll have to be careful. I don't know if the "out of the box" or, er, "off the page" Fig Forths are ROMable straight away. They certainly can be, depending on your goals, but may not be off the bat.

Working memory for an operational Forth is actually quite low. For a terminal only version you only need a stack (128 bytes is ample), and room for the PAD (which is essentially an 80 byte input buffer). If you wanted to be able to extend the Forth, you will need the HERE variable to be a RAM location, with it pointing to some open RAM, but any RAM will do. I'm sure I may be missing some other important system variables.

You could have a completely usable system with room to write several routines of code with 512 bytes of RAM. (This is assuming no mass storage, otherwise you would need at least 2K of RAM for buffers.) This is more than enough to dabble around with a board with a "monitor".

Historically, the original FIG listings were the "Johnny Appleseed" of Forth, scattering accessible Forth implementations across the silicon landscape with ports to all sorts of hardware. It was a very hands on process to bring it up on your hardware.

I don't know what your goals are, or what limitations you have. I don't know if a usable system, like I described above, can be squeezed into a 4K ROM or not. Maybe. I don't know if that's a concern. 8K is easy. 4K, not so sure.
 
Not for an 8080 - but I found this interesting article/code for a 4K (ish) Z80 in ROM (although the ROM is sized as 8K). https://github.com/jhlagado/firth. This is in ROM, and is for use with a simple 6850 ACIA to a terminal (and using hardware handshake by the look of it).

Dave
 
The best monitor for you is the one you write yourself. There was at least one 8080 one that included a simple editor and assembler. I think it took about 4-5KB.
 
Well, glancing at the FIG 8080 listing, as is, it clocks in at more than 6K, but there's a lot there that could be culled. I think getting it under 4K would be readily achievable. You could pretty easily wholesale comment out word definitions and keep re-assembling it to see if a reference breaks.

It says at the top that it's not ROMable, so there'd need to be a little more analysis to try and fix that.
 
I did a quick look. The list states that it isn't ROMable but most of the code looks fine. Two obvious places are near the end, being P! ( port store ) and P@ ( port fetch ). Also I think the vocabulary Forth may need a little relocating. Most of the RAM items are the 2 stacks (one is the 8080s stack but a second one is needed ), User variables, buffers and dictionary space.
I understand you want to get is ROM'd early. Please don't do this until you have verified that you have a matching source, using the method I described. ( no one is perfect )
The port operators can be allocated near the beginning of the user variables. The transfer of these to RAM can be added to COLD. The 8080 has no generic random port instruction but since you are planning to put it on a Z80, you can modify it to be that.
As for what assembler, it looks to be quite generic. I don't see any use of macros or special operators.
Like I said, you will save a lot of grief by entering it in, unmodified and then do a byte by byte comparison. Once there you can start to modify things.
If you look carefully at the listings, you'll see that the are a few low level code words and then most of the later stuff is written in those low level words. The words are set up in a simple linked list. This is so if you enter a word, a simple search down the linked list will find a match. I don't recall if the fig Forth was case sensitive but I think it was. Some newer Forths are not. This version does what is called indirect threading. There are several threading methods. Some are faster but more difficult to handle some of the complexities for standard Forth.
On some of the new processors call threading is quite fast. ( I use a type of call threading on my Blue Pills ).
Each word is organized in several fields. The name field has the name and bit markers to help on searches as well as a bit called smudge and immediate. Smudge is a protection that the compiler uses to mark a newly created word as unusable until it appears to have been completed without syntax errors. ( meaning you can't use it unless it will do something ) Immediate marks it for the compiler to execute it rather than just compile it. Control structure are the main ones using the immediate flag, like IF ELSE THEN, that have obvious compiler functions. After The name and flag bits there is the link field. This is a single direction link to the next word before it to continue the lookup of the desired word. After that is the code field.This point to machine code to handle the following parameter filed(s). Typically these will be a high level Forth word, a code word, constant , variable or possible user defined operation. It is require to be a pointer to executable machine code.
This is a 16 bit Forth with several 32 bit math operators. For operations that you might normally use floating point, there is often a scaler operations using 32 bit values, to get more dynamic range.
Being an integer language it follows rounding rules for things like MODulo and division. I don't recall if this math is round towards zero or floored math. Most processors do round toward zero but that causes a lot of cumulative errors with integer math. I prefer floored math. One thing you'll grow to like is that you can choose any convenient number base, besides the regular decimal, octal, Hex and binary, it could be base 12 or 9 or 20 or most any reasonable base. I've come to live in Hex. I'm mostly a hardware tinkerer.
Dwight
 
I should mention that early versions EForth where intended to be easily modified and portable to other environments. It was not intended that the developers would provide patches to make it work in someone else's environment.
The version of EForth that I have running on my Blue Pill was intended for the Blue Pill. I had to make several changes.
Most later EForths were intended to be romable but for the 8080 or Z80 was not likely thought to be used that way.
There are few parts of the code that look to need changes for ROM use in this FIG forth. Those that are there should be easy to fix. Like I said, only the port operations that require self modifying code to use any port, for the 8080, look to need patching. There are several simple fixes for this. One is to move the need code to a location in RAM on COLD boot, that already writes USER variables to a RAM area. An alternate that I've used is to write the code to the stack area and execute it there ( not as efficient as a special location in RAM but it was re-entrant from interrupts ). Like I said, it is a simple Z80 code changeif that is the processor you intend to run.
You can see from the listing of this FIG version 1.1 was intended to use on top of CP/M. The earlier version that I brought up used MDS800 calls that are different from CP/M. Most people didn't have access to a MDS800 as these cost over $10,000.
Dwight

eForth gets a positive mention but http://www.forth.org/eforth.html doesn't show any obvious interest in ROM-ability.
 
This is a 16 bit Forth with several 32 bit math operators.
Now, for me, if the 4K was a goal, for a monitor, the double word math would be the first on the chopping block. All of the disk I/O would go, etc.

I'd hack and slash early and often to the most minimal I could come up with, and then start adding back. Especially if I could start adding back an assembler. (I honestly don't know if you can fit a core Forth and assembler in 4K).

The premise being that this is not a "full boat" Forth, rather it's a stripped Forth for use as a monitor, and doing monitor things. Not so much a general purpose development environment, as a flexible toolset for monitor tasks. Sacrifices made to fit in 4K.

If you have 8K, then skies the limit, honestly.
 
Back
Top