~ubuntu-branches/ubuntu/utopic/vice/utopic

« back to all changes in this revision

Viewing changes to src/event.c

  • Committer: Package Import Robot
  • Author(s): Logan Rosen
  • Date: 2014-05-10 21:08:23 UTC
  • mfrom: (17.2.1 utopic-proposed)
  • Revision ID: package-import@ubuntu.com-20140510210823-r7x98jmpl1x7rgop
Tags: 2.4.dfsg+2.4.6-1ubuntu1
Use autotools-dev to update config.{sub,guess} for new arches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
 * Written by
5
5
 *  Andreas Boose <viceteam@t-online.de>
6
6
 *  Andreas Matthies <aDOTmatthiesATgmxDOTnet>
7
 
 *  
 
7
 *
8
8
 * This file is part of VICE, the Versatile Commodore Emulator.
9
9
 * See README for copyright notice.
10
10
 *
99
99
static char *event_snapshot_path(const char *snapshot_file)
100
100
{
101
101
    lib_free(event_snapshot_path_str);
102
 
    event_snapshot_path_str = 
103
 
        util_concat(event_snapshot_dir, snapshot_file, NULL);
 
102
    event_snapshot_path_str = util_concat(event_snapshot_dir, snapshot_file, NULL);
104
103
 
105
104
    return event_snapshot_path_str;
106
105
}
109
108
/* searches for a filename in the image list    */
110
109
/* returns 0 if found                           */
111
110
/* returns 1 and appends it if not found        */
112
 
static int event_image_append(const char *filename, 
113
 
                              char **mapped_name, int append)
 
111
static int event_image_append(const char *filename, char **mapped_name, int append)
114
112
{
115
113
    event_image_list_t *event_image_list_ptr = event_image_list_base;
116
114
 
138
136
    event_image_list_ptr->next = NULL;
139
137
    event_image_list_ptr->orig_filename = lib_stralloc(filename);
140
138
    event_image_list_ptr->mapped_filename = NULL;
141
 
    if (mapped_name != NULL && append)
 
139
    if (mapped_name != NULL && append) {
142
140
        event_image_list_ptr->mapped_filename = lib_stralloc(*mapped_name);
 
141
    }
143
142
 
144
143
    return 1;
145
144
}
158
157
 
159
158
    util_fname_split(filename, &strdir, &strfile);
160
159
 
161
 
    if (event_image_include)
 
160
    if (event_image_include) {
162
161
        size = (unsigned int)strlen(filename) + 3;
163
 
    else
 
162
    } else {
164
163
        size = (unsigned int)strlen(strfile) + sizeof(long) + 4;
 
164
    }
165
165
 
166
166
    event_data = lib_malloc(size);
167
167
    event_data[0] = unit;
