Changeset 32 for branches/UltimatOS


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

Legend:

Unmodified
Added
Removed
  • branches/UltimatOS

    • Property svn:ignore
      •  

        old new  
        22UltimatOS.lps
        33UltimatOS.res
         4UltimatOS.dbg
        45lib
  • branches/UltimatOS/Forms/UFormMain.lfm

    r30 r32  
    1010  OnCreate = FormCreate
    1111  OnDestroy = FormDestroy
     12  OnKeyUp = FormKeyUp
    1213  OnShow = FormShow
    1314  LCLVersion = '2.2.0.4'
     
    1718    Top = 8
    1819    Width = 640
     20    OnMouseMove = PaintBox1MouseMove
    1921    OnPaint = PaintBox1Paint
    2022  end
    21   object ButtonRun: TButton
     23  object ButtonStart: TButton
    2224    Left = 8
    2325    Height = 33
    2426    Top = 496
    2527    Width = 98
    26     Caption = 'Run'
    27     OnClick = ButtonRunClick
     28    Caption = 'Start'
     29    OnClick = ButtonStartClick
    2830    TabOrder = 0
    2931  end
     
    4446  end
    4547  object ButtonMemory: TButton
    46     Left = 128
     48    Left = 550
    4749    Height = 33
    4850    Top = 496
     
    5153    OnClick = ButtonMemoryClick
    5254    TabOrder = 2
     55  end
     56  object ButtonStop: TButton
     57    Left = 112
     58    Height = 33
     59    Top = 496
     60    Width = 98
     61    Caption = 'Stop'
     62    OnClick = ButtonStopClick
     63    TabOrder = 3
     64  end
     65  object ButtonRestart: TButton
     66    Left = 216
     67    Height = 33
     68    Top = 496
     69    Width = 98
     70    Caption = 'Restart'
     71    OnClick = ButtonRestartClick
     72    TabOrder = 4
     73  end
     74  object ButtonCompile: TButton
     75    Left = 8
     76    Height = 33
     77    Top = 536
     78    Width = 98
     79    Caption = 'Compile'
     80    OnClick = ButtonCompileClick
     81    TabOrder = 5
    5382  end
    5483  object Timer1: TTimer
  • branches/UltimatOS/Forms/UFormMain.pas

    r30 r32  
    1313  TFormMain = class(TForm)
    1414    ButtonMemory: TButton;
    15     ButtonRun: TButton;
     15    ButtonCompile: TButton;
     16    ButtonStart: TButton;
     17    ButtonStop: TButton;
     18    ButtonRestart: TButton;
    1619    Label1: TLabel;
    1720    MemoCode: TMemo;
    1821    PaintBox1: TPaintBox;
    1922    Timer1: TTimer;
     23    procedure ButtonCompileClick(Sender: TObject);
    2024    procedure ButtonMemoryClick(Sender: TObject);
    21     procedure ButtonRunClick(Sender: TObject);
     25    procedure ButtonRestartClick(Sender: TObject);
     26    procedure ButtonStartClick(Sender: TObject);
     27    procedure ButtonStopClick(Sender: TObject);
    2228    procedure FormCreate(Sender: TObject);
    2329    procedure FormDestroy(Sender: TObject);
     30    procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
    2431    procedure FormShow(Sender: TObject);
     32    procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
     33      Y: Integer);
    2534    procedure PaintBox1Paint(Sender: TObject);
    2635    procedure Timer1Timer(Sender: TObject);
    2736  private
    2837    procedure InitProgram;
     38    procedure UpdateInterface;
    2939  public
    3040    Machine: TMachine;
     
    4050
    4151uses
    42   UInstructionWriter, UFormMemory;
     52  UAssembler, UFormMemory;
    4353
    4454{ TFormMain }
     
    5060end;
    5161
    52 procedure TFormMain.ButtonRunClick(Sender: TObject);
     62procedure TFormMain.ButtonStartClick(Sender: TObject);
    5363begin
    5464  Machine.Reset;
    55   with TInstructionWriter.Create do
    56   try
    57     Memory := Machine.Cpu.Memory;
    58     Parse(MemoCode.Lines);
    59   finally
    60     Free;
    61   end;
    62   Machine.Cpu.Run;
    63   Label1.Caption := 'Executed instructions: ' + IntToStr(Machine.Cpu.ExecutedCount);
     65  ButtonCompile.Click;
     66  Machine.Running := True;
     67  UpdateInterface;
     68end;
     69
     70procedure TFormMain.ButtonStopClick(Sender: TObject);
     71begin
     72  Machine.Running := False;
     73  UpdateInterface;
    6474end;
    6575
     
    7080end;
    7181
     82procedure TFormMain.ButtonCompileClick(Sender: TObject);
     83begin
     84  with TAssembler.Create do
     85  try
     86    Memory := Machine.Cpu.Memory;
     87    Parse(MemoCode.Lines);
     88  finally
     89    Free;
     90  end;
     91end;
     92
     93procedure TFormMain.ButtonRestartClick(Sender: TObject);
     94begin
     95  ButtonStop.Click;
     96  ButtonStart.Click;
     97end;
     98
    7299procedure TFormMain.FormDestroy(Sender: TObject);
    73100begin
     
    75102end;
    76103
     104procedure TFormMain.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState
     105  );
     106begin
     107  Machine.Keyboard.Press(Key);
     108end;
     109
    77110procedure TFormMain.FormShow(Sender: TObject);
    78111begin
     112  UpdateInterface;
     113end;
     114
     115procedure TFormMain.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
     116  Y: Integer);
     117begin
     118  Machine.Mouse.Move(X, Y);
    79119end;
    80120
     
    99139    PaintBox1.Repaint;
    100140  end;
     141  Label1.Caption := 'Executed instructions: ' + IntToStr(Machine.Cpu.ExecutedCount) + LineEnding +
     142    'Interrupts: ' + IntToStr(Machine.Cpu.InterruptCount);
    101143end;
    102144
     
    106148end;
    107149
     150procedure TFormMain.UpdateInterface;
     151begin
     152  ButtonStart.Enabled := not Machine.Running;
     153  ButtonStop.Enabled := Machine.Running;
     154  ButtonRestart.Enabled := not Machine.Running;
     155end;
     156
    108157end.
    109158
  • branches/UltimatOS/Graphics.asm

    r31 r32  
    1414  PUSH R0
    1515  PUSH R1
    16 Start:
     16RectangleStart:
    1717  COPY R0, R8
    1818  COPY R1, R9
    1919  CALL SetPixelAddr 
    2020  COPY R5, R3
    21 Line:
     21RectangleLine:
    2222  OUT  (ScreenWriteData), R7
    2323  DEC  R5
    24   JPNZ R5, Line
     24  JPNZ R5, RectangleLine
    2525  DEC  R6
    2626  INC  R9
    27   JPNZ R6, Start
     27  JPNZ R6, RectangleStart
    2828  POP  R1
    2929  POP  R0
  • branches/UltimatOS/IO.asm

    r29 r32  
    1010  .const ScreenSetAddr 0
    1111  .const ScreenWriteData 1
     12  .const CounterSetInterval 2
     13  .const CounterSetState 3
    1214 
     15  ; Interrupt vectors
     16  .const InterruptVectorCounter 2
     17  .const InterruptVectorMouse 3
     18  .const InterruptVectorKeyboard 4
     19 
  • branches/UltimatOS/Program.asm

    r30 r32  
    11  .include IO.asm
    22 
     3  CALL Start
     4  .org 8
     5  .dd  InterruptHandlerCounter
     6  .dd  InterruptHandlerMouse
     7  .dd  InterruptHandlerKeyboard
     8 
     9  .org $100
     10Start: 
    311  ;SET  R0, $ff7700 ; Color
    412  ;SET  R1, 100     ; X
     
    2230  ;CALL WriteChar
    2331 
    24   HALT
     32StartLoop:
     33  JP   StartLoop
     34  ;HALT
     35 
     36InterruptHandlerCounter:
     37  RETI
     38 
     39MousePosX:
     40  .dd 0 
     41MousePosY:
     42  .dd 0 
     43 
     44InterruptHandlerMouse:
     45  PUSH R0
     46  PUSH R1
     47  IN   R0, (MouseGetPosX)
     48  SET  R1, MousePosX
     49  ST   (R1), R0
     50  IN   R0, (MouseGetPosY)
     51  SET  R1, MousePosY
     52  ST   (R1), R0
     53  POP  R1
     54  POP  R0
     55  RETI
     56
     57InterruptHandlerKeyboard:
     58  RETI
    2559 
    2660HelloWorld: .db "Hello world", 0
  • 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);
  • branches/UltimatOS/UCpu.pas

    r31 r32  
    99  TInstruction = (inNop, inHalt, inSet, inInput, inOutput, inInc, inDec, inJp,
    1010    inJpz, inJpnz, inAdd, inSub, inCall, inRet, inPush, inPop, inCopy,
    11     inShl, inShr, inLoad, inLoadi, inStore, inMul, inAnd, inAndi, inOr, inXor);
     11    inShl, inShr, inLoad, inLoadi, inStore, inMul, inAnd, inAndi, inOr, inXor,
     12    inInt, inReti, inEnableInt, inDisableInt);
    1213  TAddress = Integer;
    1314  PAddress = ^TAddress;
     
    1920  TOnOutput = procedure (Address: Integer; Value: TData) of object;
    2021
     22  TCpu = class;
     23
     24  { TCpuThread }
     25
     26  TCpuThread = class(TThread)
     27    Cpu: TCpu;
     28    procedure Execute; override;
     29    destructor Destroy; override;
     30  end;
     31
    2132  { TCpu }
    2233
    2334  TCpu = class
    2435  private
     36    FCpuThread: TCpuThread;
    2537    FOnInput: TOnInput;
    2638    FOnOutput: TOnOutput;
     39    InterruptPending: Boolean;
     40    InterruptVector: Integer;
     41    InterruptEnabled: Boolean;
     42    function GetRunning: Boolean;
    2743    function ReadByte: Byte;
    2844    function ReadAddress: TAddress;
     
    3046    procedure Push(Value: Integer);
    3147    function Pop: Integer;
     48    procedure SetRunning(AValue: Boolean);
    3249  public
    3350    ExecutedCount: Integer;
     51    InterruptCount: Integer;
    3452    Terminated: Boolean;
    3553    Memory: TMemory;
     
    3856    SP: TAddress;
    3957    procedure Run;
     58    procedure Start;
     59    procedure Stop;
    4060    procedure Step;
    4161    procedure Reset;
     62    procedure Interrupt(Vector: Integer);
     63    constructor Create;
     64    destructor Destroy; override;
    4265    property OnInput: TOnInput read FOnInput write FOnInput;
    4366    property OnOutput: TOnOutput read FOnOutput write FOnOutput;
     67    property Running: Boolean read GetRunning write SetRunning;
    4468  end;
    4569
    4670
    4771implementation
     72
     73{ TCpuThread }
     74
     75procedure TCpuThread.Execute;
     76begin
     77  Cpu.Run;
     78end;
     79
     80destructor TCpuThread.Destroy;
     81begin
     82  Cpu.FCpuThread := nil;
     83  inherited;
     84end;
    4885
    4986{ TCpu }
     
    5592end;
    5693
     94function TCpu.GetRunning: Boolean;
     95begin
     96  Result := Assigned(FCpuThread);
     97end;
     98
    5799function TCpu.ReadAddress: TAddress;
    58100begin
     
    79121end;
    80122
     123procedure TCpu.SetRunning(AValue: Boolean);
     124begin
     125  if AValue and not Assigned(FCpuThread) then begin
     126    FCpuThread := TCpuThread.Create(True);
     127    FCpuThread.FreeOnTerminate := True;
     128    FCpuThread.Cpu := Self;
     129    FCpuThread.Start;
     130  end else
     131  if not AValue and Assigned(FCpuThread) then begin
     132    Terminated := True;
     133    FreeAndNil(FCpuThread);
     134  end;
     135end;
     136
    81137procedure TCpu.Run;
    82138begin
    83   while not Terminated do
     139  while not Terminated do begin
     140    if InterruptEnabled and InterruptPending then begin
     141      InterruptEnabled := False;
     142      InterruptPending := False;
     143      Push(IP);
     144      IP := PAddress(@Memory.Data[InterruptVector * SizeOf(TAddress)])^;
     145    end;
    84146    Step;
     147  end;
     148end;
     149
     150procedure TCpu.Start;
     151begin
     152  Running := True;
     153end;
     154
     155procedure TCpu.Stop;
     156begin
     157  Running := False;
    85158end;
    86159
     
    214287      R[RegIndex] := R[RegIndex] xor R[RegIndex2];
    215288    end;
     289    inInt: begin
     290      Interrupt(ReadByte);
     291    end;
     292    inReti: begin
     293      IP := Pop;
     294      InterruptEnabled := True;
     295    end;
     296    inEnableInt: InterruptEnabled := True;
     297    inDisableInt: InterruptEnabled := False;
    216298  end;
    217299end;
     
    223305  SP := 0;
    224306  ExecutedCount := 0;
     307  InterruptEnabled := True;
     308  InterruptPending := False;
     309  InterruptCount := 0;
     310end;
     311
     312procedure TCpu.Interrupt(Vector: Integer);
     313begin
     314  InterruptPending := True;
     315  InterruptVector := Vector;
     316  Inc(InterruptCount);
     317end;
     318
     319constructor TCpu.Create;
     320begin
     321end;
     322
     323destructor TCpu.Destroy;
     324begin
     325  Running := False;
     326  inherited;
    225327end;
    226328
  • branches/UltimatOS/UMachine.pas

    r31 r32  
    44
    55uses
    6   Classes, SysUtils, UCpu, UMemory;
     6  Classes, SysUtils, UCpu, UMemory, ExtCtrls;
    77
    88type
     9  TMachine = class;
    910
    1011  { TDevice }
    1112
    1213  TDevice = class
     14    Machine: TMachine;
    1315    procedure Reset; virtual;
    1416  end;
     17
     18  { TMouse }
    1519
    1620  TMouse = class(TDevice)
    1721    Position: TPoint;
     22    InterruptVector: Integer;
     23    procedure Move(X, Y: Integer);
    1824  end;
    1925
     
    5460  TKeyboard = class(TDevice)
    5561    Buffer: TFifo;
     62    InterruptVector: Integer;
    5663    function ReadKey: Integer;
    5764    function KeyReady: Integer;
     
    5966    destructor Destroy; override;
    6067    procedure Reset; override;
     68    procedure Press(KeyCode: Integer);
     69  end;
     70
     71  { TCounter }
     72
     73  TCounter = class(TDevice)
     74  private
     75    Timer: TTimer;
     76    function GetEnabled: Boolean;
     77    function GetInterval: Integer;
     78    procedure SetEnabled(AValue: Boolean);
     79    procedure SetInterval(AValue: Integer);
     80    procedure DoTimer(Sender: TObject);
     81  public
     82    InterruptVector: Integer;
     83    constructor Create;
     84    destructor Destroy; override;
     85    property Enabled: Boolean read GetEnabled write SetEnabled;
     86    property Interval: Integer read GetInterval write SetInterval;
    6187  end;
    6288
     
    6793    function CpuInput(Address: TAddress): TData;
    6894    procedure CpuOutput(Address: TAddress; Value: TData);
     95    function GetRunning: Boolean;
     96    procedure SetRunning(AValue: Boolean);
    6997  public
    7098    Cpu: TCpu;
     
    73101    Mouse: TMouse;
    74102    Screen: TScreen;
     103    Counter: TCounter;
    75104    procedure Reset;
    76105    constructor Create;
    77106    destructor Destroy; override;
     107    property Running: Boolean read GetRunning write SetRunning;
    78108  end;
    79109
    80110
    81111implementation
     112
     113{ TMouse }
     114
     115procedure TMouse.Move(X, Y: Integer);
     116begin
     117  Position := Point(X, Y);
     118  Machine.Cpu.Interrupt(InterruptVector);
     119end;
     120
     121{ TCounter }
     122
     123function TCounter.GetEnabled: Boolean;
     124begin
     125  Result := Timer.Enabled;
     126end;
     127
     128function TCounter.GetInterval: Integer;
     129begin
     130  Result := Timer.Interval;
     131end;
     132
     133procedure TCounter.SetEnabled(AValue: Boolean);
     134begin
     135  Timer.Enabled := AValue;
     136end;
     137
     138procedure TCounter.SetInterval(AValue: Integer);
     139begin
     140  Timer.Interval := AValue;
     141end;
     142
     143procedure TCounter.DoTimer(Sender: TObject);
     144begin
     145  Machine.Cpu.Interrupt(InterruptVector);
     146end;
     147
     148constructor TCounter.Create;
     149begin
     150  Timer := TTimer.Create(nil);
     151  Timer.OnTimer := DoTimer;
     152  Enabled := False;
     153end;
     154
     155destructor TCounter.Destroy;
     156begin
     157  FreeAndNil(Timer);
     158  inherited;
     159end;
    82160
    83161{ TDevice }
     
    183261begin
    184262  Buffer.Clear;
     263end;
     264
     265procedure TKeyboard.Press(KeyCode: Integer);
     266begin
     267  Buffer.Put(KeyCode);
     268  Machine.Cpu.Interrupt(InterruptVector);
    185269end;
    186270
     
    201285begin
    202286  if Address = 0 then Screen.SetPointer(Value)
    203   else if Address = 1 then Screen.WriteData(Value);
     287  else if Address = 1 then Screen.WriteData(Value)
     288  else if Address = 2 then Counter.Interval := Value
     289  else if Address = 3 then Counter.Enabled := Value = 1;
     290end;
     291
     292function TMachine.GetRunning: Boolean;
     293begin
     294  Result := Cpu.Running;
     295end;
     296
     297procedure TMachine.SetRunning(AValue: Boolean);
     298begin
     299  Cpu.Running := AValue;
    204300end;
    205301
     
    213309constructor TMachine.Create;
    214310begin
     311  Counter := TCounter.Create;
     312  Counter.Machine := Self;
     313  Counter.InterruptVector := 2;
    215314  Memory := TMemory.Create;
    216315  Memory.Size := 200000;
    217316  Keyboard := TKeyboard.Create;
     317  Keyboard.Machine := Self;
     318  Keyboard.InterruptVector := 4;
    218319  Mouse := TMouse.Create;
     320  Mouse.Machine := Self;
     321  Mouse.InterruptVector := 3;
    219322  Screen := TScreen.Create;
    220323  Screen.Size := Point(640, 480);
     
    232335  FreeAndNil(Screen);
    233336  FreeAndNil(Memory);
     337  FreeAndNil(Counter);
    234338  inherited;
    235339end;
  • branches/UltimatOS/UltimatOS.lpi

    r30 r32  
    5252            </Options>
    5353          </Linking>
     54          <Other>
     55            <CompilerMessages>
     56              <IgnoredMessages idx6058="True" idx3124="True" idx3123="True"/>
     57            </CompilerMessages>
     58          </Other>
    5459        </CompilerOptions>
    5560      </Item>
     
    9297      </Unit>
    9398      <Unit>
    94         <Filename Value="UInstructionWriter.pas"/>
     99        <Filename Value="UAssembler.pas"/>
    95100        <IsPartOfProject Value="True"/>
    96101      </Unit>
     
    99104        <IsPartOfProject Value="True"/>
    100105        <ComponentName Value="FormMemory"/>
     106        <HasResources Value="True"/>
    101107        <ResourceBaseClass Value="Form"/>
    102108      </Unit>
     
    132138    </CodeGeneration>
    133139    <Linking>
     140      <Debugging>
     141        <UseExternalDbgSyms Value="True"/>
     142      </Debugging>
    134143      <Options>
    135144        <Win32>
     
    138147      </Options>
    139148    </Linking>
     149    <Other>
     150      <CompilerMessages>
     151        <IgnoredMessages idx6058="True" idx3124="True" idx3123="True"/>
     152      </CompilerMessages>
     153    </Other>
    140154  </CompilerOptions>
    141155  <Debugging>
  • branches/UltimatOS/UltimatOS.lpr

    r30 r32  
    1111  {$ENDIF}
    1212  Interfaces, // this includes the LCL widgetset
    13   Forms, UFormMain, UMachine, UCpu, UMemory, UInstructionWriter, UFormMemory
     13  Forms, UFormMain, UMachine, UCpu, UMemory, UAssembler, UFormMemory
    1414  { you can add units after this };
    1515
Note: See TracChangeset for help on using the changeset viewer.