-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathdebugger.cpp
More file actions
163 lines (146 loc) · 6.63 KB
/
debugger.cpp
File metadata and controls
163 lines (146 loc) · 6.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
// *******************************************************************************************************************************
// *******************************************************************************************************************************
//
// Name: debugger.c
// Purpose: Debugger Code (System Independent)
// Created: 29th June 2022
// Author: Paul Robson ([email protected])
//
// *******************************************************************************************************************************
// *******************************************************************************************************************************
#include <stdio.h>
#include <ctype.h>
#include "gfx.h"
#include "sys_processor.h"
#include "debugger.h"
static int isInitialised = 0; // Flag to initialise first time
static int addressSettings[] = { 0,0,0,0x20FFFF }; // Adjustable values : Code, Data, Other, Break.
static int keyMapping[16]; // Mapping for control keys to key values
static int inRunMode = 0; // Non zero when free Running
static int lastKey,currentKey; // Last and Current key state
static int stepBreakPoint; // Extra breakpoint used for step over.
static Uint32 nextFrame = 0; // Time of next frame.
static int frameCount = 0;
#ifdef EMSCRIPTEN
#define FRAMESKIP (1)
#else
#define FRAMESKIP (0)
#endif
// *******************************************************************************************************************************
// Handle one frame of rendering etc. for the debugger.
// *******************************************************************************************************************************
int GFXXRender(SDL_Surface *surface,int autoStart) {
frameCount++;
int repaint = (frameCount & FRAMESKIP) == 0;
if (isInitialised == 0) { // Check if first time
isInitialised = 1; // Now initialised
inRunMode = autoStart; // Now running
addressSettings[0] = DEBUG_HOMEPC(); // Set default locations
addressSettings[1] = DEBUG_RAMSTART;
addressSettings[3] = 0x000000;
DBGDefineKey(DBGKEY_RESET,GFXKEY_F1); // Assign default keys
DBGDefineKey(DBGKEY_SHOW,GFXKEY_TAB);
DBGDefineKey(DBGKEY_STEP,GFXKEY_F7);
DBGDefineKey(DBGKEY_STEPOVER,GFXKEY_F8);
DBGDefineKey(DBGKEY_RUN,GFXKEY_F5);
DBGDefineKey(DBGKEY_BREAK,GFXKEY_F6);
DBGDefineKey(DBGKEY_HOME,GFXKEY_F2);
DBGDefineKey(DBGKEY_SETBREAK,GFXKEY_F9);
lastKey = currentKey = -1;
}
if (repaint) {
if (inRunMode != 0 || GFXIsKeyPressed(keyMapping[DBGKEY_SHOW])) // Display system screen if Run or Sjhow
DEBUG_VDURENDER(addressSettings);
else // Otherwise show Debugger screen
DEBUG_CPURENDER(addressSettings);
}
#ifdef INCLUDE_DEBUGGING_SUPPORT
currentKey = -1; // Identify which key is pressed.
for (int i = 0;i < 128;i++) {
if (!GFXISMODIFIERKEY(i)) { // Don't return SHIFT and CTRL as keypresses.
if (GFXIsKeyPressed(i)) {
currentKey = i;
}
}
}
if (currentKey != lastKey) { // Key changed
lastKey = currentKey; // Update current key.
currentKey = DEBUG_KEYMAP(currentKey,inRunMode != 0); // Pass keypress to called.
if (currentKey >= 0) { // Key depressed ?
currentKey = toupper(currentKey); // Make it capital.
#define CMDKEY(n) GFXIsKeyPressed(keyMapping[n]) // Support Macro.
if (CMDKEY(DBGKEY_RESET)) { // Reset processor (F1)
DEBUG_RESET();
addressSettings[0] = DEBUG_HOMEPC();
GFXSilence();
}
if (inRunMode == 0) {
GFXSilence(); // Will drive us mental otherwise.
if (isxdigit(currentKey)) { // Is it a hex digit 0-9 A-F.
int digit = isdigit(currentKey)?currentKey:(currentKey-'A'+10); // Convert to a number.
int setting = 0; // Which value is being changed ?
if (GFXIsKeyPressed(GFXKEY_SHIFT)) setting = 1;
if (GFXIsKeyPressed(GFXKEY_CONTROL)) setting = 2;
addressSettings[setting] = // Shift it using this macro (so we could use Octal, say)
DEBUG_SHIFT(addressSettings[setting],(digit & 0x0F));
}
if (CMDKEY(DBGKEY_HOME)) { // Home pointer (F2)
addressSettings[0] = DEBUG_HOMEPC();
}
if (CMDKEY(DBGKEY_RUN)) { // Run program (F5)
inRunMode = 1;
stepBreakPoint = -1;
}
if (CMDKEY(DBGKEY_STEP)) { // Execute a single instruction (F7)
DEBUG_SINGLESTEP();
addressSettings[0] = DEBUG_HOMEPC();
}
if (CMDKEY(DBGKEY_STEPOVER)) { // Step over program calls (F8)
stepBreakPoint = DEBUG_GETOVERBREAK(); // Where if anywhere should we break ?
if (stepBreakPoint == 0) { // No step over, just single step.
DEBUG_SINGLESTEP();
addressSettings[0] = DEBUG_HOMEPC();
} else {
inRunMode = 1; // Run until step break or normal break.
}
}
if (CMDKEY(DBGKEY_SETBREAK)) { // Set Breakpoint (F9)
addressSettings[3] = addressSettings[0];
}
} else { // In Run mode.
if (CMDKEY(DBGKEY_BREAK)) {
inRunMode = 0;
addressSettings[0] = DEBUG_HOMEPC();
}
}
}
}
#endif
if (inRunMode != 0) { // Running a program.
int frameRate = DEBUG_RUN(addressSettings[3],stepBreakPoint); // Run a frame, or try to.
if (frameRate == 0) { // Run code with step breakpoint, maybe.
inRunMode = 0; // Break has occurred.
} else {
while (SDL_GetTicks() < nextFrame) {}; // Wait for frame timer to elapse.
nextFrame = SDL_GetTicks() + 1000 / frameRate; // And calculate the next sync time.
}
addressSettings[0] = DEBUG_HOMEPC();
}
return repaint;
}
// *******************************************************************************************************************************
// Redefine a key
// *******************************************************************************************************************************
void DBGDefineKey(int keyID,int gfxKey) {
keyMapping[keyID] = gfxKey;
}
// *******************************************************************************************************************************
// Draw a vertical set of labels (helper)
// *******************************************************************************************************************************
void DBGVerticalLabel(int x,int y,const char *labels[],int fgr,int bgr) {
int n = 0;
while (labels[n] != NULL) {
GFXString(GRID(x,y),labels[n],GRIDSIZE,fgr,bgr);
y++;n++;
}
}