1 | unit UFormMain;
|
---|
2 |
|
---|
3 | {$mode delphi}{$H+}
|
---|
4 |
|
---|
5 | interface
|
---|
6 |
|
---|
7 | uses
|
---|
8 | Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, UCpu;
|
---|
9 |
|
---|
10 | type
|
---|
11 |
|
---|
12 | { TFormMain }
|
---|
13 |
|
---|
14 | TFormMain = class(TForm)
|
---|
15 | ButtonRun: TButton;
|
---|
16 | Memo1: TMemo;
|
---|
17 | procedure ButtonRunClick(Sender: TObject);
|
---|
18 | procedure FormKeyPress(Sender: TObject; var Key: char);
|
---|
19 | procedure FormShow(Sender: TObject);
|
---|
20 | private
|
---|
21 | KeyBuffer: array of Char;
|
---|
22 | procedure CpuOutput(Address: TAddress; Data: TData);
|
---|
23 | function CpuInput(Address: TAddress): TData;
|
---|
24 | public
|
---|
25 | end;
|
---|
26 |
|
---|
27 | var
|
---|
28 | FormMain: TFormMain;
|
---|
29 |
|
---|
30 | implementation
|
---|
31 |
|
---|
32 | {$R *.lfm}
|
---|
33 |
|
---|
34 | { TFormMain }
|
---|
35 |
|
---|
36 | procedure TFormMain.FormShow(Sender: TObject);
|
---|
37 | begin
|
---|
38 | end;
|
---|
39 |
|
---|
40 | procedure TFormMain.FormKeyPress(Sender: TObject; var Key: char);
|
---|
41 | begin
|
---|
42 | SetLength(KeyBuffer, Length(KeyBuffer) + 1);
|
---|
43 | KeyBuffer[0] := Key;
|
---|
44 | end;
|
---|
45 |
|
---|
46 | procedure TFormMain.ButtonRunClick(Sender: TObject);
|
---|
47 | var
|
---|
48 | Cpu: TCpu;
|
---|
49 | LabelLoop: TAddress;
|
---|
50 | LabelText: TAddress;
|
---|
51 | LabelTextRef: TAddress;
|
---|
52 | LabelLoop2: TAddress;
|
---|
53 | Output: string;
|
---|
54 | I: Integer;
|
---|
55 | VarCount: TAddress;
|
---|
56 | VarText: TAddress;
|
---|
57 | VarAnd: TAddress;
|
---|
58 | VarEnterKey: TAddress;
|
---|
59 | PortText: TAddress;
|
---|
60 | begin
|
---|
61 | Memo1.Lines.Clear;
|
---|
62 | Memo1.SetFocus;
|
---|
63 | Cpu := TCpu.Create;
|
---|
64 | with Cpu do begin
|
---|
65 | OnOutput := CpuOutput;
|
---|
66 | OnInput := CpuInput;
|
---|
67 | SetLength(Memory, 1000);
|
---|
68 | Memo1.Lines.Add('Memory size: ' + IntToStr(Length(Memory)));
|
---|
69 |
|
---|
70 | VarCount := 200;
|
---|
71 | VarText := VarCount + SizeOf(TData);
|
---|
72 | VarAnd := VarText + SizeOf(TAddress);
|
---|
73 | VarEnterKey := VarAnd + SizeOf(TData);
|
---|
74 | PortText := 0;
|
---|
75 | LabelText := 0;
|
---|
76 |
|
---|
77 | WriteOpcode(opLdca); WriteData(13);
|
---|
78 | WriteOpcode(opSta); WriteAddress(VarCount);
|
---|
79 |
|
---|
80 | WriteOpcode(opLdcp); LabelTextRef := IP; WriteAddress(LabelText);
|
---|
81 | WriteOpcode(opStp); WriteAddress(VarText);
|
---|
82 |
|
---|
83 | WriteOpcode(opLdca); WriteData(255);
|
---|
84 | WriteOpcode(opSta); WriteAddress(VarAnd);
|
---|
85 |
|
---|
86 | WriteOpcode(opLdca); WriteData(13);
|
---|
87 | WriteOpcode(opSta); WriteAddress(VarEnterKey);
|
---|
88 |
|
---|
89 | LabelLoop := IP;
|
---|
90 |
|
---|
91 | WriteOpcode(opLdi); WriteAddress(VarText);
|
---|
92 | WriteOpcode(opAnd); WriteAddress(VarAnd);
|
---|
93 | WriteOpcode(opOut); WriteAddress(PortText);
|
---|
94 |
|
---|
95 | Writeopcode(opLdp); WriteAddress(VarText);
|
---|
96 | WriteOpcode(opIncp);
|
---|
97 | Writeopcode(opStp); WriteAddress(VarText);
|
---|
98 |
|
---|
99 | Writeopcode(opLda); WriteAddress(VarCount);
|
---|
100 | WriteOpcode(opDeca);
|
---|
101 | Writeopcode(opSta); WriteAddress(VarCount);
|
---|
102 |
|
---|
103 | WriteOpcode(opBrnz); WriteAddress(LabelLoop);
|
---|
104 |
|
---|
105 |
|
---|
106 | LabelLoop2 := IP;
|
---|
107 | WriteOpcode(opInp); WriteAddress(PortText);
|
---|
108 | WriteOpcode(opOut); WriteAddress(PortText);
|
---|
109 | WriteOpcode(opSuba); WriteAddress(VarEnterKey);
|
---|
110 | WriteOpcode(opBrnz); WriteAddress(LabelLoop2);
|
---|
111 |
|
---|
112 | WriteOpcode(opHalt);
|
---|
113 |
|
---|
114 | LabelText := IP;
|
---|
115 | WriteString('Hello world!');
|
---|
116 |
|
---|
117 | Memo1.Lines.Add('Program size: ' + IntToStr(IP));
|
---|
118 |
|
---|
119 | // Update refs
|
---|
120 | IP := LabelTextRef;
|
---|
121 | WriteAddress(LabelText);
|
---|
122 |
|
---|
123 | Reset;
|
---|
124 | Run;
|
---|
125 | Memo1.Lines.Add('Cycles: ' + IntToStr(Cycles));
|
---|
126 | Output := '';
|
---|
127 | for I := 0 to Length(Memory) - 1 do
|
---|
128 | Output := Output + IntToHex(Memory[I], 2) + ' ';
|
---|
129 | Memo1.Lines.Add(Output);
|
---|
130 | Free;
|
---|
131 | end;
|
---|
132 | end;
|
---|
133 |
|
---|
134 | procedure TFormMain.CpuOutput(Address: TAddress; Data: TData);
|
---|
135 | begin
|
---|
136 | if Address = 0 then begin
|
---|
137 | Memo1.Text := Memo1.Text + Chr(Data);
|
---|
138 | end;
|
---|
139 | end;
|
---|
140 |
|
---|
141 | function TFormMain.CpuInput(Address: TAddress): TData;
|
---|
142 | begin
|
---|
143 | if Address = 0 then begin
|
---|
144 | while Length(KeyBuffer) = 0 do begin
|
---|
145 | Application.ProcessMessages;
|
---|
146 | end;
|
---|
147 | Result := Ord(KeyBuffer[0]);
|
---|
148 | SetLength(KeyBuffer, Length(KeyBuffer) - 1);
|
---|
149 | end;
|
---|
150 | end;
|
---|
151 |
|
---|
152 | end.
|
---|
153 |
|
---|