Another interesting BASIC to test the 8080 instructions

A project log for Isetta TTL computer

Retro computer built from TTL, with 6502 and Z80 instruction set. Includes video system.

roelhroelh 05/23/2023 at 18:521 Comment

Since the Isetta supports instructions of the Z80 processor, it also supports the famous 8080 processor, because the Z80 has the 8080 instruction set as a basis. The 8080 is interesting because it is the grandfather of almost all INTEL CPU's for personal computers of the past 40 years.

One of the very first personal computers was the Altair 8800 from the company MITS. It was built around the 8080 processor. Bill Gates, Paul Allen and Monte Davidoff created a BASIC interpreter for this computer, the Altair BASIC. It was called a 4KByte BASIC. But the actual program was smaller than 4K, because 4K was all memory that the Altair had ! There were only 790 bytes free for user programs ! Altair BASIC was the very first product of Microsoft !

So I used this Altair BASIC to test the 8080 instructions on the Javascript emulator of the Isetta processor. I found an Annotated disassembly and a binary version. And I really needed the disassembly, to understand a little of the program.

Subtract and compare

After the first tests, I found that for the 8080/Z80, the carry flag behaviour for the subtract and compare instructions is inverted w.r.t. the behaviour in the 6502. I created a new microinstruction that complements the carry flag for the 8080/Z80. In several situations, it can be executed at the same time as another microinstruction.

Parity flag

Altair Basic has a FCompare at 0A4C that compares two floating point numbers. It returns
one of the following values:

That's very logical. Now you can simply test the sign flag or zero flag to jump according to the result.

But in two instances, at 0B63 and 0C03, it is followed by a JP PO (jump on parity odd) instruction, that will jump if the result is greater than zero (as 0x01 is the only one of these three values that has an odd number of '1' bits in the byte)

On the 8080, (almost ?) all arithmetic and logic instructions that act on the accumulator will 
set the P flag according to the parity.

But on the Z80, the parity flag behaviour is different. Logic instructions will set the flag according to the parity, but the arithmetic instructions will set the flag when there is an overflow. And indeed, it has been reported on the Internet that the Altair Basic will not work on a replica Altair that has a Z80 processor instead of the 8080 in the original Altair.

So, although it is widely believed that the Z80 can run all programs intended for the 8080, this is not true because the behaviour of the P/V flag is different.

And on the Isetta it is also a problem because parity is not implemented at all.

The parity flag is tested with JP PO on only two occasions, at 0B66 and 0C04. Both instances are preceded by a call to FCompare at 0A4C. I replaced the calls to FCompare by a new subroutine, that does the following:

Both JP PO instructions are now replaced by JP P (jump if positive). The parity flag is not needed any more (at least not for this BASIC).

A nasty bug

Strange thing were going on. The display of numbers displayed the first digit as a letter. And with another test program (TRS-80 Basic), identifiers were not recognized. After a few days, I found out that the carry flag was not cleared after an XOR A,A instruction. The microcode seemed ok, it said the carry was written (and at the same time a load operation was done). But for the carry-complement (for subtract and compare) I changed the behaviour such that writing the carry while doing a load resulted in a complement-carry ! Sometimes it is difficult to program your own contraptions.

Other changes to the BASIC

The code at the following positions was changed for character output and keyboard input:

Another thing was, that this basic is full of self-modifying code. I found that when the program is initializing, it somehow seems to find out at which I/O ports the character I/O is, and writes the I/O addresses directly into the instructions that do the I/O ! So these initialisation code was changed to NOP's.

The initialization code is at the end of the program. After initialization, this code is overwritten by the user's program.

After all is done, we see the following:

At startup, the user must tell what the memory size is, and how many characters will fit on a line of his display (or printer). It then asks if you want certain functions to be available. If you say 'N', these functions will be overwritten by your application program (providing more free bytes).

A small test program:

Yes, it does floating point ! If want to know what it can do look in the Altair BASIC reference manual. And if you program in this basic and encounter a problem, some help is never far away:


Ken KD5ZXG wrote 05/24/2023 at 14:10 point

  Are you sure? yes | no