6 ConstantsClass
, FunctionsClass
, HardwareClass
, ResourcesClass
, TypesClass
;
21 function pErrorSet
: Boolean; virtual;
22 procedure pSetError(Input
: String = GLOB_NO_ERROR
); virtual;
24 constructor Create(Owner
: TStepping
; Call
: TInstruction
); virtual;
25 function ExecuteCall
: Integer; virtual;
26 function Valid
: Boolean; virtual;
27 property CallFunction
: TInstruction read pCall write pCall
;
28 property LastError
: String read pError
;
29 property Position
: Integer read pPosition write pPosition default
-1;
30 property IsBranch
: Boolean read pBranch
;
31 destructor Destroy
; override;
39 pSteps
: array of TStepBlock
;
41 pLength
, pStepBlock
: Integer;
42 pOldOnOperand
, pOnStep
: TChangeEvent
;
44 function pBlockFromCall(Position
: Integer; Call
: TInstruction
): TStepBlock
; virtual;
45 function pErrorSet
: Boolean; virtual;
46 function pGetBlock(Position
: Integer): TStepBlock
; virtual;
47 function pValidPosition(var Position
: Integer): Boolean; virtual;
48 procedure pOnOperand(Sender
: TObject
); virtual;
49 procedure pSetError(Input
: String = GLOB_NO_ERROR
; Where
: String = ''); virtual;
50 procedure pSetHardware(Input
: THardware
); virtual;
51 procedure pSetStepBlock(Input
: Integer); virtual;
53 constructor Create
; virtual;
54 function AddStepBlock(Position
: Integer; Call
: TInstruction
): Boolean; virtual;
55 function ChangeStepBlock(Position
: Integer; Call
: TInstruction
): Boolean; virtual;
56 function RemoveStepBlock(Position
: Integer): Boolean; virtual;
57 function Valid
: Boolean; virtual;
58 procedure InitializeBlocks
; virtual;
59 procedure SingleStep
; virtual;
60 // ? function Animate(Input: Pointer); ?
61 destructor Destroy
; override;
62 property Block
[Position
: Integer]: TStepBlock read pGetBlock
; default
;
63 property Hardware
: THardware read pHardware write pSetHardware
;
64 property LastError
: String read pError
;
65 property Length
: Integer read pLength default
0;
66 property OnStep
: TChangeEvent read pOnStep write pOnStep
;
67 property StepBlock
: Integer read pStepBlock write pSetStepBlock
;
73 // ************************************************************************** //
74 // * TStepBlock implementation * //
75 // ************************************************************************** //
77 function TStepBlock
.pErrorSet
: Boolean;
79 Result
:= not(pError
= GLOB_NO_ERROR
);
82 procedure TStepBlock
.pSetError(Input
: String = GLOB_NO_ERROR
);
87 constructor TStepBlock
.Create(Owner
: TStepping
; Call
: TInstruction
);
91 pBranch
:= (not(Call
= nil) and (Call
.Branch
= BRANCH_BRANCH
));
95 function TStepBlock
.ExecuteCall
: Integer;
98 if not Valid
then Exit
;
99 if pCall
.Execute
and IsBranch
then
100 Result
:= StringToAddress(pCall
.BranchAddress
, Position
)
102 Result
:= Position
+ 1;
105 function TStepBlock
.Valid
: Boolean;
111 if (pCall
= nil) then pSetError(STEP_NO_CALL_FUNCTION
)
112 else if not pCall
.Hardware
.ValidateInstruction(pCall
) then
113 pSetError(pCall
.Hardware
.LastError
)
114 else if IsBranch
then
116 lbranch
:= StringToAddress(pCall
.BranchAddress
, Position
);
117 if (lbranch
< 0) or (lbranch
> pOwner
.Length
) then
118 pSetError(STEP_BRANCH_OUT_OF_RANGE
);
120 if not pErrorSet
then Result
:= True;
123 destructor TStepBlock
.Destroy
;
129 // ************************************************************************** //
130 // * TStepping implementation * //
131 // ************************************************************************** //
133 function TStepping
.pBlockFromCall(Position
: Integer; Call
: TInstruction
139 pSetError(STEP_NO_CALL_FUNCTION
);
142 Result
:= TStepBlock
.Create(Self
, Call
);
143 Result
.Position
:= Position
;
147 function TStepping
.pErrorSet
: Boolean;
149 Result
:= not(pError
= GLOB_NO_ERROR
);
152 function TStepping
.pGetBlock(Position
: Integer): TStepBlock
;
154 if pValidPosition(Position
) then Result
:= pSteps
[Position
]
158 function TStepping
.pValidPosition(var Position
: Integer): Boolean;
161 if (Position
< STEP_FIRST
) then Exit
;
162 if (Position
= STEP_LAST
) then Position
:= pLength
- 1;
163 if (Position
< Length
) then Result
:= True;
166 procedure TStepping
.pOnOperand(Sender
: TObject
);
169 if not(@pOldOnOperand
= nil) then pOldOnOperand(Sender
);
172 procedure TStepping
.pSetError(Input
: String = GLOB_NO_ERROR
;
176 if not(Where
= '') then pError
:= Where
+ ': ' + pError
;
177 if not(pError
= GLOB_NO_ERROR
) then LogWrite(pError
, True);
180 procedure TStepping
.pSetHardware(Input
: THardware
);
182 if not(pHardware
= nil) then pHardware
.OnOperand
:= pOldOnOperand
;
184 if not(Input
= nil) then
186 pOldOnOperand
:= Input
.OnOperand
;
187 Input
.OnOperand
:= pOnOperand
;
191 procedure TStepping
.pSetStepBlock(Input
: Integer);
194 if not pValidPosition(Input
) then Input
:= -1;
196 if not(@pOnStep
= nil) then pOnStep(Self
);
199 constructor TStepping
.Create
;
205 function TStepping
.AddStepBlock(Position
: Integer; Call
: TInstruction
213 pLength
:= pLength
+ 1;
214 if not pValidPosition(Position
) then
216 pLength
:= pLength
- 1;
219 lblock
:= pBlockFromCall(Position
, Call
);
222 pLength
:= pLength
- 1;
225 SetLength(pSteps
, pLength
);
226 for i
:= (pLength
- 2) downto Position
do
228 pSteps
[i
+ 1] := pSteps
[i
];
229 pSteps
[i
+ 1].Position
:= i
+ 1;
231 pSteps
[Position
] := lblock
;
232 if not(Hardware
= nil) then Hardware
.MaxAddress
:= pLength
;
237 function TStepping
.ChangeStepBlock(Position
: Integer; Call
: TInstruction
244 if not pValidPosition(Position
) then Exit
;
245 lblock
:= pBlockFromCall(Position
, Call
);
246 if pErrorSet
then Exit
;
247 pSteps
[Position
].Free
;
248 pSteps
[Position
] := lblock
;
253 function TStepping
.RemoveStepBlock(Position
: Integer): Boolean;
259 if not pValidPosition(Position
) then Exit
;
260 pSteps
[Position
].Free
;
261 for i
:= Position
to (pLength
- 2) do
263 pSteps
[i
] := pSteps
[i
+ 1];
264 pSteps
[i
].Position
:= i
;
266 pLength
:= pLength
- 1;
267 SetLength(pSteps
, pLength
);
268 if not(Hardware
= nil) then Hardware
.MaxAddress
:= pLength
;
273 function TStepping
.Valid
: Boolean;
280 for i
:= 0 to (pLength
- 1) do
282 Result
:= pSteps
[i
].Valid
and Result
;
283 if pSteps
[i
].pErrorSet
then
284 pSetError(pSteps
[i
].LastError
, ZeroPaddedInteger(i
, CONST_PADDING
));
289 procedure TStepping
.InitializeBlocks
;
294 for i
:= 0 to (pLength
- 1) do pSteps
[i
].Free
;
295 SetLength(pSteps
, 0);
300 procedure TStepping
.SingleStep
;
305 if (StepBlock
< 0) then pValid
:= False;
306 if not pValid
then Valid
;
313 if not pValidPosition(lpos
) then StepBlock
:= 0
314 else StepBlock
:= pSteps
[lpos
].ExecuteCall
;
317 destructor TStepping
.Destroy
;
319 while (Length
> 0) do RemoveStepBlock(STEP_LAST
);