@@ -841,9 +841,16 @@ class Cpu
841841 return v;
842842 }
843843
844+ uint16_t doSetmo () {
845+ _carry = false ;
846+ _overflow = false ;
847+ _auxiliary = false ;
848+ doPZS (0xFFFF );
849+ return 0xFFFF ;
850+ }
851+
844852 uint16_t doALU () {
845853 uint16_t t;
846- bool oldAF;
847854 uint32_t a = _registers[_aluInput + 12 ], v;
848855 switch (_alu) {
849856 case 0x00 : // ADD
@@ -868,50 +875,70 @@ class Cpu
868875 case 0x0b : // RRCY
869876 return doRotate (((a & wordMask ()) >> 1 ) | topBit (_carry), a, lowBit (a));
870877 case 0x0c : // SHL
871- return doShift (a << 1 , a, topBit (a), (a & 8 ) != 0 );
878+ return doShift (a << 1 , a, topBit (a), (a & 0x08 ) != 0 );
872879 case 0x0d : // SHR
873- return doShift ((a & wordMask ()) >> 1 , a, lowBit (a), (a & 0x20 ) != 0 );
880+ return doShift ((a & wordMask ()) >> 1 , a, lowBit (a), false );
874881 case 0x0e : // SETMO
875- return doShift ( 0xffff , a, false , false );
882+ return doSetmo ( );
876883 case 0x0f : // SAR
877- return doShift (((a & wordMask ()) >> 1 ) | topBit (topBit (a)), a, lowBit (a), (a & 0x20 ) != 0 );
884+ return doShift (((a & wordMask ()) >> 1 ) | topBit (topBit (a)), a, lowBit (a), false );
878885 case 0x10 : // PASS
879886 // return doShift(a, a, false, false);
880887 return doPass (a);
881888 case 0x14 : // DAA
882- oldAF = _auxiliary;
889+ {
890+ const bool old_af = _auxiliary;
891+ const bool old_cf = _carry;
883892 t = a;
884- if (oldAF || (a & 0x0f ) > 9 ) {
885- t = a + 6 ;
886- _overflow = topBit (t & (t ^ a));
893+ auto adj = 0 ;
894+
895+ // Extremely funky undefined OF behavior (from MartyPC)
896+ _overflow = (a <= 0x7f ) && ((!old_cf && a >= 0x7A ) || (old_cf && a >= 0x1A ));
897+
898+ if (old_af || (a & 0x0f ) > 9 ) {
899+ adj = 6 ;
900+ t = a + adj;
901+ // _overflow = topBit(t & (t ^ a));
887902 _auxiliary = true ;
888903 }
889- if (_carry || a > (oldAF ? 0x9fU : 0x99U )) {
890- v = t + 0x60 ;
891- _overflow = topBit (v & (v ^ t));
904+ if (_carry || a > (old_af ? 0x9fU : 0x99U )) {
905+ adj = 0x60 ;
906+ v = t + adj;
907+ // _overflow = topBit(v & (v ^ t));
892908 _carry = true ;
893909 }
894- else
910+ else {
895911 v = t;
912+ }
913+ // _overflow = (a ^ v) & (adj ^ v) & 0x80 != 0;
896914 doPZS (v);
897915 break ;
916+ }
898917 case 0x15 : // DAS
899- oldAF = _auxiliary;
918+ {
919+ bool old_af = _auxiliary;
900920 t = a;
901- if (oldAF || (a & 0x0f ) > 9 ) {
921+ auto adj = 0 ;
922+ if (old_af || (a & 0x0f ) > 9 ) {
902923 t = a - 6 ;
903- _overflow = topBit (a & (t ^ a));
924+ adj = 6 ;
925+ // _overflow = topBit(a & (t ^ a));
904926 _auxiliary = true ;
905927 }
906- if (_carry || a > (oldAF ? 0x9fU : 0x99U )) {
928+ if (_carry || a > (old_af ? 0x9fU : 0x99U )) {
907929 v = t - 0x60 ;
908- _overflow = topBit (t & (v ^ t));
930+ adj = 0x60 ;
931+ // _overflow = topBit(t & (v ^ t));
909932 _carry = true ;
910933 }
911- else
934+ else {
912935 v = t;
936+ }
937+ // More undefined overflow flag fun!
938+ _overflow = ((a ^ adj) & (a ^ v) & 0x80 ) != 0 ;
913939 doPZS (v);
914940 break ;
941+ }
915942 case 0x16 : // AAA
916943 _carry = (_auxiliary || (a & 0xf ) > 9 );
917944 _auxiliary = _carry;
@@ -1002,7 +1029,8 @@ class Cpu
10021029 rb (_destination & 3 ) = v;
10031030 break ;
10041031 case 15 : // F
1005- flags () = (v & 0xfd5 ) | 2 ;
1032+ // Ensure our reserved flags are always set correctly
1033+ flags () = (v & 0xFFD5 ) | 0xF002 ;
10061034 break ;
10071035 case 16 : // X (AH)
10081036 case 17 : // B (CH)? - not used
0 commit comments