172
172
        if (event_image_append(filename, NULL, 0) == 1) {
173
173
            FILE *fd;
174
174
            size_t file_len = 0;
175
 
        
 
175
 
176
176
            fd = fopen(filename, MODE_READ);
177
177
 
178
178
            if (fd != NULL) {
179
179
                file_len = util_file_length(fd);
180
180
                event_data = lib_realloc(event_data, size + file_len);
181
181
 
182
 
                if (fread(&event_data[size], file_len, 1, fd) != 1)
 
182
                if (fread(&event_data[size], file_len, 1, fd) != 1) {
183
183
                    log_error(event_log, "Cannot load image file %s", filename);
 
184
                }
184
185
 
185
186
                fclose(fd);
186
187
            } else {
205
206
void event_record_attach_image(unsigned int unit, const char *filename,
206
207
                               unsigned int read_only)
207
208
{
208
 
    if (record_active == 0)
 
209
    if (record_active == 0) {
209
210
        return;
 
211
    }
210
212
 
211
213
    event_record_attach_in_list(event_list, unit, filename, read_only);
212
214
}
228
230
        orig_filename = (char *) data + 3 + sizeof(long);
229
231
 
230
232
        if (event_image_append(orig_filename, &filename, 0) != 0) {
231
 
            crc_to_attach = *(unsigned long *)(((char *)data)+3);
 
233
            crc_to_attach = *(unsigned long *)(((char *)data) + 3);
232
234
            do {
233
235
                filename = ui_get_file("Please attach image %s (CRC32 checksum 0x%x)",
234
 
                            (char *) data + 3 + sizeof(long), crc_to_attach);
 
236
                                       (char *) data + 3 + sizeof(long), crc_to_attach);
235
237
            } while (filename != NULL && crc_to_attach != crc32_file(filename));
236
238
            if (filename == NULL) {
237
239
                ui_error("Image wasn't attached. Playback will probably get out of sync.");
240
242
            event_image_append(orig_filename, &filename, 1);
241
243
        }
242
244
    } else {
243
 
        file_len  = size - strlen(orig_filename) - 3;
 
245
        file_len = size - strlen(orig_filename) - 3;
244
246
 
245
247
        if (file_len > 0) {
246
248
            FILE *fd;
247
249
 
248
250
            fd = archdep_mkstemp_fd(&filename, MODE_WRITE);
249
 
    
 
251
 
250
252
            if (fd == NULL) {
251
253
                ui_error(translate_text(IDGS_CANNOT_CREATE_IMAGE), filename);
252
254
                goto error;
274
276
        resources_set_int_sprintf("AttachDevice%dReadonly", read_only, unit);
275
277
        file_system_event_playback(unit, filename);
276
278
    }
277
 
    
 
279
 
278
280
error:
279
281
    lib_free(filename);
280
282
}
288
290
    /*log_debug("EVENT RECORD %i CLK %i", type, maincpu_clk);*/
289
291
 
290
292
    switch (type) {
291
 
      case EVENT_RESETCPU:
292
 
        next_timestamp_clk -= maincpu_clk;
293
 
      case EVENT_KEYBOARD_MATRIX:
294
 
      case EVENT_KEYBOARD_RESTORE:
295
 
      case EVENT_KEYBOARD_DELAY:
296
 
      case EVENT_JOYSTICK_VALUE:
297
 
      case EVENT_DATASETTE:
298
 
      case EVENT_ATTACHDISK:
299
 
      case EVENT_ATTACHTAPE:
300
 
      case EVENT_ATTACHIMAGE:
301
 
      case EVENT_INITIAL:
302
 
      case EVENT_SYNC_TEST:
303
 
      case EVENT_RESOURCE:
304
 
        event_data = lib_malloc(size);
305
 
        memcpy(event_data, data, size);
306
 
        break;
307
 
      case EVENT_LIST_END:
308
 
      case EVENT_OVERFLOW:
309
 
      case EVENT_KEYBOARD_CLEAR:
310
 
        break;
311
 
      default:
312
 
        /*log_error(event_log, "Unknow event type %i.", type);*/
313
 
        return;
 
293
        case EVENT_RESETCPU:
 
294
            next_timestamp_clk -= maincpu_clk;
 
295
        case EVENT_KEYBOARD_MATRIX:
 
296
        case EVENT_KEYBOARD_RESTORE:
 
297
        case EVENT_KEYBOARD_DELAY:
 
298
        case EVENT_JOYSTICK_VALUE:
 
299
        case EVENT_DATASETTE:
 
300
        case EVENT_ATTACHDISK:
 
301
        case EVENT_ATTACHTAPE:
 
302
        case EVENT_ATTACHIMAGE:
 
303
        case EVENT_INITIAL:
 
304
        case EVENT_SYNC_TEST:
 
305
        case EVENT_RESOURCE:
 
306
            event_data = lib_malloc(size);
 
307
            memcpy(event_data, data, size);
 
308
            break;
 
309
        case EVENT_LIST_END:
 
310
        case EVENT_OVERFLOW:
 
311
        case EVENT_KEYBOARD_CLEAR:
 
312
            break;
 
313
        default:
 
314
            /*log_error(event_log, "Unknow event type %i.", type);*/
 
315
            return;
314
316
    }
315
317
 
316
318
    list->current->type = type;
324
326
 
325
327
void event_record(unsigned int type, void *data, unsigned int size)
326
328
{
327
 
    if (record_active == 1)
 
329
    if (record_active == 1) {
328
330
        event_record_in_list(event_list, type, data, size);
 
331
    }
329
332
}
330
333
 
331
334
 
336
339
    new_value = event_list->current->clk;
337
340
 
338
341
    if (maincpu_clk > CLKGUARD_SUB_MIN
339
 
        && new_value < maincpu_clk - CLKGUARD_SUB_MIN)
 
342
        && new_value < maincpu_clk - CLKGUARD_SUB_MIN) {
340
343
        new_value += clk_guard_clock_sub(maincpu_clk_guard);
 
344
    }
341
345
 
342
346
    alarm_set(event_alarm, new_value);
343
347
}
354
358
    /* when recording set a timestamp */
355
359
    if (record_active) {
356
360
        ui_display_event_time(current_timestamp++, 0);
357
 
        next_timestamp_clk = next_timestamp_clk 
358
 
                                + machine_get_cycles_per_second();
 
361
        next_timestamp_clk = next_timestamp_clk + machine_get_cycles_per_second();
359
362
        alarm_set(event_alarm, next_timestamp_clk);
360
363
        return;
361
364
    }
364
367
              event_list_current->clk);*/
365
368
 
