Changeset 59
- Timestamp:
- Nov 25, 2023, 11:47:52 PM (13 months ago)
- Location:
- branches/ByteArray
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/ByteArray/Assembler.pas
r56 r59 14 14 RefPos: Integer; 15 15 TextPos: TPoint; 16 class function Create(LabelName: string; RefPos: Integer ): TLabelRef; static;16 class function Create(LabelName: string; RefPos: Integer; TextPos: TPoint): TLabelRef; static; 17 17 end; 18 18 … … 23 23 FOnError: TErrorEvent; 24 24 Parser: TParser; 25 InstDataWidth: TBigIntSize; 26 InstAddressWidth: TBigIntSize; 25 27 function ParseVar: Boolean; 26 28 function ParseDb: Boolean; 27 29 function ParseOrg: Boolean; 28 30 function ParseInstruction: Boolean; 31 function ParseInstructionParameter(ParamType: TParamType; Memory: TMemory): Boolean; 29 32 function ParseLabel: Boolean; 30 33 procedure UpdateLabelRefs; 31 34 function ParseNumParam(out Number: TBigInt): Boolean; 32 35 function ParseReg(out RegIndex: TRegIndex): Boolean; 36 function ParseDataWidth(out Size: TBigIntSize): Boolean; 37 function ParseAddressWidth(out Size: TBigIntSize): Boolean; 33 38 public 34 InstructionSet: TInstruction Set;39 InstructionSet: TInstructionInfos; 35 40 Memory: TMemory; 36 41 Labels: TDictionary<string, TBigInt>; … … 38 43 Variables: TDictionary<string, TBigInt>; 39 44 Messages: TMessages; 45 DataWidth: TBigIntSize; 46 AddressWidth: TBigIntSize; 40 47 procedure Error(Text: string; Pos: TPoint); 41 48 procedure Compile(Source: string); … … 58 65 SExpectedVariableValue = 'Expected variable value.'; 59 66 SUnsupportedParameterType = 'Unsupported parameter type'; 67 SDuplicateLabel = 'Duplicate label %s.'; 68 SLabelReferencedButNotDefined = 'Label %s referenced but not defined.'; 69 SDuplicateVariableName = 'Duplicate variable name %s'; 70 SExpectedParameter = 'Expected parameter'; 71 SExpectedParameterType = 'Expected parameter type [%s]'; 72 SExpectedNumberButFound = 'Expected number but %s found.'; 60 73 61 74 { TLabelRef } 62 75 63 class function TLabelRef.Create(LabelName: string; RefPos: Integer ): TLabelRef;76 class function TLabelRef.Create(LabelName: string; RefPos: Integer; TextPos: TPoint): TLabelRef; 64 77 begin 65 78 Result.LabelName := LabelName; 66 79 Result.RefPos := RefPos; 80 Result.TextPos := TextPos; 67 81 end; 68 82 … … 77 91 if Labels.TryGetValue(LabelRefs[I].LabelName, Addr) then 78 92 Memory.Write(LabelRefs[I].RefPos, 1, Addr) 79 else Error('Label ' + LabelRefs[I].LabelName + ' referenced but not defined.', LabelRefs[I].TextPos); 93 else Error(Format(SLabelReferencedButNotDefined, [LabelRefs[I].LabelName]), 94 LabelRefs[I].TextPos); 80 95 end; 81 96 end; … … 84 99 var 85 100 Token: TToken; 86 begin 101 LastPos: TParserPos; 102 begin 103 LastPos := Parser.Pos; 87 104 Result := False; 88 105 Token := Parser.ReadNext; … … 99 116 Result := True; 100 117 end else begin 101 LabelRefs.Add(TLabelRef.Create(Token.Value, Memory.Position ));118 LabelRefs.Add(TLabelRef.Create(Token.Value, Memory.Position + 1, Parser.Pos.Pos)); 102 119 Number := 0; 103 120 Result := True; 104 121 end; 105 end else Error('Unexpected token ' + Token.Value + '.', Token.Pos); 122 end; 123 if not Result then Parser.Pos := LastPos; 106 124 end; 107 125 … … 110 128 LastPos: TParserPos; 111 129 Token: TToken; 130 Index: Integer; 112 131 begin 113 132 Result := False; 114 133 LastPos := Parser.Pos; 115 134 Token := Parser.ReadNext; 116 if (Length(Token.Value) = 1) and (Token.Value[1] in ['A'..'H']) then begin 117 RegIndex := TRegIndex(Ord(Token.Value[1]) - Ord('A')); 118 Result := True; 119 end else Parser.Pos := LastPos; 135 if (Length(Token.Value) >= 2) and (Token.Value[1] = 'R') then begin 136 if TryStrToInt(Copy(Token.Value, 2, MaxInt), Index) then begin 137 RegIndex := Index; 138 Result := True; 139 end; 140 end; 141 if not Result then Parser.Pos := LastPos; 142 end; 143 144 function TAssembler.ParseDataWidth(out Size: TBigIntSize): Boolean; 145 var 146 LastPos: TParserPos; 147 Token: TToken; 148 Index: Integer; 149 begin 150 Result := False; 151 LastPos := Parser.Pos; 152 Token := Parser.ReadNext; 153 if (Length(Token.Value) >= 2) and (Token.Value[1] = 'D') then begin 154 if TryStrToInt(Copy(Token.Value, 2, MaxInt), Index) then begin 155 Size := Index; 156 Result := True; 157 end; 158 end; 159 if not Result then Parser.Pos := LastPos; 160 end; 161 162 function TAssembler.ParseAddressWidth(out Size: TBigIntSize): Boolean; 163 var 164 LastPos: TParserPos; 165 Token: TToken; 166 Index: Integer; 167 begin 168 Result := False; 169 LastPos := Parser.Pos; 170 Token := Parser.ReadNext; 171 if (Length(Token.Value) >= 2) and (Token.Value[1] = 'A') then begin 172 if TryStrToInt(Copy(Token.Value, 2, MaxInt), Index) then begin 173 Size := Index; 174 Result := True; 175 end; 176 end; 177 if not Result then Parser.Pos := LastPos; 120 178 end; 121 179 … … 134 192 Labels.Clear; 135 193 LabelRefs.Clear; 194 Variables.Clear; 136 195 Parser.Reset; 137 196 Parser.Source := Source; … … 172 231 if TryStrToBigInt(TokenValue.Value, Number) then 173 232 Variables.Add(TokenName.Value, Number) 174 else Error( 'Expected number', TokenValue.Pos);175 end else Error( 'Duplicate variable name ' + TokenName.Value, TokenName.Pos);233 else Error(SExpectedNumber, TokenValue.Pos); 234 end else Error(Format(SDuplicateVariableName, [TokenName.Value]), TokenName.Pos); 176 235 end else Error(SExpectedVariableValue, TokenValue.Pos); 177 236 end else Error(SExpectedVariableName, TokenName.Pos); … … 199 258 if Token.Kind = tkString then begin 200 259 Memory.WriteStringPos(Token.Value); 201 end else raise Exception.Create('Expected parameter'); 260 end else 261 if Token.Kind = tkEof then 262 else if Token.Kind = tkEol then 263 else raise Exception.Create(SExpectedParameter); 202 264 end; 203 265 if Parser.CheckNextAndRead(tkSpecialSymbol, ',') then begin … … 219 281 if Token.Kind = tkNumber then begin 220 282 Memory.Position := StrToInt(Token.Value); 221 end else Error( 'Expected number but ' + Token.Value + ' found.', Token.Pos);283 end else Error(Format(SExpectedNumberButFound, [Token.Value]), Token.Pos); 222 284 end; 223 285 end; … … 225 287 function TAssembler.ParseInstruction: Boolean; 226 288 var 227 InstructionInfo : TInstructionInfo;289 InstructionInfos: TInstructionInfos; 228 290 I: Integer; 229 291 Token: TToken; 230 292 LastPos: TParserPos; 293 J: Integer; 294 AllowedParams: set of TParamType; 295 ParamType: TParamType; 296 ParamOk: Boolean; 297 LastMessagesCount: Integer; 298 Text: string; 299 EmptyParam: Boolean; 300 InstructionMemory: TMemory; 301 ParamMemory: TMemory; 302 begin 303 Result := False; 304 LastPos := Parser.Pos; 305 Token := Parser.ReadNext; 306 InstructionInfos := InstructionSet.SearchByNameMultiple(Token.Value); 307 InstDataWidth := DataWidth; 308 InstAddressWidth := AddressWidth; 309 InstructionMemory := TMemory.Create; 310 InstructionMemory.Grow := True; 311 ParamMemory := TMemory.Create; 312 ParamMemory.Grow := True; 313 J := 0; 314 if InstructionInfos.Count > 0 then 315 repeat 316 EmptyParam := False; 317 318 if J > 0 then 319 Parser.Expect(tkSpecialSymbol, ','); 320 321 // Get allowed parameters 322 AllowedParams := []; 323 for I := 0 to InstructionInfos.Count - 1 do begin 324 if Length(InstructionInfos[I].Params) > J then 325 AllowedParams := AllowedParams + [InstructionInfos[I].Params[J]] 326 else EmptyParam := True; 327 end; 328 329 if AllowedParams <> [] then begin 330 ParamOk := False; 331 for ParamType := Low(TParamType) to High(TParamType) do begin 332 if ParamType in AllowedParams then begin 333 LastMessagesCount := Messages.Count; 334 ParamMemory.Clear; 335 if ParseInstructionParameter(ParamType, ParamMemory) and 336 (LastMessagesCount = Messages.Count) then begin 337 ParamOk := True; 338 InstructionMemory.WriteMemoryPos(ParamMemory); 339 Break; 340 end else Messages.Count := LastMessagesCount; 341 end; 342 end; 343 if not ParamOk then begin 344 if EmptyParam then begin 345 ParamType := ptNone; 346 end else begin 347 Text := ''; 348 for ParamType := Low(TParamType) to High(TParamType) do begin 349 if ParamType in AllowedParams then begin 350 if Text <> '' then Text := Text + ' or '; 351 Text := Text + ParamTypeString[ParamType] 352 end; 353 end; 354 355 Error(Format(SExpectedParameterType, [Text]), Parser.Pos.Pos); 356 Break; 357 end; 358 end; 359 end; 360 361 // Remove not matching instruction infos 362 for I := InstructionInfos.Count - 1 downto 0 do 363 if (Length(InstructionInfos[I].Params) > J) and 364 (InstructionInfos[I].Params[J] <> ParamType) then InstructionInfos.Delete(I); 365 366 if (InstructionInfos.Count = 1) and (J >= (Length(InstructionInfos[0].Params) - 1)) then begin 367 Memory.WritePos(1, Byte(InstructionInfos[0].Instruction)); 368 Memory.WriteMemoryPos(InstructionMemory); 369 Result := True; 370 Break; 371 end; 372 373 Inc(J); 374 until False; 375 376 if not Result then Parser.Pos := LastPos; 377 FreeAndNil(ParamMemory); 378 FreeAndNil(InstructionMemory); 379 end; 380 381 function TAssembler.ParseInstructionParameter(ParamType: TParamType; Memory: TMemory): Boolean; 382 var 383 LastPos: TParserPos; 384 I: Integer; 231 385 RegIndex: TRegIndex; 232 386 Number: TBigInt; 233 begin 234 Result := False; 235 LastPos := Parser.Pos; 236 Token := Parser.ReadNext; 237 InstructionInfo := InstructionSet.SearchName(Token.Value); 238 if Assigned(InstructionInfo) then begin 239 Result := True; 240 Memory.WritePos(1, Integer(InstructionInfo.Instruction)); 241 for I := 0 to Length(InstructionInfo.Params) - 1 do begin 242 if I > 0 then 243 Parser.Expect(tkSpecialSymbol, ','); 244 if InstructionInfo.Params[I] = ptNumber then begin 245 if ParseNumParam(Number) then Memory.WritePos(1, Number) 246 else Error(SExpectedNumber, Token.Pos); 247 end else 248 if InstructionInfo.Params[I] = ptReg then begin 249 if ParseReg(RegIndex) then Memory.WritePos(1, Byte(RegIndex)) 250 else Error(SExpectedRegisterName, Token.Pos); 251 end else 252 if InstructionInfo.Params[I] = ptRegIndirect then begin 253 Parser.Expect(tkSpecialSymbol, '('); 254 if ParseReg(RegIndex) then Memory.WritePos(1, Byte(RegIndex)) 255 else Error(SExpectedRegisterName, Token.Pos); 256 Parser.Expect(tkSpecialSymbol, ')'); 257 end else 258 if InstructionInfo.Params[I] = ptRegIndirectIndex then begin 259 Parser.Expect(tkSpecialSymbol, '('); 260 if ParseReg(RegIndex) then begin 261 Memory.WritePos(1, Byte(RegIndex)); 262 Parser.Expect(tkSpecialSymbol, '+'); 263 Token := Parser.ReadNext; 264 if ParseNumParam(Number) then Memory.WritePos(1, Number) 265 else Error(SExpectedNumericIndex, Token.Pos); 266 end else Error(SExpectedRegisterName, Token.Pos); 267 Parser.Expect(tkSpecialSymbol, ')'); 268 end else Error(SUnsupportedParameterType, Token.Pos); 387 Token: TToken; 388 begin 389 LastPos := Parser.Pos; 390 Result := True; 391 case ParamType of 392 ptData: begin 393 if ParseNumParam(Number) then Memory.WritePos(InstDataWidth, Number) 394 else begin 395 Error(SExpectedNumber, Parser.Pos.Pos); 396 Result := False; 397 end; 398 end; 399 ptAddress: begin 400 if ParseNumParam(Number) then Memory.WritePos(InstAddressWidth, Number) 401 else begin 402 Error(SExpectedNumber, Parser.Pos.Pos); 403 Result := False; 404 end; 405 end; 406 ptReg: begin 407 if ParseReg(RegIndex) then Memory.WritePos(1, Byte(RegIndex)) 408 else begin 409 Error(SExpectedRegisterName, Parser.Pos.Pos); 410 Result := False; 411 end; 412 end; 413 ptRegIndirect: begin 414 if not Parser.Expect(tkSpecialSymbol, '(') then Result := False; 415 if ParseReg(RegIndex) then Memory.WritePos(1, Byte(RegIndex)) 416 else begin 417 Error(SExpectedRegisterName, Parser.Pos.Pos); 418 Result := False; 419 end; 420 if not Parser.Expect(tkSpecialSymbol, ')') then Result := False;; 421 end; 422 ptRegIndirectIndex: begin 423 if not Parser.Expect(tkSpecialSymbol, '(') then Result := False; 424 if ParseReg(RegIndex) then begin 425 Memory.WritePos(1, Byte(RegIndex)); 426 if not Parser.Expect(tkSpecialSymbol, '+') then Result := False; 427 if ParseNumParam(Number) then Memory.WritePos(InstAddressWidth, Number) 428 else begin 429 Error(SExpectedNumericIndex, Parser.Pos.Pos); 430 Result := False; 431 end; 432 end else begin 433 Error(SExpectedRegisterName, Parser.Pos.Pos); 434 Result := False; 435 end; 436 if not Parser.Expect(tkSpecialSymbol, ')') then Result := False; 437 end; 438 ptDataWidth: begin 439 if ParseDataWidth(InstDataWidth) then begin 440 Memory.WritePos(1, InstDataWidth) 441 end else begin 442 Error(SExpectedRegisterName, Parser.Pos.Pos); 443 Result := False; 444 end; 445 end; 446 ptAddressWidth: begin 447 if ParseAddressWidth(InstAddressWidth) then begin 448 Memory.WritePos(1, InstAddressWidth) 449 end else begin 450 Error(SExpectedRegisterName, Parser.Pos.Pos); 451 Result := False; 452 end; 453 end; 454 else begin 455 Result := False; 456 Error(SUnsupportedParameterType, Parser.Pos.Pos); 269 457 end; 270 458 end; … … 285 473 if not Labels.TryGetValue(Token.Value, Addr) then begin 286 474 Labels.Add(Token.Value, Memory.Position); 287 end else Error( 'Duplicate label ' + Token.Value + '.', Token.Pos);475 end else Error(Format(SDuplicateLabel, [Token.Value]), Token.Pos); 288 476 end; 289 477 if not Result then Parser.Pos := LastPos; … … 323 511 Messages := TMessages.Create; 324 512 Memory := TMemory.Create; 325 InstructionSet := TInstructionSet.Create; 513 InstructionSet := TInstructionInfos.Create; 514 InstructionSet.Init; 326 515 Labels := TDictionary<string, TBigInt>.Create; 327 516 LabelRefs := TList<TLabelRef>.Create; -
branches/ByteArray/ByteArray.lpi
r58 r59 231 231 <IsPartOfProject Value="True"/> 232 232 <ComponentName Value="Core"/> 233 <HasResources Value="True"/> 233 234 <ResourceBaseClass Value="DataModule"/> 234 235 </Unit> … … 237 238 <IsPartOfProject Value="True"/> 238 239 <ComponentName Value="FormDebugger"/> 240 <HasResources Value="True"/> 239 241 <ResourceBaseClass Value="Form"/> 240 242 </Unit> -
branches/ByteArray/Core.lfm
r58 r59 3 3 OnDestroy = DataModuleDestroy 4 4 OldCreateOrder = False 5 Height = 486 6 HorizontalOffset = 661 7 VerticalOffset = 547 8 Width = 716 5 Height = 729 6 HorizontalOffset = 992 7 VerticalOffset = 653 8 Width = 1074 9 PPI = 144 9 10 object PersistentForm1: TPersistentForm 10 11 MinVisiblePart = 50 11 12 EntireVisible = False 12 Left = 40813 Top = 8813 Left = 612 14 Top = 132 14 15 end 15 16 object ApplicationInfo1: TApplicationInfo … … 27 28 RegistryRoot = rrKeyCurrentUser 28 29 License = 'CC0' 29 Left = 20830 Top = 8830 Left = 312 31 Top = 132 31 32 end 32 33 object Translator1: TTranslator 33 34 POFilesFolder = 'Languages' 34 Left = 41935 Top = 18235 Left = 629 36 Top = 273 36 37 end 37 38 object ThemeManager1: TThemeManager 38 Left = 19939 Top = 18739 Left = 299 40 Top = 281 40 41 end 41 42 object ActionList1: TActionList 42 Left = 56843 Top = 8843 Left = 852 44 Top = 132 44 45 object ASourceEditor: TAction 45 46 Caption = 'Source editor' -
branches/ByteArray/Core.pas
r58 r59 78 78 begin 79 79 Machine := TMachine.Create; 80 InitMachine;80 //InitMachine; 81 81 LoadConfig; 82 82 … … 118 118 end; 119 119 FormDisassembler.Disassembler.Memory := Machine.Memory; 120 FormDisassembler.Disassembler.DataWidth := Machine.Cpu.DataWidth; 121 FormDisassembler.Disassembler.AddressWidth := Machine.Cpu.AddressWidth; 120 122 FormDisassembler.Show; 121 123 end; … … 222 224 // LD A, 'A' 223 225 WriteInstruction(inLoadConst); 224 WriteRegister( riA);226 WriteRegister(0); 225 227 Write(DataWidth, Ord('A')); 226 228 227 229 // LD B, 8 228 230 WriteInstruction(inLoadConst); 229 WriteRegister( riB);231 WriteRegister(1); 230 232 Write(DataWidth, Machine.Serial.BaseAddress); 231 233 232 234 // OUT (B), A 233 235 WriteInstruction(inOutput); 234 WriteRegister( riB);235 WriteRegister( riA);236 WriteRegister(1); 237 WriteRegister(0); 236 238 237 239 // LD B, 238 240 WriteInstruction(inLoadConst); 239 WriteRegister( riB);241 WriteRegister(1); 240 242 Write(DataWidth, Machine.FrameBuffer.BaseAddress); 241 243 242 244 WriteInstruction(inLoadConst); 243 WriteRegister( riC);245 WriteRegister(2); 244 246 Write(DataWidth, 10); 245 247 … … 247 249 248 250 WriteInstruction(inOutput); 249 WriteRegister( riB);250 WriteRegister( riA);251 WriteRegister(1); 252 WriteRegister(0); 251 253 252 254 WriteInstruction(inInc); 253 WriteRegister( riA);255 WriteRegister(0); 254 256 255 257 WriteInstruction(inDec); 256 WriteRegister( riC);258 WriteRegister(2); 257 259 258 260 WriteInstruction(inJumpNotZero); 259 WriteRegister( riC);261 WriteRegister(2); 260 262 Write(AddressWidth, Loop); 261 263 … … 278 280 else ThemeManager1.Theme := ThemeManager1.Themes.FindByName('System'); 279 281 StartUpForm := ReadStringWithDefault('StartUpForm', 'Screen'); 282 AutoStartMachine := ReadBoolWithDefault('AutoStartMachine', True); 280 283 finally 281 284 Free; … … 295 298 else DeleteValue('Theme'); 296 299 WriteString('StartUpForm', StartUpForm); 300 WriteBool('AutoStartMachine', AutoStartMachine); 297 301 finally 298 302 Free; -
branches/ByteArray/Cpu.pas
r57 r59 12 12 inLoadMem, inLoadMemSize, 13 13 inStoreMem, inStoreMemSize, 14 inLoadMemIndex, inLoadMemIndexSize, 15 inStoreMemIndex, inStoreMemIndexSize, 14 16 inInput, inInputSize, 15 17 inOutput, inOutputSize, … … 38 40 inCompare); 39 41 40 TRegIndex = (riA, riB, riC, riD, riE, riF, riG, riH);42 TRegIndex = Byte; 41 43 42 44 TInstructionEvent = procedure of object; … … 64 66 procedure InstructionStoreMem; 65 67 procedure InstructionStoreMemSize; 68 procedure InstructionLoadMemIndex; 69 procedure InstructionLoadMemIndexSize; 70 procedure InstructionStoreMemIndex; 71 procedure InstructionStoreMemIndexSize; 66 72 procedure InstructionJump; 67 73 procedure InstructionJumpSize; … … 213 219 procedure TCpu.InstructionLoadMem; 214 220 var 215 Address: TBigInt;216 RegIndex : TRegIndex;217 begin 218 RegIndex := ReadRegIndex;219 Address := Read(AddressWidth);220 Regs[RegIndex ] := Memory.Read(Address, DataWidth);221 RegIndex1: TRegIndex; 222 RegIndex2: TRegIndex; 223 begin 224 RegIndex1 := ReadRegIndex; 225 RegIndex2 := ReadRegIndex; 226 Regs[RegIndex1] := Memory.Read(Regs[RegIndex2], DataWidth); 221 227 end; 222 228 … … 224 230 var 225 231 DataSize: TBigIntSize; 226 AddressSize: TBigIntSize; 227 Address: TBigInt; 228 RegIndex: TRegIndex; 229 begin 230 DataSize := ReadSize; 231 AddressSize := Read(SizeOf(TBigIntSize)); 232 RegIndex := ReadRegIndex; 233 Address := Read(AddressSize); 234 Regs[RegIndex] := Memory.Read(Address, DataSize); 232 RegIndex1: TRegIndex; 233 RegIndex2: TRegIndex; 234 begin 235 DataSize := ReadSize; 236 RegIndex1 := ReadRegIndex; 237 RegIndex2 := ReadRegIndex; 238 Regs[RegIndex1] := Memory.Read(Regs[RegIndex2], DataSize); 235 239 end; 236 240 237 241 procedure TCpu.InstructionStoreMem; 238 242 var 239 Address: TBigInt;240 RegIndex : TRegIndex;241 begin 242 Address := Read(AddressWidth);243 RegIndex := ReadRegIndex;244 Memory.Write( Address, DataWidth, Regs[RegIndex]);243 RegIndex1: TRegIndex; 244 RegIndex2: TRegIndex; 245 begin 246 RegIndex1 := ReadRegIndex; 247 RegIndex2 := ReadRegIndex; 248 Memory.Write(Regs[RegIndex1], DataWidth, Regs[RegIndex2]); 245 249 end; 246 250 … … 248 252 var 249 253 DataSize: TBigIntSize; 250 AddressSize: TBigIntSize; 251 Address: TBigInt; 252 RegIndex: TRegIndex; 253 begin 254 DataSize := ReadSize; 255 AddressSize := Read(SizeOf(TBigIntSize)); 256 Address := Read(AddressSize); 257 RegIndex := ReadRegIndex; 258 Memory.Write(Address, DataSize, Regs[RegIndex]); 254 RegIndex1: TRegIndex; 255 RegIndex2: TRegIndex; 256 begin 257 DataSize := ReadSize; 258 RegIndex1 := ReadRegIndex; 259 RegIndex2 := ReadRegIndex; 260 Memory.Write(Regs[RegIndex1], DataSize, Regs[RegIndex2]); 261 end; 262 263 procedure TCpu.InstructionLoadMemIndex; 264 var 265 RegIndex1: TRegIndex; 266 RegIndex2: TRegIndex; 267 RelativeAddress: TBigInt; 268 begin 269 RegIndex1 := ReadRegIndex; 270 RegIndex2 := ReadRegIndex; 271 RelativeAddress := Read(AddressWidth); 272 Regs[RegIndex1] := Memory.Read(Regs[RegIndex2] + RelativeAddress, DataWidth); 273 end; 274 275 procedure TCpu.InstructionLoadMemIndexSize; 276 var 277 DataSize: TBigIntSize; 278 RegIndex1: TRegIndex; 279 RegIndex2: TRegIndex; 280 RelativeAddress: TBigInt; 281 begin 282 DataSize := ReadSize; 283 RegIndex1 := ReadRegIndex; 284 RegIndex2 := ReadRegIndex; 285 RelativeAddress := Read(AddressWidth); 286 Regs[RegIndex1] := Memory.Read(Regs[RegIndex2] + RelativeAddress, DataSize); 287 end; 288 289 procedure TCpu.InstructionStoreMemIndex; 290 var 291 RegIndex1: TRegIndex; 292 RegIndex2: TRegIndex; 293 RelativeAddress: TBigInt; 294 begin 295 RegIndex1 := ReadRegIndex; 296 RegIndex2 := ReadRegIndex; 297 RelativeAddress := Read(AddressWidth); 298 Memory.Write(Regs[RegIndex1] + RelativeAddress, DataWidth, Regs[RegIndex2]); 299 end; 300 301 procedure TCpu.InstructionStoreMemIndexSize; 302 var 303 DataSize: TBigIntSize; 304 RegIndex1: TRegIndex; 305 RegIndex2: TRegIndex; 306 RelativeAddress: TBigInt; 307 begin 308 DataSize := ReadSize; 309 RegIndex1 := ReadRegIndex; 310 RegIndex2 := ReadRegIndex; 311 RelativeAddress := Read(AddressWidth); 312 Memory.Write(Regs[RegIndex1] + RelativeAddress, DataSize, Regs[RegIndex2]); 259 313 end; 260 314 … … 603 657 FInstructions[inStoreMem] := InstructionStoreMem; 604 658 FInstructions[inStoreMemSize] := InstructionStoreMemSize; 659 FInstructions[inLoadMemIndex] := InstructionLoadMemIndex; 660 FInstructions[inLoadMemIndexSize] := InstructionLoadMemIndexSize; 661 FInstructions[inStoreMemIndex] := InstructionStoreMemIndex; 662 FInstructions[inStoreMemIndexSize] := InstructionStoreMemIndexSize; 605 663 FInstructions[inJump] := InstructionJump; 606 664 FInstructions[inJumpSize] := InstructionJumpSize; … … 802 860 - bit index 2048 (256 * 8) (8 + 3) bits = 2^11 803 861 862 LD R0, R1 863 LD2 R0, R1 864 LD.2 R0, R1 865 LD:2 R0, R1 866 LD D2, R0, R1 867 LD D2, A16, R0, (R1) 868 LD D2:A16: R0, (R1) 869 RET 870 RET2 871 RET.2 872 RET:2 873 RET A2 874 PUSH R0 875 PUSH2 R0 876 PUSH.2 R0 877 PUSH:2 R0 878 PUSH D2, R0 879 PUSH D2:R0 880 PUSH R0.2 881 PUSH R0:2 882 LD (R0), (R2) 883 LD D1, A2, (R0), (R2) 884 LDIR (R0), (R1), R2 885 LDIR D1, A2, (R0), (R1), R2 886 LDI 887 OUT (R0), R1 888 OUT D1, (R0), R1 889 OUT D1, A2, (R0), R1 804 890 805 891 -
branches/ByteArray/Devices/FrameBuffer.pas
r47 r59 44 44 begin 45 45 Memory.Size := Width * Height; 46 Memory. Clean;46 Memory.FillZero; 47 47 end; 48 48 -
branches/ByteArray/Devices/Memory.pas
r56 r59 16 16 function GetSize: Integer; 17 17 procedure SetSize(AValue: Integer); 18 procedure CheckGrow(Address: Integer); 18 19 public 19 20 Position: Integer; 21 Grow: Boolean; 20 22 procedure Assign(Source: TMemory); 21 23 function Read(Address: TBigInt; ASize: TBigIntSize): TBigInt; … … 28 30 procedure SetChannel(Channel: TChannel); override; 29 31 procedure SaveToFile(FileName: string); 30 procedure Clean; 32 procedure FillZero; 33 procedure Clear; 31 34 property Size: Integer read FSize write SetSize; 32 35 destructor Destroy; override; … … 50 53 FSize := AValue; 51 54 FData := ReAllocMem(FData, AValue); 55 end; 56 57 procedure TMemory.CheckGrow(Address: Integer); 58 begin 59 if Grow and (Size < Address) then Size := Address; 52 60 end; 53 61 … … 90 98 procedure TMemory.WritePos(ASize: Byte; Value: TBigInt); 91 99 begin 100 CheckGrow(Position + ASize); 92 101 Write(Position, ASize, Value); 93 102 Inc(Position, ASize); … … 98 107 I: Integer; 99 108 begin 109 CheckGrow(Position + Length(Value)); 100 110 if Length(Value) > 0 then begin 101 111 if Position + Length(Value) > FSize then Size := Position + Length(Value); … … 108 118 procedure TMemory.WriteMemoryPos(Memory: TMemory); 109 119 begin 120 CheckGrow(Position + Memory.Size); 110 121 if Memory.Size > 0 then begin 111 122 if Position + Memory.Size > FSize then Size := Position + Memory.Size; … … 126 137 end; 127 138 128 procedure TMemory. Clean;139 procedure TMemory.FillZero; 129 140 begin 130 141 FillChar(FData^, FSize, 0); 142 end; 143 144 procedure TMemory.Clear; 145 begin 146 Size := 0; 147 Position := 0; 131 148 end; 132 149 -
branches/ByteArray/Disassembler.pas
r55 r59 4 4 5 5 uses 6 Classes, SysUtils, Cpu, Instructions, StrUtils, Memory ;6 Classes, SysUtils, Cpu, Instructions, StrUtils, Memory, BigInt; 7 7 8 8 type … … 12 12 TDisassembler = class 13 13 private 14 function RegToStr(RegIndex: Byte): string; 14 InstText: string; 15 InstBytes: string; 16 InstDataWidth: TBigIntSize; 17 InstAddressWidth: TBigIntSize; 18 procedure DisassembleData; 19 procedure DisassembleAddress; 20 procedure DisassembleRegister; 21 procedure DisassembleRegisterIndirect; 22 procedure DisassembleRegisterIndirectIndex; 23 procedure DisassembleDataWidth; 24 procedure DisassembleAddressWidth; 15 25 public 16 InstructionSet: TInstruction Set;26 InstructionSet: TInstructionInfos; 17 27 Memory: TMemory; 28 DataWidth: TBigIntSize; 29 AddressWidth: TBigIntSize; 18 30 procedure Disassemble(Lines: TStrings); 19 31 procedure SaveToFile(FileName: string); … … 25 37 implementation 26 38 27 uses 28 BigInt; 39 procedure TDisassembler.DisassembleData; 40 var 41 Text: string; 42 begin 43 Text := IntToHex(Memory.ReadPos(InstDataWidth)); 44 if not (Copy(Text, 1, 1)[1] in ['0'..'9']) then Text := '0' + Text; 45 InstText := InstText + Text + 'h'; 46 end; 29 47 30 function TDisassembler.RegToStr(RegIndex: Byte): string; 48 procedure TDisassembler.DisassembleAddress; 49 var 50 Text: string; 31 51 begin 32 Result := Chr(Ord('A') + RegIndex); 52 Text := IntToHex(Memory.ReadPos(InstAddressWidth)); 53 if not (Copy(Text, 1, 1)[1] in ['0'..'9']) then Text := '0' + Text; 54 InstText := InstText + Text + 'h'; 55 end; 56 57 procedure TDisassembler.DisassembleRegister; 58 begin 59 InstText := InstText + 'R' + IntToStr(Byte(Memory.ReadPos(1))); 60 end; 61 62 procedure TDisassembler.DisassembleRegisterIndirect; 63 begin 64 InstText := InstText + '(R' + IntToStr(Byte(Memory.ReadPos(1))) + ')'; 65 end; 66 67 procedure TDisassembler.DisassembleRegisterIndirectIndex; 68 begin 69 InstText := InstText + '(R' + IntToStr(Byte(Memory.ReadPos(1))) + 70 ' + '; 71 DisassembleAddress; 72 InstText := InstText + ')'; 73 end; 74 75 procedure TDisassembler.DisassembleDataWidth; 76 begin 77 InstDataWidth := Memory.ReadPos(1); 78 InstText := InstText + 'D' + IntToStr(InstDataWidth); 79 end; 80 81 procedure TDisassembler.DisassembleAddressWidth; 82 begin 83 InstAddressWidth := Memory.ReadPos(1); 84 InstText := InstText + 'A' + IntToStr(InstAddressWidth); 33 85 end; 34 86 35 87 procedure TDisassembler.Disassemble(Lines: TStrings); 36 88 var 37 I: Integer;38 89 J: Integer; 39 90 Value: TBigInt; … … 41 92 InstructionInfo: TInstructionInfo; 42 93 Line: string; 43 InstText: string; 44 InstBytes: string; 94 MemoryPos: Integer; 95 InstructionByteSize: Integer; 96 I: Integer; 45 97 begin 46 98 Memory.Position := 0; 47 99 while Memory.Position < Memory.Size do begin 48 100 Line := IntToHex(Memory.Position, 8) + ' '; 101 MemoryPos := Memory.Position; 49 102 Value := Memory.ReadPos(1); 50 103 InstBytes := IntToHex(Value, 2) + ' '; 51 104 InstText := ''; 105 InstAddressWidth := AddressWidth; 106 InstDataWidth := DataWidth; 52 107 if (Value >= 0) and (Value <= Integer(High(TInstruction))) then begin 53 108 Instruction := TInstruction(Int64(Value)); … … 56 111 InstText := InstructionInfo.Name; 57 112 for J := 0 to Length(InstructionInfo.Params) - 1 do begin 58 Value := Memory.ReadPos(1);59 InstBytes := InstBytes + IntToHex(Value, 2) + ' ';60 113 if J > 0 then 61 114 InstText := InstText + ', ' else 62 115 InstText := InstText + ' '; 63 if InstructionInfo.Params[J] = ptNumber then begin 64 InstText := InstText + IntToHex(Value) + 'h'; 65 end else 66 if InstructionInfo.Params[J] = ptReg then begin 67 InstText := InstText + RegToStr(Value); 68 end else 69 if InstructionInfo.Params[J] = ptRegIndirect then begin 70 InstText := InstText + '(' + RegToStr(Value) + ')'; 71 end else 72 if InstructionInfo.Params[J] = ptRegIndirectIndex then begin 73 InstText := InstText + '(' + RegToStr(Value); 74 Value := Memory.ReadPos(1); 75 InstBytes := InstBytes + IntToHex(Value, 2) + ' '; 76 InstText := InstText + ' + ' + IntToStr(Value) + ')'; 116 case InstructionInfo.Params[J] of 117 ptData: DisassembleData; 118 ptAddress: DisassembleAddress; 119 ptReg: DisassembleRegister; 120 ptRegIndirect: DisassembleRegisterIndirect; 121 ptRegIndirectIndex: DisassembleRegisterIndirectIndex; 122 ptDataWidth: DisassembleDataWidth; 123 ptAddressWidth: DisassembleAddressWidth; 77 124 end; 78 125 end; 79 InstBytes := InstBytes + DupeString(' ', 13 - Length(InstBytes));80 126 end; 81 127 end; 128 129 // Instruction bytes to hex string 130 InstructionByteSize := Memory.Position - MemoryPos; 131 Memory.Position := MemoryPos; 132 InstBytes := ''; 133 for I := 0 to InstructionByteSize - 1 do 134 InstBytes := InstBytes + IntToHex(Memory.ReadPos(1), 2) + ' '; 135 InstBytes := InstBytes + DupeString(' ', 13 - Length(InstBytes)); 136 82 137 Line := Line + InstBytes + InstText; 83 138 Lines.Add(Line); … … 97 152 constructor TDisassembler.Create; 98 153 begin 99 InstructionSet := TInstructionSet.Create; 154 InstructionSet := TInstructionInfos.Create; 155 InstructionSet.Init; 156 DataWidth := 1; 157 AddressWidth := 1; 100 158 end; 101 159 -
branches/ByteArray/Forms/FormSourceEditor.pas
r58 r59 121 121 AStop.Execute; 122 122 with Assembler do begin 123 DataWidth := Machine.Cpu.DataWidth; 124 AddressWidth := Machine.Cpu.AddressWidth; 123 125 Compile(FormAssembler.SynEdit1.Lines.Text); 124 126 Memory.SaveToFile('compiled.bin'); -
branches/ByteArray/Instructions.pas
r56 r59 7 7 8 8 type 9 TParamType = (ptNone, pt Number, ptReg, ptRegIndirect, ptRegIndirectIndex,10 pt Size);9 TParamType = (ptNone, ptRegIndirectIndex, ptRegIndirect, ptReg, 10 ptDataWidth, ptAddressWidth, ptData, ptAddress); 11 11 TParamTypeArray = array of TParamType; 12 12 … … 18 18 end; 19 19 20 { TInstruction Set}20 { TInstructionInfos } 21 21 22 TInstruction Set = class23 Items: TObjectList<TInstructionInfo>;24 function Search Name(Name: string): TInstructionInfo;22 TInstructionInfos = class(TObjectList<TInstructionInfo>) 23 function SearchByName(Name: string): TInstructionInfo; 24 function SearchByNameMultiple(Name: string): TInstructionInfos; 25 25 function SearchInstruction(Instruction: TInstruction): TInstructionInfo; 26 26 function AddNew(Instruction: TInstruction; Name: string; 27 27 Params: TParamTypeArray; Description: string): TInstructionInfo; 28 constructor Create; 29 destructor Destroy; override; 28 procedure Init; 30 29 end; 30 31 const 32 ParamTypeString: array[TParamType] of string = ('None', 'Data', 'Address', 33 'Register', 'Indirect register', 'Indirect indexed register', 34 'Data width', 'Address width'); 31 35 32 36 33 37 implementation 34 38 35 { TInstruction Set}39 { TInstructionInfos } 36 40 37 function TInstruction Set.SearchName(Name: string): TInstructionInfo;41 function TInstructionInfos.SearchByName(Name: string): TInstructionInfo; 38 42 var 39 43 I: Integer; 40 44 begin 41 45 I := 0; 42 while (I < Items.Count) and (Items[I].Name <> Name) do Inc(I);43 if I < Items.Count then Result := Items[I]46 while (I < Count) and (Items[I].Name <> Name) do Inc(I); 47 if I < Count then Result := Items[I] 44 48 else Result := nil; 45 49 end; 46 50 47 function TInstructionSet.SearchInstruction(Instruction: TInstruction 51 function TInstructionInfos.SearchByNameMultiple(Name: string 52 ): TInstructionInfos; 53 var 54 I: Integer; 55 begin 56 Result := TInstructionInfos.Create(False); 57 for I := 0 to Count - 1 do 58 if Items[I].Name = Name then Result.Add(Items[I]); 59 end; 60 61 function TInstructionInfos.SearchInstruction(Instruction: TInstruction 48 62 ): TInstructionInfo; 49 63 var … … 51 65 begin 52 66 I := 0; 53 while (I < Items.Count) and (Items[I].Instruction <> Instruction) do Inc(I);54 if I < Items.Count then Result := Items[I]67 while (I < Count) and (Items[I].Instruction <> Instruction) do Inc(I); 68 if I < Count then Result := Items[I] 55 69 else Result := nil; 56 70 end; 57 71 58 function TInstruction Set.AddNew(Instruction: TInstruction; Name: string;72 function TInstructionInfos.AddNew(Instruction: TInstruction; Name: string; 59 73 Params: TParamTypeArray; Description: string): TInstructionInfo; 60 74 begin … … 64 78 Result.Params := Params; 65 79 Result.Description := Description; 66 Items.Add(Result);80 Add(Result); 67 81 end; 68 82 69 constructor TInstructionSet.Create;83 procedure TInstructionInfos.Init; 70 84 begin 71 Items := TObjectList<TInstructionInfo>.Create;85 Clear; 72 86 AddNew(inNop, 'NOP', [], 'No operation - The instruction doesn''t do anything.'); 73 87 AddNew(inHalt, 'HALT', [], 'It terminates program execution and halts processor. Processor can be waked up by interrupt.'); 74 AddNew(inLoadConst, 'LD', [ptReg, pt Number], 'Sets register to immediate constant value.');75 AddNew(inLoadConstSize, 'LD', [pt Size, ptReg, ptNumber], 'Sets register to immediate constant value.');88 AddNew(inLoadConst, 'LD', [ptReg, ptData], 'Sets register to immediate constant value.'); 89 AddNew(inLoadConstSize, 'LD', [ptDataWidth, ptReg, ptData], 'Sets register to immediate constant value.'); 76 90 AddNew(inLoad, 'LD', [ptReg, ptReg], 'Copies value from one register to another.'); 91 AddNew(inLoadSize, 'LD', [ptDataWidth, ptReg, ptReg], 'Copies value from one register to another.'); 92 AddNew(inLoadMem, 'LD', [ptReg, ptRegIndirect], 'Loads value from memory to register.'); 93 AddNew(inLoadMemSize, 'LD', [ptDataWidth, ptReg, ptRegIndirect], 'Loads value from memory to register.'); 94 AddNew(inStoreMem, 'LD', [ptRegIndirect, ptReg], 'Stores value from register to memory.'); 95 AddNew(inStoreMemSize, 'LD', [ptDataWidth, ptRegIndirect, ptReg], 'Stores value from register to memory.'); 96 AddNew(inLoadMemIndex, 'LD', [ptReg, ptRegIndirectIndex], 'Loads value from memory with numeric index to register.'); 97 AddNew(inLoadMemIndexSize, 'LD', [ptDataWidth, ptReg, ptRegIndirectIndex], 'Loads value from memory with numeric index to register.'); 98 AddNew(inStoreMemIndex, 'LD', [ptRegIndirectIndex, ptReg], 'Stores value from register to memory with numeric index.'); 99 AddNew(inStoreMemIndexSize, 'LD', [ptDataWidth, ptRegIndirectIndex, ptReg], 'Stores value from register to memory with numeric index.'); 77 100 AddNew(inInc, 'INC', [ptReg], 'Increments value in specified register.'); 101 AddNew(inIncSize, 'INC', [ptDataWidth, ptReg], 'Increments value in specified register.'); 78 102 AddNew(inDec, 'DEC', [ptReg], 'Decrements value in specified register.'); 79 AddNew(inLoadMem, 'LD', [ptReg, ptRegIndirect], 'Loads value from memory to register.'); 80 AddNew(inStoreMem, 'ST', [ptRegIndirect, ptReg], 'Stores value from register to memory.'); 103 AddNew(inDecSize, 'DEC', [ptDataWidth, ptReg], 'Decrements value in specified register.'); 81 104 AddNew(inAdd, 'ADD', [ptReg, ptReg], 'Adds second register to first register.'); 105 AddNew(inAddSize, 'ADD', [ptDataWidth, ptReg, ptReg], 'Adds second register to first register.'); 82 106 AddNew(inSub, 'SUB', [ptReg, ptReg], 'Subtracts second register from first register.'); 107 AddNew(inSubSize, 'SUB', [ptDataWidth, ptReg, ptReg], 'Subtracts second register from first register.'); 83 108 AddNew(inInput, 'IN', [ptReg, ptRegIndirect], 'Reads value from input port to register.'); 84 109 AddNew(inOutput, 'OUT', [ptRegIndirect, ptReg], 'Writes value from register to output port.'); 85 AddNew(inJumpZero, 'JZ', [ptReg, pt Number], 'Jumps to given address if value of register is zero');86 AddNew(inJumpNotZero, 'JNZ', [ptReg, pt Number], 'Jumps to given address if value of register is not zero');110 AddNew(inJumpZero, 'JZ', [ptReg, ptAddress], 'Jumps to given address if value of register is zero'); 111 AddNew(inJumpNotZero, 'JNZ', [ptReg, ptAddress], 'Jumps to given address if value of register is not zero'); 87 112 AddNew(inPush, 'PUSH', [ptReg], 'Pushes value of register to top of the stack.'); 113 AddNew(inPushSize, 'PUSH', [ptDataWidth, ptReg], 'Pushes value of register to top of the stack.'); 88 114 AddNew(inPop, 'POP', [ptReg], 'Pops value of register from top of the stack.'); 89 AddNew(inCall, 'CALL', [ptNumber], 'Calls subroutine at given address. Stores return address to the stack.'); 115 AddNew(inPopSize, 'POP', [ptDataWidth, ptReg], 'Pops value of register from top of the stack.'); 116 AddNew(inCall, 'CALL', [ptAddress], 'Calls subroutine at given address. Stores return address to the stack.'); 117 AddNew(inCallSize, 'CALL', [ptAddressWidth, ptAddress], 'Calls subroutine at given address. Stores return address to the stack.'); 90 118 AddNew(inRet, 'RET', [], 'Return from subroutine. Reads return address from top of the stack to IP register.'); 119 AddNew(inRetSize, 'RET', [ptAddressWidth], 'Return from subroutine. Reads return address from top of the stack to IP register.'); 91 120 AddNew(inAnd, 'AND', [ptReg, ptReg], 'Bitwise AND operation. Result is stored in first parameter.'); 121 AddNew(inAndSize, 'AND', [ptDataWidth, ptReg, ptReg], 'Bitwise AND operation. Result is stored in first parameter.'); 92 122 AddNew(inOr, 'OR', [ptReg, ptReg], 'Bitwise OR operation. Result is stored in first parameter.'); 123 AddNew(inOrSize, 'OR', [ptDataWidth, ptReg, ptReg], 'Bitwise OR operation. Result is stored in first parameter.'); 93 124 AddNew(inXor, 'XOR', [ptReg, ptReg], 'Bitwise XOR operation. Result is stored in first parameter.'); 94 AddNew(inXor, 'SHL', [ptReg, ptReg], 'Shifts all bits to the left in first register by n bits according value of second register.'); 95 AddNew(inXor, 'SHR', [ptReg, ptReg], 'Shifts all bits to the right in first register by n bits according value of second register.'); 125 AddNew(inXorSize, 'XOR', [ptDataWidth, ptReg, ptReg], 'Bitwise XOR operation. Result is stored in first parameter.'); 126 AddNew(inShl, 'SHL', [ptReg, ptReg], 'Shifts all bits to the left in first register by n bits according value of second register.'); 127 AddNew(inShlSize, 'SHL', [ptDataWidth, ptReg, ptReg], 'Shifts all bits to the left in first register by n bits according value of second register.'); 128 AddNew(inShr, 'SHR', [ptReg, ptReg], 'Shifts all bits to the right in first register by n bits according value of second register.'); 129 AddNew(inShrSize, 'SHR', [ptDataWidth, ptReg, ptReg], 'Shifts all bits to the right in first register by n bits according value of second register.'); 96 130 AddNew(inMul, 'MUL', [ptReg, ptReg], 'Multiplies first register with second register value.'); 131 AddNew(inMulSize, 'MUL', [ptDataWidth, ptReg, ptReg], 'Multiplies first register with second register value.'); 97 132 AddNew(inDiv, 'DIV', [ptReg, ptReg], 'Diviedes first register with second register value.'); 133 AddNew(inDivSize, 'DIV', [ptDataWidth, ptReg, ptReg], 'Diviedes first register with second register value.'); 98 134 //AddNew(inMod, 'MOD', [ptReg, ptReg], 'Returns modulo in first registr after division of values.'); 99 AddNew(inJump, 'JP', [pt Number], 'Unconditional absolute jump to defined address.');100 AddNew(inJump Rel, 'JR', [ptNumber], 'Unconditional relative jump to defined address.');101 //AddNew(inLoadIndex, 'LDI', [ptReg, ptRegIndirectIndex], 'Loads value from memory with numeric index to register.');102 //AddNew(inStoreIndex, 'STI', [ptRegIndirectIndex, ptReg], 'Stores value from register to memory with numeric index.');135 AddNew(inJump, 'JP', [ptAddress], 'Unconditional absolute jump to defined address.'); 136 AddNew(inJumpSize, 'JP', [ptAddressWidth, ptAddress], 'Unconditional absolute jump to defined address.'); 137 AddNew(inJumpRel, 'JR', [ptAddress], 'Unconditional relative jump to defined address.'); 138 AddNew(inJumpRelSize, 'JR', [ptAddressWidth, ptAddress], 'Unconditional relative jump to defined address.'); 103 139 //AddNew(inLoadCpu, 'LDC', [], 'Loads value from system register.'); 104 140 //AddNew(inStoreCpu, 'STC', [], 'Stores value to system register.'); … … 107 143 end; 108 144 109 destructor TInstructionSet.Destroy;110 begin111 FreeAndNil(Items);112 inherited;113 end;114 115 145 end. 116 146 -
branches/ByteArray/Languages/ByteArray.cs.po
r58 r59 16 16 msgstr "Překlad dokončen." 17 17 18 #: assembler.sduplicatelabel 19 #, object-pascal-format 20 msgid "Duplicate label %s." 21 msgstr "Zdvojený štítek %s." 22 23 #: assembler.sduplicatevariablename 24 #, object-pascal-format 25 msgid "Duplicate variable name %s" 26 msgstr "Zdvojený název proměnné %s" 27 18 28 #: assembler.sexpectednumber 19 29 msgid "Expected number." 20 30 msgstr "Očekáváno číslo." 21 31 32 #: assembler.sexpectednumberbutfound 33 #, object-pascal-format 34 msgid "Expected number but %s found." 35 msgstr "Očekáváno číslo, ale nalezeno %s." 36 22 37 #: assembler.sexpectednumericindex 23 38 msgid "Expected numeric register index." 24 39 msgstr "Očekáván číselný index registru." 25 40 41 #: assembler.sexpectedparameter 42 msgid "Expected parameter" 43 msgstr "Očekáván parametr" 44 45 #: assembler.sexpectedparametertype 46 #, object-pascal-format 47 msgid "Expected parameter type [%s]" 48 msgstr "Očekáván typ parametru [%s]" 49 26 50 #: assembler.sexpectedregistername 27 51 msgid "Expected register name." … … 35 59 msgid "Expected variable value." 36 60 msgstr "Očekávána hodnota proměnné." 61 62 #: assembler.slabelreferencedbutnotdefined 63 #, object-pascal-format 64 msgid "Label %s referenced but not defined." 65 msgstr "Odkazované, ale neurčené návěstí %s." 37 66 38 67 #: assembler.sunsupportedparametertype … … 85 114 msgstr "Adresa mimo rozsah." 86 115 116 #: parser.sexpectedbutfound 117 #, object-pascal-format 118 msgid "Expected %s but %s found." 119 msgstr "Očekáváno %s, ale nalezeno %s." 120 87 121 #: parser.sunknowncharacter 88 122 #, object-pascal-format -
branches/ByteArray/Languages/ByteArray.pot
r58 r59 6 6 msgstr "" 7 7 8 #: assembler.sduplicatelabel 9 #, object-pascal-format 10 msgid "Duplicate label %s." 11 msgstr "" 12 13 #: assembler.sduplicatevariablename 14 #, object-pascal-format 15 msgid "Duplicate variable name %s" 16 msgstr "" 17 8 18 #: assembler.sexpectednumber 9 19 msgid "Expected number." 10 20 msgstr "" 11 21 22 #: assembler.sexpectednumberbutfound 23 #, object-pascal-format 24 msgid "Expected number but %s found." 25 msgstr "" 26 12 27 #: assembler.sexpectednumericindex 13 28 msgid "Expected numeric register index." 14 29 msgstr "" 15 30 31 #: assembler.sexpectedparameter 32 msgid "Expected parameter" 33 msgstr "" 34 35 #: assembler.sexpectedparametertype 36 #, object-pascal-format 37 msgid "Expected parameter type [%s]" 38 msgstr "" 39 16 40 #: assembler.sexpectedregistername 17 41 msgid "Expected register name." … … 24 48 #: assembler.sexpectedvariablevalue 25 49 msgid "Expected variable value." 50 msgstr "" 51 52 #: assembler.slabelreferencedbutnotdefined 53 #, object-pascal-format 54 msgid "Label %s referenced but not defined." 26 55 msgstr "" 27 56 … … 75 104 msgstr "" 76 105 106 #: parser.sexpectedbutfound 107 #, object-pascal-format 108 msgid "Expected %s but %s found." 109 msgstr "" 110 77 111 #: parser.sunknowncharacter 78 112 #, object-pascal-format -
branches/ByteArray/Machine.pas
r50 r59 42 42 begin 43 43 Memory := TMemory.Create; 44 Memory.Size := 10000 0;44 Memory.Size := 10000; 45 45 FrameBuffer := TFrameBuffer.Create; 46 46 Storage := TStorage.Create; -
branches/ByteArray/Parser.pas
r50 r59 45 45 function CheckNextKind(Kind: TTokenKind): Boolean; 46 46 function CheckNextAndRead(Kind: TTokenKind; Value: string = ''): Boolean; 47 procedure Expect(Kind: TTokenKind; Value: string = '');47 function Expect(Kind: TTokenKind; Value: string = ''): Boolean; 48 48 procedure Error(Text: string; Pos: TPoint); 49 49 procedure Reset; … … 57 57 resourcestring 58 58 SUnknownCharacter = 'Unknown character %s'; 59 SExpectedButFound = 'Expected %s but %s found.'; 59 60 60 61 { TParserPos } … … 227 228 end; 228 229 229 procedure TParser.Expect(Kind: TTokenKind; Value: string = ''); 230 var 231 Token: TToken; 232 begin 233 Token := ReadNext; 234 if (Token.Kind <> Kind) or (LowerCase(Token.Value) <> LowerCase(Value)) then 235 Error('Expected ' + Value + ' but ' + Token.Value +' found.', Token.Pos); 230 function TParser.Expect(Kind: TTokenKind; Value: string = ''): Boolean; 231 var 232 Token: TToken; 233 begin 234 Result := True; 235 Token := ReadNext; 236 if (Token.Kind <> Kind) or (LowerCase(Token.Value) <> LowerCase(Value)) then begin 237 Result := False; 238 Error(Format(SExpectedButFound, [Value, Token.Value]), Token.Pos); 239 end; 236 240 end; 237 241 -
branches/ByteArray/Sample.asm
r57 r59 1 NOP 1 JP Start 2 NOP 3 NOP 4 NOP 2 5 3 LD A, 64 4 LD B, 8 5 OUT (B), A 6 LD B, 0 7 LD C, 10 8 OUT (B), A 6 RET 7 LD R0, (R1) 8 LD (R0), R1 9 LD R0, R1 10 LD R0, 1 11 LD (R0 + 1), R1 12 ;LD (R0), (R1) 13 LD D1, R0, 1 14 LD D1, R0, R1 15 16 JP Start 17 NOP 18 NOP 19 NOP 20 21 VAR DeviceConsole 1 22 VAR ConsoleReadChar 0 23 VAR ConsoleWriteChar 0 24 25 VAR DeviceKeyboard 2 26 27 VAR DeviceScreen 3 28 VAR ScreenGetWidth 0 29 VAR ScreenGetHeight 1 30 VAR ScreenSetAddr 0 31 VAR ScreenWrite 1 32 33 Start: 34 LD R0, 64 35 LD R1, 8 36 OUT (R1), R0 37 LD R1, 0 38 LD R2, 10 39 OUT (R1), R0 9 40 Loop: 10 INC A11 DEC C12 JNZ C, Loop13 HALT41 INC R0 42 DEC R2 43 JNZ R2, Loop 44 HALT 14 45 15 46 WriteStr: 47 ; R0 - string address 48 ; R1 - string length 16 49 PUSH R2 17 50 PUSH R3 18 51 PUSH R4 19 SET R3, ConsoleWriteChar 20 SET R4, DeviceConsole 52 LD R3, ConsoleWriteChar 21 53 WriteStrLoop: 22 54 LD R2, (R0) 23 OUT (R 4: R3), R255 OUT (R3), R2 24 56 INC R0 25 57 DEC R1 … … 35 67 PUSH R2 36 68 PUSH R3 37 SET R0, ScreenSetAddr 38 SET R1, 0 39 SET R3, DeviceScreen 40 OUT (R3: R0), R1 41 SET R0, ScreenGetWidth 42 IN R1, (R3: R0) 43 SET R0, ScreenGetHeight 44 IN R2, (R3: R0) 69 LD R0, ScreenSetAddr 70 LD R1, 0 71 OUT (R0), R1 72 LD R0, ScreenGetWidth 73 IN R1, (R0) 74 LD R0, ScreenGetHeight 75 IN R2, (R0) 45 76 MUL R2, R1 46 SETR0, ScreenWrite47 SETR1, 12077 LD R0, ScreenWrite 78 LD R1, 120 48 79 ClearScreenLoop: 49 OUT (R 3: R0), R180 OUT (R0), R1 50 81 DEC R2 51 82 JNZ R2, ClearScreenLoop … … 58 89 Hello: 59 90 DB 'Hello friend' 91 92 KeyInterrupt: 93 ; Echo key 94 PUSH R3 95 PUSH R2 96 PUSH R4 97 LD R3, ConsoleReadChar 98 IN R2, (R3) 99 LD R3, ConsoleWriteChar 100 OUT (R3), R2 101 POP R4 102 POP R2 103 POP R3 104 RET 105 106 Test: 107 LD R0, (R1 + 1) 108 LD (R1 + 12), R2
Note:
See TracChangeset
for help on using the changeset viewer.