Changeset 182 for branches/virtualcpu4/UCpu.pas
- Timestamp:
- Apr 13, 2019, 1:32:32 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/virtualcpu4/UCpu.pas
r181 r182 41 41 TCpu = class 42 42 private 43 FAddrSizeBase: TBitWidth; 44 FDataSizeBase: TBitWidth; 43 45 FOnInput: TInputEvent; 44 46 FOnOutput: TOutputEvent; … … 46 48 FTicks: Integer; 47 49 Instructions: array[TOpcode] of TInstructionEvent; 48 DataSizeLast: TBitWidth; 49 DataSizePrefix: TBitWidth; 50 AddrSizeLast: TBitWidth; 51 AddrSizePrefix: TBitWidth; 50 Prefix: Boolean; 52 51 Z: Boolean; 53 52 Thread: TCpuThread; … … 101 100 procedure InstAddrSize; 102 101 procedure InitInstructions; 102 procedure SetAddrSizeBase(AValue: TBitWidth); 103 procedure SetDataSizeBase(AValue: TBitWidth); 103 104 public 104 105 Memory: Pointer; … … 107 108 IP: TAddress; 108 109 SP: TAddress; 110 DataSize: TBitWidth; 109 111 AddrSize: TBitWidth; 110 DataSize: TBitWidth;111 112 procedure Run; 112 113 procedure Step; inline; … … 121 122 constructor Create; 122 123 destructor Destroy; override; 124 property DataSizeBase: TBitWidth read FDataSizeBase write SetDataSizeBase; 125 property AddrSizeBase: TBitWidth read FAddrSizeBase write SetAddrSizeBase; 123 126 property Ticks: Integer read FTicks; 124 127 property Running: Boolean read FRunning; … … 140 143 Param2: TOpcodeParam; 141 144 Param3: TOpcodeParam; 145 Prefix: Boolean; 142 146 end; 143 147 … … 146 150 BitWidthText: array[TBitWidth] of string = ('None', '8-bit', '16-bit', '32-bit', '64-bit'); 147 151 OpcodeDef: array[TOpcode] of TOpcodeDef = ( 148 (Name: 'NOP'; Param1: prNone; Param2: prNone; Param3: prNone ),149 (Name: 'HALT'; Param1: prNone; Param2: prNone; Param3: prNone ),150 (Name: 'LD'; Param1: prReg; Param2: prReg; Param3: prNone ),151 (Name: 'LDI'; Param1: prReg; Param2: prData; Param3: prNone ),152 (Name: 'JP'; Param1: prAddr; Param2: prNone; Param3: prNone ),153 (Name: 'JPZ'; Param1: prAddr; Param2: prNone; Param3: prNone ),154 (Name: 'JPNZ'; Param1: prAddr; Param2: prNone; Param3: prNone ),155 (Name: 'JR'; Param1: prAddrRel; Param2: prNone; Param3: prNone ),156 (Name: 'JRZ'; Param1: prAddrRel; Param2: prNone; Param3: prNone ),157 (Name: 'JRNZ'; Param1: prAddrRel; Param2: prNone; Param3: prNone ),158 (Name: 'NEG'; Param1: prReg; Param2: prNone; Param3: prNone ),159 (Name: 'CLR'; Param1: prReg; Param2: prNone; Param3: prNone ),160 (Name: 'LDM'; Param1: prReg; Param2: prReg; Param3: prNone ),161 (Name: 'STM'; Param1: prReg; Param2: prReg; Param3: prNone ),162 (Name: 'EX'; Param1: prReg; Param2: prReg; Param3: prNone ),163 (Name: 'PUSH'; Param1: prReg; Param2: prNone; Param3: prNone ),164 (Name: 'POP'; Param1: prReg; Param2: prNone; Param3: prNone ),165 (Name: 'CALL'; Param1: prAddr; Param2: prNone; Param3: prNone ),166 (Name: 'RET'; Param1: prNone; Param2: prNone; Param3: prNone ),167 (Name: 'ADD'; Param1: prReg; Param2: prReg; Param3: prNone ),168 (Name: 'ADDI'; Param1: prReg; Param2: prData; Param3: prNone ),169 (Name: 'SUB'; Param1: prReg; Param2: prReg; Param3: prNone ),170 (Name: 'SUBI'; Param1: prReg; Param2: prData; Param3: prNone ),171 (Name: 'INC'; Param1: prReg; Param2: prNone; Param3: prNone ),172 (Name: 'DEC'; Param1: prReg; Param2: prNone; Param3: prNone ),173 (Name: 'IN'; Param1: prReg; Param2: prAddr; Param3: prNone ),174 (Name: 'OUT'; Param1: prAddr; Param2: prReg; Param3: prNone ),175 (Name: 'SHL'; Param1: prReg; Param2: prReg; Param3: prNone ),176 (Name: 'SHR'; Param1: prReg; Param2: prReg; Param3: prNone ),177 (Name: 'DP8'; Param1: prNone; Param2: prNone; Param3: prNone ),178 (Name: 'DP16'; Param1: prNone; Param2: prNone; Param3: prNone ),179 (Name: 'DP32'; Param1: prNone; Param2: prNone; Param3: prNone ),180 (Name: 'DP64'; Param1: prNone; Param2: prNone; Param3: prNone ),181 (Name: 'DS'; Param1: prNone; Param2: prNone; Param3: prNone ),182 (Name: 'AS'; Param1: prNone; Param2: prNone; Param3: prNone ),183 (Name: 'TEST'; Param1: prReg; Param2: prNone; Param3: prNone ),184 (Name: 'AND'; Param1: prReg; Param2: prReg; Param3: prNone ),185 (Name: 'OR'; Param1: prReg; Param2: prReg; Param3: prNone ),186 (Name: 'XOR'; Param1: prReg; Param2: prReg; Param3: prNone ),187 (Name: 'LDDR'; Param1: prReg; Param2: prReg; Param3: prReg ),188 (Name: 'LDDR'; Param1: prReg; Param2: prReg; Param3: prReg ),189 (Name: 'MUL'; Param1: prReg; Param2: prReg; Param3: prNone ),190 (Name: 'DIV'; Param1: prReg; Param2: prReg; Param3: prNone ),191 (Name: 'MOD'; Param1: prReg; Param2: prReg; Param3: prNone ),192 (Name: 'AP8'; Param1: prNone; Param2: prNone; Param3: prNone ),193 (Name: 'AP16'; Param1: prNone; Param2: prNone; Param3: prNone ),194 (Name: 'AP32'; Param1: prNone; Param2: prNone; Param3: prNone ),195 (Name: 'AP64'; Param1: prNone; Param2: prNone; Param3: prNone )152 (Name: 'NOP'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: False), 153 (Name: 'HALT'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: False), 154 (Name: 'LD'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False), 155 (Name: 'LDI'; Param1: prReg; Param2: prData; Param3: prNone; Prefix: False), 156 (Name: 'JP'; Param1: prAddr; Param2: prNone; Param3: prNone; Prefix: False), 157 (Name: 'JPZ'; Param1: prAddr; Param2: prNone; Param3: prNone; Prefix: False), 158 (Name: 'JPNZ'; Param1: prAddr; Param2: prNone; Param3: prNone; Prefix: False), 159 (Name: 'JR'; Param1: prAddrRel; Param2: prNone; Param3: prNone; Prefix: False), 160 (Name: 'JRZ'; Param1: prAddrRel; Param2: prNone; Param3: prNone; Prefix: False), 161 (Name: 'JRNZ'; Param1: prAddrRel; Param2: prNone; Param3: prNone; Prefix: False), 162 (Name: 'NEG'; Param1: prReg; Param2: prNone; Param3: prNone; Prefix: False), 163 (Name: 'CLR'; Param1: prReg; Param2: prNone; Param3: prNone; Prefix: False), 164 (Name: 'LDM'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False), 165 (Name: 'STM'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False), 166 (Name: 'EX'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False), 167 (Name: 'PUSH'; Param1: prReg; Param2: prNone; Param3: prNone; Prefix: False), 168 (Name: 'POP'; Param1: prReg; Param2: prNone; Param3: prNone; Prefix: False), 169 (Name: 'CALL'; Param1: prAddr; Param2: prNone; Param3: prNone; Prefix: False), 170 (Name: 'RET'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: False), 171 (Name: 'ADD'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False), 172 (Name: 'ADDI'; Param1: prReg; Param2: prData; Param3: prNone; Prefix: False), 173 (Name: 'SUB'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False), 174 (Name: 'SUBI'; Param1: prReg; Param2: prData; Param3: prNone; Prefix: False), 175 (Name: 'INC'; Param1: prReg; Param2: prNone; Param3: prNone; Prefix: False), 176 (Name: 'DEC'; Param1: prReg; Param2: prNone; Param3: prNone; Prefix: False), 177 (Name: 'IN'; Param1: prReg; Param2: prAddr; Param3: prNone; Prefix: False), 178 (Name: 'OUT'; Param1: prAddr; Param2: prReg; Param3: prNone; Prefix: False), 179 (Name: 'SHL'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False), 180 (Name: 'SHR'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False), 181 (Name: 'DP8'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: True), 182 (Name: 'DP16'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: False), 183 (Name: 'DP32'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: True), 184 (Name: 'DP64'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: True), 185 (Name: 'DS'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: False), 186 (Name: 'AS'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: False), 187 (Name: 'TEST'; Param1: prReg; Param2: prNone; Param3: prNone; Prefix: False), 188 (Name: 'AND'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False), 189 (Name: 'OR'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False), 190 (Name: 'XOR'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False), 191 (Name: 'LDDR'; Param1: prReg; Param2: prReg; Param3: prReg; Prefix: False), 192 (Name: 'LDDR'; Param1: prReg; Param2: prReg; Param3: prReg; Prefix: False), 193 (Name: 'MUL'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False), 194 (Name: 'DIV'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False), 195 (Name: 'MOD'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False), 196 (Name: 'AP8'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: True), 197 (Name: 'AP16'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: True), 198 (Name: 'AP32'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: True), 199 (Name: 'AP64'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: True) 196 200 ); 197 201 … … 991 995 procedure TCpu.InstDataPrefix8; 992 996 begin 993 DataSizePrefix := bw8; 997 DataSize := bw8; 998 Prefix := True; 994 999 end; 995 1000 996 1001 procedure TCpu.InstDataPrefix16; 997 1002 begin 998 DataSizePrefix := bw16; 1003 DataSize := bw16; 1004 Prefix := True; 999 1005 end; 1000 1006 1001 1007 procedure TCpu.InstDataPrefix32; 1002 1008 begin 1003 DataSizePrefix := bw32; 1009 DataSize := bw32; 1010 Prefix := True; 1004 1011 end; 1005 1012 1006 1013 procedure TCpu.InstDataPrefix64; 1007 1014 begin 1008 DataSizePrefix := bw64; 1015 DataSize := bw64; 1016 Prefix := True; 1009 1017 end; 1010 1018 1011 1019 procedure TCpu.InstDataSize; 1012 1020 begin 1013 DataSize := TBitWidth(Read8); 1021 DataSizeBase := TBitWidth(Read8); 1022 DataSize := DataSizeBase; 1014 1023 end; 1015 1024 1016 1025 procedure TCpu.InstAddrPrefix8; 1017 1026 begin 1018 AddrSizePrefix := bw8; 1027 AddrSize := bw8; 1028 Prefix := True; 1019 1029 end; 1020 1030 1021 1031 procedure TCpu.InstAddrPrefix16; 1022 1032 begin 1023 AddrSizePrefix := bw16; 1033 AddrSize := bw16; 1034 Prefix := True; 1024 1035 end; 1025 1036 1026 1037 procedure TCpu.InstAddrPrefix32; 1027 1038 begin 1028 AddrSizePrefix := bw32; 1039 AddrSize := bw32; 1040 Prefix := True; 1029 1041 end; 1030 1042 1031 1043 procedure TCpu.InstAddrPrefix64; 1032 1044 begin 1033 AddrSizePrefix := bw64; 1045 AddrSize := bw64; 1046 Prefix := True; 1034 1047 end; 1035 1048 1036 1049 procedure TCpu.InstAddrSize; 1037 1050 begin 1038 AddrSize := TBitWidth(Read8); 1051 AddrSizeBase := TBitWidth(Read8); 1052 AddrSize := AddrSizeBase; 1039 1053 end; 1040 1054 … … 1091 1105 end; 1092 1106 1107 procedure TCpu.SetAddrSizeBase(AValue: TBitWidth); 1108 begin 1109 if FAddrSizeBase = AValue then Exit; 1110 FAddrSizeBase := AValue; 1111 AddrSize := AValue; 1112 end; 1113 1114 procedure TCpu.SetDataSizeBase(AValue: TBitWidth); 1115 begin 1116 if FDataSizeBase = AValue then Exit; 1117 FDataSizeBase := AValue; 1118 DataSize := AValue; 1119 end; 1120 1093 1121 procedure TCpu.Run; 1094 1122 begin 1123 DataSize := DataSizeBase; 1124 AddrSize := AddrSizeBase; 1095 1125 Terminated := False; 1096 1126 FTicks := 0; 1097 DataSizeLast := bwNone;1098 1127 IP := 0; 1099 1128 SP := MemSize(Memory); … … 1106 1135 Opcode: Byte; 1107 1136 begin 1108 if DataSizePrefix <> bwNone then begin 1109 DataSizeLast := DataSize; 1110 DataSize := DataSizePrefix; 1111 DataSizePrefix := bwNone; 1112 end; 1113 if AddrSizePrefix <> bwNone then begin 1114 AddrSizeLast := AddrSize; 1115 AddrSize := AddrSizePrefix; 1116 AddrSizePrefix := bwNone; 1117 end; 1137 Prefix := False; 1118 1138 Opcode := Read8; 1119 1139 if Opcode < Length(Instructions) then begin … … 1121 1141 else raise Exception.Create('Missing instruction handler for opcode '+ IntToStr(Opcode)); 1122 1142 end else raise Exception.Create('Unsupported opcode ' + IntToStr(Opcode) + ' at address ' + IntToHex(IP - 1, 8) + '.'); 1123 if DataSizeLast <> bwNone then begin 1124 DataSize := DataSizeLast; 1125 DataSizeLast := bwNone; 1126 end; 1127 if AddrSizeLast <> bwNone then begin 1128 AddrSize := AddrSizeLast; 1129 AddrSizeLast := bwNone; 1143 if not Prefix then begin 1144 DataSize := DataSizeBase; 1145 AddrSize := AddrSizeBase; 1130 1146 end; 1131 1147 IP := IP mod MemSize(Memory); … … 1201 1217 constructor TCpu.Create; 1202 1218 begin 1203 DataSize := bw16;1204 AddrSize := bw16;1219 DataSizeBase := bw16; 1220 AddrSizeBase := bw16; 1205 1221 SetLength(Registers, 32); 1206 1222 InitInstructions;
Note:
See TracChangeset
for help on using the changeset viewer.