~ubuntu-branches/ubuntu/maverick/vice/maverick

« back to all changes in this revision

Viewing changes to src/event.c

  • Committer: Bazaar Package Importer
  • Author(s): Zed Pobre
  • Date: 2005-02-01 11:30:26 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20050201113026-3eyakzsmmheclvjg
Tags: 1.16-1
* New upstream version
* Fixes crash on 64-bit architectures (closes: #287640)
* x128 working again (closes: #286767)
* Works fine with /dev/dsp in use (not in the main changelog, but tested
  on my local machine as working).  Presumably, this also takes care of
  the issue with dsp being held.  I'm not sure if this is because I'm
  testing it on a 2.6 kernel now -- if you are still having problems
  with /dev/dsp, please reopen the bugs. (closes: #152952, #207942)
* Don't kill Makefile.in on clean

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 *
4
4
 * Written by
5
5
 *  Andreas Boose <viceteam@t-online.de>
6
 
 *
 
6
 *  Andreas Matthies <aDOTmatthiesATgmxDOTnet>
 
7
 *  
7
8
 * This file is part of VICE, the Versatile Commodore Emulator.
8
9
 * See README for copyright notice.
9
10
 *
36
37
#include "clkguard.h"
37
38
#include "cmdline.h"
38
39
#include "datasette.h"
 
40
#include "debug.h"
39
41
#include "event.h"
40
42
#include "interrupt.h"
41
43
#include "joystick.h"
50
52
#include "types.h"
51
53
#include "ui.h"
52
54
#include "util.h"
 
55
#include "version.h"
53
56
 
54
57
 
55
58
#define EVENT_START_SNAPSHOT "start" FSDEV_EXT_SEP_STR "vsf"
66
69
};
67
70
typedef struct event_list_s event_list_t;
68
71
 
 
72
struct event_image_list_s {
 
73
    char *orig_filename;
 
74
    char *mapped_filename;
 
75
    struct event_image_list_s *next;
 
76
};
 
77
typedef struct event_image_list_s event_image_list_t;
69
78
 
70
79
static event_list_t *event_list_base = NULL, *event_list_current;
 
80
static event_image_list_t *event_image_list_base = NULL;
 
81
static int image_number;
71
82
 
72
83
static alarm_t *event_alarm = NULL;
73
84
 
75
86
 
76
87
static unsigned int playback_active = 0, record_active = 0;
77
88
 
 
89
static unsigned int current_timestamp, milestone_timestamp, playback_time;
 
90
static CLOCK next_timestamp_clk;
 
91
static CLOCK milestone_timestamp_alarm;
 
92
 
 
93
/* the VICE version an event history was made with */
 
94
static char event_version[16];
 
95
 
78
96
static char *event_snapshot_dir = NULL;
79
97
static char *event_start_snapshot = NULL;
80
98
static char *event_end_snapshot = NULL;
81
99
static char *event_snapshot_path_str = NULL;
82
100
static unsigned int event_start_mode;
83
101
 
 
102
 
84
103
static char *event_snapshot_path(const char *snapshot_file)
85
104
{
86
105
    if (event_snapshot_path_str != NULL)
92
111
    return event_snapshot_path_str;
93
112
}
94
113
 
 
114
 
 
115
/* searches for a filename in the image list    */
 
116
/* returns 0 if found                           */
 
117
/* returns 1 and appends it if not found        */
 
118
static int event_image_append(const char *filename, char **mapped_name)
 
119
{
 
120
    event_image_list_t *event_image_list_ptr = event_image_list_base;
 
121
 
 
122
    while (event_image_list_ptr->next != NULL) {
 
123
        if (strcmp(filename, event_image_list_ptr->next->orig_filename) == 0) {
 
124
            if (mapped_name != NULL)
 
125
                *mapped_name = lib_stralloc(event_image_list_ptr->next->mapped_filename);
 
126
 
 
127
            return 0;
 
128
        }
 
129
 
 
130
        event_image_list_ptr = event_image_list_ptr->next;
 
131
    }
 
132
 
 
133
    event_image_list_ptr->next = (
 
134
        event_image_list_t *) lib_calloc(1, sizeof(event_image_list_t));
 
135
 
 
136
    event_image_list_ptr = event_image_list_ptr->next;
 
137
    event_image_list_ptr->next = NULL;
 
138
    event_image_list_ptr->orig_filename = lib_stralloc(filename);
 
139
    event_image_list_ptr->mapped_filename = NULL;
 
140
    if (mapped_name != NULL)
 
141
        event_image_list_ptr->mapped_filename = lib_stralloc(*mapped_name);
 
142
 
 
143
    return 1;
 
144
}
 
145
 
 
146
 
 
147
void event_record_attach_image(unsigned int unit, const char *filename,
 
148
                        unsigned int read_only)
 
149
{
 
150
    char *event_data;
 
151
    unsigned int size;
 
152
 
 
153
    if (record_active == 0)
 
154
        return;
 
155
 
 
156
    event_list_current->type = EVENT_ATTACHIMAGE;
 
157
    event_list_current->clk = maincpu_clk;
 
158
    event_list_current->next
 
159
        = (event_list_t *)lib_calloc(1, sizeof(event_list_t));
 
160
 
 
161
    size = strlen(filename) + 3;
 
162
 
 
163
    event_data = lib_malloc(size);
 
164
    event_data[0] = unit;
 
165
    event_data[1] = read_only;
 
166
    strcpy(&event_data[2], filename);
 
167
 
 
168
    if (event_image_append(filename, NULL) == 1) {
 
169
        FILE *fd;
 
170
        size_t file_len = 0;
 
171
        
 
172
        fd = fopen(filename, MODE_READ);
 
173
 
 
174
        if (fd != NULL) {
 
175
            file_len = util_file_length(fd);
 
176
            event_data = lib_realloc(event_data, size + file_len);
 
177
 
 
178
            if (fread(&event_data[size], file_len, 1, fd) != 1)
 
179
                log_error(event_log, "Cannot load image file %s", filename);
 
180
 
 
181
            fclose(fd);
 
182
        } else {
 
183
            log_error(event_log, "Cannot open image file %s", filename);
 
184
        }
 
185
        size += file_len;
 
186
    }
 
187
 
 
188
    event_list_current->size = size;
 
189
    event_list_current->data = event_data;
 
190
    event_list_current = event_list_current->next;
 
191
}
 
192
 
 
193
 
 
194
static void event_playback_attach_image(void *data, unsigned int size)
 
195
{
 
196
    unsigned int unit, read_only;
 
197
    char *orig_filename, *filename;
 
198
    size_t file_len;
 
199
    char str[16];
 
200
 
 
201
    unit = (unsigned int)((char*)data)[0];
 
202
    read_only = (unsigned int)((char*)data)[1];
 
203
    orig_filename = &((char*)data)[2];
 
204
    file_len  = size - strlen(orig_filename) - 3;
 
205
 
 
206
    if (file_len > 0) {
 
207
        FILE *fd;
 
208
 
 
209
        sprintf(str, "img%04d", image_number++);
 
210
        filename = util_concat(event_snapshot_dir, str, FSDEV_EXT_SEP_STR,
 
211
                                util_get_extension(orig_filename), NULL);
 
212
 
 
213
        fd = fopen(filename, MODE_WRITE);
 
214
        if (fd == NULL) {
 
215
            ui_error("Cannot create image file %s", filename);
 
216
            goto error;
 
217
        }
 
218
 
 
219
        if (fwrite((char*)data + strlen(orig_filename) + 3, file_len, 1, fd) != 1) {
 
220
            ui_error("Cannot write image file %s", filename);
 
221
            goto error;
 
222
        }
 
223
 
 
224
        fclose(fd);
 
225
        event_image_append(orig_filename, &filename);
 
226
    } else {
 
227
        if (event_image_append(orig_filename, &filename) != 0) {
 
228
            ui_error("Cannot find mapped name for %s", orig_filename);
 
229
            return;
 
230
        }
 
231
    }
 
232
 
 
233
    /* now filename holds the name to attach    */
 
234
    /* FIXME: read_only isn't handled for tape  */
 
235
    if (unit == 1) {
 
236
        tape_image_event_playback(unit, filename);
 
237
    } else {
 
238
        resources_set_sprintf("AttachDevice%dReadonly", 
 
239
                                (resource_value_t) read_only, unit);
 
240
        file_system_event_playback(unit, filename);
 
241
    }
 
242
    
 
243
error:
 
244
    lib_free(filename);
 
245
}
 
246
 
 
247
 
95
248
void event_record(unsigned int type, void *data, unsigned int size)
96
249
{
97
250
    void *event_data = NULL;
102
255
    /*log_debug("EVENT RECORD %i CLK %i", type, maincpu_clk);*/
103
256
 
104
257
    switch (type) {
 
258
      case EVENT_RESETCPU:
 
259
        next_timestamp_clk -= maincpu_clk;
105
260
      case EVENT_KEYBOARD_MATRIX:
106
261
      case EVENT_KEYBOARD_RESTORE:
107
262
      case EVENT_JOYSTICK_VALUE:
108
263
      case EVENT_DATASETTE:
109
264
      case EVENT_ATTACHDISK:
110
265
      case EVENT_ATTACHTAPE:
111
 
      case EVENT_RESET:
112
266
      case EVENT_INITIAL:
113
267
        event_data = lib_malloc(size);
114
268
        memcpy(event_data, data, size);
115
269
        break;
116
270
      case EVENT_LIST_END:
 
271
      case EVENT_OVERFLOW:
117
272
        break;
118
273
      default:
119
274
        /*log_error(event_log, "Unknow event type %i.", type);*/
151
306
{
152
307
    alarm_unset(event_alarm);
153
308
 
 
309
    /* when recording set a timestamp */
 
310
    if (record_active) {
 
311
        ui_display_event_time(current_timestamp++, 0);
 
312
        next_timestamp_clk = next_timestamp_clk 
 
313
                                + machine_get_cycles_per_second();
 
314
        alarm_set(event_alarm, next_timestamp_clk);
 
315
        return;
 
316
    }
 
317
 
154
318
    /*log_debug("EVENT PLAYBACK %i CLK %i", event_list_current->type,
155
319
              event_list_current->clk);*/
156
320
 
167
331
      case EVENT_DATASETTE:
168
332
        datasette_event_playback(offset, event_list_current->data);
169
333
        break;
 
334
      case EVENT_ATTACHIMAGE:
 
335
        event_playback_attach_image(event_list_current->data,
 
336
                                    event_list_current->size);
 
337
        break;
170
338
      case EVENT_ATTACHDISK:
171
 
        file_system_event_playback(offset, event_list_current->data);
172
 
        break;
173
339
      case EVENT_ATTACHTAPE:
174
 
        tape_image_event_playback(offset, event_list_current->data);
 
340
        {
 
341
            /* old style attach via absolute filename and detach*/
 
342
            unsigned int unit;
 
343
            const char *filename;
 
344
 
 
345
            unit = (unsigned int)((char*)event_list_current->data)[0];
 
346
            filename = &((char*)event_list_current->data)[1];
 
347
            
 
348
            if (unit == 1)
 
349
                tape_image_event_playback(unit, filename);
 
350
            else
 
351
                file_system_event_playback(unit, filename);
 
352
        }
175
353
        break;
176
 
      case EVENT_RESET:
 
354
      case EVENT_RESETCPU:
177
355
        machine_reset_event_playback(offset, event_list_current->data);
178
356
        break;
 
357
      case EVENT_TIMESTAMP:
 
358
        ui_display_event_time(current_timestamp++, playback_time);
 
359
        break;
179
360
      case EVENT_LIST_END:
180
361
        event_playback_stop();
181
362
        break;
 
363
      case EVENT_OVERFLOW:
 
364
        break;
182
365
      default:
183
366
        log_error(event_log, "Unknow event type %i.", event_list_current->type);
184
367
    }
185
368
 
186
369
    if (event_list_current->type != EVENT_LIST_END
187
 
        && event_list_current->type != EVENT_RESET) {
 
370
        && event_list_current->type != EVENT_RESETCPU) {
188
371
        next_current_list();
189
372
        next_alarm_set();
190
373
    }
196
379
{
197
380
    event_list_base = (event_list_t *)lib_calloc(1, sizeof(event_list_t));
198
381
    event_list_current = event_list_base;
 
382
 
 
383
    event_image_list_base = 
 
384
        (event_image_list_t *)lib_calloc(1, sizeof(event_image_list_t));
 
385
    image_number = 0;
199
386
}
200
387
 
201
 
static void destroy_list(void)
 
388
 
 
389
static void cut_list(event_list_t *cut_base)
202
390
{
203
391
    event_list_t *c1, *c2;
204
392
 
205
 
    c1 = event_list_base;
 
393
    c1 = cut_base;
206
394
 
207
395
    while (c1 != NULL) {
208
396
        c2 = c1->next;
210
398
        lib_free(c1);
211
399
        c1 = c2;
212
400
    }
 
401
}
 
402
 
 
403
static void destroy_image_list(void)
 
404
{
 
405
    event_image_list_t *d1, *d2;
 
406
 
 
407
    d1 = event_image_list_base;
 
408
 
 
409
    while (d1 != NULL) {
 
410
        d2 = d1->next;
 
411
        lib_free(d1->orig_filename);
 
412
        if (d1->mapped_filename != NULL)
 
413
            lib_free(d1->mapped_filename);
 
414
        lib_free(d1);
 
415
        d1 = d2;
 
416
    }
 
417
 
 
418
    event_image_list_base = NULL;
 
419
}
 
420
 
 
421
static void destroy_list(void)
 
422
{
 
423
    cut_list(event_list_base);
 
424
    destroy_image_list();
213
425
 
214
426
    event_list_base = NULL;
215
427
    event_list_current = NULL;
221
433
 
222
434
    curr = event_list_base;
223
435
 
224
 
    while (curr->type != EVENT_LIST_END)
 
436
    while (curr->type != EVENT_LIST_END) {
 
437
 
 
438
        if (curr->type == EVENT_ATTACHIMAGE)
 
439
            event_image_append(&((char*)curr->data)[2], NULL);
 
440
 
225
441
        curr = curr->next;
 
442
    }
226
443
 
227
444
    memset(curr, 0, sizeof(event_list_t));
228
445
    event_list_current = curr;
229
446
}
230
 
 
231
447
/*-----------------------------------------------------------------------*/
 
448
/* writes or replaces version string in the initial event                */
 
449
static void event_write_version(void)
 
450
{
 
451
    BYTE *new_data;
 
452
    BYTE *data;
 
453
    unsigned int ver_idx;
 
454
 
 
455
    if (event_list_base->type != EVENT_INITIAL) {
 
456
        /* EVENT_INITIAL is missing (bug in 1.14.xx); fix it */
 
457
        event_list_t *new_event;
 
458
 
 
459
        new_event = (event_list_t *)lib_calloc(1, sizeof(event_list_t));
 
460
        new_event->clk = event_list_base->clk;
 
461
        new_event->size = strlen(event_start_snapshot) + 2;
 
462
        new_event->type = EVENT_INITIAL;
 
463
        data = lib_malloc(new_event->size);
 
464
        data[0] = EVENT_START_MODE_FILE_SAVE;
 
465
        strcpy((char *)&data[1], event_start_snapshot);
 
466
        new_event->data = data;
 
467
        new_event->next = event_list_base;
 
468
        event_list_base = new_event;
 
469
    }
 
470
 
 
471
    data = event_list_base->data;
 
472
 
 
473
    ver_idx = 1;
 
474
    if (data[0] == EVENT_START_MODE_FILE_SAVE)
 
475
        ver_idx += strlen((char *)&data[1]) + 1;
 
476
 
 
477
    event_list_base->size = ver_idx + strlen(VERSION) + 1;
 
478
    new_data = lib_malloc(event_list_base->size);
 
479
 
 
480
    memcpy(new_data, data, ver_idx);
 
481
 
 
482
    strcpy((char *)&new_data[ver_idx], VERSION);
 
483
 
 
484
    event_list_base->data = new_data;
 
485
    lib_free(data);
 
486
}
232
487
 
233
488
static void event_initial_write(void)
234
489
{
251
506
 
252
507
    event_record(EVENT_INITIAL, (void *)data, (unsigned int)len);
253
508
 
 
509
    event_write_version();
 
510
 
254
511
    lib_free(data);
255
512
}
256
513
 
262
519
      case EVENT_START_MODE_FILE_SAVE:
263
520
        if (machine_write_snapshot(event_snapshot_path(event_start_snapshot),
264
521
                                    1, 1, 0) < 0) {
265
 
            ui_error(_("Could not create start snapshot file."));
 
522
            ui_error(_("Could not create start snapshot file %s."), 
 
523
                        event_snapshot_path(event_start_snapshot));
 
524
            ui_display_recording(0);
266
525
            return;
267
526
        }
268
527
        destroy_list();
269
528
        create_list();
270
529
        record_active = 1;
271
530
        event_initial_write();
 
531
        next_timestamp_clk = maincpu_clk;
 
532
        current_timestamp = 0;
272
533
        break;
273
534
      case EVENT_START_MODE_FILE_LOAD:
274
535
        if (machine_read_snapshot(
275
536
                event_snapshot_path(event_end_snapshot), 1) < 0) {
276
 
            ui_error(_("Error reading start snapshot file."));
 
537
            ui_error(_("Error reading end snapshot file %s."),
 
538
                        event_snapshot_path(event_end_snapshot));
277
539
            return;
278
540
        }
279
541
        warp_end_list();
280
542
        record_active = 1;
 
543
        next_timestamp_clk = maincpu_clk;
 
544
        current_timestamp = playback_time;
281
545
        break;
282
546
      case EVENT_START_MODE_RESET:
283
547
        machine_trigger_reset(MACHINE_RESET_MODE_HARD);
285
549
        create_list();
286
550
        record_active = 1;
287
551
        event_initial_write();
 
552
        next_timestamp_clk = 0;
 
553
        current_timestamp = 0;
 
554
        break;
 
555
      case EVENT_START_MODE_PLAYBACK:
 
556
        cut_list(event_list_current->next);
 
557
        destroy_image_list();
 
558
        event_write_version();
 
559
        record_active = 1;
 
560
        next_timestamp_clk = maincpu_clk;
288
561
        break;
289
562
      default:
290
563
        log_error(event_log, "Unknown event start mode %i", event_start_mode); 
291
564
        return;
292
565
    }
 
566
 
 
567
#ifdef  DEBUG
 
568
    debug_start_recording();
 
569
#endif
 
570
 
 
571
    /* use alarm for timestamps */
 
572
    milestone_timestamp_alarm = 0;
 
573
    alarm_set(event_alarm, next_timestamp_clk);
293
574
}
294
575
 
295
576
int event_record_start(void)
296
577
{
297
 
    if (playback_active != 0)
298
 
        return -1;
 
578
    if (event_start_mode == EVENT_START_MODE_PLAYBACK) {
 
579
        if (playback_active != 0)
 
580
            event_playback_stop();
 
581
        else
 
582
            return -1;
 
583
    }
299
584
 
300
585
    if (record_active != 0)
301
586
        return -1;
302
587
 
 
588
 
303
589
    interrupt_maincpu_trigger_trap(event_record_start_trap, (void *)0);
304
590
 
305
591
    ui_display_recording(1);
311
597
{
312
598
    if (machine_write_snapshot(
313
599
            event_snapshot_path(event_end_snapshot), 1, 1, 1) < 0) {
314
 
        ui_error(_("Could not create end snapshot file."));
 
600
        ui_error(_("Could not create end snapshot file %s."),
 
601
                    event_snapshot_path(event_end_snapshot));
315
602
        return;
316
603
    }
317
604
    record_active = 0;
 
605
 
 
606
#ifdef  DEBUG
 
607
    debug_stop_recording();
 
608
#endif
318
609
}
319
610
 
320
611
int event_record_stop(void)
328
619
 
329
620
    ui_display_recording(0);
330
621
 
 
622
    alarm_unset(event_alarm);
 
623
 
331
624
    return 0;
332
625
}
333
626
 
335
628
 
336
629
static unsigned int playback_reset_ack = 0;
337
630
 
338
 
void event_playback_reset_ack(void)
 
631
void event_reset_ack(void)
339
632
{
340
633
    if (playback_reset_ack) {
341
634
        playback_reset_ack = 0;
343
636
    }
344
637
 
345
638
    if (event_list_current 
346
 
        && event_list_current->type == EVENT_RESET)
 
639
        && event_list_current->type == EVENT_RESETCPU)
347
640
    {
348
641
        next_current_list();
349
642
        next_alarm_set();
350
643
    }
 
644
 
 
645
    /* timestamp alarm needs to be set */
 
646
    if (record_active)
 
647
        alarm_set(event_alarm, next_timestamp_clk);
351
648
}
352
649
 
353
650
static void event_playback_start_trap(WORD addr, void *data)
355
652
    snapshot_t *s;
356
653
    BYTE minor, major;
357
654
 
 
655
    event_version[0] = 0;
 
656
 
358
657
    s = snapshot_open(
359
658
        event_snapshot_path(event_end_snapshot), &major, &minor, machine_name);
360
659
 
361
660
    if (s == NULL) {
362
 
        ui_error(_("Could not open end snapshot file."));
 
661
        ui_error(_("Could not open end snapshot file %s."), 
 
662
                    event_snapshot_path(event_end_snapshot));
 
663
        ui_display_playback(0, NULL);
363
664
        return;
364
665
    }
365
666
 
369
670
    if (event_snapshot_read_module(s, 1) < 0) {
370
671
        snapshot_close(s);
371
672
        ui_error(_("Could not find event section in end snapshot file."));
 
673
        ui_display_playback(0, NULL);
372
674
        return;
373
675
    }
374
676
 
382
684
          case EVENT_START_MODE_FILE_SAVE:
383
685
            /*log_debug("READING %s", (char *)(&data[1]));*/
384
686
            if (machine_read_snapshot(
385
 
                    event_snapshot_path((char *)(&data[1])), 0) < 0) {
386
 
                ui_error(_("Error reading start snapshot file."));
 
687
                    event_snapshot_path((char *)(&data[1])), 0) < 0
 
688
                && machine_read_snapshot(
 
689
                    event_snapshot_path(event_start_snapshot), 0) < 0)
 
