Ignore:
Timestamp:
Jul 10, 2022, 12:37:58 AM (2 years ago)
Author:
chronos
Message:
  • Added: Interrupt handling.
Location:
branches/UltimatOS
Files:
1 edited
1 moved

Legend:

Unmodified
Added
Removed
  • branches/UltimatOS

    • Property svn:ignore
      •  

        old new  
        22UltimatOS.lps
        33UltimatOS.res
         4UltimatOS.dbg
        45lib
  • branches/UltimatOS/UAssembler.pas

    r31 r32  
    1 unit UInstructionWriter;
     1unit UAssembler;
    22
    33interface
     
    2525  end;
    2626
     27  { TLabel }
     28
    2729  TLabel = class
    2830    Name: string;
    2931    Address: TAddress;
    3032    ForwardRefs: array of TAddress;
     33    procedure AddForwardRef(Address: TAddress);
    3134  end;
    3235
     
    5053  end;
    5154
    52   { TInstructionWriter }
    53 
    54   TInstructionWriter = class
     55  { TAssembler }
     56
     57  TAssembler = class
    5558  private
    5659    InstructionDefs: TInstructionDefs;
     
    5962    LineNumber: Integer;
    6063    function ParseText(var Text: string; Separator: Char): string;
     64    function ParseConst(Text: string; out Value: Integer): Boolean;
     65    function ParseLabel(Text: string; out Value: Integer): Boolean;
     66    function ParseNumber(Text: string; out Value: Integer): Boolean;
    6167    procedure WriteParam(Param: TInstructionParam; var Text: string);
    6268    procedure Error(Text: string);
     
    6571    IP: Integer;
    6672    procedure Parse(Lines: TStrings);
    67     procedure Write(Text: string);
     73    procedure ParseLine(Text: string);
    6874    procedure WriteInstruction(Instruction: TInstruction);
    6975    procedure WriteAddress(Address: TAddress);
     
    8086implementation
    8187
     88{ TLabel }
     89
     90procedure TLabel.AddForwardRef(Address: TAddress);
     91begin
     92  SetLength(ForwardRefs, Length(ForwardRefs) + 1);
     93  ForwardRefs[Length(ForwardRefs) - 1] := Address;
     94end;
     95
    8296{ TConstants }
    8397
     
    144158
    145159
    146 { TInstructionWriter }
    147 
    148 function TInstructionWriter.ParseText(var Text: string; Separator: Char
     160{ TAssembler }
     161
     162function TAssembler.ParseText(var Text: string; Separator: Char
    149163  ): string;
    150164var
     
    161175end;
    162176
    163 procedure TInstructionWriter.WriteParam(Param: TInstructionParam; var Text: string);
     177function TAssembler.ParseConst(Text: string; out Value: Integer): Boolean;
     178var
     179  FoundConstant: TConstant;
     180begin
     181  FoundConstant := Constants.SearchByName(UpperCase(Text));
     182  if Assigned(FoundConstant) then begin
     183    Result := True;
     184    Value := FoundConstant.Value;
     185  end;
     186  Result := False;
     187end;
     188
     189function TAssembler.ParseLabel(Text: string; out Value: Integer): Boolean;
     190var
     191  FoundLabel: TLabel;
     192begin
     193  Result := True;
     194  FoundLabel := Labels.SearchByName(UpperCase(Text));
     195  if Assigned(FoundLabel) then begin
     196    // Existing label
     197    if FoundLabel.Address = -1 then begin
     198      FoundLabel.AddForwardRef(IP);
     199      Value := 0;
     200    end else
     201      Value := FoundLabel.Address;
     202  end else begin
     203    // Forward label reference
     204    with Labels.AddNew(UpperCase(Text), -1) do begin
     205      AddForwardRef(IP);
     206    end;
     207    Value := 0;
     208  end;
     209end;
     210
     211function TAssembler.ParseNumber(Text: string; out Value: Integer): Boolean;
     212begin
     213  if TryStrToInt(Text, Value) then begin
     214    Result := True;
     215  end else
     216    Result := False;
     217end;
     218
     219procedure TAssembler.WriteParam(Param: TInstructionParam; var Text: string);
    164220var
    165221  Address: string;
     
    179235          Exit;
    180236        end;
    181         FoundLabel := Labels.SearchByName(UpperCase(Address));
    182         if Assigned(FoundLabel) then begin
    183           // Existing label
    184           WriteAddress(FoundLabel.Address);
    185         end else begin
    186           // Forward label reference
    187           with Labels.AddNew(UpperCase(Address), -1) do begin
    188             SetLength(ForwardRefs, Length(ForwardRefs) + 1);
    189             ForwardRefs[Length(ForwardRefs) - 1] := IP;
    190           end;
    191           WriteAddress(0);
    192         end;
     237        ParseLabel(Address, Value);
     238        WriteAddress(Value);
    193239      end;
    194240    end;
     
    205251            Exit;
    206252          end;
    207           FoundLabel := Labels.SearchByName(UpperCase(Address));
    208           if Assigned(FoundLabel) then begin
    209             // Existing label
    210             WriteAddress(FoundLabel.Address);
    211           end else begin
    212             // Forward label reference
    213             with Labels.AddNew(UpperCase(Address), -1) do begin
    214               SetLength(ForwardRefs, Length(ForwardRefs) + 1);
    215               ForwardRefs[Length(ForwardRefs) - 1] := IP;
    216             end;
    217             WriteAddress(0);
    218           end;
     253          ParseLabel(Address, Value);
     254          WriteAddress(Value);
    219255        end;
    220256      end else Error('Expected indirect address ' + Address);
     
    245281          Exit;
    246282        end;
    247         FoundLabel := Labels.SearchByName(UpperCase(Address));
    248         if Assigned(FoundLabel) then begin
    249           // Existing label
    250           WriteData(FoundLabel.Address);
    251         end else begin
    252           // Forward label reference
    253           with Labels.AddNew(UpperCase(Address), -1) do begin
    254             SetLength(ForwardRefs, Length(ForwardRefs) + 1);
    255             ForwardRefs[Length(ForwardRefs) - 1] := IP;
    256           end;
    257           WriteData(0);
    258         end;
     283        ParseLabel(Address, Value);
     284        WriteData(Value);
    259285      end;
    260286    end;
     
    273299end;
    274300
    275 procedure TInstructionWriter.Error(Text: string);
     301procedure TAssembler.Error(Text: string);
    276302begin
    277303  raise Exception.Create(IntToStr(LineNumber) + ': ' + Text);
    278304end;
    279305
    280 procedure TInstructionWriter.Parse(Lines: TStrings);
     306procedure TAssembler.Parse(Lines: TStrings);
    281307var
    282308  I: Integer;
     
    284310  for I := 0 to Lines.Count - 1 do begin
    285311    LineNumber := I + 1;
    286     Write(Lines[I]);
     312    ParseLine(Lines[I]);
    287313  end;
    288314  for I := 0 to Labels.Count - 1 do begin
     
    292318end;
    293319
    294 procedure TInstructionWriter.Write(Text: string);
     320procedure TAssembler.ParseLine(Text: string);
    295321var
    296322  FoundLabel: TLabel;
     
    304330  Lines: TStringList;
    305331  Param: string;
     332  Num: Integer;
    306333begin
    307334  // Remove comments
     
    375402    if InstructionName = 'dd' then begin
    376403      while Text <> '' do begin
    377         Param := ParseText(Text, ',');
     404        Param := Trim(ParseText(Text, ','));
    378405        if Param.StartsWith('"') and Param.EndsWith('"') then begin
    379406          Param := Copy(Param, 2, Length(Param) - 2);
    380407          for I := 1 to Length(Param) do
    381408            WriteCardinal(Ord(Param[I]));
    382         end else WriteCardinal(StrToInt(Param));
    383       end;
     409        end else begin
     410          if ParseNumber(Param, Num) then
     411            WriteCardinal(Num)
     412          else if ParseConst(Param, Num) then
     413            WriteCardinal(Num)
     414          else if ParseLabel(Param, Num) then
     415            WriteCardinal(Num);
     416        end;
     417      end;
     418    end else
     419    if InstructionName = 'org' then begin
     420      IP := StrToInt(Text);
    384421    end else Error('Unsupported directive name ' + InstructionName);
    385422  end else begin
     
    396433end;
    397434
    398 procedure TInstructionWriter.WriteInstruction(Instruction: TInstruction);
     435procedure TAssembler.WriteInstruction(Instruction: TInstruction);
    399436begin
    400437  Memory.Data[IP] := Byte(Instruction);
     
    402439end;
    403440
    404 procedure TInstructionWriter.WriteAddress(Address: TAddress);
     441procedure TAssembler.WriteAddress(Address: TAddress);
    405442begin
    406443  PAddress(@Memory.Data[IP])^ := Address;
     
    408445end;
    409446
    410 procedure TInstructionWriter.WriteData(Data: TData);
     447procedure TAssembler.WriteData(Data: TData);
    411448begin
    412449  PData(@Memory.Data[IP])^ := Data;
     
    414451end;
    415452
    416 procedure TInstructionWriter.WriteIndex(Index: Byte);
     453procedure TAssembler.WriteIndex(Index: Byte);
    417454begin
    418455  Memory.Data[IP] := Index;
     
    420457end;
    421458
    422 procedure TInstructionWriter.WriteReg(Index: Byte);
     459procedure TAssembler.WriteReg(Index: Byte);
    423460begin
    424461  Memory.Data[IP] := Index;
     
    426463end;
    427464
    428 procedure TInstructionWriter.WriteByte(Value: Byte);
     465procedure TAssembler.WriteByte(Value: Byte);
    429466begin
    430467  Memory.Data[IP] := Value;
     
    432469end;
    433470
    434 procedure TInstructionWriter.WriteWord(Value: Word);
     471procedure TAssembler.WriteWord(Value: Word);
    435472begin
    436473  PWord(@Memory.Data[IP])^ := Value;
     
    438475end;
    439476
    440 procedure TInstructionWriter.WriteCardinal(Value: Cardinal);
     477procedure TAssembler.WriteCardinal(Value: Cardinal);
    441478begin
    442479  PCardinal(@Memory.Data[IP])^ := Value;
     
    444481end;
    445482
    446 constructor TInstructionWriter.Create;
     483constructor TAssembler.Create;
    447484begin
    448485  Labels := TLabels.Create;
     
    477514    AddNew(inOr, 'OR', ipRegIndex, ipRegIndex);
    478515    AddNew(inXor, 'XOR', ipRegIndex, ipRegIndex);
    479   end;
    480 end;
    481 
    482 destructor TInstructionWriter.Destroy;
     516    AddNew(inInt, 'INT', ipIndex);
     517    AddNew(inReti, 'RETI');
     518    AddNew(inEnableInt, 'EI');
     519    AddNew(inDisableInt, 'DI');
     520  end;
     521end;
     522
     523destructor TAssembler.Destroy;
    483524begin
    484525  FreeAndNil(InstructionDefs);
Note: See TracChangeset for help on using the changeset viewer.