kosarev / z80

Fast and flexible Z80/i8080 emulator with C++ and Python APIs
MIT License
65 stars 10 forks source link

Revisit the SCF and CCF logic #25

Open kosarev opened 3 years ago

kosarev commented 3 years ago

In an attempt to make sure we do the right thing about the WZ register for the undocumented BIT r, b, (i + d) instructions (#21 and #22), I ran into the PORTAR MSX I/O MAPPING paper, http://datassette.nyc3.cdn.digitaloceanspaces.com/tech/portarmsxiomapping.pdf . It says:

For 'SCF' and 'CCF' flags are calculated as "(A OR F) AND 28h", ie. the flags remain set if they have been set before.

With our current implementation being changed to that, we still seem to pass ZEXALL:

diff --git a/z80.h b/z80.h
index 8c94574..dd14b32 100644
--- a/z80.h
+++ b/z80.h
@@ -3709,7 +3709,7 @@ public:
     void on_scf() {
         fast_u8 a = self().on_get_a();
         fast_u8 f = self().on_get_f();
-        f = (f & (sf_mask | zf_mask | pf_mask)) | (a & (yf_mask | xf_mask)) |
+        f = (f & (sf_mask | zf_mask | pf_mask)) | ((a | f) & (yf_mask | xf_mask)) |
                 cf_mask;
         self().on_set_f(f); }
     void on_set(unsigned b, reg r, fast_u8 d) {
Preliminary tests complete
Z80all instruction exerciser
<adc,sbc> hl,<bc,de,hl,sp>....  OK
add hl,<bc,de,hl,sp>..........  OK
add ix,<bc,de,ix,sp>..........  OK
add iy,<bc,de,iy,sp>..........  OK
aluop a,nn....................  OK
aluop a,<b,c,d,e,h,l,(hl),a>..  OK
aluop a,<ixh,ixl,iyh,iyl>.....  OK
aluop a,(<ix,iy>+1)...........  OK
bit n,(<ix,iy>+1).............  OK
bit n,<b,c,d,e,h,l,(hl),a>....  OK
cpd<r>........................  OK
cpi<r>........................  OK
<daa,cpl,scf,ccf>.............  OK

This raises some thoughts:

Marking this a bug to reflect the severity of the issue.