source: branches/virtualcpu4/UMachine.pas

Last change on this file was 185, checked in by chronos, 6 years ago
  • Added: Assembler labels reference address calculation.
  • Fixed: Displaying address/data hex numbers in opcode and instruction.
File size: 4.0 KB
Line 
1unit UMachine;
2
3{$mode delphi}
4
5interface
6
7uses
8 Classes, SysUtils, UCpu, syncobjs;
9
10type
11 TScreen = class
12 Size: TPoint;
13 MemoryBase: Integer;
14 MemorySize: Integer;
15 ChangedAreaFrom: Integer;
16 ChangedAreaTo: Integer;
17 end;
18
19 { TMachine }
20
21 TMachine = class
22 private
23 FMemorySize: Integer;
24 function CpuInput(Port: TAddress): TRegister;
25 procedure CpuOutput(Port: TAddress; Value: TRegister);
26 function GetMemorySize: Integer;
27 procedure SetMemorySize(AValue: Integer);
28 public
29 Memory: Pointer;
30 Cpu: TCpu;
31 Screen: TScreen;
32 InputBuffer: string;
33 OutputBuffer: string;
34 LockInput: TCriticalSection;
35 LockOutput: TCriticalSection;
36 procedure ClearMemory;
37 constructor Create;
38 destructor Destroy; override;
39 property MemorySize: Integer read GetMemorySize write SetMemorySize;
40 end;
41
42implementation
43
44{ TMachine }
45
46constructor TMachine.Create;
47begin
48 LockInput := TCriticalSection.Create;
49 LockOutput := TCriticalSection.Create;
50 Cpu := TCpu.Create;
51 Cpu.OnInput := CpuInput;
52 Cpu.OnOutput := CpuOutput;
53 Cpu.DataSizeBase := bw32;
54 Cpu.AddrSizeBase := bw32;
55 Screen := TScreen.Create;
56 Screen.Size := Point(320, 240);
57 Screen.MemoryBase := $200;
58 MemorySize := $1000000;
59 Cpu.Memory := Memory;
60end;
61
62destructor TMachine.Destroy;
63begin
64 Screen.Free;
65 Cpu.Free;
66 LockInput.Free;
67 LockOutput.Free;
68 inherited Destroy;
69end;
70
71function TMachine.CpuInput(Port: TAddress): TRegister;
72begin
73 Result.Q := 0;
74 case Port of
75 0: begin
76 LockInput.Acquire;
77 while (Length(InputBuffer) = 0) and not Cpu.Terminated do begin
78 LockInput.Release;
79 Sleep(100);
80 LockInput.Acquire;
81 end;
82 if Length(InputBuffer) > 0 then begin
83 Result.B := Ord(InputBuffer[1]);
84 Delete(InputBuffer, 1, 1);
85 end else Result.B := 0;
86 LockInput.Release;
87 end;
88 1: case Cpu.DataSize of
89 bw8: Result.B := Screen.Size.X;
90 bw16: Result.W := Screen.Size.X;
91 bw32: Result.D := Screen.Size.X;
92 bw64: Result.Q := Screen.Size.X;
93 end;
94 2: case Cpu.DataSize of
95 bw8: Result.B := Screen.Size.Y;
96 bw16: Result.W := Screen.Size.Y;
97 bw32: Result.D := Screen.Size.Y;
98 bw64: Result.Q := Screen.Size.Y;
99 end;
100 3: case Cpu.DataSize of
101 bw8: Result.B := Screen.MemoryBase;
102 bw16: Result.W := Screen.MemoryBase;
103 bw32: Result.D := Screen.MemoryBase;
104 bw64: Result.Q := Screen.MemoryBase;
105 end;
106 end;
107end;
108
109procedure TMachine.CpuOutput(Port: TAddress; Value: TRegister);
110begin
111 case Port of
112 0: begin
113 LockOutput.Acquire;
114 OutputBuffer := OutputBuffer + Char(Value.B);
115 LockOutput.Release;
116 end;
117 1: case Cpu.DataSize of
118 bw8: Screen.Size.X := Value.B;
119 bw16: Screen.Size.X := Value.W;
120 bw32: Screen.Size.X := Value.D;
121 bw64: Screen.Size.X := Value.Q;
122 end;
123 2: case Cpu.DataSize of
124 bw8: Screen.Size.Y := Value.B;
125 bw16: Screen.Size.Y := Value.W;
126 bw32: Screen.Size.Y := Value.D;
127 bw64: Screen.Size.Y := Value.Q;
128 end;
129 3: case Cpu.DataSize of
130 bw8: Screen.MemoryBase := Value.B;
131 bw16: Screen.MemoryBase := Value.W;
132 bw32: Screen.MemoryBase := Value.D;
133 bw64: Screen.MemoryBase := Value.Q;
134 end;
135 4: case Cpu.DataSize of
136 bw8: Screen.ChangedAreaFrom := Value.B;
137 bw16: Screen.ChangedAreaFrom := Value.W;
138 bw32: Screen.ChangedAreaFrom := Value.D;
139 bw64: Screen.ChangedAreaFrom := Value.Q;
140 end;
141 5: case Cpu.DataSize of
142 bw8: Screen.ChangedAreaTo := Value.B;
143 bw16: Screen.ChangedAreaTo := Value.W;
144 bw32: Screen.ChangedAreaTo := Value.D;
145 bw64: Screen.ChangedAreaTo := Value.Q;
146 end;
147 end;
148end;
149
150function TMachine.GetMemorySize: Integer;
151begin
152 Result := FMemorySize;
153end;
154
155procedure TMachine.SetMemorySize(AValue: Integer);
156begin
157 if FMemorySize = AValue then Exit;
158 FMemorySize := AValue;
159 Memory := ReAllocMem(Memory, FMemorySize);
160end;
161
162procedure TMachine.ClearMemory;
163begin
164 FillChar(Memory^, MemorySize, $ff);
165end;
166
167
168end.
169
Note: See TracBrowser for help on using the repository browser.