690
            {
 
691
                char *st = lib_stralloc(event_snapshot_path((char *)(&data[1])));
 
692
                ui_error(_("Error reading start snapshot file. Tried %s and %s"),
 
693
                            st, event_snapshot_path(event_start_snapshot));
 
694
                lib_free(st);
 
695
                ui_display_playback(0, NULL);
387
696
                return;
388
697
            }
 
698
 
 
699
            if (event_list_current->size > strlen(&data[1]) + 2)
 
700
                strncpy(event_version, (char *)(&data[strlen(&data[1]) + 2]), 15);
 
701
 
389
702
            next_current_list();
390
703
            next_alarm_set();
391
704
            break;
392
705
          case EVENT_START_MODE_RESET:
393
706
            /*log_debug("RESET MODE!");*/
394
707
            machine_trigger_reset(MACHINE_RESET_MODE_HARD);
 
708
            if (event_list_current->size > 1)
 
709
                strncpy(event_version, (char *)(&data[1]), 15);
395
710
            next_current_list();
396
711
            /* Alarm will be set if reset is ack'ed.  */
397
712
            playback_reset_ack = 1;
401
716
        if (machine_read_snapshot(
402
717
                event_snapshot_path(event_start_snapshot), 0) < 0) {
403
718
            ui_error(_("Error reading start snapshot file."));
 
719
            ui_display_playback(0, NULL);
404
720
            return;
405
721
        }
