source: branches/virtcpu fixed int/UMachine.pas

Last change on this file was 215, checked in by chronos, 4 years ago
  • Added: TMachine class which contains CPU and peripherals.
  • Added: Execute TCpu inside background thread.
File size: 2.8 KB
Line 
1unit UMachine;
2
3{$mode delphi}
4
5interface
6
7uses
8 Classes, SysUtils, UCpu, syncobjs;
9
10type
11 { TMachine }
12
13 TMachine = class(TComponent)
14 private
15 FOnSerialOutput: TNotifyEvent;
16 function CpuInput(Port: T): T;
17 procedure CpuOutput(Port, Value: T);
18 procedure DoSerialOutput;
19 public
20 Memory: array of T;
21 Cpu: TCpu;
22 VideoBase: T;
23 VideoWidth: T;
24 VideoHeight: T;
25 SerialBufferInput: array of Char;
26 SerialBufferOutput: array of Char;
27 SerialBufferLock: TCriticalSection;
28 constructor Create(AOwner: TComponent); override;
29 destructor Destroy; override;
30 procedure SerialInput(C: Char);
31 property OnSerialOutput: TNotifyEvent read FOnSerialOutput write FOnSerialOutput;
32 end;
33
34implementation
35
36{ TMachine }
37
38constructor TMachine.Create(AOwner: TComponent);
39begin
40 inherited;
41 SerialBufferLock := TCriticalSection.Create;
42 Cpu := TCpu.Create(nil);
43 Cpu.OnInput := CpuInput;
44 Cpu.OnOutput := CpuOutput;
45end;
46
47destructor TMachine.Destroy;
48begin
49 Cpu.Stop;
50 FreeAndNil(Cpu);
51 FreeAndNil(SerialBufferLock);
52 inherited;
53end;
54
55procedure TMachine.SerialInput(C: Char);
56begin
57 SerialBufferLock.Acquire;
58 try
59 SetLength(SerialBufferInput, Length(SerialBufferInput) + 1);
60 SerialBufferInput[High(SerialBufferInput)] := C;
61 finally
62 SerialBufferLock.Release;
63 end;
64end;
65
66function TMachine.CpuInput(Port: T): T;
67begin
68 Result := 0;
69 case Port of
70 0: begin
71 SerialBufferLock.Acquire;
72 try
73 while (Length(SerialBufferInput) = 0) and not Cpu.Terminated do begin
74 try
75 SerialBufferLock.Release;
76 Sleep(10);
77 finally
78 SerialBufferLock.Acquire;
79 end;
80 end;
81 if Length(SerialBufferInput) > 0 then begin
82 Result := Ord(SerialBufferInput[0]);
83 if Length(SerialBufferInput) > 1 then
84 Move(SerialBufferInput[1], SerialBufferInput[0], Length(SerialBufferInput) - 1);
85 SetLength(SerialBufferInput, Length(SerialBufferInput) - 1);
86 end else Result := 0;
87 finally
88 SerialBufferLock.Release;
89 end;
90 end;
91 1: begin
92 Result := Length(SerialBufferInput);
93 end;
94 end;
95end;
96
97procedure TMachine.CpuOutput(Port, Value: T);
98begin
99 case Port of
100 0: begin
101 SerialBufferLock.Acquire;
102 try
103 SetLength(SerialBufferOutput, Length(SerialBufferOutput) + 1);
104 SerialBufferOutput[High(SerialBufferOutput)] := Chr(Value);
105 finally
106 SerialBufferLock.Release;
107 end;
108 TThread.Synchronize(Cpu.Thread, DoSerialOutput);
109 end;
110 end;
111end;
112
113procedure TMachine.DoSerialOutput;
114begin
115 if Assigned(FOnSerialOutput) then
116 FOnSerialOutput(Self);
117end;
118
119end.
120
Note: See TracBrowser for help on using the repository browser.