366
369
    switch (event_list->current->type) {
367
 
      case EVENT_KEYBOARD_MATRIX:
368
 
        keyboard_event_playback(offset, event_list->current->data);
369
 
        break;
370
 
      case EVENT_KEYBOARD_RESTORE:
371
 
        keyboard_restore_event_playback(offset, event_list->current->data);
372
 
        break;
373
 
      case EVENT_JOYSTICK_VALUE:
374
 
        joystick_event_playback(offset, event_list->current->data);
375
 
        break;
376
 
      case EVENT_DATASETTE:
377
 
        datasette_event_playback(offset, event_list->current->data);
378
 
        break;
379
 
      case EVENT_ATTACHIMAGE:
380
 
        event_playback_attach_image(event_list->current->data,
381
 
                                    event_list->current->size);
382
 
        break;
383
 
      case EVENT_ATTACHDISK:
384
 
      case EVENT_ATTACHTAPE:
385
 
        {
386
 
            /* old style attach via absolute filename and detach*/
387
 
            unsigned int unit;
388
 
            const char *filename;
389
 
 
390
 
            unit = (unsigned int)((char*)event_list->current->data)[0];
391
 
            filename = &((char*)event_list->current->data)[1];
392
 
            
393
 
            if (unit == 1)
394
 
                tape_image_event_playback(unit, filename);
395
 
            else
396
 
                file_system_event_playback(unit, filename);
397
 
        }
398
 
        break;
399
 
      case EVENT_RESETCPU:
400
 
        machine_reset_event_playback(offset, event_list->current->data);
401
 
        break;
402
 
      case EVENT_TIMESTAMP:
403
 
        ui_display_event_time(current_timestamp++, playback_time);
404
 
        break;
405
 
      case EVENT_LIST_END:
406
 
        event_playback_stop();
407
 
        break;
408
 
      case EVENT_OVERFLOW:
409
 
        break;
410
 
      default:
411
 
        log_error(event_log, "Unknow event type %i.", event_list->current->type);
 
370
        case EVENT_KEYBOARD_MATRIX:
 
371
            keyboard_event_playback(offset, event_list->current->data);
 
372
            break;
 
373
        case EVENT_KEYBOARD_RESTORE:
 
374
            keyboard_restore_event_playback(offset, event_list->current->data);
 
375
            break;
 
376
        case EVENT_JOYSTICK_VALUE:
 
377
            joystick_event_playback(offset, event_list->current->data);
 
378
            break;
 
379
        case EVENT_DATASETTE:
 
380
            datasette_event_playback(offset, event_list->current->data);
 
381
            break;
 
382
        case EVENT_ATTACHIMAGE:
 
383
            event_playback_attach_image(event_list->current->data,
 
384
                                        event_list->current->size);
 
385
            break;
 
386
        case EVENT_ATTACHDISK:
 
387
        case EVENT_ATTACHTAPE:
 
388
            {
 
389
                /* old style attach via absolute filename and detach*/
 
390
                unsigned int unit;
 
391
                const char *filename;
 
392
 
 
393
                unit = (unsigned int)((char*)event_list->current->data)[0];
 
394
                filename = &((char*)event_list->current->data)[1];
 
395
 
 
396
                if (unit == 1) {
 
397
                    tape_image_event_playback(unit, filename);
 
398
                } else {
 
399
                    file_system_event_playback(unit, filename);
 
400
                }
 
401
            }
 
402
            break;
 
403
        case EVENT_RESETCPU:
 
404
            machine_reset_event_playback(offset, event_list->current->data);
 
405
            break;
 
406
        case EVENT_TIMESTAMP:
 
407
            ui_display_event_time(current_timestamp++, playback_time);
 
408
            break;
 
409
        case EVENT_LIST_END:
 
410
            event_playback_stop();
 
411
            break;
 
412
        case EVENT_OVERFLOW:
 
413
            break;
 
414
        default:
 
415
            log_error(event_log, "Unknow event type %i.", event_list->current->type);
412
416
    }
413
417
 
