6 ConstantsClass
, CustomStringGridClass
, FunctionsClass
, HardwareClass
,
7 ResourcesClass
, SteppingClass
, TypesClass
,
8 Classes
, Controls
, Dialogs
, Forms
, Graphics
, Grids
, Menus
, StdCtrls
, Types
;
16 TAsmInputBox
= class(TForm
)
18 pAssemble
, pCancel
: TButton
;
20 pDontChange
, pInsert
: Boolean;
26 procedure pBoxOnChange(Sender
: TObject
); virtual;
27 procedure pBoxOnKeyDown(Sender
: TObject
; var Key
: Word; Shift
: TShiftState
); virtual;
28 procedure pListOnDblClick(Sender
: TObject
); virtual;
29 procedure pOnButtonClick(Sender
: TObject
); virtual;
30 procedure pOnChange(Sender
: TObject
; ARow
: Integer; Text: String; Insert
: Boolean); virtual;
31 procedure pOnRemove(Sender
: TObject
; ARow
: Integer); virtual;
32 procedure pOnShow(Sender
: TObject
); virtual;
34 constructor CreateBox(AOwner
: TComponent
; AsmGrid
: TAsmGrid
); virtual;
39 TAsmGrid
= class(TCustomStringGrid
)
42 pColorTheme
: TGridTheme
;
44 pInputBox
: TAsmInputBox
;
45 pOldOnOperand
, pOldOnStep
: TChangeEvent
;
46 pOnChange
: TInsertEvent
;
47 pOnRemove
: TRemoveEvent
;
48 function pGetSelectedLine
: Integer; virtual;
49 function pGetWidth
: Integer; virtual;
50 procedure pCustomDblClick(Sender
: TObject
); virtual;
51 procedure pCustomDrawCell(Sender
: TObject
; ACol
, ARow
: Integer; Rect
: TRect
; State
: TGridDrawState
); virtual;
52 procedure pCustomKeyDown(Sender
: TObject
; var Key
: Word; Shift
: TShiftState
); virtual;
53 procedure pCustomMouseDown(Sender
: TObject
; Button
: TMouseButton
; Shift
: TShiftState
; X
, Y
: Integer); virtual;
54 procedure pCustomPopupGetOrigin(Sender
: TObject
); virtual;
55 procedure pCustomPopupInsert(Sender
: TObject
); virtual;
56 procedure pCustomPopupRemove(Sender
: TObject
); virtual;
57 procedure pCustomPopupReset(Sender
: TObject
); virtual;
58 procedure pCustomPopupSetOrigin(Sender
: TObject
); virtual;
59 procedure pCustomPopupStep(Sender
: TObject
); virtual;
60 procedure pDrawSingleCell(Canvas
: TCanvas
; ACol
, ARow
: Integer; Rect
: TRect
; Colors
: TColors
; Highlight
: Boolean); virtual;
61 procedure pOnOperand(Sender
: TObject
); virtual;
62 procedure pOnStep(Sender
: TObject
); virtual;
63 procedure pSetColorTheme(ColorTheme
: TGridTheme
); virtual;
64 procedure pSetSelectedLine(Line
: Integer); virtual;
65 procedure pSetStep(Step
: TStepping
); virtual;
66 procedure pSetWidth(Width
: Integer); virtual;
68 constructor CreateGrid(AOwner
: TComponent
; Step
: TStepping
); virtual;
69 function ChangeInstruction(ARow
: Integer; Name
: String): Boolean; overload
; virtual;
70 function ChangeInstruction(Name
: String): Boolean; overload
; virtual;
71 function InsertInstruction(ARow
: Integer; Name
: String): Boolean; overload
; virtual;
72 function InsertInstruction(Name
: String): Boolean; overload
; virtual;
73 function RemoveInstruction(ARow
: Integer): Boolean; overload
; virtual;
74 function RemoveInstruction
: Boolean; overload
; virtual;
75 function ReloadInstructions
: Boolean; virtual;
76 procedure ProgramReset
; virtual;
77 procedure ProgramStep
; virtual;
78 property ColorTheme
: TGridTheme read pColorTheme write pSetColorTheme
;
79 property InputBox
: TAsmInputBox read pInputBox write pInputBox
;
80 property OnChangeLine
: TInsertEvent read pOnChange write pOnChange
;
81 property OnRemoveLine
: TRemoveEvent read pOnRemove write pOnRemove
;
82 property SelectedLine
: Integer read pGetSelectedLine write pSetSelectedLine
;
83 property Stepping
: TStepping read pStep write pSetStep
;
84 property Width read pGetWidth write pSetWidth
;
89 // ************************************************************************** //
90 // * TAsmInputBox implementation * //
91 // ************************************************************************** //
93 procedure TAsmInputBox
.pBoxOnChange(Sender
: TObject
);
95 lstrings
: TypesClass
.TStrings
;
99 if pDontChange
then Exit
;
100 if not(pText
= pBox
.Text) or not(pPosition
= pBox
.SelStart
) then
102 ltext
:= StringBefore(pBox
.Text, pBox
.SelStart
);
103 SetLength(lstrings
, 0);
104 lstrings
:= pGrid
.Stepping
.Hardware
.InstructionsByPrefix(ltext
);
106 for i
:= 0 to (Length(lstrings
) - 1) do
107 pList
.Items
.Add(lstrings
[i
]);
108 pList
.ItemIndex
:= 0;
111 pPosition
:= pBox
.SelStart
;
114 procedure TAsmInputBox
.pOnButtonClick(Sender
: TObject
);
119 if (Count
> 0) and (ItemIndex
> 0) then
120 if not(pBox
.Text = Items
[ItemIndex
]) then
122 pListOnDblClick(Sender
);
125 lrow
:= pGrid
.SelectedLine
;
126 with pGrid
.Stepping
.Hardware
do
127 if not ValidateInstruction(pBox
.Text) then
129 if (pList
.Count
> 0) then
132 pBox
.Text := pList
.Items
[pList
.ItemIndex
];
133 pBox
.SelStart
:= Length(pBox
.Text);
134 pDontChange
:= False;
137 else pLabel
.Caption
:= LastError
;
143 InsertInstruction(lrow
, pBox
.Text)
145 ChangeInstruction(lrow
, pBox
.Text);
146 SelectedLine
:= SelectedLine
+ 1;
147 lrow
:= SelectedLine
;
149 Self
.Caption
:= ASM_INPUT_CAPTION_INSERT
+ ' ' + Cells
[0, lrow
]
151 Self
.Caption
:= ASM_INPUT_CAPTION_CHANGE
+ ' ' + Cells
[0, lrow
];
152 if not(VisibleRowCount
+ TopRow
> lrow
) then TopRow
:= TopRow
+ 1;
157 procedure TAsmInputBox
.pOnChange(Sender
: TObject
; ARow
: Integer;
158 Text: String; Insert
: Boolean);
162 Caption
:= ASM_INPUT_CAPTION_INSERT
+ ' ' + pGrid
.Cells
[0, ARow
];
167 Caption
:= ASM_INPUT_CAPTION_CHANGE
+ ' ' + pGrid
.Cells
[0, ARow
];
172 pBox
.SelStart
:= Length(Text);
173 pDontChange
:= False;
178 procedure TAsmInputBox
.pBoxOnKeyDown(Sender
: TObject
; var Key
: Word;
186 KEY_HOME
: pBox
.SelStart
:= 0;
187 KEY_END
: pBox
.SelStart
:= Length(pBox
.Text);
188 KEY_LEFT
: pBox
.SelStart
:= pBox
.SelStart
- 1;
189 KEY_UP
: pList
.ItemIndex
:= MaxOf(pList
.ItemIndex
- 1, 0);
190 KEY_RIGHT
: pBox
.SelStart
:= pBox
.SelStart
+ 1;
191 KEY_DOWN
: pList
.ItemIndex
:= pList
.ItemIndex
+ 1;
197 procedure TAsmInputBox
.pListOnDblClick(Sender
: TObject
);
199 if (pList
.Count
> 0) then
202 pBox
.Text := pList
.Items
[pList
.ItemIndex
];
203 pBox
.SelStart
:= Length(pBox
.Text);
204 pDontChange
:= False;
209 procedure TAsmInputBox
.pOnRemove(Sender
: TObject
; ARow
: Integer);
211 pGrid
.RemoveInstruction(ARow
);
214 procedure TAsmInputBox
.pOnShow(Sender
: TObject
);
216 pLabel
.Caption
:= '';
221 constructor TAsmInputBox
.CreateBox(AOwner
: TComponent
; AsmGrid
: TAsmGrid
);
223 inherited CreateNew(AOwner
, 0);
224 Position
:= poDesktopCenter
;
228 BorderStyle
:= bsDialog
;
232 OnChangeLine
:= Self
.pOnChange
;
233 OnRemoveLine
:= Self
.pOnRemove
;
235 pBox
:= TEdit
.Create(Self
);
244 OnChange
:= pBoxOnChange
;
245 OnKeyDown
:= pBoxOnKeyDown
;
247 pList
:= TListBox
.Create(Self
);
255 OnDblClick
:= pListOnDblClick
;
257 pAssemble
:= TButton
.Create(Self
);
261 Caption
:= ASM_INPUT_BUTTON_ASSEMBLE
;
266 OnClick
:= pOnButtonClick
;
269 pCancel
:= TButton
.Create(Self
);
273 Caption
:= ASM_INPUT_BUTTON_CANCEL
;
278 ModalResult
:= mrCancel
;
281 pLabel
:= TLabel
.Create(Self
);
294 // ************************************************************************** //
295 // * TAsmGrid implementation * //
296 // ************************************************************************** //
298 function TAsmGrid
.pGetSelectedLine
: Integer;
300 Result
:= Selection
.Top
;
303 function TAsmGrid
.pGetWidth
: Integer;
305 Result
:= inherited Width
;
308 procedure TAsmGrid
.pCustomDblClick(Sender
: TObject
);
313 pCustomKeyDown(Self
, lkey
, []);
316 procedure TAsmGrid
.pCustomDrawCell(Sender
: TObject
; ACol
, ARow
: Integer;
317 Rect
: TRect
; State
: TGridDrawState
);
321 if (Stepping
.StepBlock
= ARow
) and (ACol
= 0) then
323 pDrawSingleCell(Canvas
, ACol
, ARow
, Rect
, ColorTheme
.Step
, False);
326 if (gdSelected
in State
) and Selected
then
327 if (ACol
= 0) then lcolors
:= ColorTheme
.Address
.Selected
328 else lcolors
:= ColorTheme
.Assembly
.Selected
330 if (ACol
= 0) then lcolors
:= ColorTheme
.Address
.None
331 else lcolors
:= ColorTheme
.Assembly
.None
;
332 if not(Objects
[Acol
, Arow
] = nil) and
333 (TStepBlock(Objects
[ACol
, ARow
]).IsBranch
) then
334 pDrawSingleCell(Canvas
, ACol
, ARow
, Rect
, lcolors
, True)
336 pDrawSingleCell(Canvas
, ACol
, ARow
, Rect
, lcolors
, False);
339 procedure TAsmGrid
.pCustomKeyDown(Sender
: TObject
; var Key
: Word;
342 lselect
, ltop
: Integer;
345 lselect
:= SelectedLine
;
346 ltext
:= Cells
[1, lselect
];
347 if (Key
= KEY_RETURN
) and (lselect
= RowCount
- 1) then Key
:= KEY_INSERT
;
348 if (Key
= KEY_ASTERISK_SFT
) and (ssShift
in Shift
) then Key
:= KEY_ASTERISK
;
352 if not(@pOnRemove
= nil) then pOnRemove(Self
, lselect
- 1);
353 SelectedLine
:= SelectedLine
- 1;
355 KEY_RETURN
, KEY_SPACE
:
356 if not(@pOnChange
= nil) then pOnChange(Self
, lselect
, ltext
, False);
358 if not(@pOnChange
= nil) then pOnChange(Self
, lselect
, ltext
, True);
360 if not(@pOnRemove
= nil) then pOnRemove(Self
, lselect
);
362 if (ssCtrl
in Shift
) then
363 Stepping
.StepBlock
:= lselect
366 SelectedLine
:= Stepping
.StepBlock
;
367 ltop
:= Stepping
.StepBlock
- (VisibleRowCount
div 2);
368 if (ltop
< 0) then ltop
:= 0;
371 KEY_F2
: if (ssCtrl
in Shift
) then ProgramReset
;
376 procedure TAsmGrid
.pCustomMouseDown(Sender
: TObject
; Button
: TMouseButton
;
377 Shift
: TShiftState
; X
, Y
: Integer);
379 ldummy
, lrow
: Integer;
381 MouseToCell(X
, Y
, ldummy
, lrow
);
382 if not(lrow
< 0) then SelectedLine
:= lrow
;
385 procedure TAsmGrid
.pCustomPopupGetOrigin(Sender
: TObject
);
389 lkey
:= KEY_ASTERISK
;
390 pCustomKeyDown(Sender
, lkey
, []);
393 procedure TAsmGrid
.pCustomPopupInsert(Sender
: TObject
);
398 pCustomKeyDown(Sender
, lkey
, []);
401 procedure TAsmGrid
.pCustomPopupRemove(Sender
: TObject
);
406 pCustomKeyDown(Sender
, lkey
, []);
409 procedure TAsmGrid
.pCustomPopupReset(Sender
: TObject
);
414 pCustomKeyDown(Sender
, lkey
, [ssCtrl
]);
417 procedure TAsmGrid
.pCustomPopupSetOrigin(Sender
: TObject
);
421 lkey
:= KEY_ASTERISK
;
422 pCustomKeyDown(Sender
, lkey
, [ssCtrl
]);
425 procedure TAsmGrid
.pCustomPopupStep(Sender
: TObject
);
430 pCustomKeyDown(Sender
, lkey
, []);
433 procedure TAsmGrid
.pDrawSingleCell(Canvas
: TCanvas
; ACol
, ARow
: Integer;
434 Rect
: TRect
; Colors
: TColors
; Highlight
: Boolean);
441 Canvas
.Brush
.Color
:= Colors
.BG
;
442 Canvas
.FillRect(Rect
);
443 lsize
:= Canvas
.TextExtent(Cells
[ACol
, ARow
]);
446 lx
:= (Right
- Left
- lsize
.cx
) div 2 + Left
;
447 Canvas
.Pen
.Color
:= Colors
.FG
;
448 Canvas
.MoveTo(Right
- 1, Top
);
449 Canvas
.LineTo(Right
- 1, Bottom
);
452 lx
:= Left
+ Canvas
.TextWidth(' ');
453 ly
:= (Bottom
- Top
- lsize
.cy
) div 2 + Top
;
456 Canvas
.Brush
.Color
:= ColorTheme
.Highlight
.BG
;
457 Canvas
.Font
.Color
:= ColorTheme
.Highlight
.FG
;
460 Canvas
.Font
.Color
:= Colors
.FG
;
462 // For compatibility with Lazarus :-(
463 Canvas
.FillRect(lx
, ly
+ 1, lx
+ lsize
.cx
- 1, ly
+ lsize
.cy
- 1);
464 // ...since Lazarus doesn't use Brush for text background...
466 Canvas
.TextOut(lx
, ly
, Cells
[ACol
, ARow
]);
470 procedure TAsmGrid
.pOnOperand(Sender
: TObject
);
472 if not(Stepping
.StepBlock
< 0) then pAskReset
:= True;
473 if not(@pOldOnOperand
= nil) then pOldOnOperand(Sender
);
476 procedure TAsmGrid
.pOnStep(Sender
: TObject
);
480 if not(Stepping
.StepBlock
< 0) then
482 SelectedLine
:= Stepping
.StepBlock
;
483 ltop
:= Stepping
.StepBlock
;
484 if (ltop
< TopRow
) or not(ltop
< (TopRow
+ VisibleRowCount
)) then
486 ltop
:= ltop
- (VisibleRowCount
div 2);
487 if (ltop
< 0) then ltop
:= 0;
494 procedure TAsmGrid
.pSetColorTheme(ColorTheme
: TGridTheme
);
496 pColorTheme
:= ColorTheme
;
497 Color
:= ColorTheme
.Assembly
.None
.BG
;
500 procedure TAsmGrid
.pSetSelectedLine(Line
: Integer);
504 if (Line
< 0) then Line
:= 0;
505 if (Line
> RowCount
) then Line
:= RowCount
- 1;
508 // Lazarus is really nice, by having incompatible calls :-(
511 lselect
.Bottom
:= Line
;
514 Selection
:= lselect
;
518 procedure TAsmGrid
.pSetStep(Step
: TStepping
);
520 if not(pStep
= nil) then
522 pStep
.OnStep
:= pOldOnStep
;
523 if not(pStep
.Hardware
= nil) then
524 pStep
.Hardware
.OnOperand
:= pOldOnOperand
;
527 if not(Step
= nil) then
529 pOldOnStep
:= Step
.OnStep
;
530 Step
.OnStep
:= pOnStep
;
531 if not(Step
.Hardware
= nil) then
533 pOldOnOperand
:= Step
.Hardware
.OnOperand
;
534 Step
.Hardware
.OnOperand
:= pOnOperand
;
539 procedure TAsmGrid
.pSetWidth(Width
: Integer);
541 inherited Width
:= Width
;
542 ColWidths
[1] := ClientWidth
- ColWidths
[0];
545 constructor TAsmGrid
.CreateGrid(AOwner
: TComponent
; Step
: TStepping
);
547 inherited Create(AOwner
);
548 ColorTheme
:= THEME_GRID_DEFAULT
;
551 ScrollBars
:= ssVertical
;
553 Options
:= [goRangeSelect
, goRowSelect
, goThumbTracking
];
554 // Behavior of goRangeSelect differ in Lazarus :-(
556 Options
:= [goRowSelect
, goThumbTracking
];
558 DefaultDrawing
:= False;
559 OnDrawCell
:= pCustomDrawCell
;
560 OnDblClick
:= pCustomDblClick
;
561 OnKeyDown
:= pCustomKeyDown
;
562 OnMouseDown
:= pCustomMouseDown
;
563 InputBox
:= TAsmInputBox
.CreateBox(Self
, Self
);
564 PopupMenu
:= TPopupMenu
.Create(Self
);
567 Items
.Add(TMenuItem
.Create(PopupMenu
));
568 with Items
[Items
.Count
- 1] do
570 Caption
:= POP_ASM_CHANGE
;
571 OnClick
:= pCustomDblClick
;
574 Items
.Add(TMenuItem
.Create(PopupMenu
));
575 with Items
[Items
.Count
- 1] do
577 Caption
:= POP_ASM_INSERT
;
578 OnClick
:= pCustomPopupInsert
;
580 Items
.Add(TMenuItem
.Create(PopupMenu
));
581 with Items
[Items
.Count
- 1] do
583 Caption
:= POP_ASM_REMOVE
;
584 OnClick
:= pCustomPopupRemove
;
586 Items
.Add(TMenuItem
.Create(PopupMenu
));
587 Items
[Items
.Count
- 1].Caption
:= '-';
588 Items
.Add(TMenuItem
.Create(PopupMenu
));
589 with Items
[Items
.Count
- 1] do
591 Caption
:= POP_ASM_STEP
;
592 OnClick
:= pCustomPopupStep
;
594 Items
.Add(TMenuItem
.Create(PopupMenu
));
595 with Items
[Items
.Count
- 1] do
597 Caption
:= POP_ASM_RESET
;
598 OnClick
:= pCustomPopupReset
;
600 Items
.Add(TMenuItem
.Create(PopupMenu
));
601 Items
[Items
.Count
- 1].Caption
:= '-';
602 Items
.Add(TMenuItem
.Create(PopupMenu
));
603 with Items
[Items
.Count
- 1] do
605 Caption
:= POP_ASM_GET_ORIGIN
;
606 OnClick
:= pCustomPopupGetOrigin
;
608 Items
.Add(TMenuItem
.Create(PopupMenu
));
609 with Items
[Items
.Count
- 1] do
611 Caption
:= POP_ASM_SET_ORIGIN
;
612 OnClick
:= pCustomPopupSetOrigin
;
619 function TAsmGrid
.ChangeInstruction(ARow
: Integer; Name
: String): Boolean;
623 if not(Stepping
.StepBlock
< 0) then pAskReset
:= True;
624 if (ARow
= RowCount
- 1) then
626 Result
:= Self
.InsertInstruction(ARow
, Name
);
629 Stepping
.Hardware
.Address
:= ARow
;
630 linst
:= Stepping
.Hardware
.InstructionByName(Name
);
631 Result
:= Stepping
.ChangeStepBlock(ARow
, linst
);
634 Objects
[1, ARow
] := Stepping
[ARow
];
635 Cells
[1, ARow
] := linst
.Name
;
639 function TAsmGrid
.ChangeInstruction(Name
: String): Boolean;
641 Result
:= ChangeInstruction(SelectedLine
, Name
);
644 function TAsmGrid
.InsertInstruction(ARow
: Integer; Name
: String): Boolean;
649 if not(Stepping
.StepBlock
< 0) then pAskReset
:= True;
650 Stepping
.Hardware
.Address
:= ARow
;
651 linst
:= Stepping
.Hardware
.InstructionByName(Name
);
652 Result
:= Stepping
.AddStepBlock(ARow
, linst
);
655 RowCount
:= RowCount
+ 1;
656 for i
:= (RowCount
- 2) downto ARow
do
658 Cells
[1, i
+ 1] := Cells
[1, i
];
659 Cells
[0, i
+ 1] := ZeroPaddedInteger(i
+ 1, CONST_PADDING
);
660 Objects
[1, i
+ 1] := Objects
[1, i
];
662 Objects
[1, ARow
] := Stepping
[ARow
];
663 Cells
[1, ARow
] := linst
.Name
;
664 Cells
[0, ARow
] := ZeroPaddedInteger(ARow
, CONST_PADDING
);
668 function TAsmGrid
.InsertInstruction(Name
: String): Boolean;
670 Result
:= InsertInstruction(SelectedLine
, Name
);
673 function TAsmGrid
.RemoveInstruction(ARow
: Integer): Boolean;
677 if not(Stepping
.StepBlock
< 0) then pAskReset
:= True;
678 Result
:= Stepping
.RemoveStepBlock(ARow
);
681 for i
:= ARow
to (RowCount
- 2) do
683 Cells
[1, i
] := Cells
[1, i
+ 1];
684 Objects
[1, i
] := Objects
[1, i
+ 1];
686 RowCount
:= RowCount
- 1;
690 function TAsmGrid
.RemoveInstruction
: Boolean;
692 Result
:= RemoveInstruction(SelectedLine
);
695 function TAsmGrid
.ReloadInstructions
: Boolean;
699 RowCount
:= Stepping
.Length
+ 1;
700 for i
:= 0 to (RowCount
- 1) do
702 Cells
[0, i
] := ZeroPaddedInteger(i
, CONST_PADDING
);
703 Objects
[1, i
] := Stepping
[i
];
704 if (Objects
[1, i
] = nil) then Cells
[1, i
] := ''
705 else Cells
[1, i
] := TStepBlock(Objects
[1, i
]).CallFunction
.Name
;
710 procedure TAsmGrid
.ProgramReset
;
712 Stepping
.StepBlock
:= -1;
716 procedure TAsmGrid
.ProgramStep
;
722 lanswer
:= MessageDlg(TEXT_RESET
, mtInformation
, mbYesNoCancel
, 0);
729 if (Stepping
.StepBlock
< 0) then
732 LogWrite(POP_ASM_CHECKING
);
733 if Stepping
.Valid
then
735 LogWrite(POP_ASM_DONE_RUNNING
);
737 if (Stepping
.StepBlock
< 0) then LogWrite(POP_ASM_EXEC_STOPPED
);
739 else LogWrite(POP_ASM_ERRORS_FOUND
);
743 if (Stepping
.StepBlock
< 0) then LogWrite(POP_ASM_EXEC_STOPPED
);