406
722
        next_alarm_set();
407
723
    }
408
724
 
409
725
    playback_active = 1;
 
726
    current_timestamp = 0;
 
727
 
 
728
    ui_display_playback(1, event_version);
 
729
 
 
730
#ifdef  DEBUG
 
731
    debug_start_playback();
 
732
#endif
410
733
}
411
734
 
412
735
 
420
743
 
421
744
    interrupt_maincpu_trigger_trap(event_playback_start_trap, (void *)0);
422
745
 
423
 
    ui_display_playback(1);
424
 
 
425
746
    return 0;
426
747
}
427
748
 
434
755
 
435
756
    alarm_unset(event_alarm);
436
757
 
437
 
    ui_display_playback(0);
 
758
    ui_display_playback(0, NULL);
 
759
 
 
760
#ifdef  DEBUG
 
761
    debug_stop_playback();
 
762
#endif
438
763
 
439
764
    return 0;
440
765
}
442
767
static void event_record_set_milestone_trap(WORD addr, void *data)
443
768
{
444
769
    if (machine_write_snapshot(
445
 
            event_snapshot_path(event_end_snapshot), 1, 1, 1) < 0)
446
 
        ui_error(_("Could not create end snapshot file."));
 
770
        event_snapshot_path(event_end_snapshot), 1, 1, 1) < 0) {
 
771
            ui_error(_("Could not create end snapshot file %s."),
 
772
                        event_snapshot_path(event_end_snapshot));
 
773
    } else {
 
774
        milestone_timestamp_alarm = next_timestamp_clk;
 
775
        milestone_timestamp = current_timestamp;
 
776
#ifdef  DEBUG
 
777
        debug_set_milestone();
 
778
#endif
 
779
    }