414
418
    if (event_list->current->type != EVENT_LIST_END
425
429
 
426
430
    while (current->type != EVENT_LIST_END) {
427
431
        switch (current->type) {
428
 
          case EVENT_SYNC_TEST:
429
 
            break;
430
 
          case EVENT_KEYBOARD_DELAY:
431
 
            keyboard_register_delay(*(unsigned int*)current->data);
432
 
            break;
433
 
          case EVENT_KEYBOARD_MATRIX:
434
 
            keyboard_event_delayed_playback(current->data);
435
 
            break;
436
 
          case EVENT_KEYBOARD_RESTORE:
437
 
            keyboard_restore_event_playback(0, current->data);
438
 
            break;
439
 
          case EVENT_KEYBOARD_CLEAR:
440
 
            keyboard_register_clear();
441
 
            break;
442
 
          case EVENT_JOYSTICK_DELAY:
443
 
            joystick_register_delay(*(unsigned int*)current->data);
444
 
            break;
445
 
          case EVENT_JOYSTICK_VALUE:
446
 
            joystick_event_delayed_playback(current->data);
447
 
            break;
448
 
          case EVENT_DATASETTE:
449
 
            datasette_event_playback(0, current->data);
450
 
            break;
451
 
          case EVENT_RESETCPU:
452
 
            machine_reset_event_playback(0, current->data);
453
 
            break;
454
 
          case EVENT_ATTACHDISK:
455
 
          case EVENT_ATTACHTAPE:
456
 
            {
457
 
                /* in fact this is only for detaching */
458
 
                unsigned int unit;
459
 
 
460
 
                unit = (unsigned int)((char*)current->data)[0];
461
 
            
462
 
                if (unit == 1)
463
 
                    tape_image_event_playback(1, NULL);
464
 
                else
465
 
                    file_system_event_playback(unit, NULL);
466
 
                break;
467
 
            }
468
 
          case EVENT_ATTACHIMAGE:
469
 
            event_playback_attach_image(current->data, current->size);
470
 
            break;
471
 
          case EVENT_RESOURCE:
472
 
            resources_set_value_event(current->data, current->size);
473
 
            break;
474
 
          default:
475
 
            log_error(event_log, "Unknow event type %i.", current->type);
 
432
            case EVENT_SYNC_TEST:
 
433
                break;
 
434
            case EVENT_KEYBOARD_DELAY:
 
435
                keyboard_register_delay(*(unsigned int*)current->data);
 
436
                break;
 
437
            case EVENT_KEYBOARD_MATRIX:
 
438
                keyboard_event_delayed_playback(current->data);
 
439
                break;
 
440
            case EVENT_KEYBOARD_RESTORE:
 
441
                keyboard_restore_event_playback(0, current->data);
 
442
                break;
 
443
            case EVENT_KEYBOARD_CLEAR:
 
444
                keyboard_register_clear();
 
445
                break;
 
446
            case EVENT_JOYSTICK_DELAY:
 
447
                joystick_register_delay(*(unsigned int*)current->data);
 
448
                break;
 
449
            case EVENT_JOYSTICK_VALUE:
 
450
                joystick_event_delayed_playback(current->data);
 
451
                break;
 
452
            case EVENT_DATASETTE:
 
453
                datasette_event_playback(0, current->data);
 
454
                break;
 
455
            case EVENT_RESETCPU:
 
456
                machine_reset_event_playback(0, current->data);
 
457
                break;
 
458
            case EVENT_ATTACHDISK:
 
459
            case EVENT_ATTACHTAPE:
 
460
                {
 
461
                    /* in fact this is only for detaching */
 
462
                    unsigned int unit;
 
463
 
 
464
                    unit = (unsigned int)((char*)current->data)[0];
 
465
 
 
466
                    if (unit == 1) {
 
467
                        tape_image_event_playback(1, NULL);
 
468
                    } else {
 
469
                        file_system_event_playback(unit, NULL);
 
470
                    }
 
471
                    break;
 
472
                }
 
473
            case EVENT_ATTACHIMAGE:
 
474
                event_playback_attach_image(current->data, current->size);
 
475
                break;
 
476
            case EVENT_RESOURCE:
 
477
                resources_set_value_event(current->data, current->size);
 
478
                break;
 
479
            default:
 
480
                log_error(event_log, "Unknow event type %i.", current->type);
476
481
        }
477
482
        current = current->next;
478
483
    }
515
520
void event_destroy_image_list(void)
516
521
{
517
522
    event_image_list_t *d1, *d2;
518
 
 
 
523
 
519
524
    d1 = event_image_list_base;
520
525
 
521
526
    while (d1 != NULL) {
531
536
 
532
537
void event_clear_list(event_list_state_t *list)
533
538
{
534
 
    if (list != NULL && list->base != NULL)
 
539
    if (list != NULL && list->base != NULL) {
535
540
        cut_list(list->base);
 
541
    }
536
542
}
537
543
 
538
544
static void destroy_list(void)
549
555
    curr = event_list->base;
550
556
 
551
557
    while (curr->type != EVENT_LIST_END) {
552
 
 
553
 
        if (curr->type == EVENT_ATTACHIMAGE)
 
558
        if (curr->type == EVENT_ATTACHIMAGE) {
554
559
            event_image_append(&((char*)curr->data)[2], NULL, 0);
 
560
        }
555
561
 
556
562
        curr = curr->next;
557
563
    }
586
592
    data = event_list->base->data;
587
593
 
588
594
    ver_idx = 1;
589
 
    if (data[0] == EVENT_START_MODE_FILE_SAVE)
 
595
    if (data[0] == EVENT_START_MODE_FILE_SAVE) {
590
596
        ver_idx += (unsigned int)strlen((char *)&data[1]) + 1;
 
597
    }
591
598
 
592
599
    event_list->base->size = ver_idx + (unsigned int)strlen(VERSION) + 1;
593
600
    new_data = lib_malloc(event_list->base->size);
606
613
    size_t len = 0;
607
614
 
608
615
    switch (event_start_mode) {
609
 
      case EVENT_START_MODE_FILE_SAVE:
610
 
        len = 1 + strlen(event_start_snapshot) + 1;
611
 
        data = lib_malloc(len);
612
 
        data[0] = EVENT_START_MODE_FILE_SAVE;
613
 
        strcpy((char *)&data[1], event_start_snapshot);
614
 
        break;
615
 
      case EVENT_START_MODE_RESET:
616
 
        len = 1;
617
 
        data = lib_malloc(len);
618
 
        data[0] = EVENT_START_MODE_RESET;
619
 
        break;
 
616
        case EVENT_START_MODE_FILE_SAVE:
 
617
            len = 1 + strlen(event_start_snapshot) + 1;
 
618
            data = lib_malloc(len);
 
619
            data[0] = EVENT_START_MODE_FILE_SAVE;
 
620
            strcpy((char *)&data[1], event_start_snapshot);
 
621
            break;
 
622
        case EVENT_START_MODE_RESET:
 
623
            len = 1;
 
624
            data = lib_malloc(len);
 
625
            data[0] = EVENT_START_MODE_RESET;
 
626
            break;
620
627
    }
621
628
 
622
629
    event_record(EVENT_INITIAL, (void *)data, (unsigned int)len);
631
638
static void event_record_start_trap(WORD addr, void *data)
632
639
{
633
640
    switch (event_start_mode) {
634
 
      case EVENT_START_MODE_FILE_SAVE:
635
 
        if (machine_write_snapshot(event_snapshot_path(event_start_snapshot),
636
 
                                    1, 1, 0) < 0) {
637
 
            ui_error(translate_text(IDGS_CANT_CREATE_START_SNAP_S), 
638
 
                        event_snapshot_path(event_start_snapshot));
639
 
            ui_display_recording(0);
640
 
            return;
641
 
        }
642
 
        destroy_list();
643
 
        create_list();
644
 
        record_active = 1;
645
 
        event_initial_write();
646
 
        next_timestamp_clk = maincpu_clk;
647
 
        current_timestamp = 0;
648
 
        break;
649
 
      case EVENT_START_MODE_FILE_LOAD:
650
 
        if (machine_read_snapshot(
651
 
                event_snapshot_path(event_end_snapshot), 1) < 0) {
652
 
            ui_error(translate_text(IDGS_ERROR_READING_END_SNAP_S),
653
 
                        event_snapshot_path(event_end_snapshot));
654
 
            return;
655
 
        }
656
 
        warp_end_list();
657
 
        record_active = 1;
658
 
        next_timestamp_clk = maincpu_clk;
659
 
        current_timestamp = playback_time;
660
 
        break;
661
 
      case EVENT_START_MODE_RESET:
662
 
        machine_trigger_reset(MACHINE_RESET_MODE_HARD);
663
 
        destroy_list();
664
 
        create_list();
665
 
        record_active = 1;
666
 
        event_initial_write();
667
 
        next_timestamp_clk = 0;
668
 
        current_timestamp = 0;
669
 
        break;
670
 
      case EVENT_START_MODE_PLAYBACK:
671
 
        cut_list(event_list->current->next);
672
 
        event_list->current->next = NULL;
673
 
        event_list->current->type = EVENT_LIST_END;
674
 
        event_destroy_image_list();
675
 
        event_write_version();
676
 
        record_active = 1;
677
 
        next_timestamp_clk = maincpu_clk;
678
 
        break;
679
 
      default:
680
 
        log_error(event_log, "Unknown event start mode %i", event_start_mode); 
681
 
        return;
 
641
        case EVENT_START_MODE_FILE_SAVE:
 
642
            if (machine_write_snapshot(event_snapshot_path(event_start_snapshot),
 
643
                                       1, 1, 0) < 0) {
 
644
                ui_error(translate_text(IDGS_CANT_CREATE_START_SNAP_S),
 
645
                         event_snapshot_path(event_start_snapshot));
 
646
                ui_display_recording(0);
 
647
                return;
 
648
            }
 
649
            destroy_list();
 
650
            create_list();
 
651
            record_active = 1;
 
652
            event_initial_write();
 
653
            next_timestamp_clk = maincpu_clk;
 
654
            current_timestamp = 0;
 
655
            break;
 
656
        case EVENT_START_MODE_FILE_LOAD:
 
657
            if (machine_read_snapshot(
 
658
                    event_snapshot_path(event_end_snapshot), 1) < 0) {
 
659
                ui_error(translate_text(IDGS_ERROR_READING_END_SNAP_S),
 
660
                         event_snapshot_path(event_end_snapshot));
 
661
                return;
 
662
            }
 
663
            warp_end_list();
 
664
            record_active = 1;
 
665
            next_timestamp_clk = maincpu_clk;
 
666
            current_timestamp = playback_time;
 
667
            break;
 
668
        case EVENT_START_MODE_RESET:
 
669
            machine_trigger_reset(MACHINE_RESET_MODE_HARD);
 
670
            destroy_list();
 
671
            create_list();
 
672
            record_active = 1;
 
673
            event_initial_write();
 
674
            next_timestamp_clk = 0;
 
675
            current_timestamp = 0;
 
676
            break;
 
677
        case EVENT_START_MODE_PLAYBACK:
 
678
            cut_list(event_list->current->next);
 
679
            event_list->current->next = NULL;
 
680
            event_list->current->type = EVENT_LIST_END;
 
681
            event_destroy_image_list();
 
682
            event_write_version();
 
683
            record_active = 1;
 
684
            next_timestamp_clk = maincpu_clk;
 
685
            break;
 
686
        default:
 
687
            log_error(event_log, "Unknown event start mode %i", event_start_mode);
 
688
            return;
682
689
    }
683
690
 
684
691
#ifdef  DEBUG
693
700
int event_record_start(void)
694
701
{
695
702
    if (event_start_mode == EVENT_START_MODE_PLAYBACK) {
696
 
        if (playback_active != 0)
 
703
        if (playback_active != 0) {
697
704
            event_playback_stop();
698
 
        else
 
705
        } else {
699
706
            return -1;
 
707
        }
700
708
    }
701
709
 
702
 
    if (record_active != 0 || autostart_in_progress())
703
 
    {
 
710
    if (record_active != 0 || autostart_in_progress()) {
704
711
        return -1;
705
712
    }
706
713
 
716
723
    if (machine_write_snapshot(
717
724
            event_snapshot_path(event_end_snapshot), 1, 1, 1) < 0) {
718
725
        ui_error(translate_text(IDGS_CANT_CREATE_END_SNAP_S),
719
 
                    event_snapshot_path(event_end_snapshot));
 
726
                 event_snapshot_path(event_end_snapshot));
720
727
        return;
721
728
    }
722
729
    record_active = 0;
728
735
 
729
736
int event_record_stop(void)
730
737
{
731
 
    if (record_active == 0)
 
738
    if (record_active == 0) {
732
739
        return -1;
 
740
    }
733
741
 
734
742
    event_record(EVENT_LIST_END, NULL, 0);
735
743
 
748
756
 
749
757
void event_reset_ack(void)
750
758
{
751
 
    if (event_list == NULL)
 
759
    if (event_list == NULL) {
752
760
        return;
 
761
    }
753
762
 
754
763
    if (playback_reset_ack) {
755
764
        playback_reset_ack = 0;
756
765
        next_alarm_set();
757
766
    }
758
767
 
759
 
    if (event_list->current 
760
 
        && event_list->current->type == EVENT_RESETCPU)
761
 
    {
 
768
    if (event_list->current && event_list->current->type == EVENT_RESETCPU) {
762
769
        next_current_list();
763
770
        next_alarm_set();
764
771
    }
765
772
 
766
773
    /* timestamp alarm needs to be set */
767
 
    if (record_active)
 
774
    if (record_active) {
768
775
        alarm_set(event_alarm, next_timestamp_clk);
 
776
    }
769
777
}
770
778
 
771
779
static void event_playback_start_trap(WORD addr, void *data)
779
787
        event_snapshot_path(event_end_snapshot), &major, &minor, machine_name);
780
788
 
781
789
    if (s == NULL) {
782
 
        ui_error(translate_text(IDGS_CANT_OPEN_END_SNAP_S), 
783
 
                    event_snapshot_path(event_end_snapshot));
 
790
        ui_error(translate_text(IDGS_CANT_OPEN_END_SNAP_S),
 
791
                 event_snapshot_path(event_end_snapshot));
784
792
        ui_display_playback(0, NULL);
785
793
        return;
786
794
    }
802
810
    if (event_list->current->type == EVENT_INITIAL) {
803
811
        BYTE *data = (BYTE *)(event_list->current->data);
804
812
        switch (data[0]) {
805
 
          case EVENT_START_MODE_FILE_SAVE:
806
 
            /*log_debug("READING %s", (char *)(&data[1]));*/
807
 
            if (machine_read_snapshot(
808
 
                    event_snapshot_path((char *)(&data[1])), 0) < 0
809
 
                && machine_read_snapshot(
810
 
                    event_snapshot_path(event_start_snapshot), 0) < 0)
811
 
            {
812
 
                char *st = lib_stralloc(event_snapshot_path((char *)(&data[1])));
813
 
                ui_error(translate_text(IDGS_ERROR_READING_START_SNAP_TRIED),
814
 
                            st, event_snapshot_path(event_start_snapshot));
815
 
                lib_free(st);
816
 
                ui_display_playback(0, NULL);
817
 
                return;
818
 
            }
819
 
 
820
 
            if (event_list->current->size > strlen((char *)&data[1]) + 2)
821
 
                strncpy(event_version, (char *)(&data[strlen((char *)&data[1]) + 2]), 15);
822
 
 
823
 
            next_current_list();
824
 
            next_alarm_set();
825
 
            break;
826
 
          case EVENT_START_MODE_RESET:
827
 
            /*log_debug("RESET MODE!");*/
828
 
            machine_trigger_reset(MACHINE_RESET_MODE_HARD);
829
 
            if (event_list->current->size > 1)
830
 
                strncpy(event_version, (char *)(&data[1]), 15);
831
 
            next_current_list();
832
 
            /* Alarm will be set if reset is ack'ed.  */
833
 
            playback_reset_ack = 1;
834
 
            break;
 
813
            case EVENT_START_MODE_FILE_SAVE:
 
814
                /*log_debug("READING %s", (char *)(&data[1]));*/
 
815
                if (machine_read_snapshot(
 
816
                        event_snapshot_path((char *)(&data[1])), 0) < 0
 
817
                    && machine_read_snapshot(
 
818
                        event_snapshot_path(event_start_snapshot), 0) < 0) {
 
819
                    char *st = lib_stralloc(event_snapshot_path((char *)(&data[1])));
 
820
                    ui_error(translate_text(IDGS_ERROR_READING_START_SNAP_TRIED),
 
821
                             st, event_snapshot_path(event_start_snapshot));
 
822
                    lib_free(st);
 
823
                    ui_display_playback(0, NULL);
 
824
                    return;
 
825
                }
 
826
 
 
827
                if (event_list->current->size > strlen((char *)&data[1]) + 2) {
 
828
                    strncpy(event_version, (char *)(&data[strlen((char *)&data[1]) + 2]), 15);
 
829
                }
 
830
 
 
831
                next_current_list();
 
832
                next_alarm_set();
 
833
                break;
 
834
            case EVENT_START_MODE_RESET:
 
835
                /*log_debug("RESET MODE!");*/
 
836
                machine_trigger_reset(MACHINE_RESET_MODE_HARD);
 
837
                if (event_list->current->size > 1) {
 
838
                    strncpy(event_version, (char *)(&data[1]), 15);
 
839
                }
 
840
                next_current_list();
 
841
                /* Alarm will be set if reset is ack'ed.  */
 
842
                playback_reset_ack = 1;
 
843
                break;
835
844
        }
836
845
    } else {
837
846
        if (machine_read_snapshot(
856
865
 
857
866
int event_playback_start(void)
858
867
{
859
 
    if (record_active != 0 || playback_active != 0 || autostart_in_progress())
860
 
    {
 
868
    if (record_active != 0 || playback_active != 0 || autostart_in_progress()) {
861
869
        return -1;
862
870
    }
863
871
 
868
876
 
869
877
int event_playback_stop(void)
870
878
{
871
 
    if (playback_active == 0)
 
879
    if (playback_active == 0) {
872
880
        return -1;
 
881
    }
873
882
 
874
883
    playback_active = 0;
875
884
 
886
895
 
887
896
static void event_record_set_milestone_trap(WORD addr, void *data)
888
897
{
889
 
    if (machine_write_snapshot(
890
 
        event_snapshot_path(event_end_snapshot), 1, 1, 1) < 0) {
891
 
            ui_error(translate_text(IDGS_CANT_CREATE_END_SNAP_S),
892
 
                        event_snapshot_path(event_end_snapshot));
 
898
    if (machine_write_snapshot(event_snapshot_path(event_end_snapshot), 1, 1, 1) < 0) {
 
899
        ui_error(translate_text(IDGS_CANT_CREATE_END_SNAP_S),
 
900
                 event_snapshot_path(event_end_snapshot));
893
901
    } else {
894
902
        milestone_timestamp_alarm = next_timestamp_clk;
895
903
        milestone_timestamp = current_timestamp;
901
909
 
902
910
int event_record_set_milestone(void)
903
911
{
904
 
    if (record_active == 0)
 
912
    if (record_active == 0) {
905
913
        return -1;
 
914
    }
906
915
 
907
916
    interrupt_maincpu_trigger_trap(event_record_set_milestone_trap, (void *)0);
908
917
 
918
927
    if (machine_read_snapshot(
919
928
            event_snapshot_path(event_end_snapshot), 1) < 0) {
920
929
        ui_error(translate_text(IDGS_ERROR_READING_END_SNAP_S),
921
 
                    event_snapshot_path(event_end_snapshot));
 
930
                 event_snapshot_path(event_end_snapshot));
922
931
        return;
923
932
    }
924
933
    warp_end_list();
935
944
 
936
945
int event_record_reset_milestone(void)
937
946
{
938
 
    if (playback_active != 0)
 
947
    if (playback_active != 0) {
939
948
        return -1;
 
949
    }
940
950
 
941
 
    if (record_active == 0)
 
951
    if (record_active == 0) {
942
952
        return -1;
 
953
    }
943
954
 
944
955
    interrupt_maincpu_trigger_trap(event_record_reset_milestone_trap, (void *)0);
945
956
 
976
987
    event_list_t *curr;
977
988
    unsigned int num_of_timestamps;
978
989
 
979
 
    if (event_mode == 0)
 
990
    if (event_mode == 0) {
980
991
        return 0;
 
992
    }
981
993
 
982
994
    m = snapshot_module_open(s, "EVENT", &major_version, &minor_version);
983
995
 
984
996
    /* This module is not mandatory.  */
985
 
    if (m == NULL)
 
997
    if (m == NULL) {
986
998
        return 0;
 
999
    }
987
1000
 
988
1001
    destroy_list();
989
1002
    create_list();
998
1011
        CLOCK clk;
999
1012
        BYTE *data = NULL;
1000
1013
 
1001
 
        /* 
 
1014
        /*
1002
1015
            throw away recorded timestamp (recording them  was introduced in
1003
1016
            1.14.x so there might exist history files with TIMESTAMP events)
1004
1017
        */
1017
1030
                snapshot_module_close(m);
1018
1031
                return -1;
1019
1032
            }
1020
 
 
1021
1033
        } while (type == EVENT_TIMESTAMP);
1022
1034
 
1023
1035
        if (size > 0) {
1028
1040
            }
1029
1041
        }
1030
1042
 
1031
 
        if (next_timestamp_clk == CLOCK_MAX) /* if EVENT_INITIAL is missing */
 
1043
        if (next_timestamp_clk == CLOCK_MAX) { /* if EVENT_INITIAL is missing */
1032
1044
            next_timestamp_clk = clk;
 
1045
        }
1033
1046
 
1034
1047
        if (type == EVENT_INITIAL) {
1035
 
            if (data[0] == EVENT_START_MODE_RESET)
 
1048
            if (data[0] == EVENT_START_MODE_RESET) {
1036
1049
                next_timestamp_clk = 0;
1037
 
            else
 
1050
            } else {
1038
1051
                next_timestamp_clk = clk;
 
1052
            }
1039
1053
        } else {
1040
1054
            /* insert timestamps each second */
1041
 
            while (next_timestamp_clk < clk || (type == EVENT_OVERFLOW 
1042
 
                && next_timestamp_clk < maincpu_clk_guard->clk_max_value))
 
1055
            while (next_timestamp_clk < clk || (type == EVENT_OVERFLOW && next_timestamp_clk < maincpu_clk_guard->clk_max_value))
1043
1056
            {
1044
1057
                curr->type = EVENT_TIMESTAMP;
1045
1058
                curr->clk = next_timestamp_clk;
1050
1063
                num_of_timestamps++;
1051
1064
            }
1052
1065
 
1053
 
            if (type == EVENT_OVERFLOW)
1054
 
                    next_timestamp_clk -= clk_guard_clock_sub(maincpu_clk_guard);
 
1066
            if (type == EVENT_OVERFLOW) {
 
1067
                next_timestamp_clk -= clk_guard_clock_sub(maincpu_clk_guard);
 
1068
            }
1055
1069
        }
1056
1070
 
1057
1071
        curr->type = type;
1059
1073
        curr->size = size;
1060
1074
        curr->data = (size > 0 ? data : NULL);
1061
1075
 
1062
 
        if (type == EVENT_LIST_END)
 
1076
        if (type == EVENT_LIST_END) {
1063
1077
            break;
 
1078
        }
1064
1079
 
1065
 
        if (type == EVENT_RESETCPU)
 
1080
        if (type == EVENT_RESETCPU) {
1066
1081
            next_timestamp_clk -= clk;
 
1082
        }
1067
1083
 
1068
1084
        curr->next = lib_calloc(1, sizeof(event_list_t));
1069
1085
        curr = curr->next;
1070
1086
    }
1071
1087
 
1072
 
    if (num_of_timestamps > 0)
 
1088
    if (num_of_timestamps > 0) {
1073
1089
        playback_time = num_of_timestamps - 1;
 
1090
    }
1074
1091
 
1075
1092
    snapshot_module_close(m);
1076
1093
 
1082
1099
    snapshot_module_t *m;
1083
1100
    event_list_t *curr;
1084
1101
 
1085
 
    if (event_mode == 0)
 
1102
    if (event_mode == 0) {
1086
1103
        return 0;
 
1104
    }
1087
1105
 
1088
1106
    m = snapshot_module_create(s, "EVENT", 0, 0);
1089
1107
 
1090
 
    if (m == NULL)
 
1108
    if (m == NULL) {
1091
1109
        return -1;
 
1110
    }
1092
1111
 
1093
1112
    curr = event_list->base;
1094
1113
 
1095
1114
    while (curr != NULL) {
1096
1115
        if (curr->type != EVENT_TIMESTAMP
1097
1116
            && (0
1098
 
            || SMW_DW(m, (DWORD)curr->type) < 0
1099
 
            || SMW_DW(m, (DWORD)curr->clk) < 0
1100
 
            || SMW_DW(m, (DWORD)curr->size) < 0
1101
 
            || SMW_BA(m, curr->data, curr->size) < 0)) {
 
1117
                || SMW_DW(m, (DWORD)curr->type) < 0
 
1118
                || SMW_DW(m, (DWORD)curr->clk) < 0
 
1119
                || SMW_DW(m, (DWORD)curr->size) < 0
 
1120
                || SMW_BA(m, curr->data, curr->size) < 0)) {
1102
1121
            snapshot_module_close(m);
1103
1122
            return -1;
1104
1123
        }
1105
1124
        curr = curr->next;
1106
1125
    }
1107
1126
 
1108
 
    if (snapshot_module_close(m) < 0)
 
1127
    if (snapshot_module_close(m) < 0) {
1109
1128
        return -1;
 
1129
    }
1110
1130
 
1111
1131
    return 0;
1112
1132
}
1130
1150
 
1131
1151
static int set_event_start_snapshot(const char *val, void *param)
1132
1152
{
1133
 
    if (util_string_set(&event_start_snapshot, val))
 
1153
    if (util_string_set(&event_start_snapshot, val)) {
1134
1154
        return 0;
 
1155
    }
1135
1156
 
1136
1157
    return 0;
1137
1158
}
1138
1159
 
1139
1160
static int set_event_end_snapshot(const char *val, void *param)
1140
1161
{
1141
 
    if (util_string_set(&event_end_snapshot, val))
 
1162
    if (util_string_set(&event_end_snapshot, val)) {
1142
1163
        return 0;
 
1164
    }
1143
1165
 
1144
1166
    return 0;
1145
1167
}
1149
1171
    if (mode != EVENT_START_MODE_FILE_SAVE
1150
1172
        && mode != EVENT_START_MODE_FILE_LOAD
1151
1173
        && mode != EVENT_START_MODE_RESET
1152
 
        && mode != EVENT_START_MODE_PLAYBACK)
 
1174
        && mode != EVENT_START_MODE_PLAYBACK) {
1153
1175
        return -1;
 
1176
    }
1154
1177
 
1155
1178
    event_start_mode = mode;
1156
1179
 
1164
1187
}
1165
1188
 
1166
1189
static const resource_string_t resources_string[] = {
1167
 
    { "EventSnapshotDir", 
 
1190
    { "EventSnapshotDir",
1168
1191
      FSDEVICE_DEFAULT_DIR FSDEV_DIR_SEP_STR, RES_EVENT_NO, NULL,
1169
1192
      &event_snapshot_dir, set_event_snapshot_dir, NULL },
1170
1193
    { "EventStartSnapshot", EVENT_START_SNAPSHOT, RES_EVENT_NO, NULL,
1184
1207
 
1185
1208
int event_resources_init(void)
1186
1209
{
1187
 
    if (resources_register_string(resources_string) < 0)
 
1210
    if (resources_register_string(resources_string) < 0) {
1188
1211
        return -1;
 
1212
    }
1189
1213
 
1190
1214
    return resources_register_int(resources_int);
1191
1215
}
1225
1249
 
1226
1250
static void clk_overflow_callback(CLOCK sub, void *data)
1227
1251
{
1228
 
    if (event_record_active())
 
1252
    if (event_record_active()) {
1229
1253
        event_record(EVENT_OVERFLOW, NULL, 0);
 
1254
    }
1230
1255
 
1231
 
    if (next_timestamp_clk)
 
1256
    if (next_timestamp_clk) {
1232
1257
        next_timestamp_clk -= sub;
 
1258
    }
1233
1259
}
1234
1260
 
1235
1261
 
1242
1268
 
1243
1269
    clk_guard_add_callback(maincpu_clk_guard, clk_overflow_callback, NULL);
1244
1270
}
1245