@@ -110,7 +110,7 @@ void debug_open(int reason, uint32_t data) {
110110 }
111111 }
112112
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 )) {
114114 return ;
115115 }
116116
@@ -142,6 +142,135 @@ void debug_open(int reason, uint32_t data) {
142142 cpu .flashDelayCycles = debug .flashDelayCycles ;
143143}
144144
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+
145274void debug_watch (uint32_t addr , int mask , bool set ) {
146275 addr &= 0xFFFFFF ;
147276 if (set ) {
0 commit comments