source: branches/AVR/UMainForm.pas

Last change on this file was 1, checked in by george, 15 years ago
  • Přidáno: Větve AVR a Z80.
File size: 6.8 KB
Line 
1unit UMainForm;
2
3interface
4
5uses
6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
7 Dialogs, UInstructionDefinition, StdCtrls, UIntelHexFile;
8
9type
10 TStringArray = array of string;
11
12 TOperandType = (otNone, otRegister, otConstant, otIOAddress, otDisplacement,
13 otIndirectAddressRegister, otBit, otAddress);
14
15 TOperand = class
16 public
17 OperandType: TOperandType;
18 Mask: Word;
19 procedure Init(AOperandType: TOperandType; AMask: Word);
20 end;
21
22 TInstruction = class
23 private
24 procedure AddOperand(OperandType: TOperandType; Mask: Word);
25 public
26 ShortName: string;
27 FullName: string;
28 Cycles: Byte;
29 Opcode: Word;
30 OpcodeMask: Word;
31 Operands: TList; // TList<TOperand>;
32 constructor Create;
33 procedure Init(AShortName: string; AOpcode: Word; AOpcodeMask: Word;
34 AFullName: string);
35 destructor Destroy;
36 end;
37
38 TFlags = record
39 Carry: Boolean;
40 Zero: Boolean;
41 Negative: Boolean;
42 TwosComplementOverflow: Boolean;
43 HalfCarray: Boolean;
44 GlobalInterruptEnable: Boolean;
45 end;
46
47 TRegisters = record
48 R: array[0..31] of Byte;
49 SP: Word;
50 PC: Word;
51 SREG: Byte;
52 end;
53
54 TAVRCore = class
55 private
56 Instructions: TList; // TList<TInstruction>
57 function BitSubRange(Value: Cardinal; Start, Count: Byte): Cardinal;
58 procedure OpcodeAdd(Operand1, Operand2: Word);
59 procedure OpcodeAdc(Operand1, Operand2: Word);
60 public
61 Registers: TRegisters;
62 Flags: TFlags;
63 ProgramMemory: array [0..12800] of Byte;
64 Memory: array [0..65535] of Byte;
65
66 constructor Create;
67 procedure ExecuteInstruction;
68 procedure Init;
69 procedure Run;
70 destructor Destroy;
71 end;
72
73
74 TMainForm = class(TForm)
75 Memo1: TMemo;
76 Button1: TButton;
77 Memo2: TMemo;
78 procedure FormShow(Sender: TObject);
79 procedure FormClose(Sender: TObject; var Action: TCloseAction);
80 procedure Button1Click(Sender: TObject);
81 procedure FormCreate(Sender: TObject);
82 procedure FormDestroy(Sender: TObject);
83 private
84 { Private declarations }
85 public
86 AVRCore: TAVRCore;
87 BinaryCode: TIntelHexFile;
88 procedure Analyze;
89 function ParseString(var Text: string; Separator: string): string;
90 end;
91
92var
93 MainForm: TMainForm;
94
95implementation
96
97{$R *.dfm}
98
99{ TAVRCore }
100
101function TAVRCore.BitSubRange(Value: Cardinal; Start, Count: Byte): Cardinal;
102begin
103 if Start + Count > 31 then raise ERangeError.Create('BitSubRange range overflow.');
104 Result := (Value shr Start) and ((1 shl Count) - 1);
105end;
106
107constructor TAVRCore.Create;
108begin
109 Instructions := TList.Create;
110end;
111
112destructor TAVRCore.Destroy;
113var
114 I: Integer;
115begin
116 for I := 0 to Instructions.Count - 1 do
117 TInstruction(Instructions[I]).Destroy;
118 Instructions.Destroy;
119end;
120
121procedure TAVRCore.ExecuteInstruction;
122var
123 Instruction: Word;
124 Source: Word;
125 Destination: Word;
126 I: Integer;
127begin
128 Instruction := ProgramMemory[Registers.PC];
129 Inc(Registers.PC);
130 I := 0;
131 while (I < Instructions.Count) and
132 ((Instruction and TInstruction(Instructions[I]).OpcodeMask) <>
133 TInstruction(Instructions[I]).Opcode) do
134 Inc(I);
135 if I < Instructions.Count then with TInstruction(Instructions[I]) do begin
136 MainForm.Memo2.Lines.Add(ShortName);
137
138 end else raise Exception.Create('Neznámá instrukce');
139end;
140
141procedure TAVRCore.Init;
142begin
143 with Instructions do begin
144 with TInstruction(Items[Add(TInstruction.Create)]) do begin
145 Init('ADC', $1c00, $fc00, 'Add with Carry');
146 with Operands do begin
147 with TOperand(Items[Add(TOperand.Create)]) do Init(otRegister, $01f0);
148 with TOperand(Items[Add(TOperand.Create)]) do Init(otRegister, $01f0);
149 end;
150 end;
151 with TInstruction(Items[Add(TInstruction.Create)]) do begin
152 Init('ADD', $0c00, $fc00, 'Add without Carry');
153 with Operands do begin
154 with TOperand(Items[Add(TOperand.Create)]) do Init(otRegister, $01f0);
155 with TOperand(Items[Add(TOperand.Create)]) do Init(otRegister, $01f0);
156 end;
157 end;
158 with TInstruction(Items[Add(TInstruction.Create)]) do begin
159 Init('ADIW', $9600, $ff00, 'Add immediate to Word');
160 end;
161 end;
162end;
163
164procedure TAVRCore.OpcodeAdc(Operand1, Operand2: Word);
165begin
166 Registers.R[Operand1] := Registers.R[Operand1] + Registers.R[Operand2];
167 // Registers.;
168end;
169
170procedure TAVRCore.OpcodeAdd(Operand1, Operand2: Word);
171begin
172 Registers.R[Operand1] := Registers.R[Operand1] + Registers.R[Operand2];
173end;
174
175procedure TAVRCore.Run;
176begin
177 repeat
178 ExecuteInstruction;
179 until False;
180end;
181
182procedure TMainForm.Analyze;
183var
184 I: Integer;
185 Row: string;
186 RowParts: TStringArray;
187 LabelPart: string;
188 InstructionPart: string;
189 Operand1: string;
190 Operand2: string;
191begin
192 for I := 0 to Memo1.Lines.Count - 1 do begin
193 Row := Memo1.Lines[I];
194 Row := StringReplace(Row, #9, ' ', [rfReplaceAll]);
195 LabelPart := Trim(ParseString(Row, ':'));
196 InstructionPart := Trim(ParseString(Row, ' '));
197 Operand1 := Trim(ParseString(Row, ','));
198 Operand2 := Trim(ParseString(Row, ''));
199 end;
200end;
201
202procedure TMainForm.Button1Click(Sender: TObject);
203begin
204 Analyze;
205end;
206
207procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
208begin
209 Memo1.Lines.SaveToFile('sample.asm');
210end;
211
212procedure TMainForm.FormCreate(Sender: TObject);
213begin
214 AVRCore := TAVRCore.Create;
215end;
216
217procedure TMainForm.FormDestroy(Sender: TObject);
218begin
219 AVRCore.Free;
220end;
221
222procedure TMainForm.FormShow(Sender: TObject);
223var
224 Buffer: TArrayOfByte;
225 I: Integer;
226begin
227 Memo1.Lines.LoadFromFile('sample.asm');
228 BinaryCode := TIntelHexFile.Create('tester_E291.hex', fmOpenRead);
229 Buffer := BinaryCode.ReadContent;
230 for I := 0 to (Length(Buffer) - 1) div 2 do
231 AVRCore.ProgramMemory[I] := Buffer[I * 2] or (Buffer[I * 2 + 1] shl 8);
232 AVRCore.Run;
233end;
234
235function TMainForm.ParseString(var Text: string; Separator: string): string;
236begin
237 Result := Copy(Text, 1, Pos(Separator, Text) - 1);
238 Delete(Text, 1, Length(Result) + 1);
239end;
240
241{ TInstruction }
242
243procedure TInstruction.AddOperand(OperandType: TOperandType; Mask: Word);
244begin
245
246end;
247
248constructor TInstruction.Create;
249begin
250 Operands := TList.Create;
251end;
252
253destructor TInstruction.Destroy;
254var
255 I: Integer;
256begin
257 for I := 0 to Operands.Count - 1 do
258 TOperand(Operands[I]).Free;
259 Operands.Destroy;
260end;
261
262procedure TInstruction.Init(AShortName: string; AOpcode, AOpcodeMask: Word;
263 AFullName: string);
264begin
265 ShortName := AShortName;
266 Opcode := AOpcode;
267 OpcodeMask := AOpcodeMask;
268 FullName := AFullName;
269end;
270
271{ TOperand }
272
273procedure TOperand.Init(AOperandType: TOperandType; AMask: Word);
274begin
275 OperandType := AOperandType;
276 Mask := AMask;
277end;
278
279end.
Note: See TracBrowser for help on using the repository browser.