447
780
}
448
781
 
449
782
int event_record_set_milestone(void)
464
797
 
465
798
    if (machine_read_snapshot(
466
799
            event_snapshot_path(event_end_snapshot), 1) < 0) {
467
 
        ui_error(_("Error reading end snapshot file."));
 
800
        ui_error(_("Error reading end snapshot file %s."),
 
801
                    event_snapshot_path(event_end_snapshot));
468
802
        return;
469
803
    }
470
804
    warp_end_list();
471
805
    record_active = 1;
 
806
    if (milestone_timestamp_alarm > 0) {
 
807
        alarm_set(event_alarm, milestone_timestamp_alarm);
 
808
        next_timestamp_clk = milestone_timestamp_alarm;
 
809
        current_timestamp = milestone_timestamp;
 
810
    }
 
811
#ifdef  DEBUG
 
812
    debug_reset_milestone();
 
813
#endif
472
814
}
473
815
 
474
816
int event_record_reset_milestone(void)
503
845
    snapshot_module_t *m;
504
846
    BYTE major_version, minor_version;
505
847
    event_list_t *curr;
 
848
    unsigned int num_of_timestamps;
506
849
 
507
850
    if (event_mode == 0)
508
851
        return 0;
517
860
    create_list();
518
861
 
519
862
    curr = event_list_base;
 
