Changeset 59


Ignore:
Timestamp:
Nov 25, 2023, 11:47:52 PM (5 months ago)
Author:
chronos
Message:
  • Fixed: Assembler and disassembler to work correctly with supported instructions.
Location:
branches/ByteArray
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • branches/ByteArray/Assembler.pas

    r56 r59  
    1414    RefPos: Integer;
    1515    TextPos: TPoint;
    16     class function Create(LabelName: string; RefPos: Integer): TLabelRef; static;
     16    class function Create(LabelName: string; RefPos: Integer; TextPos: TPoint): TLabelRef; static;
    1717  end;
    1818
     
    2323    FOnError: TErrorEvent;
    2424    Parser: TParser;
     25    InstDataWidth: TBigIntSize;
     26    InstAddressWidth: TBigIntSize;
    2527    function ParseVar: Boolean;
    2628    function ParseDb: Boolean;
    2729    function ParseOrg: Boolean;
    2830    function ParseInstruction: Boolean;
     31    function ParseInstructionParameter(ParamType: TParamType; Memory: TMemory): Boolean;
    2932    function ParseLabel: Boolean;
    3033    procedure UpdateLabelRefs;
    3134    function ParseNumParam(out Number: TBigInt): Boolean;
    3235    function ParseReg(out RegIndex: TRegIndex): Boolean;
     36    function ParseDataWidth(out Size: TBigIntSize): Boolean;
     37    function ParseAddressWidth(out Size: TBigIntSize): Boolean;
    3338  public
    34     InstructionSet: TInstructionSet;
     39    InstructionSet: TInstructionInfos;
    3540    Memory: TMemory;
    3641    Labels: TDictionary<string, TBigInt>;
     
    3843    Variables: TDictionary<string, TBigInt>;
    3944    Messages: TMessages;
     45    DataWidth: TBigIntSize;
     46    AddressWidth: TBigIntSize;
    4047    procedure Error(Text: string; Pos: TPoint);
    4148    procedure Compile(Source: string);
     
    5865  SExpectedVariableValue = 'Expected variable value.';
    5966  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.';
    6073
    6174{ TLabelRef }
    6275
    63 class function TLabelRef.Create(LabelName: string; RefPos: Integer): TLabelRef;
     76class function TLabelRef.Create(LabelName: string; RefPos: Integer; TextPos: TPoint): TLabelRef;
    6477begin
    6578  Result.LabelName := LabelName;
    6679  Result.RefPos := RefPos;
     80  Result.TextPos := TextPos;
    6781end;
    6882
     
    7791    if Labels.TryGetValue(LabelRefs[I].LabelName, Addr) then
    7892      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);
    8095  end;
    8196end;
     
    8499var
    85100  Token: TToken;
    86 begin
     101  LastPos: TParserPos;
     102begin
     103  LastPos := Parser.Pos;
    87104  Result := False;
    88105  Token := Parser.ReadNext;
     
    99116      Result := True;
    100117    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));
    102119      Number := 0;
    103120      Result := True;
    104121    end;
    105   end else Error('Unexpected token ' + Token.Value + '.', Token.Pos);
     122  end;
     123  if not Result then Parser.Pos := LastPos;
    106124end;
    107125
     
    110128  LastPos: TParserPos;
    111129  Token: TToken;
     130  Index: Integer;
    112131begin
    113132  Result := False;
    114133  LastPos := Parser.Pos;
    115134  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;
     142end;
     143
     144function TAssembler.ParseDataWidth(out Size: TBigIntSize): Boolean;
     145var
     146  LastPos: TParserPos;
     147  Token: TToken;
     148  Index: Integer;
     149begin
     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;
     160end;
     161
     162function TAssembler.ParseAddressWidth(out Size: TBigIntSize): Boolean;
     163var
     164  LastPos: TParserPos;
     165  Token: TToken;
     166  Index: Integer;
     167begin
     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;
    120178end;
    121179
     
    134192  Labels.Clear;
    135193  LabelRefs.Clear;
     194  Variables.Clear;
    136195  Parser.Reset;
    137196  Parser.Source := Source;
     
    172231            if TryStrToBigInt(TokenValue.Value, Number) then
    173232              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);
    176235        end else Error(SExpectedVariableValue, TokenValue.Pos);
    177236      end else Error(SExpectedVariableName, TokenName.Pos);
     
    199258        if Token.Kind = tkString then begin
    200259          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);
    202264      end;
    203265      if Parser.CheckNextAndRead(tkSpecialSymbol, ',') then begin
     
    219281    if Token.Kind = tkNumber then begin
    220282      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);
    222284  end;
    223285end;
     
    225287function TAssembler.ParseInstruction: Boolean;
    226288var
    227   InstructionInfo: TInstructionInfo;
     289  InstructionInfos: TInstructionInfos;
    228290  I: Integer;
    229291  Token: TToken;
    230292  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;
     302begin
     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);
     379end;
     380
     381function TAssembler.ParseInstructionParameter(ParamType: TParamType; Memory: TMemory): Boolean;
     382var
     383  LastPos: TParserPos;
     384  I: Integer;
    231385  RegIndex: TRegIndex;
    232386  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;
     388begin
     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);
    269457    end;
    270458  end;
     
    285473    if not Labels.TryGetValue(Token.Value, Addr) then begin
    286474      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);
    288476  end;
    289477  if not Result then Parser.Pos := LastPos;
     
    323511  Messages := TMessages.Create;
    324512  Memory := TMemory.Create;
    325   InstructionSet := TInstructionSet.Create;
     513  InstructionSet := TInstructionInfos.Create;
     514  InstructionSet.Init;
    326515  Labels := TDictionary<string, TBigInt>.Create;
    327516  LabelRefs := TList<TLabelRef>.Create;
  • branches/ByteArray/ByteArray.lpi

    r58 r59  
    231231        <IsPartOfProject Value="True"/>
    232232        <ComponentName Value="Core"/>
     233        <HasResources Value="True"/>
    233234        <ResourceBaseClass Value="DataModule"/>
    234235      </Unit>
     
    237238        <IsPartOfProject Value="True"/>
    238239        <ComponentName Value="FormDebugger"/>
     240        <HasResources Value="True"/>
    239241        <ResourceBaseClass Value="Form"/>
    240242      </Unit>
  • branches/ByteArray/Core.lfm

    r58 r59  
    33  OnDestroy = DataModuleDestroy
    44  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
    910  object PersistentForm1: TPersistentForm
    1011    MinVisiblePart = 50
    1112    EntireVisible = False
    12     Left = 408
    13     Top = 88
     13    Left = 612
     14    Top = 132
    1415  end
    1516  object ApplicationInfo1: TApplicationInfo
     
    2728    RegistryRoot = rrKeyCurrentUser
    2829    License = 'CC0'
    29     Left = 208
    30     Top = 88
     30    Left = 312
     31    Top = 132
    3132  end
    3233  object Translator1: TTranslator
    3334    POFilesFolder = 'Languages'
    34     Left = 419
    35     Top = 182
     35    Left = 629
     36    Top = 273
    3637  end
    3738  object ThemeManager1: TThemeManager
    38     Left = 199
    39     Top = 187
     39    Left = 299
     40    Top = 281
    4041  end
    4142  object ActionList1: TActionList
    42     Left = 568
    43     Top = 88
     43    Left = 852
     44    Top = 132
    4445    object ASourceEditor: TAction
    4546      Caption = 'Source editor'
  • branches/ByteArray/Core.pas

    r58 r59  
    7878begin
    7979  Machine := TMachine.Create;
    80   InitMachine;
     80  //InitMachine;
    8181  LoadConfig;
    8282
     
    118118  end;
    119119  FormDisassembler.Disassembler.Memory := Machine.Memory;
     120  FormDisassembler.Disassembler.DataWidth := Machine.Cpu.DataWidth;
     121  FormDisassembler.Disassembler.AddressWidth := Machine.Cpu.AddressWidth;
    120122  FormDisassembler.Show;
    121123end;
     
    222224    // LD A, 'A'
    223225    WriteInstruction(inLoadConst);
    224     WriteRegister(riA);
     226    WriteRegister(0);
    225227    Write(DataWidth, Ord('A'));
    226228
    227229    // LD B, 8
    228230    WriteInstruction(inLoadConst);
    229     WriteRegister(riB);
     231    WriteRegister(1);
    230232    Write(DataWidth, Machine.Serial.BaseAddress);
    231233
    232234    // OUT (B), A
    233235    WriteInstruction(inOutput);
    234     WriteRegister(riB);
    235     WriteRegister(riA);
     236    WriteRegister(1);
     237    WriteRegister(0);
    236238
    237239    // LD B,
    238240    WriteInstruction(inLoadConst);
    239     WriteRegister(riB);
     241    WriteRegister(1);
    240242    Write(DataWidth, Machine.FrameBuffer.BaseAddress);
    241243
    242244    WriteInstruction(inLoadConst);
    243     WriteRegister(riC);
     245    WriteRegister(2);
    244246    Write(DataWidth, 10);
    245247
     
    247249
    248250    WriteInstruction(inOutput);
    249     WriteRegister(riB);
    250     WriteRegister(riA);
     251    WriteRegister(1);
     252    WriteRegister(0);
    251253
    252254    WriteInstruction(inInc);
    253     WriteRegister(riA);
     255    WriteRegister(0);
    254256
    255257    WriteInstruction(inDec);
    256     WriteRegister(riC);
     258    WriteRegister(2);
    257259
    258260    WriteInstruction(inJumpNotZero);
    259     WriteRegister(riC);
     261    WriteRegister(2);
    260262    Write(AddressWidth, Loop);
    261263
     
    278280      else ThemeManager1.Theme := ThemeManager1.Themes.FindByName('System');
    279281    StartUpForm := ReadStringWithDefault('StartUpForm', 'Screen');
     282    AutoStartMachine := ReadBoolWithDefault('AutoStartMachine', True);
    280283  finally
    281284    Free;
     
    295298      else DeleteValue('Theme');
    296299    WriteString('StartUpForm', StartUpForm);
     300    WriteBool('AutoStartMachine', AutoStartMachine);
    297301  finally
    298302    Free;
  • branches/ByteArray/Cpu.pas

    r57 r59  
    1212    inLoadMem, inLoadMemSize,
    1313    inStoreMem, inStoreMemSize,
     14    inLoadMemIndex, inLoadMemIndexSize,
     15    inStoreMemIndex, inStoreMemIndexSize,
    1416    inInput, inInputSize,
    1517    inOutput, inOutputSize,
     
    3840    inCompare);
    3941
    40   TRegIndex = (riA, riB, riC, riD, riE, riF, riG, riH);
     42  TRegIndex = Byte;
    4143
    4244  TInstructionEvent = procedure of object;
     
    6466    procedure InstructionStoreMem;
    6567    procedure InstructionStoreMemSize;
     68    procedure InstructionLoadMemIndex;
     69    procedure InstructionLoadMemIndexSize;
     70    procedure InstructionStoreMemIndex;
     71    procedure InstructionStoreMemIndexSize;
    6672    procedure InstructionJump;
    6773    procedure InstructionJumpSize;
     
    213219procedure TCpu.InstructionLoadMem;
    214220var
    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;
     223begin
     224  RegIndex1 := ReadRegIndex;
     225  RegIndex2 := ReadRegIndex;
     226  Regs[RegIndex1] := Memory.Read(Regs[RegIndex2], DataWidth);
    221227end;
    222228
     
    224230var
    225231  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;
     234begin
     235  DataSize := ReadSize;
     236  RegIndex1 := ReadRegIndex;
     237  RegIndex2 := ReadRegIndex;
     238  Regs[RegIndex1] := Memory.Read(Regs[RegIndex2], DataSize);
    235239end;
    236240
    237241procedure TCpu.InstructionStoreMem;
    238242var
    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;
     245begin
     246  RegIndex1 := ReadRegIndex;
     247  RegIndex2 := ReadRegIndex;
     248  Memory.Write(Regs[RegIndex1], DataWidth, Regs[RegIndex2]);
    245249end;
    246250
     
    248252var
    249253  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;
     256begin
     257  DataSize := ReadSize;
     258  RegIndex1 := ReadRegIndex;
     259  RegIndex2 := ReadRegIndex;
     260  Memory.Write(Regs[RegIndex1], DataSize, Regs[RegIndex2]);
     261end;
     262
     263procedure TCpu.InstructionLoadMemIndex;
     264var
     265  RegIndex1: TRegIndex;
     266  RegIndex2: TRegIndex;
     267  RelativeAddress: TBigInt;
     268begin
     269  RegIndex1 := ReadRegIndex;
     270  RegIndex2 := ReadRegIndex;
     271  RelativeAddress := Read(AddressWidth);
     272  Regs[RegIndex1] := Memory.Read(Regs[RegIndex2] + RelativeAddress, DataWidth);
     273end;
     274
     275procedure TCpu.InstructionLoadMemIndexSize;
     276var
     277  DataSize: TBigIntSize;
     278  RegIndex1: TRegIndex;
     279  RegIndex2: TRegIndex;
     280  RelativeAddress: TBigInt;
     281begin
     282  DataSize := ReadSize;
     283  RegIndex1 := ReadRegIndex;
     284  RegIndex2 := ReadRegIndex;
     285  RelativeAddress := Read(AddressWidth);
     286  Regs[RegIndex1] := Memory.Read(Regs[RegIndex2] + RelativeAddress, DataSize);
     287end;
     288
     289procedure TCpu.InstructionStoreMemIndex;
     290var
     291  RegIndex1: TRegIndex;
     292  RegIndex2: TRegIndex;
     293  RelativeAddress: TBigInt;
     294begin
     295  RegIndex1 := ReadRegIndex;
     296  RegIndex2 := ReadRegIndex;
     297  RelativeAddress := Read(AddressWidth);
     298  Memory.Write(Regs[RegIndex1] + RelativeAddress, DataWidth, Regs[RegIndex2]);
     299end;
     300
     301procedure TCpu.InstructionStoreMemIndexSize;
     302var
     303  DataSize: TBigIntSize;
     304  RegIndex1: TRegIndex;
     305  RegIndex2: TRegIndex;
     306  RelativeAddress: TBigInt;
     307begin
     308  DataSize := ReadSize;
     309  RegIndex1 := ReadRegIndex;
     310  RegIndex2 := ReadRegIndex;
     311  RelativeAddress := Read(AddressWidth);
     312  Memory.Write(Regs[RegIndex1] + RelativeAddress, DataSize, Regs[RegIndex2]);
    259313end;
    260314
     
    603657  FInstructions[inStoreMem] := InstructionStoreMem;
    604658  FInstructions[inStoreMemSize] := InstructionStoreMemSize;
     659  FInstructions[inLoadMemIndex] := InstructionLoadMemIndex;
     660  FInstructions[inLoadMemIndexSize] := InstructionLoadMemIndexSize;
     661  FInstructions[inStoreMemIndex] := InstructionStoreMemIndex;
     662  FInstructions[inStoreMemIndexSize] := InstructionStoreMemIndexSize;
    605663  FInstructions[inJump] := InstructionJump;
    606664  FInstructions[inJumpSize] := InstructionJumpSize;
     
    802860- bit index 2048 (256 * 8) (8 + 3) bits = 2^11
    803861
     862LD   R0, R1
     863LD2  R0, R1
     864LD.2 R0, R1
     865LD:2 R0, R1
     866LD   D2, R0, R1
     867LD   D2, A16, R0, (R1)
     868LD   D2:A16: R0, (R1)
     869RET
     870RET2
     871RET.2
     872RET:2
     873RET  A2
     874PUSH   R0
     875PUSH2  R0
     876PUSH.2 R0
     877PUSH:2 R0
     878PUSH   D2, R0
     879PUSH   D2:R0
     880PUSH   R0.2
     881PUSH   R0:2
     882LD     (R0), (R2)
     883LD     D1, A2, (R0), (R2)
     884LDIR   (R0), (R1), R2
     885LDIR   D1, A2, (R0), (R1), R2
     886LDI
     887OUT    (R0), R1
     888OUT    D1, (R0), R1
     889OUT    D1, A2, (R0), R1
    804890
    805891
  • branches/ByteArray/Devices/FrameBuffer.pas

    r47 r59  
    4444begin
    4545  Memory.Size := Width * Height;
    46   Memory.Clean;
     46  Memory.FillZero;
    4747end;
    4848
  • branches/ByteArray/Devices/Memory.pas

    r56 r59  
    1616    function GetSize: Integer;
    1717    procedure SetSize(AValue: Integer);
     18    procedure CheckGrow(Address: Integer);
    1819  public
    1920    Position: Integer;
     21    Grow: Boolean;
    2022    procedure Assign(Source: TMemory);
    2123    function Read(Address: TBigInt; ASize: TBigIntSize): TBigInt;
     
    2830    procedure SetChannel(Channel: TChannel); override;
    2931    procedure SaveToFile(FileName: string);
    30     procedure Clean;
     32    procedure FillZero;
     33    procedure Clear;
    3134    property Size: Integer read FSize write SetSize;
    3235    destructor Destroy; override;
     
    5053  FSize := AValue;
    5154  FData := ReAllocMem(FData, AValue);
     55end;
     56
     57procedure TMemory.CheckGrow(Address: Integer);
     58begin
     59  if Grow and (Size < Address) then Size := Address;
    5260end;
    5361
     
    9098procedure TMemory.WritePos(ASize: Byte; Value: TBigInt);
    9199begin
     100  CheckGrow(Position + ASize);
    92101  Write(Position, ASize, Value);
    93102  Inc(Position, ASize);
     
    98107  I: Integer;
    99108begin
     109  CheckGrow(Position + Length(Value));
    100110  if Length(Value) > 0 then begin
    101111    if Position + Length(Value) > FSize then Size := Position + Length(Value);
     
    108118procedure TMemory.WriteMemoryPos(Memory: TMemory);
    109119begin
     120  CheckGrow(Position + Memory.Size);
    110121  if Memory.Size > 0 then begin
    111122    if Position + Memory.Size > FSize then Size := Position + Memory.Size;
     
    126137end;
    127138
    128 procedure TMemory.Clean;
     139procedure TMemory.FillZero;
    129140begin
    130141  FillChar(FData^, FSize, 0);
     142end;
     143
     144procedure TMemory.Clear;
     145begin
     146  Size := 0;
     147  Position := 0;
    131148end;
    132149
  • branches/ByteArray/Disassembler.pas

    r55 r59  
    44
    55uses
    6   Classes, SysUtils, Cpu, Instructions, StrUtils, Memory;
     6  Classes, SysUtils, Cpu, Instructions, StrUtils, Memory, BigInt;
    77
    88type
     
    1212  TDisassembler = class
    1313  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;
    1525  public
    16     InstructionSet: TInstructionSet;
     26    InstructionSet: TInstructionInfos;
    1727    Memory: TMemory;
     28    DataWidth: TBigIntSize;
     29    AddressWidth: TBigIntSize;
    1830    procedure Disassemble(Lines: TStrings);
    1931    procedure SaveToFile(FileName: string);
     
    2537implementation
    2638
    27 uses
    28   BigInt;
     39procedure TDisassembler.DisassembleData;
     40var
     41  Text: string;
     42begin
     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';
     46end;
    2947
    30 function TDisassembler.RegToStr(RegIndex: Byte): string;
     48procedure TDisassembler.DisassembleAddress;
     49var
     50  Text: string;
    3151begin
    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';
     55end;
     56
     57procedure TDisassembler.DisassembleRegister;
     58begin
     59  InstText := InstText + 'R' + IntToStr(Byte(Memory.ReadPos(1)));
     60end;
     61
     62procedure TDisassembler.DisassembleRegisterIndirect;
     63begin
     64  InstText := InstText + '(R' + IntToStr(Byte(Memory.ReadPos(1))) + ')';
     65end;
     66
     67procedure TDisassembler.DisassembleRegisterIndirectIndex;
     68begin
     69  InstText := InstText + '(R' + IntToStr(Byte(Memory.ReadPos(1))) +
     70    ' + ';
     71  DisassembleAddress;
     72  InstText := InstText + ')';
     73end;
     74
     75procedure TDisassembler.DisassembleDataWidth;
     76begin
     77  InstDataWidth := Memory.ReadPos(1);
     78  InstText := InstText + 'D' + IntToStr(InstDataWidth);
     79end;
     80
     81procedure TDisassembler.DisassembleAddressWidth;
     82begin
     83  InstAddressWidth := Memory.ReadPos(1);
     84  InstText := InstText + 'A' + IntToStr(InstAddressWidth);
    3385end;
    3486
    3587procedure TDisassembler.Disassemble(Lines: TStrings);
    3688var
    37   I: Integer;
    3889  J: Integer;
    3990  Value: TBigInt;
     
    4192  InstructionInfo: TInstructionInfo;
    4293  Line: string;
    43   InstText: string;
    44   InstBytes: string;
     94  MemoryPos: Integer;
     95  InstructionByteSize: Integer;
     96  I: Integer;
    4597begin
    4698  Memory.Position := 0;
    4799  while Memory.Position < Memory.Size do begin
    48100    Line := IntToHex(Memory.Position, 8) + ' ';
     101    MemoryPos := Memory.Position;
    49102    Value := Memory.ReadPos(1);
    50103    InstBytes := IntToHex(Value, 2) + ' ';
    51104    InstText := '';
     105    InstAddressWidth := AddressWidth;
     106    InstDataWidth := DataWidth;
    52107    if (Value >= 0) and (Value <= Integer(High(TInstruction))) then begin
    53108      Instruction := TInstruction(Int64(Value));
     
    56111        InstText := InstructionInfo.Name;
    57112        for J := 0 to Length(InstructionInfo.Params) - 1 do begin
    58           Value := Memory.ReadPos(1);
    59           InstBytes := InstBytes + IntToHex(Value, 2) + ' ';
    60113          if J > 0 then
    61114            InstText := InstText + ', ' else
    62115            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;
    77124          end;
    78125        end;
    79         InstBytes := InstBytes + DupeString(' ', 13 - Length(InstBytes));
    80126      end;
    81127    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
    82137    Line := Line + InstBytes + InstText;
    83138    Lines.Add(Line);
     
    97152constructor TDisassembler.Create;
    98153begin
    99   InstructionSet := TInstructionSet.Create;
     154  InstructionSet := TInstructionInfos.Create;
     155  InstructionSet.Init;
     156  DataWidth := 1;
     157  AddressWidth := 1;
    100158end;
    101159
  • branches/ByteArray/Forms/FormSourceEditor.pas

    r58 r59  
    121121  AStop.Execute;
    122122  with Assembler do begin
     123    DataWidth := Machine.Cpu.DataWidth;
     124    AddressWidth := Machine.Cpu.AddressWidth;
    123125    Compile(FormAssembler.SynEdit1.Lines.Text);
    124126    Memory.SaveToFile('compiled.bin');
  • branches/ByteArray/Instructions.pas

    r56 r59  
    77
    88type
    9   TParamType = (ptNone, ptNumber, ptReg, ptRegIndirect, ptRegIndirectIndex,
    10     ptSize);
     9  TParamType = (ptNone, ptRegIndirectIndex, ptRegIndirect, ptReg,
     10    ptDataWidth, ptAddressWidth, ptData, ptAddress);
    1111  TParamTypeArray = array of TParamType;
    1212
     
    1818  end;
    1919
    20   { TInstructionSet }
     20  { TInstructionInfos }
    2121
    22   TInstructionSet = class
    23     Items: TObjectList<TInstructionInfo>;
    24     function SearchName(Name: string): TInstructionInfo;
     22  TInstructionInfos = class(TObjectList<TInstructionInfo>)
     23    function SearchByName(Name: string): TInstructionInfo;
     24    function SearchByNameMultiple(Name: string): TInstructionInfos;
    2525    function SearchInstruction(Instruction: TInstruction): TInstructionInfo;
    2626    function AddNew(Instruction: TInstruction; Name: string;
    2727      Params: TParamTypeArray; Description: string): TInstructionInfo;
    28     constructor Create;
    29     destructor Destroy; override;
     28    procedure Init;
    3029  end;
     30
     31const
     32  ParamTypeString: array[TParamType] of string = ('None', 'Data', 'Address',
     33    'Register', 'Indirect register', 'Indirect indexed register',
     34    'Data width', 'Address width');
    3135
    3236
    3337implementation
    3438
    35 { TInstructionSet }
     39{ TInstructionInfos }
    3640
    37 function TInstructionSet.SearchName(Name: string): TInstructionInfo;
     41function TInstructionInfos.SearchByName(Name: string): TInstructionInfo;
    3842var
    3943  I: Integer;
    4044begin
    4145  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]
    4448    else Result := nil;
    4549end;
    4650
    47 function TInstructionSet.SearchInstruction(Instruction: TInstruction
     51function TInstructionInfos.SearchByNameMultiple(Name: string
     52  ): TInstructionInfos;
     53var
     54  I: Integer;
     55begin
     56  Result := TInstructionInfos.Create(False);
     57  for I := 0 to Count - 1 do
     58    if Items[I].Name = Name then Result.Add(Items[I]);
     59end;
     60
     61function TInstructionInfos.SearchInstruction(Instruction: TInstruction
    4862  ): TInstructionInfo;
    4963var
     
    5165begin
    5266  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]
    5569    else Result := nil;
    5670end;
    5771
    58 function TInstructionSet.AddNew(Instruction: TInstruction; Name: string;
     72function TInstructionInfos.AddNew(Instruction: TInstruction; Name: string;
    5973  Params: TParamTypeArray; Description: string): TInstructionInfo;
    6074begin
     
    6478  Result.Params := Params;
    6579  Result.Description := Description;
    66   Items.Add(Result);
     80  Add(Result);
    6781end;
    6882
    69 constructor TInstructionSet.Create;
     83procedure TInstructionInfos.Init;
    7084begin
    71   Items := TObjectList<TInstructionInfo>.Create;
     85  Clear;
    7286  AddNew(inNop, 'NOP', [], 'No operation - The instruction doesn''t do anything.');
    7387  AddNew(inHalt, 'HALT', [], 'It terminates program execution and halts processor. Processor can be waked up by interrupt.');
    74   AddNew(inLoadConst, 'LD', [ptReg, ptNumber], 'Sets register to immediate constant value.');
    75   AddNew(inLoadConstSize, 'LD', [ptSize, 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.');
    7690  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.');
    77100  AddNew(inInc, 'INC', [ptReg], 'Increments value in specified register.');
     101  AddNew(inIncSize, 'INC', [ptDataWidth, ptReg], 'Increments value in specified register.');
    78102  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.');
    81104  AddNew(inAdd, 'ADD', [ptReg, ptReg], 'Adds second register to first register.');
     105  AddNew(inAddSize, 'ADD', [ptDataWidth, ptReg, ptReg], 'Adds second register to first register.');
    82106  AddNew(inSub, 'SUB', [ptReg, ptReg], 'Subtracts second register from first register.');
     107  AddNew(inSubSize, 'SUB', [ptDataWidth, ptReg, ptReg], 'Subtracts second register from first register.');
    83108  AddNew(inInput, 'IN', [ptReg, ptRegIndirect], 'Reads value from input port to register.');
    84109  AddNew(inOutput, 'OUT', [ptRegIndirect, ptReg], 'Writes value from register to output port.');
    85   AddNew(inJumpZero, 'JZ', [ptReg, ptNumber], 'Jumps to given address if value of register is zero');
    86   AddNew(inJumpNotZero, 'JNZ', [ptReg, ptNumber], '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');
    87112  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.');
    88114  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.');
    90118  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.');
    91120  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.');
    92122  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.');
    93124  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.');
    96130  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.');
    97132  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.');
    98134  //AddNew(inMod, 'MOD', [ptReg, ptReg], 'Returns modulo in first registr after division of values.');
    99   AddNew(inJump, 'JP', [ptNumber], 'Unconditional absolute jump to defined address.');
    100   AddNew(inJumpRel, '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.');
    103139  //AddNew(inLoadCpu, 'LDC', [], 'Loads value from system register.');
    104140  //AddNew(inStoreCpu, 'STC', [], 'Stores value to system register.');
     
    107143end;
    108144
    109 destructor TInstructionSet.Destroy;
    110 begin
    111   FreeAndNil(Items);
    112   inherited;
    113 end;
    114 
    115145end.
    116146
  • branches/ByteArray/Languages/ByteArray.cs.po

    r58 r59  
    1616msgstr "Překlad dokončen."
    1717
     18#: assembler.sduplicatelabel
     19#, object-pascal-format
     20msgid "Duplicate label %s."
     21msgstr "Zdvojený štítek %s."
     22
     23#: assembler.sduplicatevariablename
     24#, object-pascal-format
     25msgid "Duplicate variable name %s"
     26msgstr "Zdvojený název proměnné %s"
     27
    1828#: assembler.sexpectednumber
    1929msgid "Expected number."
    2030msgstr "Očekáváno číslo."
    2131
     32#: assembler.sexpectednumberbutfound
     33#, object-pascal-format
     34msgid "Expected number but %s found."
     35msgstr "Očekáváno číslo, ale nalezeno %s."
     36
    2237#: assembler.sexpectednumericindex
    2338msgid "Expected numeric register index."
    2439msgstr "Očekáván číselný index registru."
    2540
     41#: assembler.sexpectedparameter
     42msgid "Expected parameter"
     43msgstr "Očekáván parametr"
     44
     45#: assembler.sexpectedparametertype
     46#, object-pascal-format
     47msgid "Expected parameter type [%s]"
     48msgstr "Očekáván typ parametru [%s]"
     49
    2650#: assembler.sexpectedregistername
    2751msgid "Expected register name."
     
    3559msgid "Expected variable value."
    3660msgstr "Očekávána hodnota proměnné."
     61
     62#: assembler.slabelreferencedbutnotdefined
     63#, object-pascal-format
     64msgid "Label %s referenced but not defined."
     65msgstr "Odkazované, ale neurčené návěstí %s."
    3766
    3867#: assembler.sunsupportedparametertype
     
    85114msgstr "Adresa mimo rozsah."
    86115
     116#: parser.sexpectedbutfound
     117#, object-pascal-format
     118msgid "Expected %s but %s found."
     119msgstr "Očekáváno %s, ale nalezeno %s."
     120
    87121#: parser.sunknowncharacter
    88122#, object-pascal-format
  • branches/ByteArray/Languages/ByteArray.pot

    r58 r59  
    66msgstr ""
    77
     8#: assembler.sduplicatelabel
     9#, object-pascal-format
     10msgid "Duplicate label %s."
     11msgstr ""
     12
     13#: assembler.sduplicatevariablename
     14#, object-pascal-format
     15msgid "Duplicate variable name %s"
     16msgstr ""
     17
    818#: assembler.sexpectednumber
    919msgid "Expected number."
    1020msgstr ""
    1121
     22#: assembler.sexpectednumberbutfound
     23#, object-pascal-format
     24msgid "Expected number but %s found."
     25msgstr ""
     26
    1227#: assembler.sexpectednumericindex
    1328msgid "Expected numeric register index."
    1429msgstr ""
    1530
     31#: assembler.sexpectedparameter
     32msgid "Expected parameter"
     33msgstr ""
     34
     35#: assembler.sexpectedparametertype
     36#, object-pascal-format
     37msgid "Expected parameter type [%s]"
     38msgstr ""
     39
    1640#: assembler.sexpectedregistername
    1741msgid "Expected register name."
     
    2448#: assembler.sexpectedvariablevalue
    2549msgid "Expected variable value."
     50msgstr ""
     51
     52#: assembler.slabelreferencedbutnotdefined
     53#, object-pascal-format
     54msgid "Label %s referenced but not defined."
    2655msgstr ""
    2756
     
    75104msgstr ""
    76105
     106#: parser.sexpectedbutfound
     107#, object-pascal-format
     108msgid "Expected %s but %s found."
     109msgstr ""
     110
    77111#: parser.sunknowncharacter
    78112#, object-pascal-format
  • branches/ByteArray/Machine.pas

    r50 r59  
    4242begin
    4343  Memory := TMemory.Create;
    44   Memory.Size := 100000;
     44  Memory.Size := 10000;
    4545  FrameBuffer := TFrameBuffer.Create;
    4646  Storage := TStorage.Create;
  • branches/ByteArray/Parser.pas

    r50 r59  
    4545    function CheckNextKind(Kind: TTokenKind): Boolean;
    4646    function CheckNextAndRead(Kind: TTokenKind; Value: string = ''): Boolean;
    47     procedure Expect(Kind: TTokenKind; Value: string = '');
     47    function Expect(Kind: TTokenKind; Value: string = ''): Boolean;
    4848    procedure Error(Text: string; Pos: TPoint);
    4949    procedure Reset;
     
    5757resourcestring
    5858  SUnknownCharacter = 'Unknown character %s';
     59  SExpectedButFound = 'Expected %s but %s found.';
    5960
    6061{ TParserPos }
     
    227228end;
    228229
    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);
     230function TParser.Expect(Kind: TTokenKind; Value: string = ''): Boolean;
     231var
     232  Token: TToken;
     233begin
     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;
    236240end;
    237241
  • branches/ByteArray/Sample.asm

    r57 r59  
    1   NOP
     1    JP   Start
     2    NOP
     3    NOP
     4    NOP
    25
    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
     33Start:
     34    LD   R0, 64
     35    LD   R1, 8
     36    OUT  (R1), R0
     37    LD   R1, 0
     38    LD   R2, 10
     39    OUT  (R1), R0
    940Loop:
    10   INC A
    11   DEC C
    12   JNZ C, Loop
    13   HALT
     41    INC  R0
     42    DEC  R2
     43    JNZ  R2, Loop
     44    HALT
    1445
    1546WriteStr:
     47    ; R0 - string address
     48    ; R1 - string length
    1649    PUSH R2
    1750    PUSH R3
    1851    PUSH R4
    19     SET  R3, ConsoleWriteChar
    20     SET  R4, DeviceConsole
     52    LD   R3, ConsoleWriteChar
    2153WriteStrLoop:
    2254    LD   R2, (R0)
    23     OUT  (R4: R3), R2
     55    OUT  (R3), R2
    2456    INC  R0
    2557    DEC  R1
     
    3567    PUSH R2
    3668    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)
    4576    MUL  R2, R1
    46     SET  R0, ScreenWrite
    47     SET  R1, 120
     77    LD   R0, ScreenWrite
     78    LD   R1, 120
    4879ClearScreenLoop:
    49     OUT  (R3: R0), R1
     80    OUT  (R0), R1
    5081    DEC  R2
    5182    JNZ  R2, ClearScreenLoop
     
    5889Hello:
    5990    DB   'Hello friend'
     91
     92KeyInterrupt:
     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
     106Test:
     107    LD   R0, (R1 + 1)
     108    LD   (R1 + 12), R2
Note: See TracChangeset for help on using the changeset viewer.