source: branches/ByteArray/Cpu.pas

Last change on this file was 59, checked in by chronos, 6 months ago
  • Fixed: Assembler and disassembler to work correctly with supported instructions.
File size: 19.6 KB
Line 
1unit Cpu;
2
3interface
4
5uses
6 Classes, SysUtils, BigInt, Channel;
7
8type
9 TInstruction = (inNop, inHalt,
10 inLoadConst, inLoadConstSize,
11 inLoad, inLoadSize,
12 inLoadMem, inLoadMemSize,
13 inStoreMem, inStoreMemSize,
14 inLoadMemIndex, inLoadMemIndexSize,
15 inStoreMemIndex, inStoreMemIndexSize,
16 inInput, inInputSize,
17 inOutput, inOutputSize,
18 inInc, inIncSize, inDec, inDecSize,
19 inAdd, inAddSize, inSub, inSubSize,
20 inShr, inShrSize, inShl, inShlSize,
21 inXor, inXorSize, inAnd, inAndSize, inOr, inOrSize,
22 inJump, inJumpSize,
23 inJumpNotZero, inJumpNotZeroSize,
24 inJumpZero, inJumpZeroSize,
25 inJumpRel, inJumpRelSize,
26 inCall, inCallSize,
27 inRet, inRetSize,
28 inPush, inPushSize,
29 inPop, inPopSize,
30 inSet, inSetSize,
31 inRes, inResSize,
32 inBit, inBitSize,
33 inMul, inMulSize,
34 inDiv, inDivSize,
35 inLdir, inLdi, inLddr, inLdd,
36 inInir, inIni, inIndr, inInd,
37 inOtir, inOti, inOtdr, inOtd,
38 inCpir, inCpi, inCpdr, inCpd,
39 inEx, inEnableInterrupts, inDisableInterrupts,
40 inCompare);
41
42 TRegIndex = Byte;
43
44 TInstructionEvent = procedure of object;
45 TCpuThread = class;
46
47 { TCpu }
48
49 TCpu = class
50 private
51 FHalted: Boolean;
52 FRunning: Boolean;
53 FThread: TCpuThread;
54 FInstructions: array[TInstruction] of TInstructionEvent;
55 FTicks: QWord;
56 procedure Push(Value: TBigInt; Size: TBigIntSize);
57 function Pop(Size: TBigIntSize): TBigInt;
58 procedure InstructionNop;
59 procedure InstructionHalt;
60 procedure InstructionLoadConst;
61 procedure InstructionLoadConstSize;
62 procedure InstructionLoad;
63 procedure InstructionLoadSize;
64 procedure InstructionLoadMem;
65 procedure InstructionLoadMemSize;
66 procedure InstructionStoreMem;
67 procedure InstructionStoreMemSize;
68 procedure InstructionLoadMemIndex;
69 procedure InstructionLoadMemIndexSize;
70 procedure InstructionStoreMemIndex;
71 procedure InstructionStoreMemIndexSize;
72 procedure InstructionJump;
73 procedure InstructionJumpSize;
74 procedure InstructionJumpNotZero;
75 procedure InstructionJumpNotZeroSize;
76 procedure InstructionJumpZero;
77 procedure InstructionJumpZeroSize;
78 procedure InstructionJumpRel;
79 procedure InstructionJumpRelSize;
80 procedure InstructionCall;
81 procedure InstructionCallSize;
82 procedure InstructionRet;
83 procedure InstructionRetSize;
84 procedure InstructionPush;
85 procedure InstructionPushSize;
86 procedure InstructionPop;
87 procedure InstructionPopSize;
88 procedure InstructionInput;
89 procedure InstructionInputSize;
90 procedure InstructionOutput;
91 procedure InstructionOutputSize;
92 procedure InstructionInc;
93 procedure InstructionIncSize;
94 procedure InstructionDec;
95 procedure InstructionDecSize;
96 procedure InstructionXor;
97 procedure InstructionXorSize;
98 procedure InstructionAnd;
99 procedure InstructionAndSize;
100 procedure InstructionOr;
101 procedure InstructionOrSize;
102 procedure InstructionAdd;
103 procedure InstructionAddSize;
104 procedure InstructionSub;
105 procedure InstructionSubSize;
106 procedure InitInstructions;
107 procedure SetRunning(AValue: Boolean);
108 procedure Run;
109 procedure Step;
110 public
111 Regs: array[TRegIndex] of TBigInt;
112 PC: TBigInt;
113 SP: TBigInt;
114 DataWidth: TBigIntSize;
115 AddressWidth: TBigIntSize;
116 Memory: TChannel;
117 IO: TChannel;
118 function Read(Size: TBigIntSize): TBigInt;
119 function ReadSize: TBigIntSize;
120 function ReadRegIndex: TRegIndex;
121 procedure Write(Size: TBigIntSize; Value: TBigInt);
122 procedure WriteInstruction(Instruction: TInstruction);
123 procedure WriteRegister(Reg: TRegIndex);
124 procedure Reset;
125 procedure Start;
126 procedure Stop;
127 constructor Create;
128 destructor Destroy; override;
129 property Ticks: QWord read FTicks;
130 property Running: Boolean read FRunning write SetRunning;
131 property Halted: Boolean read FHalted;
132 end;
133
134 { TCpuThread }
135
136 TCpuThread = class(TThread)
137 Cpu: TCpu;
138 procedure Execute; override;
139 end;
140
141
142implementation
143
144{ TCpuThread }
145
146procedure TCpuThread.Execute;
147begin
148 repeat
149 if not Cpu.Halted then Cpu.Step
150 else Sleep(1);
151 //Cpu.CheckInterreupts;
152 until Terminated;
153end;
154
155{ TCpu }
156
157procedure TCpu.Push(Value: TBigInt; Size: TBigIntSize);
158begin
159 SP := SP - Size;
160 Memory.Write(SP, Size, Value);
161end;
162
163function TCpu.Pop(Size: TBigIntSize): TBigInt;
164begin
165 Result := Memory.Read(SP, Size);
166 SP := SP + Size;
167end;
168
169procedure TCpu.InstructionNop;
170begin
171 // Do nothing
172end;
173
174procedure TCpu.InstructionHalt;
175begin
176 FHalted := True;
177end;
178
179procedure TCpu.InstructionLoadConst;
180var
181 RegIndex: TRegIndex;
182begin
183 RegIndex := ReadRegIndex;
184 Regs[RegIndex] := Read(DataWidth);
185end;
186
187procedure TCpu.InstructionLoadConstSize;
188var
189 RegIndex: TRegIndex;
190 DataSize: TBigIntSize;
191begin
192 DataSize := ReadSize;
193 RegIndex := ReadRegIndex;
194 Regs[RegIndex] := Read(DataSize);
195end;
196
197procedure TCpu.InstructionLoad;
198var
199 RegIndex: TRegIndex;
200 RegIndex2: TRegIndex;
201begin
202 RegIndex := ReadRegIndex;
203 RegIndex2 := ReadRegIndex;
204 Regs[RegIndex] := Regs[RegIndex2];
205end;
206
207procedure TCpu.InstructionLoadSize;
208var
209 DataSize: TBigIntSize;
210 RegIndex: TRegIndex;
211 RegIndex2: TRegIndex;
212begin
213 DataSize := ReadSize;
214 RegIndex := ReadRegIndex;
215 RegIndex2 := ReadRegIndex;
216 Regs[RegIndex] := Regs[RegIndex2].Copy(DataSize);
217end;
218
219procedure TCpu.InstructionLoadMem;
220var
221 RegIndex1: TRegIndex;
222 RegIndex2: TRegIndex;
223begin
224 RegIndex1 := ReadRegIndex;
225 RegIndex2 := ReadRegIndex;
226 Regs[RegIndex1] := Memory.Read(Regs[RegIndex2], DataWidth);
227end;
228
229procedure TCpu.InstructionLoadMemSize;
230var
231 DataSize: TBigIntSize;
232 RegIndex1: TRegIndex;
233 RegIndex2: TRegIndex;
234begin
235 DataSize := ReadSize;
236 RegIndex1 := ReadRegIndex;
237 RegIndex2 := ReadRegIndex;
238 Regs[RegIndex1] := Memory.Read(Regs[RegIndex2], DataSize);
239end;
240
241procedure TCpu.InstructionStoreMem;
242var
243 RegIndex1: TRegIndex;
244 RegIndex2: TRegIndex;
245begin
246 RegIndex1 := ReadRegIndex;
247 RegIndex2 := ReadRegIndex;
248 Memory.Write(Regs[RegIndex1], DataWidth, Regs[RegIndex2]);
249end;
250
251procedure TCpu.InstructionStoreMemSize;
252var
253 DataSize: TBigIntSize;
254 RegIndex1: TRegIndex;
255 RegIndex2: TRegIndex;
256begin
257 DataSize := ReadSize;
258 RegIndex1 := ReadRegIndex;
259 RegIndex2 := ReadRegIndex;
260 Memory.Write(Regs[RegIndex1], DataSize, Regs[RegIndex2]);
261end;
262
263procedure TCpu.InstructionLoadMemIndex;
264var
265 RegIndex1: TRegIndex;
266 RegIndex2: TRegIndex;
267 RelativeAddress: TBigInt;
268begin
269 RegIndex1 := ReadRegIndex;
270 RegIndex2 := ReadRegIndex;
271 RelativeAddress := Read(AddressWidth);
272 Regs[RegIndex1] := Memory.Read(Regs[RegIndex2] + RelativeAddress, DataWidth);
273end;
274
275procedure TCpu.InstructionLoadMemIndexSize;
276var
277 DataSize: TBigIntSize;
278 RegIndex1: TRegIndex;
279 RegIndex2: TRegIndex;
280 RelativeAddress: TBigInt;
281begin
282 DataSize := ReadSize;
283 RegIndex1 := ReadRegIndex;
284 RegIndex2 := ReadRegIndex;
285 RelativeAddress := Read(AddressWidth);
286 Regs[RegIndex1] := Memory.Read(Regs[RegIndex2] + RelativeAddress, DataSize);
287end;
288
289procedure TCpu.InstructionStoreMemIndex;
290var
291 RegIndex1: TRegIndex;
292 RegIndex2: TRegIndex;
293 RelativeAddress: TBigInt;
294begin
295 RegIndex1 := ReadRegIndex;
296 RegIndex2 := ReadRegIndex;
297 RelativeAddress := Read(AddressWidth);
298 Memory.Write(Regs[RegIndex1] + RelativeAddress, DataWidth, Regs[RegIndex2]);
299end;
300
301procedure TCpu.InstructionStoreMemIndexSize;
302var
303 DataSize: TBigIntSize;
304 RegIndex1: TRegIndex;
305 RegIndex2: TRegIndex;
306 RelativeAddress: TBigInt;
307begin
308 DataSize := ReadSize;
309 RegIndex1 := ReadRegIndex;
310 RegIndex2 := ReadRegIndex;
311 RelativeAddress := Read(AddressWidth);
312 Memory.Write(Regs[RegIndex1] + RelativeAddress, DataSize, Regs[RegIndex2]);
313end;
314
315procedure TCpu.InstructionJump;
316begin
317 PC := Read(AddressWidth);
318end;
319
320procedure TCpu.InstructionJumpSize;
321var
322 AddressSize: TBigIntSize;
323begin
324 AddressSize := Read(SizeOf(TBigIntSize));
325 PC := Read(AddressSize);
326end;
327
328procedure TCpu.InstructionJumpNotZero;
329var
330 RegIndex: TRegIndex;
331 Address: TBigInt;
332begin
333 RegIndex := ReadRegIndex;
334 Address := Read(AddressWidth);
335 if Regs[RegIndex] <> 0 then
336 PC := Address;
337end;
338
339procedure TCpu.InstructionJumpNotZeroSize;
340var
341 RegIndex: TRegIndex;
342 Address: TBigInt;
343 DataSize: TBigIntSize;
344 AddressSize: TBigIntSize;
345begin
346 DataSize := ReadSize;
347 AddressSize := Read(SizeOf(TBigIntSize));
348 RegIndex := ReadRegIndex;
349 Address := Read(AddressSize);
350 if Regs[RegIndex].Copy(DataSize) <> 0 then
351 PC := Address;
352end;
353
354procedure TCpu.InstructionJumpZero;
355var
356 RegIndex: TRegIndex;
357 Address: TBigInt;
358begin
359 RegIndex := ReadRegIndex;
360 Address := Read(AddressWidth);
361 if Regs[RegIndex] = 0 then
362 PC := Address;
363end;
364
365procedure TCpu.InstructionJumpZeroSize;
366var
367 RegIndex: TRegIndex;
368 Address: TBigInt;
369 DataSize: TBigIntSize;
370 AddressSize: TBigIntSize;
371begin
372 DataSize := ReadSize;
373 AddressSize := Read(SizeOf(TBigIntSize));
374 RegIndex := ReadRegIndex;
375 Address := Read(AddressSize);
376 if Regs[RegIndex].Copy(DataSize) = 0 then
377 PC := Address;
378end;
379
380procedure TCpu.InstructionJumpRel;
381begin
382 PC := PC + Read(AddressWidth);
383end;
384
385procedure TCpu.InstructionJumpRelSize;
386var
387 AddressSize: TBigIntSize;
388begin
389 AddressSize := ReadSize;
390 PC := PC + Read(AddressSize);
391end;
392
393procedure TCpu.InstructionCall;
394begin
395 Push(PC, AddressWidth);
396 PC := Read(AddressWidth);
397end;
398
399procedure TCpu.InstructionCallSize;
400var
401 AddressSize: TBigIntSize;
402begin
403 AddressSize := ReadSize;
404 Push(PC, AddressSize);
405 PC := Read(AddressSize);
406end;
407
408procedure TCpu.InstructionRet;
409begin
410 PC := Pop(AddressWidth);
411end;
412
413procedure TCpu.InstructionRetSize;
414var
415 AddressSize: TBigIntSize;
416begin
417 AddressSize := ReadSize;
418 PC := Pop(AddressSize);
419end;
420
421procedure TCpu.InstructionPush;
422var
423 RegIndex: TRegIndex;
424begin
425 RegIndex := ReadRegIndex;
426 Push(Regs[RegIndex], DataWidth);
427end;
428
429procedure TCpu.InstructionPushSize;
430var
431 DataSize: TBigIntSize;
432 RegIndex: TRegIndex;
433begin
434 DataSize := ReadSize;
435 RegIndex := ReadRegIndex;
436 Push(Regs[RegIndex], DataSize);
437end;
438
439procedure TCpu.InstructionPop;
440var
441 RegIndex: TRegIndex;
442begin
443 RegIndex := ReadRegIndex;
444 Regs[RegIndex] := Pop(DataWidth);
445end;
446
447procedure TCpu.InstructionPopSize;
448var
449 DataSize: TBigIntSize;
450 RegIndex: TRegIndex;
451begin
452 DataSize := ReadSize;
453 RegIndex := ReadRegIndex;
454 Regs[RegIndex] := Pop(DataSize);
455end;
456
457procedure TCpu.InstructionInput;
458var
459 RegIndex: TRegIndex;
460 RegIndex2: TRegIndex;
461begin
462 RegIndex := ReadRegIndex;
463 RegIndex2 := ReadRegIndex;
464 Regs[RegIndex] := IO.Read(Regs[RegIndex2], DataWidth);
465end;
466
467procedure TCpu.InstructionInputSize;
468var
469 RegIndex: TRegIndex;
470 RegIndex2: TRegIndex;
471 DataSize: TBigIntSize;
472begin
473 DataSize := ReadSize;
474 RegIndex := ReadRegIndex;
475 RegIndex2 := ReadRegIndex;
476 Regs[RegIndex] := IO.Read(Regs[RegIndex2], DataSize);
477end;
478
479procedure TCpu.InstructionOutput;
480var
481 RegIndex: TRegIndex;
482 RegIndex2: TRegIndex;
483begin
484 RegIndex := ReadRegIndex;
485 RegIndex2 := ReadRegIndex;
486 IO.Write(Regs[RegIndex], DataWidth, Regs[RegIndex2]);
487end;
488
489procedure TCpu.InstructionOutputSize;
490var
491 RegIndex: TRegIndex;
492 RegIndex2: TRegIndex;
493 DataSize: TBigIntSize;
494begin
495 DataSize := ReadSize;
496 RegIndex := ReadRegIndex;
497 RegIndex2 := ReadRegIndex;
498 IO.Write(Regs[RegIndex], DataSize, Regs[RegIndex2]);
499end;
500
501procedure TCpu.InstructionInc;
502var
503 RegIndex: TRegIndex;
504begin
505 RegIndex := ReadRegIndex;
506 Regs[RegIndex] := Regs[RegIndex] + 1;
507end;
508
509procedure TCpu.InstructionIncSize;
510var
511 RegIndex: TRegIndex;
512 DataSize: TBigIntSize;
513begin
514 DataSize := ReadSize;
515 RegIndex := ReadRegIndex;
516 Regs[RegIndex] := Regs[RegIndex].Copy(DataSize) + 1;
517end;
518
519procedure TCpu.InstructionDec;
520var
521 RegIndex: TRegIndex;
522begin
523 RegIndex := ReadRegIndex;
524 Regs[RegIndex] := Regs[RegIndex] - 1;
525end;
526
527procedure TCpu.InstructionDecSize;
528var
529 RegIndex: TRegIndex;
530 DataSize: TBigIntSize;
531begin
532 DataSize := ReadSize;
533 RegIndex := ReadRegIndex;
534 Regs[RegIndex] := Regs[RegIndex].Copy(DataSize) - 1;
535end;
536
537procedure TCpu.InstructionXor;
538var
539 RegIndex: TRegIndex;
540 RegIndex2: TRegIndex;
541begin
542 RegIndex := ReadRegIndex;
543 RegIndex2 := ReadRegIndex;
544 Regs[RegIndex] := Regs[RegIndex] xor Regs[RegIndex2];
545end;
546
547procedure TCpu.InstructionXorSize;
548var
549 DataSize: TBigIntSize;
550 RegIndex: TRegIndex;
551 RegIndex2: TRegIndex;
552begin
553 DataSize := ReadSize;
554 RegIndex := ReadRegIndex;
555 RegIndex2 := ReadRegIndex;
556 Regs[RegIndex] := Regs[RegIndex].Copy(DataSize) xor Regs[RegIndex2].Copy(DataSize);
557end;
558
559procedure TCpu.InstructionAnd;
560var
561 RegIndex: TRegIndex;
562 RegIndex2: TRegIndex;
563begin
564 RegIndex := ReadRegIndex;
565 RegIndex2 := ReadRegIndex;
566 Regs[RegIndex] := Regs[RegIndex] and Regs[RegIndex2];
567end;
568
569procedure TCpu.InstructionAndSize;
570var
571 DataSize: TBigIntSize;
572 RegIndex: TRegIndex;
573 RegIndex2: TRegIndex;
574begin
575 DataSize := ReadSize;
576 RegIndex := ReadRegIndex;
577 RegIndex2 := ReadRegIndex;
578 Regs[RegIndex] := Regs[RegIndex].Copy(DataSize) and Regs[RegIndex2].Copy(DataSize);
579end;
580
581procedure TCpu.InstructionOr;
582var
583 RegIndex: TRegIndex;
584 RegIndex2: TRegIndex;
585begin
586 RegIndex := ReadRegIndex;
587 RegIndex2 := ReadRegIndex;
588 Regs[RegIndex] := Regs[RegIndex] or Regs[RegIndex2];
589end;
590
591procedure TCpu.InstructionOrSize;
592var
593 DataSize: TBigIntSize;
594 RegIndex: TRegIndex;
595 RegIndex2: TRegIndex;
596begin
597 DataSize := ReadSize;
598 RegIndex := ReadRegIndex;
599 RegIndex2 := ReadRegIndex;
600 Regs[RegIndex] := Regs[RegIndex].Copy(DataSize) or Regs[RegIndex2].Copy(DataSize);
601end;
602
603procedure TCpu.InstructionAdd;
604var
605 RegIndex: TRegIndex;
606 RegIndex2: TRegIndex;
607begin
608 RegIndex := ReadRegIndex;
609 RegIndex2 := ReadRegIndex;
610 Regs[RegIndex] := Regs[RegIndex] + Regs[RegIndex2];
611end;
612
613procedure TCpu.InstructionAddSize;
614var
615 DataSize: TBigIntSize;
616 RegIndex: TRegIndex;
617 RegIndex2: TRegIndex;
618begin
619 DataSize := ReadSize;
620 RegIndex := ReadRegIndex;
621 RegIndex2 := ReadRegIndex;
622 Regs[RegIndex] := Regs[RegIndex].Copy(DataSize) + Regs[RegIndex2].Copy(DataSize);
623end;
624
625procedure TCpu.InstructionSub;
626var
627 RegIndex: TRegIndex;
628 RegIndex2: TRegIndex;
629begin
630 RegIndex := ReadRegIndex;
631 RegIndex2 := ReadRegIndex;
632 Regs[RegIndex] := Regs[RegIndex] - Regs[RegIndex2];
633end;
634
635procedure TCpu.InstructionSubSize;
636var
637 DataSize: TBigIntSize;
638 RegIndex: TRegIndex;
639 RegIndex2: TRegIndex;
640begin
641 DataSize := ReadSize;
642 RegIndex := ReadRegIndex;
643 RegIndex2 := ReadRegIndex;
644 Regs[RegIndex] := Regs[RegIndex].Copy(DataSize) + Regs[RegIndex2].Copy(DataSize);
645end;
646
647procedure TCpu.InitInstructions;
648begin
649 FInstructions[inNop] := InstructionNop;
650 FInstructions[inHalt] := InstructionHalt;
651 FInstructions[inLoadConst] := InstructionLoadConst;
652 FInstructions[inLoadConstSize] := InstructionLoadConstSize;
653 FInstructions[inLoad] := InstructionLoad;
654 FInstructions[inLoadSize] := InstructionLoadSize;
655 FInstructions[inLoadMem] := InstructionLoadMem;
656 FInstructions[inLoadMemSize] := InstructionLoadMemSize;
657 FInstructions[inStoreMem] := InstructionStoreMem;
658 FInstructions[inStoreMemSize] := InstructionStoreMemSize;
659 FInstructions[inLoadMemIndex] := InstructionLoadMemIndex;
660 FInstructions[inLoadMemIndexSize] := InstructionLoadMemIndexSize;
661 FInstructions[inStoreMemIndex] := InstructionStoreMemIndex;
662 FInstructions[inStoreMemIndexSize] := InstructionStoreMemIndexSize;
663 FInstructions[inJump] := InstructionJump;
664 FInstructions[inJumpSize] := InstructionJumpSize;
665 FInstructions[inJumpNotZero] := InstructionJumpNotZero;
666 FInstructions[inJumpNotZeroSize] := InstructionJumpNotZeroSize;
667 FInstructions[inJumpZero] := InstructionJumpZero;
668 FInstructions[inJumpZeroSize] := InstructionJumpZeroSize;
669 FInstructions[inJumpRel] := InstructionJumpRel;
670 FInstructions[inJumpRelSize] := InstructionJumpRelSize;
671 FInstructions[inCall] := InstructionCall;
672 FInstructions[inCallSize] := InstructionCallSize;
673 FInstructions[inRet] := InstructionRet;
674 FInstructions[inRetSize] := InstructionRetSize;
675 FInstructions[inPush] := InstructionPush;
676 FInstructions[inPushSize] := InstructionPushSize;
677 FInstructions[inPop] := InstructionPop;
678 FInstructions[inPopSize] := InstructionPopSize;
679 FInstructions[inInput] := InstructionInput;
680 FInstructions[inInputSize] := InstructionInputSize;
681 FInstructions[inOutput] := InstructionOutput;
682 FInstructions[inOutputSize] := InstructionOutputSize;
683 FInstructions[inInc] := InstructionInc;
684 FInstructions[inIncSize] := InstructionIncSize;
685 FInstructions[inDec] := InstructionDec;
686 FInstructions[inDecSize] := InstructionDecSize;
687 FInstructions[inXor] := InstructionXor;
688 FInstructions[inXorSize] := InstructionXorSize;
689 FInstructions[inAnd] := InstructionAnd;
690 FInstructions[inAndSize] := InstructionAndSize;
691 FInstructions[inOr] := InstructionOr;
692 FInstructions[inOrSize] := InstructionOrSize;
693 FInstructions[inAdd] := InstructionAdd;
694 FInstructions[inAddSize] := InstructionAddSize;
695 FInstructions[inSub] := InstructionSub;
696 FInstructions[inSubSize] := InstructionSubSize;
697end;
698
699procedure TCpu.SetRunning(AValue: Boolean);
700begin
701 if FRunning = AValue then Exit;
702 if AValue then Start
703 else Stop;
704end;
705
706function TCpu.Read(Size: TBigIntSize): TBigInt;
707begin
708 Result := Memory.Read(PC, Size);
709 PC := PC + Size;
710end;
711
712function TCpu.ReadSize: TBigIntSize;
713begin
714 Result := Read(SizeOf(TBigIntSize));
715end;
716
717function TCpu.ReadRegIndex: TRegIndex;
718begin
719 Result := TRegIndex(Byte(Read(1)));
720end;
721
722procedure TCpu.Write(Size: TBigIntSize; Value: TBigInt);
723begin
724 Memory.Write(PC, Size, Value);
725 PC := PC + Size;
726end;
727
728procedure TCpu.WriteInstruction(Instruction: TInstruction);
729begin
730 Write(1, Byte(Instruction));
731end;
732
733procedure TCpu.WriteRegister(Reg: TRegIndex);
734begin
735 Write(1, Byte(Reg));
736end;
737
738procedure TCpu.Reset;
739var
740 I: TRegIndex;
741begin
742 DataWidth := 1;
743 AddressWidth := 1;
744 for I := Low(TRegIndex) to High(TRegIndex) do
745 Regs[I] := 0;
746 PC := 0;
747 SP := 0;
748 FHalted := False;
749 FTicks := 0;
750end;
751
752procedure TCpu.Run;
753begin
754 Reset;
755 while not FHalted do
756 Step;
757end;
758
759procedure TCpu.Step;
760var
761 Instruction: TInstruction;
762begin
763 Instruction := TInstruction(Byte(Read(1)));
764 FInstructions[Instruction];
765 Inc(FTicks);
766end;
767
768procedure TCpu.Start;
769begin
770 if not Running then begin
771 Reset;
772 FThread := TCpuThread.Create(True);
773 FThread.Cpu := Self;
774 FThread.Start;
775 FRunning := True;
776 end;
777end;
778
779procedure TCpu.Stop;
780begin
781 if Running then begin
782 FHalted := True;
783 FThread.Terminate;
784 FThread.WaitFor;
785 FreeAndNil(FThread);
786 FRunning := False;
787 end;
788end;
789
790constructor TCpu.Create;
791begin
792 Memory := TChannel.Create;
793 IO := TChannel.Create;
794 InitInstructions;
795 Reset;
796end;
797
798destructor TCpu.Destroy;
799begin
800 Stop;
801 FreeAndNil(Memory);
802 FreeAndNil(IO);
803 inherited;
804end;
805
806end.
807
808
80932-bit
810
811LD A, B
812LD A1, B1
813LD A2, $aabb
814LD A2, (B2)
815LD A2, ($ffff)
816LD A.2, ($00ff.2)
817LD.2.2 A2, ($ffff)
818JR.128 $ff
819LD (A2), (B2)
820LD (n.1), (n.1)
821LD (n.1), (n.1)
822
823LD A, B
824LD2 A, B
825LD A2, B2
826LD.2 A, n
827LD A, (B)
828LD.1 A, (n)
829IN.1 A, (n)
830IN.1 A, (B)
831JP n
832JP.1 n
833JR n
834JR.1 n
835PUSH A
836PUSH.1 A
837PUSH.4 A
838PUSH.128 A
839RET
840LD.2 (A), (B)
841INC A
842LD.1 A, n
843SHL.2 A
844LD.1 A, n
845AND.2 A, n
846LD.2 B, A
847IN C, (B)
848IN.d1.a1 C, (B)
849CALL n
850CALL.4 n
851LD A, (B + n)
852LD.1.2.1 A, (B + n)
853LD.d1.a2.r1 A, (B + n)
854LD A, (B + n)
855LDIR A, B, C
856LDIR.4 (A), (B), C
857LDI (A), (B), C
858SET.4 A, 20
859
860- bit index 2048 (256 * 8) (8 + 3) bits = 2^11
861
862LD R0, R1
863LD2 R0, R1
864LD.2 R0, R1
865LD:2 R0, R1
866LD D2, R0, R1
867LD D2, A16, R0, (R1)
868LD D2:A16: R0, (R1)
869RET
870RET2
871RET.2
872RET:2
873RET A2
874PUSH R0
875PUSH2 R0
876PUSH.2 R0
877PUSH:2 R0
878PUSH D2, R0
879PUSH D2:R0
880PUSH R0.2
881PUSH R0:2
882LD (R0), (R2)
883LD D1, A2, (R0), (R2)
884LDIR (R0), (R1), R2
885LDIR D1, A2, (R0), (R1), R2
886LDI
887OUT (R0), R1
888OUT D1, (R0), R1
889OUT D1, A2, (R0), R1
890
891
892
893 LD A, TEXT
894 CALL PRINT
895
896:PRINT
897 PUSH B
898:PRINT_START
899 LD B, (A)
900 TEST B
901 JR Z, PRINT_END
902 OUT (n), B
903 INC A
904 JR PRINT_START
905:PRINT_END
906 POP B
907 RET
908
Note: See TracBrowser for help on using the repository browser.