1 | unit UMachine;
|
---|
2 |
|
---|
3 | {$mode delphi}{$H+}
|
---|
4 |
|
---|
5 | interface
|
---|
6 |
|
---|
7 | uses
|
---|
8 | Classes, SysUtils, UVarInt, UCpu, syncobjs;
|
---|
9 |
|
---|
10 | type
|
---|
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(TComponent)
|
---|
22 | private
|
---|
23 | FMemorySize: Integer;
|
---|
24 | procedure SetMemorySize(AValue: Integer);
|
---|
25 | function CpuInput(Port: T): T;
|
---|
26 | procedure CpuOutput(Port: T; Value: T);
|
---|
27 | public
|
---|
28 | Cpu: TCpu;
|
---|
29 | Memory: Pointer;
|
---|
30 | Screen: TScreen;
|
---|
31 | InputBuffer: string;
|
---|
32 | OutputBuffer: string;
|
---|
33 | LockInput: TCriticalSection;
|
---|
34 | LockOutput: TCriticalSection;
|
---|
35 | property MemorySize: Integer read FMemorySize write SetMemorySize;
|
---|
36 | constructor Create(AOwner: TComponent); override;
|
---|
37 | destructor Destroy; override;
|
---|
38 | end;
|
---|
39 |
|
---|
40 |
|
---|
41 | implementation
|
---|
42 |
|
---|
43 | { TMachine }
|
---|
44 |
|
---|
45 | procedure TMachine.SetMemorySize(AValue: Integer);
|
---|
46 | begin
|
---|
47 | if FMemorySize = AValue then Exit;
|
---|
48 | FMemorySize := AValue;
|
---|
49 | Memory := ReAllocMem(Memory, FMemorySize);
|
---|
50 | Cpu.Memory := Memory;
|
---|
51 | Cpu.OnOutput := CpuOutput;
|
---|
52 | Cpu.OnInput := CpuInput;
|
---|
53 | end;
|
---|
54 |
|
---|
55 | function TMachine.CpuInput(Port: T): T;
|
---|
56 | begin
|
---|
57 | Result := 0;
|
---|
58 | case Integer(Port) of
|
---|
59 | 0: begin
|
---|
60 | LockInput.Acquire;
|
---|
61 | while (Length(InputBuffer) = 0) and not Cpu.Terminated do begin
|
---|
62 | LockInput.Release;
|
---|
63 | Sleep(100);
|
---|
64 | LockInput.Acquire;
|
---|
65 | end;
|
---|
66 | if Length(InputBuffer) > 0 then begin
|
---|
67 | Result := Ord(InputBuffer[1]);
|
---|
68 | Delete(InputBuffer, 1, 1);
|
---|
69 | end else Result := 0;
|
---|
70 | LockInput.Release;
|
---|
71 | end;
|
---|
72 | 1: Result := Screen.Size.X;
|
---|
73 | 2: Result := Screen.Size.Y;
|
---|
74 | 3: Result := Screen.MemoryBase;
|
---|
75 | end;
|
---|
76 | end;
|
---|
77 |
|
---|
78 | procedure TMachine.CpuOutput(Port: T; Value: T);
|
---|
79 | begin
|
---|
80 | case Integer(Port) of
|
---|
81 | 0: begin
|
---|
82 | LockOutput.Acquire;
|
---|
83 | OutputBuffer := OutputBuffer + Char(Value);
|
---|
84 | LockOutput.Release;
|
---|
85 | end;
|
---|
86 | 1: Screen.Size.X := Value;
|
---|
87 | 2: Screen.Size.Y := Value;
|
---|
88 | 3: Screen.MemoryBase := Value;
|
---|
89 | 4: Screen.ChangedAreaFrom := Value;
|
---|
90 | 5: Screen.ChangedAreaTo := Value;
|
---|
91 | end;
|
---|
92 | end;
|
---|
93 |
|
---|
94 | constructor TMachine.Create(AOwner: TComponent);
|
---|
95 | begin
|
---|
96 | inherited;
|
---|
97 | LockInput := TCriticalSection.Create;
|
---|
98 | LockOutput := TCriticalSection.Create;
|
---|
99 | Cpu := TCpu.Create(nil);
|
---|
100 | MemorySize := 1000;
|
---|
101 | Screen := TScreen.Create;
|
---|
102 | Screen.Size := Point(320, 240);
|
---|
103 | Screen.MemoryBase := $200;
|
---|
104 | end;
|
---|
105 |
|
---|
106 | destructor TMachine.Destroy;
|
---|
107 | begin
|
---|
108 | MemorySize := 0;
|
---|
109 | FreeAndNil(Screen);
|
---|
110 | FreeAndNil(Cpu);
|
---|
111 | inherited Destroy;
|
---|
112 | end;
|
---|
113 |
|
---|
114 | end.
|
---|
115 |
|
---|