Close

Will it work on an 8080/8085?

A project log for eForth/z80 modifications

A more hackable eForth/z80

ken-yapKen Yap 08/10/2019 at 10:516 Comments

One of my motivations is to also get it to work on my 8085 SBC. It turns out to be fairly straightforward.

I have a hacked asz80 that flags instructions that are not in the 8080 subset. Here is the output of a grep '^[a-z]' efz80.lst

a  0105 ED 79         [12]   11         OUT (C), A
a  0109 ED 79         [12]   13         OUT (C), A
a  010D ED 79         [12]   15         OUT (C), A
a  0111 ED 79         [12]   17         OUT (C), A
a  0117 ED 79         [12]   21         OUT (C), A
a  011B ED 79         [12]   23         OUT (C), A
a  011F ED 79         [12]   25         OUT (C), A
a  0123 ED 79         [12]   27         OUT (C), A
a  0129 ED 79         [12]   31         OUT (C), A
a  012F ED 79         [12]   35         OUT (C), A
a  0131 ED 5E         [ 8]   39         IM 2
a  014A ED 79         [12]   58         OUT (C), A
a  0000 D9            [ 4]    8         EXX                     ;4t
a  0003 ED 47         [ 9]   10         LD I, A
a  001E ED 79         [12]   26         OUT (C), A
a  0022 ED 79         [12]   28         OUT (C), A
a  0028 ED 79         [12]   34         OUT (C), A
a  002C ED 79         [12]   36         OUT (C), A
a  0030 ED 79         [12]   38         OUT (C), A
a  0034 ED 79         [12]   40         OUT (C), A
a  003A ED 79         [12]   44         OUT (C), A
a  003E ED 79         [12]   46         OUT (C), A
a  0042 ED 79         [12]   48         OUT (C), A
a  0046 ED 79         [12]   50         OUT (C), A
a  004C ED 79         [12]   54         OUT (C), A
a  0052 ED 79         [12]   58         OUT (C), A
a  0058 ED 79         [12]   64         OUT (C), A
a  005C ED 79         [12]   66         OUT (C), A
a  0060 ED 79         [12]   68         OUT (C), A
a  0064 ED 79         [12]   71         OUT (C), A
a  0068 ED 79         [12]   73         OUT (C), A
a  006C ED 79         [12]   76         OUT (C), A
a  0070 ED 79         [12]   78         OUT (C), A
a  0074 ED 79         [12]   81         OUT (C), A
a  0078 ED 79         [12]   83         OUT (C), A
a  007C ED 79         [12]   85         OUT (C), A
a  0080 ED 79         [12]   88         OUT (C), A
a  0086 D9            [ 4]   98         EXX                     ;4t
a  0000 D9            [ 4]    7         EXX             ; 4t
a  0004 ED 79         [12]   11         OUT (C), A      ;12t
a  0006 D9            [ 4]   12         EXX             ; 4t
a  0000 D9            [ 4]   21         EXX             ; 4t
a  0002 ED 78         [12]   23         IN A, (C)       ;12t
a  0008 D9            [ 4]   27         EXX             ; 4t
a  0035 ED 4D         [14]   55         RETI                    ;14t
a  003D ED 79         [12]   63         OUT (C), A              ; reset
a  0043 ED 79         [12]   66         OUT (C), A
a  0048 ED 4D         [14]   70         RETI

All the OUT (C), A and IN A,(C) instrutions need to be replaced by OUT (port),A and IN A,(port). Most of them happen in the device initialisation routines, where C is loaded with a constant, lots of OUT instructions are done, then C is changed, and so on. In the port output and input routines, a modifiable code fragment will need to be provided so that any arbitrary port can be selected, as the 8080 doesn't support variable ports. This fragment have to be constructed in RAM, not ROM.

IM 2 (Interrupt Mode 2), LD I,A, and RETI don't exist on the 8080 so interrupt routines would have to use 8080 methods.

EXX would have to be replaced by pushes and pops of affected registers at the cost of execution time.

It's interesting that the author didn't use IX, IY, or the other extended instructions.

But I won't try this now. I have to find a Z80 simulator to check that eForth works, then I can try a modified 8080 image in the same simulator.

Discussions

Thomas wrote 08/10/2019 at 15:06 point

Which simulator do you use?
Just an idea: maybe the different instruction sets can be abstracted with macros (e.g. for interrupts).

  Are you sure? yes | no

Ken Yap wrote 08/10/2019 at 21:11 point

I haven't decided on a simulator yet. They are all fine when it comes to siimulating the instruction set but fall short when it comes to simulating input or ports. z80sim can do input but it's blocking input for stdin so can't handle the polling of eForth. z80-asm has port simulation using a shared file 256 bytes long so in theory I could even simulate the SIO device but I'd have to write an auxiliary program to interact with the user and change the "ports".

The 8085 is just the 8080 with a couple of extra instructions RIM and SIM so can be treated as an 8080. The EXX in the interrupts can't be replaced with macros as at the beginning of an ISR should save registers and at the end should restore registers, but there are only a few spots like that. It's not too difficult to make a separate eForth version that's nearly identical to the Z80 version as only a few files are affected. and these are the platform dependent ones anyway. I don't know of many people other than myself interested in the 8080, most retro hackers go for the Z80.

  Are you sure? yes | no

Thomas wrote 08/11/2019 at 10:08 point

Blocking I/O can be sufficient for eForth (the original STM8 eForth essentially used a spin-lock to turn the UART into a blocking device - I introduced the "idle task" to change that). Maybe that's also an option for a basic simulator version, here.

It's true, the retro-computing community doesn't appear to be too interested in the 8080 or the 8085. I did a quick check with Google Trends: surprisingly there are 4x as many searches worldwide for "Intel 8085" than for "Intel 8080" or (!) Zilog "Z80". The question is: where does all that interest for the 8085 come from? In embedded control applications it used to be quite popular for some time, but today?

  Are you sure? yes | no

Ken Yap wrote 08/10/2019 at 23:59 point

One thing I could do is write a CP/M executable version of eForth. I don't know how the CP/M emulators implement it, but kbhit() is available, so that would satisfy the non-blocking input requirement. And it would make eForth more accessible to people who build Z80 computers and run CP/M.

  Are you sure? yes | no

Thomas wrote 08/11/2019 at 10:28 point

That would certainly be nice.
CP/M also works in 8080 emulators like this one https://www.tramm.li/i8080/emu8080.html

By the way, emu8080 contains a volks4th.cpm disk umage - I used "r 0 volks4th.cpm", "b", "g" but I only got a CP/M boot message followed by a HALT.

  Are you sure? yes | no

Ken Yap wrote 08/11/2019 at 11:39 point

There are encouraging signs. CP/M loads programs at 0x100 and jumps there. eForth/z80 already has that as the entry point after a JP from 0. So I just need to relocate the user variable list at 0x80, set the top of memory for eForth below BDOS, and make the input and output routines use BDOS calls, then throw away the first 256 bytes of the binary file.

  Are you sure? yes | no