863
    num_of_timestamps = 0;
 
864
    playback_time = 0;
 
865
    next_timestamp_clk = CLOCK_MAX;
520
866
 
521
867
    while (1) {
522
 
        if (SMR_DW_INT(m, (int*)&(curr->type)) < 0) {
523
 
            snapshot_module_close(m);
524
 
            return -1;
525
 
        }
526
 
 
527
 
        if (SMR_DW(m, &(curr->clk)) < 0) {
528
 
            snapshot_module_close(m);
529
 
            return -1;
530
 
        }
531
 
 
532
 
        if (SMR_DW_INT(m, (int*)&(curr->size)) < 0) {
533
 
            snapshot_module_close(m);
534
 
            return -1;
535
 
        }
536
 
 
537
 
        if (curr->size > 0) {
538
 
            curr->data = lib_malloc(curr->size);
539
 
            if (SMR_BA(m, curr->data, curr->size) < 0) {
540
 
                snapshot_module_close(m);
541
 
                return -1;
542
 
            }
543
 
        }
544
 
 
545
 
        if (curr->type == EVENT_LIST_END)
 
868
        unsigned int type, size;
 
869
        CLOCK clk;
 
870
        BYTE *data = NULL;
 
871
 
 
872
        /* 
 
873
            throw away recorded timestamp (recording them  was introduced in
 
874
            1.14.x so there might exist history files with TIMESTAMP events)
 
875
        */
 
876
        do {
 
877
            if (SMR_DW_INT(m, (int*)&(type)) < 0) {
 
878
                snapshot_module_close(m);
 
879
                return -1;
 
880
            }
 
881
 
 
882
            if (SMR_DW(m, &(clk)) < 0) {
 
883
                snapshot_module_close(m);
 
884
                return -1;
 
885
            }
 
886
 
 
887
            if (SMR_DW_INT(m, (int*)&(size)) < 0) {
 
888
                snapshot_module_close(m);
 
889
                return -1;
 
890
            }
 
891
 
 
892
        } while (type == EVENT_TIMESTAMP);
 
893
 
 
894
        if (size > 0) {
 
895
            data = lib_malloc(size);
 
896
            if (SMR_BA(m, data, size) < 0) {
 
897
                snapshot_module_close(m);
 
898
                return -1;
 
899
            }
 
900
        }
 
901
 
 
902
        if (next_timestamp_clk == CLOCK_MAX) /* if EVENT_INITIAL is missing */
 
903
            next_timestamp_clk = clk;
 
904
 
 
905
        if (type == EVENT_INITIAL) {
 
906
            if (data[0] == EVENT_START_MODE_RESET)
 
907
                next_timestamp_clk = 0;
 
908
            else
 
909
                next_timestamp_clk = clk;
 
910
        } else {
 
911
            /* insert timestamps each second */
 
912
            while (next_timestamp_clk < clk || (type == EVENT_OVERFLOW 
 
913
                && next_timestamp_clk < maincpu_clk_guard->clk_max_value))
 
914
            {
 
915
                curr->type = EVENT_TIMESTAMP;
 
916
                curr->clk = next_timestamp_clk;
 
917
                curr->size = 0;
 
918
                curr->next = (event_list_t *)lib_calloc(1, sizeof(event_list_t));
 
919
                curr = curr->next;
 
920
                next_timestamp_clk += machine_get_cycles_per_second();
 
921
                num_of_timestamps++;
 
922
            }
 
923
 
 
924
            if (type == EVENT_OVERFLOW)
 
925
                    next_timestamp_clk -= clk_guard_clock_sub(maincpu_clk_guard);
 
926
        }
 
927
 
 
928
        curr->type = type;
 
929
        curr->clk = clk;
 
930
        curr->size = size;
 
931
        curr->data = (size > 0 ? data : NULL);
 
932
 
 
933
        if (type == EVENT_LIST_END)
546
934
            break;
547
935
 
 
936
        if (type == EVENT_RESETCPU)
 
937
            next_timestamp_clk -= clk;
 
938
 
548
939
        curr->next = (event_list_t *)lib_calloc(1, sizeof(event_list_t));
549
940
        curr = curr->next;
550
941
    }
