Changeset 10 for trunk/Z80/Z80.pas
- Timestamp:
- Apr 20, 2026, 9:52:45 PM (6 days ago)
- File:
-
- 1 edited
-
trunk/Z80/Z80.pas (modified) (20 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Z80/Z80.pas
r9 r10 57 57 MessageText: string; 58 58 procedure Error(Message: string); 59 function GetCarry: Boolean; 60 function GetParityOverflow: Boolean; 61 function GetSignNegative: Boolean; 62 function GetZero: Boolean; 63 procedure SetCarry(AValue: Boolean); 64 procedure SetParityOverflow(AValue: Boolean); 65 procedure SetSignNegative(AValue: Boolean); 66 procedure SetZero(AValue: Boolean); 59 67 procedure SetRunning(AValue: Boolean); 60 68 function DoRead(Address: Word): Byte; … … 72 80 procedure Call(Address: Word); 73 81 procedure CallCond(Address: Word; Condition: Boolean); 74 procedure Cp (Data: Byte);82 procedure CpByte(Data: Byte); 75 83 procedure Jr(Condition: Boolean); 76 84 procedure Jp(Condition: Boolean); … … 808 816 RegI: Byte; 809 817 RegR: Byte; 810 Carry: Boolean;811 Zero: Boolean;812 ParityOverflow: Boolean;813 SignNegative: Boolean;814 818 Memory: TMemory; 815 819 Ticks: Cardinal; … … 823 827 constructor Create; 824 828 destructor Destroy; override; 829 property Carry: Boolean read GetCarry write SetCarry; 830 property Zero: Boolean read GetZero write SetZero; 831 property ParityOverflow: Boolean read GetParityOverflow 832 write SetParityOverflow; 833 property SignNegative: Boolean read GetSignNegative write SetSignNegative; 825 834 property Thread: TCpuThread read FThread; 826 835 property Running: Boolean read FRunning write SetRunning; … … 858 867 DoMessage(Message + ' on address ' + IntToHex(Word(PC), 4)); 859 868 Halt; 869 end; 870 871 function TCpuZ80.GetCarry: Boolean; 872 begin 873 Result := (AF.F and $1) <> 0; 874 end; 875 876 function TCpuZ80.GetParityOverflow: Boolean; 877 begin 878 Result := (AF.F and $4) <> 0; 879 end; 880 881 function TCpuZ80.GetSignNegative: Boolean; 882 begin 883 Result := (AF.F and $80) <> 0; 884 end; 885 886 function TCpuZ80.GetZero: Boolean; 887 begin 888 Result := (AF.F and $40) <> 0; 889 end; 890 891 procedure TCpuZ80.SetCarry(AValue: Boolean); 892 begin 893 AF.F := (AF.F and $fe) or Byte(AValue); 894 end; 895 896 procedure TCpuZ80.SetParityOverflow(AValue: Boolean); 897 begin 898 AF.F := (AF.F and $fb) or (Byte(AValue) shl 2); 899 end; 900 901 procedure TCpuZ80.SetSignNegative(AValue: Boolean); 902 begin 903 AF.F := (AF.F and $7f) or (Byte(AValue) shl 7); 904 end; 905 906 procedure TCpuZ80.SetZero(AValue: Boolean); 907 begin 908 AF.F := (AF.F and $bf) or (Byte(AValue) shl 6); 860 909 end; 861 910 … … 968 1017 end; 969 1018 970 procedure TCpuZ80.Cp (Data: Byte);1019 procedure TCpuZ80.CpByte(Data: Byte); 971 1020 var 972 TempByte: Byte; 973 begin 974 Carry := Data > AF.A; 975 TempByte := Byte(ShortInt(AF.A) - ShortInt(Data)); 976 Zero := TempByte = 0; 1021 Temp: Byte; 1022 begin 1023 Temp := AF.A; 1024 SubByte(Temp, Data); 977 1025 end; 978 1026 … … 1011 1059 1012 1060 procedure TCpuZ80.AddByte(var Target: Byte; Second: Byte); 1013 begin 1014 Target := Byte(Target + Second); 1061 var 1062 Temp: Word; 1063 begin 1064 Temp := Target + Second; 1065 ParityOverflow := ((Target and $80) = (Second and $80)) and 1066 ((Target and $80) <> (Temp and $80)); 1067 Carry := (Temp and $100) <> 0; 1068 Zero := Byte(Temp) = 0; 1069 SignNegative := (Temp and $80) <> 0; 1070 Target := Byte(Temp); 1015 1071 end; 1016 1072 1017 1073 procedure TCpuZ80.AddWord(var Target: Word; Second: Word); 1018 begin 1019 Target := Word(Target + Second); 1074 var 1075 Temp: Cardinal; 1076 begin 1077 Temp := Target + Second; 1078 Carry := Temp > $ffff; 1079 Target := Word(Temp + Second); 1020 1080 end; 1021 1081 1022 1082 procedure TCpuZ80.AdcByte(var Target: Byte; Second: Byte); 1023 begin 1024 Target := Target + Second; 1083 var 1084 Temp: Word; 1085 begin 1086 Temp := Target + Second + Byte(Carry); 1087 ParityOverflow := ((Target and $80) = (Second and $80)) and 1088 ((Target and $80) <> (Temp and $80)); 1089 Carry := (Temp and $100) <> 0; 1090 Zero := Byte(Temp) = 0; 1091 SignNegative := (Temp and $80) <> 0; 1092 Target := Byte(Temp); 1025 1093 end; 1026 1094 1027 1095 procedure TCpuZ80.AdcWord(var Target: Word; Second: Word); 1028 begin 1029 Target := Target - Second; 1096 var 1097 Temp: Cardinal; 1098 begin 1099 Temp := Target + Second + Byte(Carry); 1100 Carry := Temp > $ffff; 1101 Target := Word(Temp + Second); 1030 1102 end; 1031 1103 1032 1104 procedure TCpuZ80.SubByte(var Target: Byte; Second: Byte); 1033 begin 1034 Target := Byte(Target - Second); 1105 var 1106 Temp: SmallInt; 1107 begin 1108 Temp := ShortInt(Target) - ShortInt(Second); 1109 ParityOverflow := ((Target and $80) <> (Second and $80)) and 1110 ((Target and $80) <> (Temp and $80)); 1111 Carry := (Temp and $100) <> 0; 1112 Zero := Byte(Temp) = 0; 1113 SignNegative := (Temp and $80) <> 0; 1114 Target := Byte(Temp); 1035 1115 end; 1036 1116 1037 1117 procedure TCpuZ80.SbcByte(var Target: Byte; Second: Byte); 1038 begin 1039 Target := Target - Second; 1118 var 1119 Temp: SmallInt; 1120 begin 1121 Temp := ShortInt(Target) - ShortInt(Second) - Byte(Carry); 1122 ParityOverflow := ((Target and $80) <> (Second and $80)) and 1123 ((Target and $80) <> (Temp and $80)); 1124 Carry := (Temp and $100) <> 0; 1125 Zero := Byte(Temp) = 0; 1126 SignNegative := (Temp and $80) <> 0; 1127 Target := Byte(Temp); 1040 1128 end; 1041 1129 1042 1130 procedure TCpuZ80.SbcWord(var Target: Word; Second: Word); 1043 begin 1044 Target := Target - Second; 1131 var 1132 Temp: Integer; 1133 begin 1134 Temp := SmallInt(Target) - SmallInt(Second); 1135 ParityOverflow := ((Target and $8000) <> (Second and $8000)) and 1136 ((Target and $8000) <> (Temp and $8000)); 1137 Carry := (Temp and $10000) <> 0; 1138 Zero := Word(Temp) = 0; 1139 SignNegative := (Temp and $8000) <> 0; 1140 Target := Word(Temp); 1045 1141 end; 1046 1142 … … 1048 1144 begin 1049 1145 Target := Target xor Second; 1146 Carry := False; 1147 Zero := Target = 0; 1148 ParityOverflow := not Odd(Target); 1149 SignNegative := (Target and $80) <> 0; 1050 1150 end; 1051 1151 … … 1053 1153 begin 1054 1154 Target := Target or Second; 1155 Carry := False; 1156 Zero := Target = 0; 1157 ParityOverflow := not Odd(Target); 1158 SignNegative := (Target and $80) <> 0; 1055 1159 end; 1056 1160 … … 1058 1162 begin 1059 1163 Target := Target and Second; 1164 Carry := False; 1165 Zero := Target = 0; 1166 ParityOverflow := not Odd(Target); 1167 SignNegative := (Target and $80) <> 0; 1060 1168 end; 1061 1169 1062 1170 procedure TCpuZ80.IncByte(var Reg: Byte); 1063 1171 begin 1172 ParityOverflow := Reg = $7f; 1173 1064 1174 if Reg = High(Reg) then Reg := 0 1065 1175 else Inc(Reg); 1176 1177 Zero := Reg = 0; 1178 SignNegative := (Reg and $80) <> 0; 1066 1179 end; 1067 1180 … … 1074 1187 procedure TCpuZ80.DecByte(var Reg: Byte); 1075 1188 begin 1189 ParityOverflow := Reg = $80; 1190 1076 1191 if Reg = 0 then Reg := High(Reg) 1077 else Dec(Reg) 1192 else Dec(Reg); 1193 1194 Zero := Reg = 0; 1195 SignNegative := (Reg and $80) <> 0; 1078 1196 end; 1079 1197 … … 1081 1199 begin 1082 1200 if Reg = 0 then Reg := High(Reg) 1083 else Dec(Reg) 1201 else Dec(Reg); 1084 1202 end; 1085 1203 … … 1087 1205 begin 1088 1206 Carry := (Data and $80) <> 0; 1089 Data := ( Data shl 1) or Byte(Carry);1207 Data := ((Data shl 1) and $ff) or Byte(Carry); 1090 1208 end; 1091 1209 … … 1884 2002 Temp: ShortInt; 1885 2003 begin 1886 Dec(BC.B); 2004 if BC.B = 0 then BC.B := $ff 2005 else Dec(BC.B); 1887 2006 Temp := ShortInt(ReadByte); 1888 2007 if BC.B <> 0 then … … 2743 2862 procedure TCpuZ80.CP_B; 2744 2863 begin 2745 Cp (BC.B);2864 CpByte(BC.B); 2746 2865 end; 2747 2866 2748 2867 procedure TCpuZ80.CP_C; 2749 2868 begin 2750 Cp (BC.C);2869 CpByte(BC.C); 2751 2870 end; 2752 2871 2753 2872 procedure TCpuZ80.CP_D; 2754 2873 begin 2755 Cp (DE.D);2874 CpByte(DE.D); 2756 2875 end; 2757 2876 2758 2877 procedure TCpuZ80.CP_E; 2759 2878 begin 2760 Cp (DE.E);2879 CpByte(DE.E); 2761 2880 end; 2762 2881 2763 2882 procedure TCpuZ80.CP_H; 2764 2883 begin 2765 Cp (HL.H);2884 CpByte(HL.H); 2766 2885 end; 2767 2886 2768 2887 procedure TCpuZ80.CP_L; 2769 2888 begin 2770 Cp (HL.L);2889 CpByte(HL.L); 2771 2890 end; 2772 2891 2773 2892 procedure TCpuZ80.CP_HL_Indirect; 2774 2893 begin 2775 C P(DoRead(HL.Value));2894 CpByte(DoRead(HL.Value)); 2776 2895 end; 2777 2896 2778 2897 procedure TCpuZ80.CP_A; 2779 2898 begin 2780 C P(AF.A);2899 CpByte(AF.A); 2781 2900 end; 2782 2901 … … 3091 3210 procedure TCpuZ80.CP_N; 3092 3211 begin 3093 Cp (ReadByte);3212 CpByte(ReadByte); 3094 3213 end; 3095 3214 … … 3121 3240 procedure TCpuZ80.NEG; 3122 3241 begin 3242 ParityOverflow := AF.A = $80; 3243 Carry := AF.A <> $0; 3123 3244 AF.A := AF.A xor $ff; 3124 3245 IncByte(AF.A); 3246 SignNegative := (AF.A and $80) <> 1; 3247 Zero := AF.A = 0; 3125 3248 end; 3126 3249 … … 3312 3435 procedure TCpuZ80.CPI; 3313 3436 begin 3314 Cp (DoRead(HL.Value));3437 CpByte(DoRead(HL.Value)); 3315 3438 IncWord(HL.Value); 3316 3439 DecWord(BC.Value); … … 3341 3464 procedure TCpuZ80.CPD; 3342 3465 begin 3343 Cp (DoRead(HL.Value));3466 CpByte(DoRead(HL.Value)); 3344 3467 DecWord(HL.Value); 3345 3468 DecWord(BC.Value); … … 5372 5495 Opcode := ReadByte; 5373 5496 if Opcode = $CB then begin 5497 Opcode := ReadByte; 5374 5498 Instruction := TInstruction($100 or ReadByte); 5375 5499 end 5376 5500 else if Opcode = $DD then begin 5377 Instruction := TInstruction($200 or ReadByte); 5501 Opcode := ReadByte; 5502 if Opcode = $CB then begin 5503 Opcode := ReadByte; 5504 Instruction := TInstruction($500 or Opcode); 5505 end else Instruction := TInstruction($200 or Opcode); 5378 5506 end 5379 5507 else if Opcode = $ED then begin 5380 Instruction := TInstruction($300 or ReadByte); 5508 Opcode := ReadByte; 5509 Instruction := TInstruction($300 or Opcode); 5381 5510 end 5382 5511 else if Opcode = $FD then begin 5383 Instruction := TInstruction($400 or ReadByte); 5512 Opcode := ReadByte; 5513 if Opcode = $CB then begin 5514 Opcode := ReadByte; 5515 Instruction := TInstruction($600 or Opcode); 5516 end else Instruction := TInstruction($400 or Opcode); 5384 5517 end 5385 5518 else Instruction := TInstruction(Opcode);
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/mzxemu/chrome/site/your_project_logo.png)