spjewkes / jrnz

A work-in-progress ZX Spectrum emulator
MIT License
1 stars 0 forks source link

z80doc is reporting issue with tests for daa, cpl, scf, ccf #38

Closed spjewkes closed 6 months ago

spjewkes commented 6 months ago

We need to look at the problem here. It may just be setting of flags is wrong or something worse. Ideally we should write some unit tests to go alongside.

spjewkes commented 6 months ago

Regarding the DAA instruction, I cam across this article on stackoverflow: https://stackoverflow.com/questions/8119577/z80-daa-instruction which might be useful.

I also wonder if the Trashman issue (where the bonus jumps down very quickly) is related to the DAA instruction. It does seem to be executing the DAA a few times in the code.

spjewkes commented 6 months ago

I counted the DAA instructions being executed in Trashman and it seems to relate to the number of time the bonus descreases. So I wonder if that is the problem. It might be possible to break on this instruction in the emulator and Fuse to see what is going on.

It's located at 0xcb46

spjewkes commented 6 months ago

DAA is broken because you need to take into account whether the AddSubtract is set (i.e. a negative instruction was done previously). If this is the case then the values need to be added using 2's complement.

There's the following table in my Rodney Zaks book which should (hopefully) make it a little clearer:

--------------------------------------------------------------------------------
|           | C Flag  | HEX value in | H Flag | HEX value in | Number  | C flag|
| Operation | Before  | upper digit  | Before | lower digit  | added   | After |
|           | DAA     | (bit 7-4)    | DAA    | (bit 3-0)    | to byte | DAA   |
|------------------------------------------------------------------------------|
|           |    0    |     0-9      |   0    |     0-9      |   00    |   0   |
|   ADD     |    0    |     0-8      |   0    |     A-F      |   06    |   0   |
|           |    0    |     0-9      |   1    |     0-3      |   06    |   0   |
|   ADC     |    0    |     A-F      |   0    |     0-9      |   60    |   1   |
|           |    0    |     9-F      |   0    |     A-F      |   66    |   1   |
|   INC     |    0    |     A-F      |   1    |     0-3      |   66    |   1   |
|           |    1    |     0-2      |   0    |     0-9      |   60    |   1   |
|           |    1    |     0-2      |   0    |     A-F      |   66    |   1   |
|           |    1    |     0-3      |   1    |     0-3      |   66    |   1   |
|------------------------------------------------------------------------------|
|   SUB     |    0    |     0-9      |   0    |     0-9      |   00    |   0   |
|   SBC     |    0    |     0-8      |   1    |     6-F      |   FA    |   0   |
|   DEC     |    1    |     7-F      |   0    |     0-9      |   A0    |   1   |
|   NEG     |    1    |     6-F      |   1    |     6-F      |   9A    |   1   |
|------------------------------------------------------------------------------|

I think my earlier attempts at an implementation was using a website that described the DAA instruction. However, this was not as detailed as the above table and only really described the Addition case.

spjewkes commented 6 months ago

I'm still seeing a failure at version 730215bda04afc7919a80a924d34ba4f97b4e31a. This is after (what I believe) is the correct behaviour for the DAA instruction. I should compare it against the Fuse emulator to make sure. I also need to check the DAA's flag settings in case I've done something stupid there.

CPL, SCF and CCF all need to be checked too as they may be the cause.

spjewkes commented 6 months ago

z80doc is now passing. I think the issue was primarily due to the fact I was not setting the half flag correctly. The reason is that instruction.cpp relies on a side effect in storage_elements when we do addition and subtraction to set this flag up. The problem was that my implementation was bypassing storage_element's addition/subtraction. Now I've fixed this, it now works.

Closing issue.