551
942
 
 
943
    if (num_of_timestamps > 0)
 
944
        playback_time = num_of_timestamps - 1;
 
945
 
552
946
    snapshot_module_close(m);
553
947
 
554
948
    return 0;
570
964
    curr = event_list_base;
571
965
 
572
966
    while (curr != NULL) {
573
 
        if (0
 
967
        if (curr->type != EVENT_TIMESTAMP
 
968
            && (0
574
969
            || SMW_DW(m, (DWORD)curr->type) < 0
575
970
            || SMW_DW(m, (DWORD)curr->clk) < 0
576
971
            || SMW_DW(m, (DWORD)curr->size) < 0
577
 
            || SMW_BA(m, curr->data, curr->size) < 0) {
 
972
            || SMW_BA(m, curr->data, curr->size) < 0)) {
578
973
            snapshot_module_close(m);
579
974
            return -1;
580
975
        }
629
1024
 
630
1025
    if (mode != EVENT_START_MODE_FILE_SAVE
631
1026
        && mode != EVENT_START_MODE_FILE_LOAD
632
 
        && mode != EVENT_START_MODE_RESET)
 
1027
        && mode != EVENT_START_MODE_RESET
 
1028
        && mode != EVENT_START_MODE_PLAYBACK)
633
1029
        return -1;
634
1030
 
635
1031
    event_start_mode = mode;
686
1082
 
687
1083
/*-----------------------------------------------------------------------*/
688
1084
 
 
1085
static void clk_overflow_callback(CLOCK sub, void *data)
 
1086
{
 
1087
    if (event_record_active())
 
1088
        event_record(EVENT_OVERFLOW, NULL, 0);
 
1089
 
 
1090
    if (next_timestamp_clk)
 
1091
        next_timestamp_clk -= sub;
 
1092
}
 
1093
 
 
1094
 
689
1095
void event_init(void)
690
1096
{
691
1097
    event_log = log_open("Event");
692
1098
 
693
1099
    event_alarm = alarm_new(maincpu_alarm_context, "Event",
694
1100
                            event_alarm_handler, NULL);
 
1101
 
 
1102
    clk_guard_add_callback(maincpu_clk_guard, clk_overflow_callback, NULL);
695
1103
}
696
1104