After remembering where I was in the project I started to look for bugs in my CPU. I know it does not fully work, for example since running in TI BASIC I get:

PRINT 1*-1 1

So something is not working in the CPU. In order to work on this, I took advantage of my previous design, which combines a real TMS99105 CPU with my FPGA implementation of the TI-99/4A. Running the above on it yields the correct result, -1.

So I wrote a piece of test code, ran it both on the FPGA CPU and the TMS99105 while capturing the results (by dumping a section of memory on both systems to a file), below is the comparison:

Left hand side is TMS99105, right hand side is my soft CPU, i.e. the FPGA TMS9900 core. Each instruction is tested 8 times with different data. The source code of this test is below, after the explanation below.



Each instruction test output takes 8 bytes or 4 words. The last word of the output are the flags (only top 6 bits preserved). The result words are R1,R2,R3 and flags. The instruction is always executed like SUB R1,R2. Thus R2 is the result and R1 shows the source operand.

With that, we can see that there is a difference with the second instruction under test. It is the subtract instruction.

The first subtraction works fine (SUB 1,2, i.e. 2-1) but the second has a difference in the flags (SUB >7FFF,1) where the soft CPU has >2800 while the real CPU has >2000.

The flag that is different is ST4 i.e. the overflow flag. Also in the the other SUB instructions the overflow flag is sometimes bogus, here is a table of the eight cases:

SUB >1,>2 OK (note that with the TMS9900 this actually is the 2-1 operation)

SUB >7FFF,1 Bug: soft-cpu asserts overflow

SUB >8000,>7FFF Bug: soft-cpu does not assert overflow

SUB >7FFF,>8000 Bug: soft-cpu does not assert overflow

SUB >FFFF,>8000 OK

SUB >8000,>FFFF Bug: soft-cpu asserts overflow

SUB >8000,>8000 Bug: soft-cpu asserts overflow

SUB >0,>8000 OK

Looking at the data sheet carefully, there is a difference how ST4 (overflow) is asserted for adds and subs, the first condition is inverted. I bet I don’t do this.

Adds: If MSB(SA) == MSB(DA) and MSB of result != MSB(DA)

Subs: If MSB(SA) != MSB(DA) and MSB of result != MSB(DA)

The only other difference with this data is at >0120, and here the result is wrong (but flags ok). Since R3 has changed, it must be a DIV or MPY instruction.

First instruction test output at 0..>3F, 2nd at 40..7F, 3rd at 80..BF, 4th at C0..FF, 5th at 100..13F. So the fifth instruction.

And indeed it is the DIV instruction - like PNR reported. One of my test cases at least now catches the problem. It is fifth test case, from above it is

DIV >FFFF,>8000 i.e. >8000 divided by >FFFF. The result should be >8000 as quotient and >8000 as remainder.

But my code gives >FFFE as quotient and >FFFE as remainder too.

Here is the TMS9900 assembler test code (story continues after the listing):