branches/kale/src/emu/debug/dvbpoints.c
| r244571 | r244572 | |
| 13 | 13 | |
| 14 | 14 | |
| 15 | 15 | |
| 16 | // Sorting functors for the qsort function |
| 17 | static int cIndexAscending(const void* a, const void* b) |
| 18 | { |
| 19 | const device_debug::breakpoint* left = *(device_debug::breakpoint**)a; |
| 20 | const device_debug::breakpoint* right = *(device_debug::breakpoint**)b; |
| 21 | return left->index() - right->index(); |
| 22 | } |
| 23 | |
| 24 | static int cIndexDescending(const void* a, const void* b) |
| 25 | { |
| 26 | return cIndexAscending(b, a); |
| 27 | } |
| 28 | |
| 29 | static int cEnabledAscending(const void* a, const void* b) |
| 30 | { |
| 31 | const device_debug::breakpoint* left = *(device_debug::breakpoint**)a; |
| 32 | const device_debug::breakpoint* right = *(device_debug::breakpoint**)b; |
| 33 | return (left->enabled() ? 1 : 0) - (right->enabled() ? 1 : 0); |
| 34 | } |
| 35 | |
| 36 | static int cEnabledDescending(const void* a, const void* b) |
| 37 | { |
| 38 | return cEnabledAscending(b, a); |
| 39 | } |
| 40 | |
| 41 | static int cCpuAscending(const void* a, const void* b) |
| 42 | { |
| 43 | const device_debug::breakpoint* left = *(device_debug::breakpoint**)a; |
| 44 | const device_debug::breakpoint* right = *(device_debug::breakpoint**)b; |
| 45 | return strcmp(left->debugInterface()->device().tag(), right->debugInterface()->device().tag()); |
| 46 | } |
| 47 | |
| 48 | static int cCpuDescending(const void* a, const void* b) |
| 49 | { |
| 50 | return cCpuAscending(b, a); |
| 51 | } |
| 52 | |
| 53 | static int cAddressAscending(const void* a, const void* b) |
| 54 | { |
| 55 | const device_debug::breakpoint* left = *(device_debug::breakpoint**)a; |
| 56 | const device_debug::breakpoint* right = *(device_debug::breakpoint**)b; |
| 57 | return (left->address() > right->address()) ? 1 : (left->address() < right->address()) ? -1 : 0; |
| 58 | } |
| 59 | |
| 60 | static int cAddressDescending(const void* a, const void* b) |
| 61 | { |
| 62 | return cAddressAscending(b, a); |
| 63 | } |
| 64 | |
| 65 | static int cConditionAscending(const void* a, const void* b) |
| 66 | { |
| 67 | const device_debug::breakpoint* left = *(device_debug::breakpoint**)a; |
| 68 | const device_debug::breakpoint* right = *(device_debug::breakpoint**)b; |
| 69 | return strcmp(left->condition(), right->condition()); |
| 70 | } |
| 71 | |
| 72 | static int cConditionDescending(const void* a, const void* b) |
| 73 | { |
| 74 | return cConditionAscending(b, a); |
| 75 | } |
| 76 | |
| 77 | static int cActionAscending(const void* a, const void* b) |
| 78 | { |
| 79 | const device_debug::breakpoint* left = *(device_debug::breakpoint**)a; |
| 80 | const device_debug::breakpoint* right = *(device_debug::breakpoint**)b; |
| 81 | return strcmp(left->action(), right->action()); |
| 82 | } |
| 83 | |
| 84 | static int cActionDescending(const void* a, const void* b) |
| 85 | { |
| 86 | return cActionAscending(b, a); |
| 87 | } |
| 88 | |
| 89 | |
| 16 | 90 | //************************************************************************** |
| 17 | 91 | // DEBUG VIEW BREAK POINTS |
| 18 | 92 | //************************************************************************** |
| r244571 | r244572 | |
| 26 | 100 | |
| 27 | 101 | debug_view_breakpoints::debug_view_breakpoints(running_machine &machine, debug_view_osd_update_func osdupdate, void *osdprivate) |
| 28 | 102 | : debug_view(machine, DVT_BREAK_POINTS, osdupdate, osdprivate), |
| 29 | | m_sortType(SORT_INDEX_ASCENDING) |
| 103 | m_sortType(cIndexAscending) |
| 30 | 104 | { |
| 31 | 105 | // fail if no available sources |
| 32 | 106 | enumerate_sources(); |
| r244571 | r244572 | |
| 79 | 153 | |
| 80 | 154 | if (clickedTopRow) |
| 81 | 155 | { |
| 82 | | if (pos.x < tableBreaks[0] && m_sortType == SORT_INDEX_ASCENDING) |
| 83 | | m_sortType = SORT_INDEX_DESCENDING; |
| 84 | | else if (pos.x < tableBreaks[0]) |
| 85 | | m_sortType = SORT_INDEX_ASCENDING; |
| 86 | | else if (pos.x < tableBreaks[1] && m_sortType == SORT_ENABLED_ASCENDING) |
| 87 | | m_sortType = SORT_ENABLED_DESCENDING; |
| 156 | if (pos.x < tableBreaks[0]) |
| 157 | m_sortType = (m_sortType == &cIndexAscending) ? &cIndexDescending : &cIndexAscending; |
| 88 | 158 | else if (pos.x < tableBreaks[1]) |
| 89 | | m_sortType = SORT_ENABLED_ASCENDING; |
| 90 | | else if (pos.x < tableBreaks[2] && m_sortType == SORT_CPU_ASCENDING) |
| 91 | | m_sortType = SORT_CPU_DESCENDING; |
| 159 | m_sortType = (m_sortType == &cEnabledAscending) ? &cEnabledDescending : &cEnabledAscending; |
| 92 | 160 | else if (pos.x < tableBreaks[2]) |
| 93 | | m_sortType = SORT_CPU_ASCENDING; |
| 94 | | else if (pos.x < tableBreaks[3] && m_sortType == SORT_ADDRESS_ASCENDING) |
| 95 | | m_sortType = SORT_ADDRESS_DESCENDING; |
| 161 | m_sortType = (m_sortType == &cCpuAscending) ? &cCpuDescending : &cCpuAscending; |
| 96 | 162 | else if (pos.x < tableBreaks[3]) |
| 97 | | m_sortType = SORT_ADDRESS_ASCENDING; |
| 98 | | else if (pos.x < tableBreaks[4] && m_sortType == SORT_CONDITION_ASCENDING) |
| 99 | | m_sortType = SORT_CONDITION_DESCENDING; |
| 163 | m_sortType = (m_sortType == &cAddressAscending) ? &cAddressDescending : &cAddressAscending; |
| 100 | 164 | else if (pos.x < tableBreaks[4]) |
| 101 | | m_sortType = SORT_CONDITION_ASCENDING; |
| 102 | | else if (pos.x < tableBreaks[5] && m_sortType == SORT_ACTION_ASCENDING) |
| 103 | | m_sortType = SORT_ACTION_DESCENDING; |
| 165 | m_sortType = (m_sortType == &cConditionAscending) ? &cConditionDescending : &cConditionAscending; |
| 104 | 166 | else if (pos.x < tableBreaks[5]) |
| 105 | | m_sortType = SORT_ACTION_ASCENDING; |
| 167 | m_sortType = (m_sortType == &cActionAscending) ? &cActionDescending : &cActionAscending; |
| 106 | 168 | } |
| 107 | 169 | else |
| 108 | 170 | { |
| 109 | 171 | // Gather a sorted list of all the breakpoints for all the CPUs |
| 110 | | device_debug::breakpoint** bpList = NULL; |
| 111 | | const int numBPs = breakpoints(SORT_NONE, bpList); |
| 172 | gather_breakpoints(); |
| 112 | 173 | |
| 113 | | const int bpIndex = pos.y - 1; |
| 114 | | if (bpIndex > numBPs || bpIndex < 0) |
| 174 | int const bpIndex = pos.y - 1; |
| 175 | if ((bpIndex >= m_buffer.count()) || (bpIndex < 0)) |
| 115 | 176 | return; |
| 116 | 177 | |
| 117 | 178 | // Enable / disable |
| 118 | | if (bpList[bpIndex]->enabled()) |
| 119 | | bpList[bpIndex]->setEnabled(false); |
| 120 | | else |
| 121 | | bpList[bpIndex]->setEnabled(true); |
| 179 | m_buffer[bpIndex]->setEnabled(!m_buffer[bpIndex]->enabled()); |
| 122 | 180 | |
| 123 | | delete[] bpList; |
| 124 | | |
| 125 | 181 | machine().debug_view().update_all(DVT_DISASSEMBLY); |
| 126 | 182 | } |
| 127 | 183 | |
| r244571 | r244572 | |
| 145 | 201 | } |
| 146 | 202 | |
| 147 | 203 | |
| 148 | | // Sorting functors for the qsort function |
| 149 | | static int cIndexAscending(const void* a, const void* b) |
| 204 | void debug_view_breakpoints::gather_breakpoints() |
| 150 | 205 | { |
| 151 | | const device_debug::breakpoint* left = *(device_debug::breakpoint**)a; |
| 152 | | const device_debug::breakpoint* right = *(device_debug::breakpoint**)b; |
| 153 | | return left->index() > right->index(); |
| 154 | | } |
| 155 | | |
| 156 | | static int cIndexDescending(const void* a, const void* b) |
| 157 | | { |
| 158 | | const device_debug::breakpoint* left = *(device_debug::breakpoint**)a; |
| 159 | | const device_debug::breakpoint* right = *(device_debug::breakpoint**)b; |
| 160 | | return left->index() < right->index(); |
| 161 | | } |
| 162 | | |
| 163 | | static int cEnabledAscending(const void* a, const void* b) |
| 164 | | { |
| 165 | | const device_debug::breakpoint* left = *(device_debug::breakpoint**)a; |
| 166 | | const device_debug::breakpoint* right = *(device_debug::breakpoint**)b; |
| 167 | | return left->enabled() < right->enabled(); |
| 168 | | } |
| 169 | | |
| 170 | | static int cEnabledDescending(const void* a, const void* b) |
| 171 | | { |
| 172 | | const device_debug::breakpoint* left = *(device_debug::breakpoint**)a; |
| 173 | | const device_debug::breakpoint* right = *(device_debug::breakpoint**)b; |
| 174 | | return left->enabled() > right->enabled(); |
| 175 | | } |
| 176 | | |
| 177 | | static int cCpuAscending(const void* a, const void* b) |
| 178 | | { |
| 179 | | const device_debug::breakpoint* left = *(device_debug::breakpoint**)a; |
| 180 | | const device_debug::breakpoint* right = *(device_debug::breakpoint**)b; |
| 181 | | const int result = strcmp(left->debugInterface()->device().tag(), right->debugInterface()->device().tag()); |
| 182 | | return result >= 0; |
| 183 | | } |
| 184 | | |
| 185 | | static int cCpuDescending(const void* a, const void* b) |
| 186 | | { |
| 187 | | const device_debug::breakpoint* left = *(device_debug::breakpoint**)a; |
| 188 | | const device_debug::breakpoint* right = *(device_debug::breakpoint**)b; |
| 189 | | const int result = strcmp(left->debugInterface()->device().tag(), right->debugInterface()->device().tag()); |
| 190 | | return result < 0; |
| 191 | | } |
| 192 | | |
| 193 | | static int cAddressAscending(const void* a, const void* b) |
| 194 | | { |
| 195 | | const device_debug::breakpoint* left = *(device_debug::breakpoint**)a; |
| 196 | | const device_debug::breakpoint* right = *(device_debug::breakpoint**)b; |
| 197 | | return left->address() > right->address(); |
| 198 | | } |
| 199 | | |
| 200 | | static int cAddressDescending(const void* a, const void* b) |
| 201 | | { |
| 202 | | const device_debug::breakpoint* left = *(device_debug::breakpoint**)a; |
| 203 | | const device_debug::breakpoint* right = *(device_debug::breakpoint**)b; |
| 204 | | return left->address() < right->address(); |
| 205 | | } |
| 206 | | |
| 207 | | static int cConditionAscending(const void* a, const void* b) |
| 208 | | { |
| 209 | | const device_debug::breakpoint* left = *(device_debug::breakpoint**)a; |
| 210 | | const device_debug::breakpoint* right = *(device_debug::breakpoint**)b; |
| 211 | | const int result = strcmp(left->condition(), right->condition()); |
| 212 | | return result >= 0; |
| 213 | | } |
| 214 | | |
| 215 | | static int cConditionDescending(const void* a, const void* b) |
| 216 | | { |
| 217 | | const device_debug::breakpoint* left = *(device_debug::breakpoint**)a; |
| 218 | | const device_debug::breakpoint* right = *(device_debug::breakpoint**)b; |
| 219 | | const int result = strcmp(left->condition(), right->condition()); |
| 220 | | return result < 0; |
| 221 | | } |
| 222 | | |
| 223 | | static int cActionAscending(const void* a, const void* b) |
| 224 | | { |
| 225 | | const device_debug::breakpoint* left = *(device_debug::breakpoint**)a; |
| 226 | | const device_debug::breakpoint* right = *(device_debug::breakpoint**)b; |
| 227 | | const int result = strcmp(left->action(), right->action()); |
| 228 | | return result >= 0; |
| 229 | | } |
| 230 | | |
| 231 | | static int cActionDescending(const void* a, const void* b) |
| 232 | | { |
| 233 | | const device_debug::breakpoint* left = *(device_debug::breakpoint**)a; |
| 234 | | const device_debug::breakpoint* right = *(device_debug::breakpoint**)b; |
| 235 | | const int result = strcmp(left->action(), right->action()); |
| 236 | | return result < 0; |
| 237 | | } |
| 238 | | |
| 239 | | |
| 240 | | int debug_view_breakpoints::breakpoints(SortMode sort, device_debug::breakpoint**& bpList) |
| 241 | | { |
| 242 | | // Alloc |
| 243 | | int numBPs = 0; |
| 244 | | bpList = NULL; |
| 206 | m_buffer.resize(0); |
| 245 | 207 | for (const debug_view_source *source = m_source_list.first(); source != NULL; source = source->next()) |
| 246 | 208 | { |
| 247 | | const device_debug& debugInterface = *source->device()->debug(); |
| 248 | | for (device_debug::breakpoint *bp = debugInterface.breakpoint_first(); bp != NULL; bp = bp->next()) |
| 249 | | numBPs++; |
| 250 | | } |
| 251 | | bpList = new device_debug::breakpoint*[numBPs]; |
| 252 | | |
| 253 | | int bpAddIndex = 0; |
| 254 | | for (const debug_view_source *source = m_source_list.first(); source != NULL; source = source->next()) |
| 255 | | { |
| 256 | 209 | // Collect |
| 257 | | device_debug& debugInterface = *source->device()->debug(); |
| 210 | device_debug &debugInterface = *source->device()->debug(); |
| 258 | 211 | for (device_debug::breakpoint *bp = debugInterface.breakpoint_first(); bp != NULL; bp = bp->next()) |
| 259 | | { |
| 260 | | bpList[bpAddIndex] = bp; |
| 261 | | bpAddIndex++; |
| 262 | | } |
| 212 | m_buffer.append() = bp; |
| 263 | 213 | } |
| 264 | 214 | |
| 265 | 215 | // And now for the sort |
| 266 | | switch (m_sortType) |
| 267 | | { |
| 268 | | case SORT_NONE: |
| 269 | | break; |
| 270 | | case SORT_INDEX_ASCENDING: |
| 271 | | qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cIndexAscending); |
| 272 | | break; |
| 273 | | case SORT_INDEX_DESCENDING: |
| 274 | | qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cIndexDescending); |
| 275 | | break; |
| 276 | | case SORT_ENABLED_ASCENDING: |
| 277 | | qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cEnabledAscending); |
| 278 | | break; |
| 279 | | case SORT_ENABLED_DESCENDING: |
| 280 | | qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cEnabledDescending); |
| 281 | | break; |
| 282 | | case SORT_CPU_ASCENDING: |
| 283 | | qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cCpuAscending); |
| 284 | | break; |
| 285 | | case SORT_CPU_DESCENDING: |
| 286 | | qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cCpuDescending); |
| 287 | | break; |
| 288 | | case SORT_ADDRESS_ASCENDING: |
| 289 | | qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cAddressAscending); |
| 290 | | break; |
| 291 | | case SORT_ADDRESS_DESCENDING: |
| 292 | | qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cAddressDescending); |
| 293 | | break; |
| 294 | | case SORT_CONDITION_ASCENDING: |
| 295 | | qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cConditionAscending); |
| 296 | | break; |
| 297 | | case SORT_CONDITION_DESCENDING: |
| 298 | | qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cConditionDescending); |
| 299 | | break; |
| 300 | | case SORT_ACTION_ASCENDING: |
| 301 | | qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cActionAscending); |
| 302 | | break; |
| 303 | | case SORT_ACTION_DESCENDING: |
| 304 | | qsort(bpList, numBPs, sizeof(device_debug::breakpoint*), cActionDescending); |
| 305 | | break; |
| 306 | | } |
| 307 | | |
| 308 | | return numBPs; |
| 216 | qsort(&m_buffer[0], m_buffer.count(), sizeof(device_debug::breakpoint *), m_sortType); |
| 309 | 217 | } |
| 310 | 218 | |
| 311 | 219 | |
| r244571 | r244572 | |
| 317 | 225 | void debug_view_breakpoints::view_update() |
| 318 | 226 | { |
| 319 | 227 | // Gather a list of all the breakpoints for all the CPUs |
| 320 | | device_debug::breakpoint** bpList = NULL; |
| 321 | | const int numBPs = breakpoints(SORT_NONE, bpList); |
| 228 | gather_breakpoints(); |
| 322 | 229 | |
| 323 | 230 | // Set the view region so the scroll bars update |
| 324 | | m_total.y = numBPs + 1; |
| 231 | m_total.x = tableBreaks[ARRAY_LENGTH(tableBreaks) - 1]; |
| 232 | m_total.y = m_buffer.count() + 1; |
| 325 | 233 | if (m_total.y < 10) |
| 326 | 234 | m_total.y = 10; |
| 327 | 235 | |
| 328 | 236 | // Draw |
| 329 | | debug_view_char *dest = m_viewdata; |
| 330 | | for (int row = 0; row < m_visible.y; row++) |
| 237 | debug_view_char *dest = m_viewdata; |
| 238 | astring linebuf; |
| 239 | |
| 240 | // Header |
| 241 | if (m_visible.y > 0) |
| 331 | 242 | { |
| 332 | | UINT32 effrow = m_topleft.y + row; |
| 243 | linebuf.reset(); |
| 244 | linebuf.cat("ID"); |
| 245 | if (m_sortType == &cIndexAscending) linebuf.cat('\\'); |
| 246 | else if (m_sortType == &cIndexDescending) linebuf.cat('/'); |
| 247 | pad_astring_to_length(linebuf, tableBreaks[0]); |
| 248 | linebuf.cat("En"); |
| 249 | if (m_sortType == &cEnabledAscending) linebuf.cat('\\'); |
| 250 | else if (m_sortType == &cEnabledDescending) linebuf.cat('/'); |
| 251 | pad_astring_to_length(linebuf, tableBreaks[1]); |
| 252 | linebuf.cat("CPU"); |
| 253 | if (m_sortType == &cCpuAscending) linebuf.cat('\\'); |
| 254 | else if (m_sortType == &cCpuDescending) linebuf.cat('/'); |
| 255 | pad_astring_to_length(linebuf, tableBreaks[2]); |
| 256 | linebuf.cat("Address"); |
| 257 | if (m_sortType == &cAddressAscending) linebuf.cat('\\'); |
| 258 | else if (m_sortType == &cAddressDescending) linebuf.cat('/'); |
| 259 | pad_astring_to_length(linebuf, tableBreaks[3]); |
| 260 | linebuf.cat("Condition"); |
| 261 | if (m_sortType == &cConditionAscending) linebuf.cat('\\'); |
| 262 | else if (m_sortType == &cConditionDescending) linebuf.cat('/'); |
| 263 | pad_astring_to_length(linebuf, tableBreaks[4]); |
| 264 | linebuf.cat("Action"); |
| 265 | if (m_sortType == &cActionAscending) linebuf.cat('\\'); |
| 266 | else if (m_sortType == &cActionDescending) linebuf.cat('/'); |
| 267 | pad_astring_to_length(linebuf, tableBreaks[5]); |
| 333 | 268 | |
| 334 | | // Header |
| 335 | | if (row == 0) |
| 269 | for (UINT32 i = m_topleft.x; i < (m_topleft.x + m_visible.x); i++, dest++) |
| 336 | 270 | { |
| 337 | | astring header; |
| 338 | | header.printf("ID"); |
| 339 | | if (m_sortType == SORT_INDEX_ASCENDING) header.catprintf("\\"); |
| 340 | | else if (m_sortType == SORT_INDEX_DESCENDING) header.catprintf("/"); |
| 341 | | pad_astring_to_length(header, tableBreaks[0]); |
| 342 | | header.catprintf("En"); |
| 343 | | if (m_sortType == SORT_ENABLED_ASCENDING) header.catprintf("\\"); |
| 344 | | else if (m_sortType == SORT_ENABLED_DESCENDING) header.catprintf("/"); |
| 345 | | pad_astring_to_length(header, tableBreaks[1]); |
| 346 | | header.catprintf("CPU"); |
| 347 | | if (m_sortType == SORT_CPU_ASCENDING) header.catprintf("\\"); |
| 348 | | else if (m_sortType == SORT_CPU_DESCENDING) header.catprintf("/"); |
| 349 | | pad_astring_to_length(header, tableBreaks[2]); |
| 350 | | header.catprintf("Address"); |
| 351 | | if (m_sortType == SORT_ADDRESS_ASCENDING) header.catprintf("\\"); |
| 352 | | else if (m_sortType == SORT_ADDRESS_DESCENDING) header.catprintf("/"); |
| 353 | | pad_astring_to_length(header, tableBreaks[3]); |
| 354 | | header.catprintf("Condition"); |
| 355 | | if (m_sortType == SORT_CONDITION_ASCENDING) header.catprintf("\\"); |
| 356 | | else if (m_sortType == SORT_CONDITION_DESCENDING) header.catprintf("/"); |
| 357 | | pad_astring_to_length(header, tableBreaks[4]); |
| 358 | | header.catprintf("Action"); |
| 359 | | if (m_sortType == SORT_ACTION_ASCENDING) header.catprintf("\\"); |
| 360 | | else if (m_sortType == SORT_ACTION_DESCENDING) header.catprintf("/"); |
| 361 | | pad_astring_to_length(header, tableBreaks[5]); |
| 362 | | |
| 363 | | for (int i = 0; i < m_visible.x; i++) |
| 364 | | { |
| 365 | | dest->byte = (i < header.len()) ? header[i] : ' '; |
| 366 | | dest->attrib = DCA_ANCILLARY; |
| 367 | | dest++; |
| 368 | | } |
| 369 | | continue; |
| 271 | dest->byte = (i < linebuf.len()) ? linebuf[i] : ' '; |
| 272 | dest->attrib = DCA_ANCILLARY; |
| 370 | 273 | } |
| 274 | } |
| 371 | 275 | |
| 276 | for (int row = 1; row < m_visible.y; row++) |
| 277 | { |
| 372 | 278 | // Breakpoints |
| 373 | | int bpi = effrow-1; |
| 374 | | if (bpi < numBPs && bpi >= 0) |
| 279 | int bpi = row + m_topleft.y - 1; |
| 280 | if ((bpi < m_buffer.count()) && (bpi >= 0)) |
| 375 | 281 | { |
| 376 | | device_debug::breakpoint* bp = bpList[bpi]; |
| 282 | device_debug::breakpoint *const bp = m_buffer[bpi]; |
| 377 | 283 | |
| 378 | | astring buffer; |
| 379 | | buffer.printf("%X", bp->index()); |
| 380 | | pad_astring_to_length(buffer, tableBreaks[0]); |
| 381 | | buffer.catprintf("%c", bp->enabled() ? 'X' : 'O'); |
| 382 | | pad_astring_to_length(buffer, tableBreaks[1]); |
| 383 | | buffer.catprintf("%s", bp->debugInterface()->device().tag()); |
| 384 | | pad_astring_to_length(buffer, tableBreaks[2]); |
| 385 | | buffer.catprintf("%s", core_i64_hex_format(bp->address(), bp->debugInterface()->logaddrchars())); |
| 386 | | pad_astring_to_length(buffer, tableBreaks[3]); |
| 387 | | if (astring(bp->condition()) != astring("1")) |
| 388 | | { |
| 389 | | buffer.catprintf("%s", bp->condition()); |
| 390 | | pad_astring_to_length(buffer, tableBreaks[4]); |
| 391 | | } |
| 392 | | if (astring(bp->action()) != astring("")) |
| 393 | | { |
| 394 | | buffer.catprintf("%s", bp->action()); |
| 395 | | pad_astring_to_length(buffer, tableBreaks[5]); |
| 396 | | } |
| 284 | linebuf.reset(); |
| 285 | linebuf.catprintf("%2X", bp->index()); |
| 286 | pad_astring_to_length(linebuf, tableBreaks[0]); |
| 287 | linebuf.cat(bp->enabled() ? 'X' : 'O'); |
| 288 | pad_astring_to_length(linebuf, tableBreaks[1]); |
| 289 | linebuf.cat(bp->debugInterface()->device().tag()); |
| 290 | pad_astring_to_length(linebuf, tableBreaks[2]); |
| 291 | linebuf.cat(core_i64_hex_format(bp->address(), bp->debugInterface()->logaddrchars())); |
| 292 | pad_astring_to_length(linebuf, tableBreaks[3]); |
| 293 | if (strcmp(bp->condition(), "1")) |
| 294 | linebuf.cat(bp->condition()); |
| 295 | pad_astring_to_length(linebuf, tableBreaks[4]); |
| 296 | linebuf.cat(bp->action()); |
| 297 | pad_astring_to_length(linebuf, tableBreaks[5]); |
| 397 | 298 | |
| 398 | | for (int i = 0; i < m_visible.x; i++) |
| 299 | for (UINT32 i = m_topleft.x; i < (m_topleft.x + m_visible.x); i++, dest++) |
| 399 | 300 | { |
| 400 | | dest->byte = (i < buffer.len()) ? buffer[i] : ' '; |
| 301 | dest->byte = (i < linebuf.len()) ? linebuf[i] : ' '; |
| 401 | 302 | dest->attrib = DCA_NORMAL; |
| 402 | 303 | |
| 403 | 304 | // Color disabled breakpoints red |
| 404 | | if (i == 5 && dest->byte == 'O') |
| 405 | | dest->attrib = DCA_CHANGED; |
| 406 | | |
| 407 | | dest++; |
| 305 | if ((i >= tableBreaks[0]) && (i < tableBreaks[1]) && !bp->enabled()) |
| 306 | dest->attrib |= DCA_CHANGED; |
| 408 | 307 | } |
| 409 | | continue; |
| 410 | 308 | } |
| 411 | | |
| 412 | | // Fill the remaining vertical space |
| 413 | | for (int i = 0; i < m_visible.x; i++) |
| 309 | else |
| 414 | 310 | { |
| 415 | | dest->byte = ' '; |
| 416 | | dest->attrib = DCA_NORMAL; |
| 417 | | dest++; |
| 311 | // Fill the remaining vertical space |
| 312 | for (UINT32 i = m_topleft.x; i < (m_topleft.x + m_visible.x); i++, dest++) |
| 313 | { |
| 314 | dest->byte = ' '; |
| 315 | dest->attrib = DCA_NORMAL; |
| 316 | } |
| 418 | 317 | } |
| 419 | 318 | } |
| 420 | | |
| 421 | | delete[] bpList; |
| 422 | 319 | } |
branches/kale/src/emu/debug/dvwpoints.c
| r244571 | r244572 | |
| 13 | 13 | |
| 14 | 14 | |
| 15 | 15 | |
| 16 | static int cIndexAscending(const void* a, const void* b) |
| 17 | { |
| 18 | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 19 | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 20 | return left->index() - right->index(); |
| 21 | } |
| 22 | |
| 23 | static int cIndexDescending(const void* a, const void* b) |
| 24 | { |
| 25 | return cIndexAscending(b, a); |
| 26 | } |
| 27 | |
| 28 | static int cEnabledAscending(const void* a, const void* b) |
| 29 | { |
| 30 | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 31 | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 32 | return (left->enabled() ? 1 : 0) - (right->enabled() ? 1 : 0); |
| 33 | } |
| 34 | |
| 35 | static int cEnabledDescending(const void* a, const void* b) |
| 36 | { |
| 37 | return cEnabledAscending(b, a); |
| 38 | } |
| 39 | |
| 40 | static int cCpuAscending(const void* a, const void* b) |
| 41 | { |
| 42 | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 43 | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 44 | return strcmp(left->debugInterface()->device().tag(), right->debugInterface()->device().tag()); |
| 45 | } |
| 46 | |
| 47 | static int cCpuDescending(const void* a, const void* b) |
| 48 | { |
| 49 | return cCpuAscending(b, a); |
| 50 | } |
| 51 | |
| 52 | static int cSpaceAscending(const void* a, const void* b) |
| 53 | { |
| 54 | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 55 | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 56 | return strcmp(left->space().name(), right->space().name()); |
| 57 | } |
| 58 | |
| 59 | static int cSpaceDescending(const void* a, const void* b) |
| 60 | { |
| 61 | return cSpaceAscending(b, a); |
| 62 | } |
| 63 | |
| 64 | static int cAddressAscending(const void* a, const void* b) |
| 65 | { |
| 66 | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 67 | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 68 | return (left->address() > right->address()) ? 1 : (left->address() < right->address()) ? -1 : 0; |
| 69 | } |
| 70 | |
| 71 | static int cAddressDescending(const void* a, const void* b) |
| 72 | { |
| 73 | return cAddressAscending(b, a); |
| 74 | } |
| 75 | |
| 76 | static int cTypeAscending(const void* a, const void* b) |
| 77 | { |
| 78 | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 79 | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 80 | return left->type() - right->type(); |
| 81 | } |
| 82 | |
| 83 | static int cTypeDescending(const void* a, const void* b) |
| 84 | { |
| 85 | return cTypeAscending(b, a); |
| 86 | } |
| 87 | |
| 88 | static int cConditionAscending(const void* a, const void* b) |
| 89 | { |
| 90 | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 91 | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 92 | return strcmp(left->condition(), right->condition()); |
| 93 | } |
| 94 | |
| 95 | static int cConditionDescending(const void* a, const void* b) |
| 96 | { |
| 97 | return cConditionAscending(b, a); |
| 98 | } |
| 99 | |
| 100 | static int cActionAscending(const void* a, const void* b) |
| 101 | { |
| 102 | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 103 | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 104 | return strcmp(left->action(), right->action()); |
| 105 | } |
| 106 | |
| 107 | static int cActionDescending(const void* a, const void* b) |
| 108 | { |
| 109 | return cActionAscending(b, a); |
| 110 | } |
| 111 | |
| 112 | |
| 16 | 113 | //************************************************************************** |
| 17 | 114 | // DEBUG VIEW WATCH POINTS |
| 18 | 115 | //************************************************************************** |
| r244571 | r244572 | |
| 25 | 122 | |
| 26 | 123 | debug_view_watchpoints::debug_view_watchpoints(running_machine &machine, debug_view_osd_update_func osdupdate, void *osdprivate) |
| 27 | 124 | : debug_view(machine, DVT_WATCH_POINTS, osdupdate, osdprivate), |
| 28 | | m_sortType(SORT_INDEX_ASCENDING) |
| 125 | m_sortType(&cIndexAscending) |
| 29 | 126 | { |
| 30 | 127 | // fail if no available sources |
| 31 | 128 | enumerate_sources(); |
| r244571 | r244572 | |
| 74 | 171 | |
| 75 | 172 | void debug_view_watchpoints::view_click(const int button, const debug_view_xy& pos) |
| 76 | 173 | { |
| 77 | | bool clickedTopRow = (m_topleft.y == pos.y); |
| 174 | bool const clickedTopRow = (m_topleft.y == pos.y); |
| 78 | 175 | |
| 79 | 176 | if (clickedTopRow) |
| 80 | 177 | { |
| 81 | | if (pos.x < tableBreaks[0] && m_sortType == SORT_INDEX_ASCENDING) |
| 82 | | m_sortType = SORT_INDEX_DESCENDING; |
| 83 | | else if (pos.x < tableBreaks[0]) |
| 84 | | m_sortType = SORT_INDEX_ASCENDING; |
| 85 | | else if (pos.x < tableBreaks[1] && m_sortType == SORT_ENABLED_ASCENDING) |
| 86 | | m_sortType = SORT_ENABLED_DESCENDING; |
| 178 | if (pos.x < tableBreaks[0]) |
| 179 | m_sortType = (m_sortType == &cIndexAscending) ? &cIndexDescending : &cIndexAscending; |
| 87 | 180 | else if (pos.x < tableBreaks[1]) |
| 88 | | m_sortType = SORT_ENABLED_ASCENDING; |
| 89 | | else if (pos.x < tableBreaks[2] && m_sortType == SORT_CPU_ASCENDING) |
| 90 | | m_sortType = SORT_CPU_DESCENDING; |
| 181 | m_sortType = (m_sortType == &cEnabledAscending) ? &cEnabledDescending : &cEnabledAscending; |
| 91 | 182 | else if (pos.x < tableBreaks[2]) |
| 92 | | m_sortType = SORT_CPU_ASCENDING; |
| 93 | | else if (pos.x < tableBreaks[3] && m_sortType == SORT_SPACE_ASCENDING) |
| 94 | | m_sortType = SORT_SPACE_DESCENDING; |
| 183 | m_sortType = (m_sortType == &cCpuAscending) ? &cCpuDescending : &cCpuAscending; |
| 95 | 184 | else if (pos.x < tableBreaks[3]) |
| 96 | | m_sortType = SORT_SPACE_ASCENDING; |
| 97 | | else if (pos.x < tableBreaks[4] && m_sortType == SORT_ADDRESS_ASCENDING) |
| 98 | | m_sortType = SORT_ADDRESS_DESCENDING; |
| 185 | m_sortType = (m_sortType == &cSpaceAscending) ? &cSpaceDescending : &cSpaceAscending; |
| 99 | 186 | else if (pos.x < tableBreaks[4]) |
| 100 | | m_sortType = SORT_ADDRESS_ASCENDING; |
| 101 | | else if (pos.x < tableBreaks[5] && m_sortType == SORT_TYPE_ASCENDING) |
| 102 | | m_sortType = SORT_TYPE_DESCENDING; |
| 187 | m_sortType = (m_sortType == &cAddressAscending) ? &cAddressDescending : &cAddressAscending; |
| 103 | 188 | else if (pos.x < tableBreaks[5]) |
| 104 | | m_sortType = SORT_TYPE_ASCENDING; |
| 105 | | else if (pos.x < tableBreaks[6] && m_sortType == SORT_CONDITION_ASCENDING) |
| 106 | | m_sortType = SORT_CONDITION_DESCENDING; |
| 189 | m_sortType = (m_sortType == &cTypeAscending) ? &cTypeDescending : &cTypeAscending; |
| 107 | 190 | else if (pos.x < tableBreaks[6]) |
| 108 | | m_sortType = SORT_CONDITION_ASCENDING; |
| 109 | | else if (pos.x < tableBreaks[7] && m_sortType == SORT_ACTION_ASCENDING) |
| 110 | | m_sortType = SORT_ACTION_DESCENDING; |
| 191 | m_sortType = (m_sortType == &cConditionAscending) ? &cConditionDescending : &cConditionAscending; |
| 111 | 192 | else if (pos.x < tableBreaks[7]) |
| 112 | | m_sortType = SORT_ACTION_ASCENDING; |
| 193 | m_sortType = (m_sortType == &cActionAscending) ? &cActionDescending : &cActionAscending; |
| 113 | 194 | } |
| 114 | 195 | else |
| 115 | 196 | { |
| 116 | 197 | // Gather a sorted list of all the watchpoints for all the CPUs |
| 117 | | device_debug::watchpoint** wpList = NULL; |
| 118 | | const int numWPs = watchpoints(SORT_NONE, wpList); |
| 198 | gather_watchpoints(); |
| 119 | 199 | |
| 120 | | const int wpIndex = pos.y - 1; |
| 121 | | if (wpIndex > numWPs || wpIndex < 0) |
| 200 | int const wpIndex = pos.y - 1; |
| 201 | if ((wpIndex >= m_buffer.count()) || (wpIndex < 0)) |
| 122 | 202 | return; |
| 123 | 203 | |
| 124 | 204 | // Enable / disable |
| 125 | | if (wpList[wpIndex]->enabled()) |
| 126 | | wpList[wpIndex]->setEnabled(false); |
| 127 | | else |
| 128 | | wpList[wpIndex]->setEnabled(true); |
| 129 | | |
| 130 | | delete[] wpList; |
| 205 | m_buffer[wpIndex]->setEnabled(!m_buffer[wpIndex]->enabled()); |
| 131 | 206 | } |
| 132 | 207 | |
| 133 | 208 | begin_update(); |
| r244571 | r244572 | |
| 150 | 225 | } |
| 151 | 226 | |
| 152 | 227 | |
| 153 | | // Sorting functors for the qsort function |
| 154 | | static int cIndexAscending(const void* a, const void* b) |
| 228 | void debug_view_watchpoints::gather_watchpoints() |
| 155 | 229 | { |
| 156 | | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 157 | | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 158 | | return left->index() > right->index(); |
| 159 | | } |
| 160 | | |
| 161 | | static int cIndexDescending(const void* a, const void* b) |
| 162 | | { |
| 163 | | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 164 | | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 165 | | return left->index() < right->index(); |
| 166 | | } |
| 167 | | |
| 168 | | static int cEnabledAscending(const void* a, const void* b) |
| 169 | | { |
| 170 | | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 171 | | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 172 | | return left->enabled() < right->enabled(); |
| 173 | | } |
| 174 | | |
| 175 | | static int cEnabledDescending(const void* a, const void* b) |
| 176 | | { |
| 177 | | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 178 | | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 179 | | return left->enabled() > right->enabled(); |
| 180 | | } |
| 181 | | |
| 182 | | static int cCpuAscending(const void* a, const void* b) |
| 183 | | { |
| 184 | | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 185 | | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 186 | | const int result = strcmp(left->debugInterface()->device().tag(), right->debugInterface()->device().tag()); |
| 187 | | return result >= 0; |
| 188 | | } |
| 189 | | |
| 190 | | static int cCpuDescending(const void* a, const void* b) |
| 191 | | { |
| 192 | | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 193 | | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 194 | | const int result = strcmp(left->debugInterface()->device().tag(), right->debugInterface()->device().tag()); |
| 195 | | return result < 0; |
| 196 | | } |
| 197 | | |
| 198 | | static int cSpaceAscending(const void* a, const void* b) |
| 199 | | { |
| 200 | | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 201 | | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 202 | | const int result = strcmp(left->space().name(), right->space().name()); |
| 203 | | return result >= 0; |
| 204 | | } |
| 205 | | |
| 206 | | static int cSpaceDescending(const void* a, const void* b) |
| 207 | | { |
| 208 | | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 209 | | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 210 | | const int result = strcmp(left->space().name(), right->space().name()); |
| 211 | | return result < 0; |
| 212 | | } |
| 213 | | |
| 214 | | static int cAddressAscending(const void* a, const void* b) |
| 215 | | { |
| 216 | | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 217 | | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 218 | | return left->address() > right->address(); |
| 219 | | } |
| 220 | | |
| 221 | | static int cAddressDescending(const void* a, const void* b) |
| 222 | | { |
| 223 | | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 224 | | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 225 | | return left->address() < right->address(); |
| 226 | | } |
| 227 | | |
| 228 | | static int cTypeAscending(const void* a, const void* b) |
| 229 | | { |
| 230 | | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 231 | | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 232 | | return left->type() > right->type(); |
| 233 | | } |
| 234 | | |
| 235 | | static int cTypeDescending(const void* a, const void* b) |
| 236 | | { |
| 237 | | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 238 | | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 239 | | return left->type() < right->type(); |
| 240 | | } |
| 241 | | |
| 242 | | static int cConditionAscending(const void* a, const void* b) |
| 243 | | { |
| 244 | | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 245 | | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 246 | | const int result = strcmp(left->condition(), right->condition()); |
| 247 | | return result >= 0; |
| 248 | | } |
| 249 | | |
| 250 | | static int cConditionDescending(const void* a, const void* b) |
| 251 | | { |
| 252 | | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 253 | | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 254 | | const int result = strcmp(left->condition(), right->condition()); |
| 255 | | return result < 0; |
| 256 | | } |
| 257 | | |
| 258 | | static int cActionAscending(const void* a, const void* b) |
| 259 | | { |
| 260 | | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 261 | | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 262 | | const int result = strcmp(left->action(), right->action()); |
| 263 | | return result >= 0; |
| 264 | | } |
| 265 | | |
| 266 | | static int cActionDescending(const void* a, const void* b) |
| 267 | | { |
| 268 | | const device_debug::watchpoint* left = *(device_debug::watchpoint**)a; |
| 269 | | const device_debug::watchpoint* right = *(device_debug::watchpoint**)b; |
| 270 | | const int result = strcmp(left->action(), right->action()); |
| 271 | | return result < 0; |
| 272 | | } |
| 273 | | |
| 274 | | |
| 275 | | int debug_view_watchpoints::watchpoints(SortMode sort, device_debug::watchpoint**& wpList) |
| 276 | | { |
| 277 | | // Alloc |
| 278 | | int numWPs = 0; |
| 279 | | wpList = NULL; |
| 230 | m_buffer.resize(0); |
| 280 | 231 | for (const debug_view_source *source = m_source_list.first(); source != NULL; source = source->next()) |
| 281 | 232 | { |
| 282 | | for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; spacenum++) |
| 283 | | { |
| 284 | | /* loop over the watchpoints */ |
| 285 | | const device_debug& debugInterface = *source->device()->debug(); |
| 286 | | for (device_debug::watchpoint *wp = debugInterface.watchpoint_first(spacenum); wp != NULL; wp = wp->next()) |
| 287 | | numWPs++; |
| 288 | | } |
| 289 | | } |
| 290 | | wpList = new device_debug::watchpoint*[numWPs]; |
| 291 | | |
| 292 | | int wpAddIndex = 0; |
| 293 | | for (const debug_view_source *source = m_source_list.first(); source != NULL; source = source->next()) |
| 294 | | { |
| 295 | 233 | // Collect |
| 234 | device_debug &debugInterface = *source->device()->debug(); |
| 296 | 235 | for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; spacenum++) |
| 297 | 236 | { |
| 298 | | device_debug& debugInterface = *source->device()->debug(); |
| 299 | 237 | for (device_debug::watchpoint *wp = debugInterface.watchpoint_first(spacenum); wp != NULL; wp = wp->next()) |
| 300 | | { |
| 301 | | wpList[wpAddIndex] = wp; |
| 302 | | wpAddIndex++; |
| 303 | | } |
| 238 | m_buffer.append() = wp; |
| 304 | 239 | } |
| 305 | 240 | } |
| 306 | 241 | |
| 307 | 242 | // And now for the sort |
| 308 | | switch (m_sortType) |
| 309 | | { |
| 310 | | case SORT_NONE: |
| 311 | | break; |
| 312 | | case SORT_INDEX_ASCENDING: |
| 313 | | qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cIndexAscending); |
| 314 | | break; |
| 315 | | case SORT_INDEX_DESCENDING: |
| 316 | | qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cIndexDescending); |
| 317 | | break; |
| 318 | | case SORT_ENABLED_ASCENDING: |
| 319 | | qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cEnabledAscending); |
| 320 | | break; |
| 321 | | case SORT_ENABLED_DESCENDING: |
| 322 | | qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cEnabledDescending); |
| 323 | | break; |
| 324 | | case SORT_CPU_ASCENDING: |
| 325 | | qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cCpuAscending); |
| 326 | | break; |
| 327 | | case SORT_CPU_DESCENDING: |
| 328 | | qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cCpuDescending); |
| 329 | | break; |
| 330 | | case SORT_SPACE_ASCENDING: |
| 331 | | qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cSpaceAscending); |
| 332 | | break; |
| 333 | | case SORT_SPACE_DESCENDING: |
| 334 | | qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cSpaceDescending); |
| 335 | | break; |
| 336 | | case SORT_ADDRESS_ASCENDING: |
| 337 | | qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cAddressAscending); |
| 338 | | break; |
| 339 | | case SORT_ADDRESS_DESCENDING: |
| 340 | | qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cAddressDescending); |
| 341 | | break; |
| 342 | | case SORT_TYPE_ASCENDING: |
| 343 | | qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cTypeAscending); |
| 344 | | break; |
| 345 | | case SORT_TYPE_DESCENDING: |
| 346 | | qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cTypeDescending); |
| 347 | | break; |
| 348 | | case SORT_CONDITION_ASCENDING: |
| 349 | | qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cConditionAscending); |
| 350 | | break; |
| 351 | | case SORT_CONDITION_DESCENDING: |
| 352 | | qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cConditionDescending); |
| 353 | | break; |
| 354 | | case SORT_ACTION_ASCENDING: |
| 355 | | qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cActionAscending); |
| 356 | | break; |
| 357 | | case SORT_ACTION_DESCENDING: |
| 358 | | qsort(wpList, numWPs, sizeof(device_debug::watchpoint*), cActionDescending); |
| 359 | | break; |
| 360 | | } |
| 361 | | |
| 362 | | return numWPs; |
| 243 | qsort(&m_buffer[0], m_buffer.count(), sizeof(device_debug::watchpoint *), m_sortType); |
| 363 | 244 | } |
| 364 | 245 | |
| 365 | 246 | |
| r244571 | r244572 | |
| 371 | 252 | void debug_view_watchpoints::view_update() |
| 372 | 253 | { |
| 373 | 254 | // Gather a list of all the watchpoints for all the CPUs |
| 374 | | device_debug::watchpoint** wpList = NULL; |
| 375 | | const int numWPs = watchpoints(SORT_NONE, wpList); |
| 255 | gather_watchpoints(); |
| 376 | 256 | |
| 377 | 257 | // Set the view region so the scroll bars update |
| 378 | | m_total.y = numWPs + 1; |
| 258 | m_total.x = tableBreaks[ARRAY_LENGTH(tableBreaks) - 1]; |
| 259 | m_total.y = m_buffer.count() + 1; |
| 379 | 260 | if (m_total.y < 10) |
| 380 | 261 | m_total.y = 10; |
| 381 | 262 | |
| 382 | 263 | // Draw |
| 383 | | debug_view_char *dest = m_viewdata; |
| 384 | | for (int row = 0; row < m_visible.y; row++) |
| 264 | debug_view_char *dest = m_viewdata; |
| 265 | astring linebuf; |
| 266 | |
| 267 | // Header |
| 268 | if (m_visible.y > 0) |
| 385 | 269 | { |
| 386 | | UINT32 effrow = m_topleft.y + row; |
| 270 | linebuf.reset(); |
| 271 | linebuf.cat("ID"); |
| 272 | if (m_sortType == &cIndexAscending) linebuf.cat('\\'); |
| 273 | else if (m_sortType == &cIndexDescending) linebuf.cat('/'); |
| 274 | pad_astring_to_length(linebuf, tableBreaks[0]); |
| 275 | linebuf.cat("En"); |
| 276 | if (m_sortType == &cEnabledAscending) linebuf.cat('\\'); |
| 277 | else if (m_sortType == &cEnabledDescending) linebuf.cat('/'); |
| 278 | pad_astring_to_length(linebuf, tableBreaks[1]); |
| 279 | linebuf.cat("CPU"); |
| 280 | if (m_sortType == &cCpuAscending) linebuf.cat('\\'); |
| 281 | else if (m_sortType == &cCpuDescending) linebuf.cat('/'); |
| 282 | pad_astring_to_length(linebuf, tableBreaks[2]); |
| 283 | linebuf.cat("Space"); |
| 284 | if (m_sortType == &cSpaceAscending) linebuf.cat('\\'); |
| 285 | else if (m_sortType == &cSpaceDescending) linebuf.cat('/'); |
| 286 | pad_astring_to_length(linebuf, tableBreaks[3]); |
| 287 | linebuf.cat("Addresses"); |
| 288 | if (m_sortType == &cAddressAscending) linebuf.cat('\\'); |
| 289 | else if (m_sortType == &cAddressDescending) linebuf.cat('/'); |
| 290 | pad_astring_to_length(linebuf, tableBreaks[4]); |
| 291 | linebuf.cat("Type"); |
| 292 | if (m_sortType == &cTypeAscending) linebuf.cat('\\'); |
| 293 | else if (m_sortType == &cTypeDescending) linebuf.cat('/'); |
| 294 | pad_astring_to_length(linebuf, tableBreaks[5]); |
| 295 | linebuf.cat("Condition"); |
| 296 | if (m_sortType == &cConditionAscending) linebuf.cat('\\'); |
| 297 | else if (m_sortType == &cConditionDescending) linebuf.cat('/'); |
| 298 | pad_astring_to_length(linebuf, tableBreaks[6]); |
| 299 | linebuf.cat("Action"); |
| 300 | if (m_sortType == &cActionAscending) linebuf.cat('\\'); |
| 301 | else if (m_sortType == &cActionDescending) linebuf.cat('/'); |
| 302 | pad_astring_to_length(linebuf, tableBreaks[7]); |
| 387 | 303 | |
| 388 | | // Header |
| 389 | | if (row == 0) |
| 304 | for (UINT32 i = m_topleft.x; i < (m_topleft.x + m_visible.x); i++, dest++) |
| 390 | 305 | { |
| 391 | | astring header; |
| 392 | | header.printf("ID"); |
| 393 | | if (m_sortType == SORT_INDEX_ASCENDING) header.catprintf("\\"); |
| 394 | | else if (m_sortType == SORT_INDEX_DESCENDING) header.catprintf("/"); |
| 395 | | pad_astring_to_length(header, tableBreaks[0]); |
| 396 | | header.catprintf("En"); |
| 397 | | if (m_sortType == SORT_ENABLED_ASCENDING) header.catprintf("\\"); |
| 398 | | else if (m_sortType == SORT_ENABLED_DESCENDING) header.catprintf("/"); |
| 399 | | pad_astring_to_length(header, tableBreaks[1]); |
| 400 | | header.catprintf("CPU"); |
| 401 | | if (m_sortType == SORT_CPU_ASCENDING) header.catprintf("\\"); |
| 402 | | else if (m_sortType == SORT_CPU_DESCENDING) header.catprintf("/"); |
| 403 | | pad_astring_to_length(header, tableBreaks[2]); |
| 404 | | header.catprintf("Space"); |
| 405 | | if (m_sortType == SORT_SPACE_ASCENDING) header.catprintf("\\"); |
| 406 | | else if (m_sortType == SORT_SPACE_DESCENDING) header.catprintf("/"); |
| 407 | | pad_astring_to_length(header, tableBreaks[3]); |
| 408 | | header.catprintf("Addresses"); |
| 409 | | if (m_sortType == SORT_ADDRESS_ASCENDING) header.catprintf("\\"); |
| 410 | | else if (m_sortType == SORT_ADDRESS_DESCENDING) header.catprintf("/"); |
| 411 | | pad_astring_to_length(header, tableBreaks[4]); |
| 412 | | header.catprintf("Type"); |
| 413 | | if (m_sortType == SORT_TYPE_ASCENDING) header.catprintf("\\"); |
| 414 | | else if (m_sortType == SORT_TYPE_DESCENDING) header.catprintf("/"); |
| 415 | | pad_astring_to_length(header, tableBreaks[5]); |
| 416 | | header.catprintf("Condition"); |
| 417 | | if (m_sortType == SORT_CONDITION_ASCENDING) header.catprintf("\\"); |
| 418 | | else if (m_sortType == SORT_CONDITION_DESCENDING) header.catprintf("/"); |
| 419 | | pad_astring_to_length(header, tableBreaks[6]); |
| 420 | | header.catprintf("Action"); |
| 421 | | if (m_sortType == SORT_ACTION_ASCENDING) header.catprintf("\\"); |
| 422 | | else if (m_sortType == SORT_ACTION_DESCENDING) header.catprintf("/"); |
| 423 | | pad_astring_to_length(header, tableBreaks[7]); |
| 424 | | |
| 425 | | for (int i = 0; i < m_visible.x; i++) |
| 426 | | { |
| 427 | | dest->byte = (i < header.len()) ? header[i] : ' '; |
| 428 | | dest->attrib = DCA_ANCILLARY; |
| 429 | | dest++; |
| 430 | | } |
| 431 | | continue; |
| 306 | dest->byte = (i < linebuf.len()) ? linebuf[i] : ' '; |
| 307 | dest->attrib = DCA_ANCILLARY; |
| 432 | 308 | } |
| 309 | } |
| 433 | 310 | |
| 311 | for (int row = 1; row < m_visible.y; row++) |
| 312 | { |
| 434 | 313 | // watchpoints |
| 435 | | int wpi = effrow-1; |
| 436 | | if (wpi < numWPs && wpi >= 0) |
| 314 | int const wpi = row + m_topleft.y - 1; |
| 315 | if ((wpi < m_buffer.count()) && wpi >= 0) |
| 437 | 316 | { |
| 438 | | static const char *const types[] = { "unkn ", "read ", "write", "r/w " }; |
| 439 | | device_debug::watchpoint* wp = wpList[wpi]; |
| 317 | static char const *const types[] = { "unkn ", "read ", "write", "r/w " }; |
| 318 | device_debug::watchpoint *const wp = m_buffer[wpi]; |
| 440 | 319 | |
| 441 | | astring buffer; |
| 442 | | buffer.printf("%X", wp->index()); |
| 443 | | pad_astring_to_length(buffer, tableBreaks[0]); |
| 444 | | buffer.catprintf("%c", wp->enabled() ? 'X' : 'O'); |
| 445 | | pad_astring_to_length(buffer, tableBreaks[1]); |
| 446 | | buffer.catprintf("%s", wp->debugInterface()->device().tag()); |
| 447 | | pad_astring_to_length(buffer, tableBreaks[2]); |
| 448 | | buffer.catprintf("%s", wp->space().name()); |
| 449 | | pad_astring_to_length(buffer, tableBreaks[3]); |
| 450 | | buffer.catprintf("%s-%s", |
| 451 | | core_i64_hex_format(wp->space().byte_to_address(wp->address()), wp->space().addrchars()), |
| 452 | | core_i64_hex_format(wp->space().byte_to_address_end(wp->address() + wp->length()) - 1, wp->space().addrchars())); |
| 453 | | pad_astring_to_length(buffer, tableBreaks[4]); |
| 454 | | buffer.catprintf("%s", types[wp->type() & 3]); |
| 455 | | pad_astring_to_length(buffer, tableBreaks[5]); |
| 456 | | if (astring(wp->condition()) != astring("1")) |
| 457 | | { |
| 458 | | buffer.catprintf("%s", wp->condition()); |
| 459 | | pad_astring_to_length(buffer, tableBreaks[6]); |
| 460 | | } |
| 461 | | if (astring(wp->action()) != astring("")) |
| 462 | | { |
| 463 | | buffer.catprintf("%s", wp->action()); |
| 464 | | pad_astring_to_length(buffer, tableBreaks[7]); |
| 465 | | } |
| 320 | linebuf.reset(); |
| 321 | linebuf.catprintf("%2X", wp->index()); |
| 322 | pad_astring_to_length(linebuf, tableBreaks[0]); |
| 323 | linebuf.cat(wp->enabled() ? 'X' : 'O'); |
| 324 | pad_astring_to_length(linebuf, tableBreaks[1]); |
| 325 | linebuf.cat(wp->debugInterface()->device().tag()); |
| 326 | pad_astring_to_length(linebuf, tableBreaks[2]); |
| 327 | linebuf.cat(wp->space().name()); |
| 328 | pad_astring_to_length(linebuf, tableBreaks[3]); |
| 329 | linebuf.cat(core_i64_hex_format(wp->space().byte_to_address(wp->address()), wp->space().addrchars())); |
| 330 | linebuf.cat('-'); |
| 331 | linebuf.cat(core_i64_hex_format(wp->space().byte_to_address_end(wp->address() + wp->length()) - 1, wp->space().addrchars())); |
| 332 | pad_astring_to_length(linebuf, tableBreaks[4]); |
| 333 | linebuf.cat(types[wp->type() & 3]); |
| 334 | pad_astring_to_length(linebuf, tableBreaks[5]); |
| 335 | if (strcmp(wp->condition(), "1")) |
| 336 | linebuf.cat(wp->condition()); |
| 337 | pad_astring_to_length(linebuf, tableBreaks[6]); |
| 338 | linebuf.cat(wp->action()); |
| 339 | pad_astring_to_length(linebuf, tableBreaks[7]); |
| 466 | 340 | |
| 467 | | for (int i = 0; i < m_visible.x; i++) |
| 341 | for (UINT32 i = m_topleft.x; i < (m_topleft.x + m_visible.x); i++, dest++) |
| 468 | 342 | { |
| 469 | | dest->byte = (i < buffer.len()) ? buffer[i] : ' '; |
| 343 | dest->byte = (i < linebuf.len()) ? linebuf[i] : ' '; |
| 470 | 344 | dest->attrib = DCA_NORMAL; |
| 471 | 345 | |
| 472 | 346 | // Color disabled watchpoints red |
| 473 | | if (i == 5 && dest->byte == 'O') |
| 474 | | dest->attrib = DCA_CHANGED; |
| 475 | | |
| 476 | | dest++; |
| 347 | if ((i >= tableBreaks[0]) && (i < tableBreaks[1]) && !wp->enabled()) |
| 348 | dest->attrib |= DCA_CHANGED; |
| 477 | 349 | } |
| 478 | | continue; |
| 479 | 350 | } |
| 480 | | |
| 481 | | // Fill the remaining vertical space |
| 482 | | for (int i = 0; i < m_visible.x; i++) |
| 351 | else |
| 483 | 352 | { |
| 484 | | dest->byte = ' '; |
| 485 | | dest->attrib = DCA_NORMAL; |
| 486 | | dest++; |
| 353 | // Fill the remaining vertical space |
| 354 | for (int i = 0; i < m_visible.x; i++, dest++) |
| 355 | { |
| 356 | dest->byte = ' '; |
| 357 | dest->attrib = DCA_NORMAL; |
| 358 | } |
| 487 | 359 | } |
| 488 | 360 | } |
| 489 | | |
| 490 | | delete[] wpList; |
| 491 | 361 | } |