| 1 | unit Core;
|
|---|
| 2 |
|
|---|
| 3 | interface
|
|---|
| 4 |
|
|---|
| 5 | uses
|
|---|
| 6 | Classes, SysUtils, ActnList, Controls, FormMain, Forms, ExtCtrls, FormMemory,
|
|---|
| 7 | SharpMz800, FormDisassembler, FormCpu, FormScreen, FormMessages, FormCallStack,
|
|---|
| 8 | Debugger, Disassembler;
|
|---|
| 9 |
|
|---|
| 10 | type
|
|---|
| 11 |
|
|---|
| 12 | { TCore }
|
|---|
| 13 |
|
|---|
| 14 | TCore = class(TDataModule)
|
|---|
| 15 | AViewCallStack: TAction;
|
|---|
| 16 | AInstructionSetGen: TAction;
|
|---|
| 17 | AViewMessages: TAction;
|
|---|
| 18 | AGoToAddress: TAction;
|
|---|
| 19 | AReset: TAction;
|
|---|
| 20 | AViewScreen: TAction;
|
|---|
| 21 | AViewCpu: TAction;
|
|---|
| 22 | AStop: TAction;
|
|---|
| 23 | AStepOut: TAction;
|
|---|
| 24 | ARun: TAction;
|
|---|
| 25 | AStepIn: TAction;
|
|---|
| 26 | AStepOver: TAction;
|
|---|
| 27 | ARunToCursor: TAction;
|
|---|
| 28 | APause: TAction;
|
|---|
| 29 | AViewDissssembler: TAction;
|
|---|
| 30 | AViewMemory: TAction;
|
|---|
| 31 | AExit: TAction;
|
|---|
| 32 | ActionList1: TActionList;
|
|---|
| 33 | ImageList1: TImageList;
|
|---|
| 34 | TimerUpdate: TTimer;
|
|---|
| 35 | procedure AExitExecute(Sender: TObject);
|
|---|
| 36 | procedure AGoToAddressExecute(Sender: TObject);
|
|---|
| 37 | procedure AInstructionSetGenExecute(Sender: TObject);
|
|---|
| 38 | procedure APauseExecute(Sender: TObject);
|
|---|
| 39 | procedure AResetExecute(Sender: TObject);
|
|---|
| 40 | procedure ARunExecute(Sender: TObject);
|
|---|
| 41 | procedure ARunToCursorExecute(Sender: TObject);
|
|---|
| 42 | procedure AStepInExecute(Sender: TObject);
|
|---|
| 43 | procedure AStepOutExecute(Sender: TObject);
|
|---|
| 44 | procedure AStepOverExecute(Sender: TObject);
|
|---|
| 45 | procedure AStopExecute(Sender: TObject);
|
|---|
| 46 | procedure AViewCallStackExecute(Sender: TObject);
|
|---|
| 47 | procedure AViewCpuExecute(Sender: TObject);
|
|---|
| 48 | procedure AViewDissssemblerExecute(Sender: TObject);
|
|---|
| 49 | procedure AViewMemoryExecute(Sender: TObject);
|
|---|
| 50 | procedure AViewMessagesExecute(Sender: TObject);
|
|---|
| 51 | procedure AViewScreenExecute(Sender: TObject);
|
|---|
| 52 | procedure DataModuleCreate(Sender: TObject);
|
|---|
| 53 | procedure DataModuleDestroy(Sender: TObject);
|
|---|
| 54 | procedure TimerUpdateTimer(Sender: TObject);
|
|---|
| 55 | private
|
|---|
| 56 | FUpdateInterfacePending: Boolean;
|
|---|
| 57 | procedure DoChangePC(Address: Word);
|
|---|
| 58 | procedure DebuggerChange(Sender: TObject);
|
|---|
| 59 | public
|
|---|
| 60 | FormMain: TFormMain;
|
|---|
| 61 | FormMemory: TFormMemory;
|
|---|
| 62 | FormDisassembler: TFormDisassembler;
|
|---|
| 63 | FormCpu: TFormCpu;
|
|---|
| 64 | FormScreen: TFormScreen;
|
|---|
| 65 | FormMessages: TFormMessages;
|
|---|
| 66 | FormCallStack: TFormCallStack;
|
|---|
| 67 | SharpMz800: TSharpMz800;
|
|---|
| 68 | Debugger: TDebugger;
|
|---|
| 69 | Disassembler: TDisassembler;
|
|---|
| 70 | procedure UpdateInterface;
|
|---|
| 71 | end;
|
|---|
| 72 |
|
|---|
| 73 | var
|
|---|
| 74 | Core: TCore;
|
|---|
| 75 |
|
|---|
| 76 |
|
|---|
| 77 | implementation
|
|---|
| 78 |
|
|---|
| 79 | {$R *.lfm}
|
|---|
| 80 |
|
|---|
| 81 | uses
|
|---|
| 82 | Z80, FormGoToAddress, InstructionSetGen;
|
|---|
| 83 |
|
|---|
| 84 | { TCore }
|
|---|
| 85 |
|
|---|
| 86 | procedure TCore.AExitExecute(Sender: TObject);
|
|---|
| 87 | begin
|
|---|
| 88 | Application.Terminate;
|
|---|
| 89 | end;
|
|---|
| 90 |
|
|---|
| 91 | procedure TCore.AGoToAddressExecute(Sender: TObject);
|
|---|
| 92 | var
|
|---|
| 93 | FormGoToAddress: TFormGoToAddress;
|
|---|
| 94 | Address: LongInt;
|
|---|
| 95 | begin
|
|---|
| 96 | FormGoToAddress := TFormGoToAddress.Create(nil);
|
|---|
| 97 | try
|
|---|
| 98 | if FormGoToAddress.ShowModal = mrOk then begin
|
|---|
| 99 | if TryStrToInt(FormGoToAddress.EditAddress.Text, Address) then
|
|---|
| 100 | FormDisassembler.SelectAddress(Address);
|
|---|
| 101 | end;
|
|---|
| 102 | finally
|
|---|
| 103 | FormGoToAddress.Free;
|
|---|
| 104 | end;
|
|---|
| 105 | end;
|
|---|
| 106 |
|
|---|
| 107 | procedure TCore.AInstructionSetGenExecute(Sender: TObject);
|
|---|
| 108 | var
|
|---|
| 109 | InstructionSetGen: TInstructionSetGen;
|
|---|
| 110 | begin
|
|---|
| 111 | InstructionSetGen := TInstructionSetGen.Create;
|
|---|
| 112 | InstructionSetGen.Generate('Z80/InstructionSet.html');
|
|---|
| 113 | InstructionSetGen.Free;
|
|---|
| 114 | end;
|
|---|
| 115 |
|
|---|
| 116 | procedure TCore.APauseExecute(Sender: TObject);
|
|---|
| 117 | begin
|
|---|
| 118 | SharpMz800.Cpu.Paused := True;
|
|---|
| 119 | UpdateInterface;
|
|---|
| 120 | end;
|
|---|
| 121 |
|
|---|
| 122 | procedure TCore.AResetExecute(Sender: TObject);
|
|---|
| 123 | var
|
|---|
| 124 | IsRunning: Boolean;
|
|---|
| 125 | IsPaused: Boolean;
|
|---|
| 126 | begin
|
|---|
| 127 | IsRunning := SharpMz800.Cpu.Running;
|
|---|
| 128 | IsPaused := SharpMz800.Cpu.Paused;
|
|---|
| 129 | SharpMz800.Cpu.Running := False;
|
|---|
| 130 | SharpMz800.Cpu.Reset;
|
|---|
| 131 | Debugger.Reset;
|
|---|
| 132 | if Assigned(FormMessages) then FormMessages.Messages.Clear;
|
|---|
| 133 | SharpMz800.Cpu.Running := IsRunning;
|
|---|
| 134 | SharpMz800.Cpu.Paused := IsPaused;
|
|---|
| 135 | UpdateInterface;
|
|---|
| 136 | end;
|
|---|
| 137 |
|
|---|
| 138 | procedure TCore.ARunExecute(Sender: TObject);
|
|---|
| 139 | begin
|
|---|
| 140 | SharpMz800.Cpu.Running := True;
|
|---|
| 141 | UpdateInterface;
|
|---|
| 142 | end;
|
|---|
| 143 |
|
|---|
| 144 | procedure TCore.ARunToCursorExecute(Sender: TObject);
|
|---|
| 145 | begin
|
|---|
| 146 | Debugger.DebugMode := dmStopAddress;
|
|---|
| 147 | Debugger.DebugStopAddress := FormDisassembler.GetCurrentAddress;
|
|---|
| 148 | Debugger.Cpu.Running := True;
|
|---|
| 149 | UpdateInterface;
|
|---|
| 150 | end;
|
|---|
| 151 |
|
|---|
| 152 | procedure TCore.AStepInExecute(Sender: TObject);
|
|---|
| 153 | begin
|
|---|
| 154 | Debugger.DebugMode := dmStepIn;
|
|---|
| 155 | Debugger.Cpu.Running := True;
|
|---|
| 156 | UpdateInterface;
|
|---|
| 157 | end;
|
|---|
| 158 |
|
|---|
| 159 | procedure TCore.AStepOutExecute(Sender: TObject);
|
|---|
| 160 | begin
|
|---|
| 161 | Debugger.DebugMode := dmStepOut;
|
|---|
| 162 | Debugger.Cpu.Running := True;
|
|---|
| 163 | UpdateInterface;
|
|---|
| 164 | end;
|
|---|
| 165 |
|
|---|
| 166 | procedure TCore.AStepOverExecute(Sender: TObject);
|
|---|
| 167 | begin
|
|---|
| 168 | Debugger.DebugMode := dmStepOver;
|
|---|
| 169 | Debugger.Cpu.Running := True;
|
|---|
| 170 | UpdateInterface;
|
|---|
| 171 | end;
|
|---|
| 172 |
|
|---|
| 173 | procedure TCore.AStopExecute(Sender: TObject);
|
|---|
| 174 | begin
|
|---|
| 175 | SharpMz800.Cpu.Running := False;
|
|---|
| 176 | UpdateInterface;
|
|---|
| 177 | end;
|
|---|
| 178 |
|
|---|
| 179 | procedure TCore.AViewCallStackExecute(Sender: TObject);
|
|---|
| 180 | begin
|
|---|
| 181 | if not Assigned(FormCallStack) then begin
|
|---|
| 182 | FormCallStack := TFormCallStack.Create(nil);
|
|---|
| 183 | FormCallStack.Debugger := Debugger;
|
|---|
| 184 | end;
|
|---|
| 185 | FormCallStack.Show;
|
|---|
| 186 | end;
|
|---|
| 187 |
|
|---|
| 188 | procedure TCore.AViewCpuExecute(Sender: TObject);
|
|---|
| 189 | begin
|
|---|
| 190 | if not Assigned(FormCpu) then begin
|
|---|
| 191 | FormCpu := TFormCpu.Create(nil);
|
|---|
| 192 | FormCpu.Cpu := SharpMz800.Cpu;
|
|---|
| 193 | end;
|
|---|
| 194 | FormCpu.Show;
|
|---|
| 195 | end;
|
|---|
| 196 |
|
|---|
| 197 | procedure TCore.AViewDissssemblerExecute(Sender: TObject);
|
|---|
| 198 | begin
|
|---|
| 199 | if not Assigned(FormDisassembler) then begin
|
|---|
| 200 | FormDisassembler := TFormDisassembler.Create(nil);
|
|---|
| 201 | FormDisassembler.OnChangePC := DoChangePC;
|
|---|
| 202 | FormDisassembler.Debugger := Debugger;
|
|---|
| 203 | FormDisassembler.Disassembler := Disassembler;
|
|---|
| 204 | SharpMz800.OnMemoryMappingChange := FormDisassembler.Disassemble;
|
|---|
| 205 | end;
|
|---|
| 206 | FormDisassembler.Show;
|
|---|
| 207 | FormMessages.AddMessage(FormDisassembler.Disassembler.InstructionSet.Check(SharpMz800.Cpu.Instructions));
|
|---|
| 208 | end;
|
|---|
| 209 |
|
|---|
| 210 | procedure TCore.AViewMemoryExecute(Sender: TObject);
|
|---|
| 211 | begin
|
|---|
| 212 | if not Assigned(FormMemory) then begin
|
|---|
| 213 | FormMemory := TFormMemory.Create(nil);
|
|---|
| 214 | FormMemory.Areas.Add(SharpMz800.Memory);
|
|---|
| 215 | FormMemory.Areas.Add(SharpMz800.BaseRom);
|
|---|
| 216 | FormMemory.Areas.Add(SharpMz800.ExtendedRom);
|
|---|
| 217 | FormMemory.Areas.Add(SharpMz800.VideoRam);
|
|---|
| 218 | FormMemory.Areas.Add(SharpMz800.CharacterRom);
|
|---|
| 219 | FormMemory.Areas.Add(SharpMz800.MappedIO);
|
|---|
| 220 | end;
|
|---|
| 221 | FormMemory.Show;
|
|---|
| 222 | end;
|
|---|
| 223 |
|
|---|
| 224 | procedure TCore.AViewMessagesExecute(Sender: TObject);
|
|---|
| 225 | begin
|
|---|
| 226 | if not Assigned(FormMessages) then begin
|
|---|
| 227 | FormMessages := TFormMessages.Create(nil);
|
|---|
| 228 | SharpMz800.OnMessage := FormMessages.AddMessage;
|
|---|
| 229 | end;
|
|---|
| 230 | FormMessages.Show;
|
|---|
| 231 | end;
|
|---|
| 232 |
|
|---|
| 233 | procedure TCore.AViewScreenExecute(Sender: TObject);
|
|---|
| 234 | begin
|
|---|
| 235 | if not Assigned(FormScreen) then begin
|
|---|
| 236 | FormScreen := TFormScreen.Create(nil);
|
|---|
| 237 | end;
|
|---|
| 238 | FormScreen.Show;
|
|---|
| 239 | end;
|
|---|
| 240 |
|
|---|
| 241 | procedure TCore.DataModuleCreate(Sender: TObject);
|
|---|
| 242 | begin
|
|---|
| 243 | SharpMz800 := TSharpMz800.Create;
|
|---|
| 244 | Disassembler := TDisassembler.Create;
|
|---|
| 245 | Disassembler.Memory := SharpMz800.MappedMemory;
|
|---|
| 246 | Debugger := TDebugger.Create;
|
|---|
| 247 | Debugger.Cpu := SharpMz800.Cpu;
|
|---|
| 248 | Debugger.OnChange := DebuggerChange;
|
|---|
| 249 | Debugger.Disassembler := Disassembler;
|
|---|
| 250 | UpdateInterface;
|
|---|
| 251 | FormMain := TFormMain.Create(nil);
|
|---|
| 252 | FormMain.Show;
|
|---|
| 253 | end;
|
|---|
| 254 |
|
|---|
| 255 | procedure TCore.DataModuleDestroy(Sender: TObject);
|
|---|
| 256 | begin
|
|---|
| 257 | SharpMz800.Cpu.Running := False;
|
|---|
| 258 | if Assigned(FormCpu) then FreeAndNil(FormCpu);
|
|---|
| 259 | if Assigned(FormDisassembler) then FreeAndNil(FormDisassembler);
|
|---|
| 260 | if Assigned(FormMemory) then FreeAndNil(FormMemory);
|
|---|
| 261 | if Assigned(FormScreen) then FreeAndNil(FormScreen);
|
|---|
| 262 | if Assigned(FormMessages) then FreeAndNil(FormMessages);
|
|---|
| 263 | if Assigned(FormCallStack) then FreeAndNil(FormCallStack);
|
|---|
| 264 | FreeAndNil(FormMain);
|
|---|
| 265 | FreeAndNil(Debugger);
|
|---|
| 266 | FreeAndNil(Disassembler);
|
|---|
| 267 | FreeAndNil(SharpMz800);
|
|---|
| 268 | end;
|
|---|
| 269 |
|
|---|
| 270 | procedure TCore.TimerUpdateTimer(Sender: TObject);
|
|---|
| 271 | begin
|
|---|
| 272 | if FUpdateInterfacePending then begin
|
|---|
| 273 | FUpdateInterfacePending := False;
|
|---|
| 274 | UpdateInterface;
|
|---|
| 275 | end;
|
|---|
| 276 | end;
|
|---|
| 277 |
|
|---|
| 278 | procedure TCore.DoChangePC(Address: Word);
|
|---|
| 279 | begin
|
|---|
| 280 | SharpMz800.Cpu.PC := Address;
|
|---|
| 281 | end;
|
|---|
| 282 |
|
|---|
| 283 | procedure TCore.DebuggerChange(Sender: TObject);
|
|---|
| 284 | begin
|
|---|
| 285 | if Assigned(FormCallStack) then FormCallStack.Reload;
|
|---|
| 286 | if Assigned(FormCpu) then FormCpu.Reload;
|
|---|
| 287 | FUpdateInterfacePending := True;
|
|---|
| 288 | end;
|
|---|
| 289 |
|
|---|
| 290 | procedure TCore.UpdateInterface;
|
|---|
| 291 | begin
|
|---|
| 292 | ARun.Enabled := not SharpMz800.Cpu.Running or (SharpMz800.Cpu.Running and SharpMz800.Cpu.Paused);
|
|---|
| 293 | AStop.Enabled := SharpMz800.Cpu.Running and not SharpMz800.Cpu.Paused;
|
|---|
| 294 | APause.Enabled := SharpMz800.Cpu.Running and not SharpMz800.Cpu.Paused;
|
|---|
| 295 | AStepIn.Enabled := not SharpMz800.Cpu.Running or (SharpMz800.Cpu.Running and SharpMz800.Cpu.Paused);
|
|---|
| 296 | AStepOut.Enabled := not SharpMz800.Cpu.Running or (SharpMz800.Cpu.Running and SharpMz800.Cpu.Paused);
|
|---|
| 297 | AStepOver.Enabled := not SharpMz800.Cpu.Running or (SharpMz800.Cpu.Running and SharpMz800.Cpu.Paused);
|
|---|
| 298 | ARunToCursor.Enabled := not SharpMz800.Cpu.Running or (SharpMz800.Cpu.Running and SharpMz800.Cpu.Paused);
|
|---|
| 299 | end;
|
|---|
| 300 |
|
|---|
| 301 | end.
|
|---|
| 302 |
|
|---|