fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 352 lines 6.9 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/utils/pri/event.c * 7 * Created: 2015-02-23 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2015 Hampa Hug <hampa@hampa.ch> * 9 *****************************************************************************/ 10 11/***************************************************************************** 12 * This program is free software. You can redistribute it and / or modify it * 13 * under the terms of the GNU General Public License version 2 as published * 14 * by the Free Software Foundation. * 15 * * 16 * This program is distributed in the hope that it will be useful, but * 17 * WITHOUT ANY WARRANTY, without even the implied warranty of * 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 19 * Public License for more details. * 20 *****************************************************************************/ 21 22 23#include "main.h" 24 25#include <errno.h> 26#include <stdio.h> 27#include <stdlib.h> 28#include <string.h> 29 30#include <drivers/pri/pri.h> 31 32 33struct pri_event_s { 34 unsigned long type; 35 unsigned long idx1; 36 unsigned long idx2; 37 char all; 38}; 39 40 41const char *pri_event_get_name (unsigned long type) 42{ 43 switch (type) { 44 case PRI_EVENT_WEAK: 45 return ("WEAK"); 46 47 case PRI_EVENT_CLOCK: 48 return ("CLOCK"); 49 } 50 51 return ("UNK"); 52} 53 54int pri_event_get_type (const char *name, unsigned long *type) 55{ 56 if (name == NULL) { 57 return (1); 58 } 59 60 if (strcasecmp (name, "FUZZY") == 0) { 61 *type = PRI_EVENT_WEAK; 62 } 63 else if (strcasecmp (name, "WEAK") == 0) { 64 *type = PRI_EVENT_WEAK; 65 } 66 else if (strcasecmp (name, "CLOCK") == 0) { 67 *type = PRI_EVENT_CLOCK; 68 } 69 else if (strcasecmp (name, "ALL") == 0) { 70 *type = PRI_EVENT_ALL; 71 } 72 else { 73 errno = 0; 74 75 *type = strtoul (name, NULL, 0); 76 77 if (errno) { 78 return (1); 79 } 80 } 81 82 return (0); 83} 84 85 86static 87int pri_event_clear_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque) 88{ 89 pri_trk_evt_del_all (trk, PRI_EVENT_ALL); 90 91 return (0); 92} 93 94int pri_event_clear (pri_img_t *img) 95{ 96 return (pri_for_all_tracks (img, pri_event_clear_cb, NULL)); 97} 98 99 100static 101int pri_event_add_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque) 102{ 103 struct pri_event_s *par; 104 105 par = opaque; 106 107 if (pri_trk_evt_add (trk, par->type, par->idx1, par->idx2) == NULL) { 108 return (1); 109 } 110 111 return (0); 112} 113 114int pri_event_add (pri_img_t *img, const char *type, const char *pos, const char *val) 115{ 116 struct pri_event_s par; 117 118 if (pri_event_get_type (type, &par.type)) { 119 return (1); 120 } 121 122 errno = 0; 123 124 par.idx1 = strtoul (pos, NULL, 0); 125 par.idx2 = strtoul (val, NULL, 0); 126 127 if (errno) { 128 return (1); 129 } 130 131 return (pri_for_all_tracks (img, pri_event_add_cb, &par)); 132} 133 134 135static 136int pri_event_del_idx_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque) 137{ 138 unsigned long i; 139 struct pri_event_s *par; 140 pri_evt_t *evt; 141 142 par = opaque; 143 144 if (par->all) { 145 pri_trk_evt_del_all (trk, par->type); 146 } 147 else { 148 for (i = par->idx1; i <= par->idx2; i++) { 149 evt = pri_trk_evt_get_idx (trk, par->type, par->idx1); 150 151 if (evt != NULL) { 152 pri_trk_evt_del (trk, evt); 153 } 154 } 155 } 156 157 return (0); 158} 159 160static 161int pri_event_del_pos_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque) 162{ 163 int del; 164 struct pri_event_s *par; 165 pri_evt_t *evt, *tmp, *dst; 166 167 par = opaque; 168 169 evt = trk->evt; 170 dst = NULL; 171 trk->evt = NULL; 172 173 while (evt != NULL) { 174 tmp = evt; 175 evt = evt->next; 176 tmp->next = NULL; 177 178 if ((par->type != PRI_EVENT_ALL) && (tmp->type != par->type)) { 179 del = 0; 180 } 181 else if (par->all) { 182 del = 1; 183 } 184 else if ((tmp->pos >= par->idx1) && (tmp->pos <= par->idx2)) { 185 del = 1; 186 } 187 else { 188 del = 0; 189 } 190 191 if (del) { 192 pri_evt_del (tmp); 193 } 194 else { 195 if (dst == NULL) { 196 trk->evt = tmp; 197 } 198 else { 199 dst->next = tmp; 200 } 201 202 dst = tmp; 203 } 204 } 205 206 return (0); 207} 208 209int pri_event_del (pri_img_t *img, const char *type, const char *range) 210{ 211 int byidx; 212 struct pri_event_s par; 213 214 if (pri_event_get_type (type, &par.type)) { 215 return (1); 216 } 217 218 byidx = 0; 219 220 if (*range == '@') { 221 byidx = 1; 222 range += 1; 223 } 224 225 if (pri_parse_range (range, &par.idx1, &par.idx2, &par.all)) { 226 return (1); 227 } 228 229 if (byidx) { 230 return (pri_for_all_tracks (img, pri_event_del_idx_cb, &par)); 231 } 232 else { 233 return (pri_for_all_tracks (img, pri_event_del_pos_cb, &par)); 234 } 235} 236 237 238static 239void pri_print_event (const pri_evt_t *evt, unsigned long c, unsigned long h, unsigned long i) 240{ 241 const char *str; 242 243 str = pri_event_get_name (evt->type); 244 245 printf ("%2lu/%lu %3lu: %08lX %08lX %08lX (%s %lu)\n", 246 c, h, i, evt->type, evt->pos, evt->val, 247 str, evt->pos 248 ); 249} 250 251static 252int pri_event_list_idx_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque) 253{ 254 unsigned long i; 255 struct pri_event_s *par; 256 pri_evt_t *evt1, *evt2; 257 258 par = opaque; 259 260 evt2 = trk->evt; 261 262 i = 0; 263 264 while (evt2 != NULL) { 265 evt1 = evt2; 266 evt2 = evt2->next; 267 268 if (par->type != PRI_EVENT_ALL) { 269 if (par->type != evt1->type) { 270 continue; 271 } 272 } 273 274 if (par->all == 0) { 275 if ((i < par->idx1) || (i > par->idx2)) { 276 i += 1; 277 continue; 278 } 279 } 280 281 pri_print_event (evt1, c, h, i); 282 283 i += 1; 284 } 285 286 return (0); 287} 288 289static 290int pri_event_list_pos_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque) 291{ 292 unsigned long i; 293 struct pri_event_s *par; 294 pri_evt_t *evt1, *evt2; 295 296 par = opaque; 297 298 i = 0; 299 300 evt2 = trk->evt; 301 302 while (evt2 != NULL) { 303 evt1 = evt2; 304 evt2 = evt2->next; 305 306 if (par->type != PRI_EVENT_ALL) { 307 if (par->type != evt1->type) { 308 continue; 309 } 310 } 311 312 i += 1; 313 314 if (par->all == 0) { 315 if ((evt1->pos < par->idx1) || (evt1->pos > par->idx2)) { 316 continue; 317 } 318 } 319 320 pri_print_event (evt1, c, h, i - 1); 321 } 322 323 return (0); 324} 325 326int pri_event_list (pri_img_t *img, const char *type, const char *range) 327{ 328 int byidx; 329 struct pri_event_s par; 330 331 if (pri_event_get_type (type, &par.type)) { 332 return (1); 333 } 334 335 byidx = 0; 336 337 if (*range == '@') { 338 byidx = 1; 339 range += 1; 340 } 341 342 if (pri_parse_range (range, &par.idx1, &par.idx2, &par.all)) { 343 return (1); 344 } 345 346 if (byidx) { 347 return (pri_for_all_tracks (img, pri_event_list_idx_cb, &par)); 348 } 349 else { 350 return (pri_for_all_tracks (img, pri_event_list_pos_cb, &par)); 351 } 352}