@@ -110,7 +110,7 @@ void debug_open(int reason, uint32_t data) {
110
110
}
111
111
}
112
112
113
- if ((debug_get_flags () & DBG_IGNORE ) && (reason >= DBG_BREAKPOINT && reason <= DBG_PORT_WRITE )) {
113
+ if ((debug_get_flags () & DBG_IGNORE ) && (reason >= DBG_BREAKPOINT && reason <= DBG_REG_WRITE )) {
114
114
return ;
115
115
}
116
116
@@ -142,6 +142,135 @@ void debug_open(int reason, uint32_t data) {
142
142
cpu .flashDelayCycles = debug .flashDelayCycles ;
143
143
}
144
144
145
+ static bool reg_bit_get (const uint64_t mask , const unsigned id ) {
146
+ return (id < 64 ) && ((mask >> id ) & 1u );
147
+ }
148
+
149
+ static void reg_bit_set (uint64_t * mask , const unsigned id , const bool set ) {
150
+ if (id >= 64 ) { return ; }
151
+ if (set ) {
152
+ * mask |= (1ull << id );
153
+ } else {
154
+ * mask &= ~(1ull << id );
155
+ }
156
+ }
157
+
158
+ #define BIT (x ) (1ull << (x))
159
+ static const uint64_t dbg_reg_trigger_mask [DBG_REG_COUNT ] = {
160
+ [DBG_REG_A ] = BIT (DBG_REG_A ) | BIT (DBG_REG_AF ),
161
+ [DBG_REG_F ] = BIT (DBG_REG_F ) | BIT (DBG_REG_AF ),
162
+ [DBG_REG_AF ] = BIT (DBG_REG_AF ) | BIT (DBG_REG_A ) | BIT (DBG_REG_F ),
163
+
164
+ [DBG_REG_B ] = BIT (DBG_REG_B ) | BIT (DBG_REG_BC ),
165
+ [DBG_REG_C ] = BIT (DBG_REG_C ) | BIT (DBG_REG_BC ),
166
+ [DBG_REG_BC ] = BIT (DBG_REG_BC ) | BIT (DBG_REG_B ) | BIT (DBG_REG_C ),
167
+
168
+ [DBG_REG_D ] = BIT (DBG_REG_D ) | BIT (DBG_REG_DE ),
169
+ [DBG_REG_E ] = BIT (DBG_REG_E ) | BIT (DBG_REG_DE ),
170
+ [DBG_REG_DE ] = BIT (DBG_REG_DE ) | BIT (DBG_REG_D ) | BIT (DBG_REG_E ),
171
+
172
+ [DBG_REG_H ] = BIT (DBG_REG_H ) | BIT (DBG_REG_HL ),
173
+ [DBG_REG_L ] = BIT (DBG_REG_L ) | BIT (DBG_REG_HL ),
174
+ [DBG_REG_HL ] = BIT (DBG_REG_HL ) | BIT (DBG_REG_H ) | BIT (DBG_REG_L ),
175
+
176
+ [DBG_REG_IXH ] = BIT (DBG_REG_IXH ) | BIT (DBG_REG_IX ),
177
+ [DBG_REG_IXL ] = BIT (DBG_REG_IXL ) | BIT (DBG_REG_IX ),
178
+ [DBG_REG_IX ] = BIT (DBG_REG_IX ) | BIT (DBG_REG_IXH ) | BIT (DBG_REG_IXL ),
179
+
180
+ [DBG_REG_IYH ] = BIT (DBG_REG_IYH ) | BIT (DBG_REG_IY ),
181
+ [DBG_REG_IYL ] = BIT (DBG_REG_IYL ) | BIT (DBG_REG_IY ),
182
+ [DBG_REG_IY ] = BIT (DBG_REG_IY ) | BIT (DBG_REG_IYH ) | BIT (DBG_REG_IYL ),
183
+
184
+ [DBG_REG_AP ] = BIT (DBG_REG_AP ) | BIT (DBG_REG_AFP ),
185
+ [DBG_REG_FP ] = BIT (DBG_REG_FP ) | BIT (DBG_REG_AFP ),
186
+ [DBG_REG_AFP ] = BIT (DBG_REG_AFP ) | BIT (DBG_REG_AP ) | BIT (DBG_REG_FP ),
187
+
188
+ [DBG_REG_BP ] = BIT (DBG_REG_BP ) | BIT (DBG_REG_BCP ),
189
+ [DBG_REG_CP ] = BIT (DBG_REG_CP ) | BIT (DBG_REG_BCP ),
190
+ [DBG_REG_BCP ] = BIT (DBG_REG_BCP ) | BIT (DBG_REG_BP ) | BIT (DBG_REG_CP ),
191
+
192
+ [DBG_REG_DP ] = BIT (DBG_REG_DP ) | BIT (DBG_REG_DEP ),
193
+ [DBG_REG_EP ] = BIT (DBG_REG_EP ) | BIT (DBG_REG_DEP ),
194
+ [DBG_REG_DEP ] = BIT (DBG_REG_DEP ) | BIT (DBG_REG_DP ) | BIT (DBG_REG_EP ),
195
+
196
+ [DBG_REG_HP ] = BIT (DBG_REG_HP ) | BIT (DBG_REG_HLP ),
197
+ [DBG_REG_LP ] = BIT (DBG_REG_LP ) | BIT (DBG_REG_HLP ),
198
+ [DBG_REG_HLP ] = BIT (DBG_REG_HLP ) | BIT (DBG_REG_HP ) | BIT (DBG_REG_LP ),
199
+
200
+ [DBG_REG_SPS ] = BIT (DBG_REG_SPS ),
201
+ [DBG_REG_SPL ] = BIT (DBG_REG_SPL ),
202
+ [DBG_REG_PC ] = BIT (DBG_REG_PC ),
203
+ [DBG_REG_I ] = BIT (DBG_REG_I ),
204
+ [DBG_REG_R ] = BIT (DBG_REG_R ),
205
+ [DBG_REG_MBASE ] = BIT (DBG_REG_MBASE ),
206
+ };
207
+
208
+ uint32_t debug_norm_reg_value (const unsigned regID , const uint32_t value ) {
209
+ switch (regID ) {
210
+ // 8 bit regs
211
+ case DBG_REG_A : case DBG_REG_F : case DBG_REG_B : case DBG_REG_C :
212
+ case DBG_REG_D : case DBG_REG_E : case DBG_REG_H : case DBG_REG_L :
213
+ case DBG_REG_IXH : case DBG_REG_IXL : case DBG_REG_IYH : case DBG_REG_IYL :
214
+ case DBG_REG_AP : case DBG_REG_FP : case DBG_REG_BP : case DBG_REG_CP :
215
+ case DBG_REG_DP : case DBG_REG_EP : case DBG_REG_HP : case DBG_REG_LP :
216
+ case DBG_REG_R : case DBG_REG_MBASE :
217
+ return value & 0xFFu ;
218
+ // 16 bit regs
219
+ case DBG_REG_AF : case DBG_REG_AFP : case DBG_REG_SPS : case DBG_REG_I :
220
+ return value & 0xFFFFu ;
221
+ // 24 bit regs
222
+ case DBG_REG_BC : case DBG_REG_BCP : case DBG_REG_DE : case DBG_REG_DEP :
223
+ case DBG_REG_HL : case DBG_REG_HLP : case DBG_REG_IX : case DBG_REG_IY :
224
+ case DBG_REG_SPL : case DBG_REG_PC :
225
+ return value & 0xFFFFFFu ;
226
+ default :
227
+ return value ;
228
+ }
229
+ }
230
+
231
+ void debug_reg_watch (const unsigned regID , const int mask , const bool set ) {
232
+ if (mask & DBG_MASK_READ ) {
233
+ reg_bit_set (& debug .reg_watch_r , regID , set );
234
+ }
235
+
236
+ if (mask & DBG_MASK_WRITE ) {
237
+ reg_bit_set (& debug .reg_watch_w , regID , set );
238
+ }
239
+ }
240
+
241
+ int debug_reg_get_mask (const unsigned regID ) {
242
+ int mask = 0 ;
243
+
244
+ if (reg_bit_get (debug .reg_watch_r , regID )) {
245
+ mask |= DBG_MASK_READ ;
246
+ }
247
+
248
+ if (reg_bit_get (debug .reg_watch_w , regID )) {
249
+ mask |= DBG_MASK_WRITE ;
250
+ }
251
+
252
+ return mask ;
253
+ }
254
+
255
+ void debug_touch_reg_read (const unsigned regID ) {
256
+ if (!(debug .reg_watch_r & dbg_reg_trigger_mask [regID ])) { return ; }
257
+ debug_open (DBG_REG_READ , regID );
258
+ }
259
+
260
+ void debug_touch_reg_write (const unsigned regID , const uint32_t oldValue , const uint32_t new_value ) {
261
+ if (!(debug .reg_watch_w & dbg_reg_trigger_mask [regID ])) {
262
+ return ;
263
+ }
264
+
265
+ const uint32_t old_v = debug_norm_reg_value (regID , oldValue );
266
+ const uint32_t new_v = debug_norm_reg_value (regID , new_value );
267
+ if (old_v == new_v ) {
268
+ return ;
269
+ }
270
+
271
+ debug_open (DBG_REG_WRITE , regID );
272
+ }
273
+
145
274
void debug_watch (uint32_t addr , int mask , bool set ) {
146
275
addr &= 0xFFFFFF ;
147
276
if (set ) {
0 commit comments