99
99
static char *event_snapshot_path(const char *snapshot_file)
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);
105
104
return event_snapshot_path_str;
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)
115
113
event_image_list_t *event_image_list_ptr = event_image_list_base;
172
172
if (event_image_append(filename, NULL, 0) == 1) {
174
174
size_t file_len = 0;
176
176
fd = fopen(filename, MODE_READ);
178
178
if (fd != NULL) {
179
179
file_len = util_file_length(fd);
180
180
event_data = lib_realloc(event_data, size + file_len);
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);
228
230
orig_filename = (char *) data + 3 + sizeof(long);
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);
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);
243
file_len = size - strlen(orig_filename) - 3;
245
file_len = size - strlen(orig_filename) - 3;
245
247
if (file_len > 0) {
248
250
fd = archdep_mkstemp_fd(&filename, MODE_WRITE);
250
252
if (fd == NULL) {
251
253
ui_error(translate_text(IDGS_CANNOT_CREATE_IMAGE), filename);
288
290
/*log_debug("EVENT RECORD %i CLK %i", type, maincpu_clk);*/
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:
302
case EVENT_SYNC_TEST:
304
event_data = lib_malloc(size);
305
memcpy(event_data, data, size);
309
case EVENT_KEYBOARD_CLEAR:
312
/*log_error(event_log, "Unknow event type %i.", type);*/
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:
304
case EVENT_SYNC_TEST:
306
event_data = lib_malloc(size);
307
memcpy(event_data, data, size);
311
case EVENT_KEYBOARD_CLEAR:
314
/*log_error(event_log, "Unknow event type %i.", type);*/
316
318
list->current->type = type;
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);
364
367
event_list_current->clk);*/
366
369
switch (event_list->current->type) {
367
case EVENT_KEYBOARD_MATRIX:
368
keyboard_event_playback(offset, event_list->current->data);
370
case EVENT_KEYBOARD_RESTORE:
371
keyboard_restore_event_playback(offset, event_list->current->data);
373
case EVENT_JOYSTICK_VALUE:
374
joystick_event_playback(offset, event_list->current->data);
376
case EVENT_DATASETTE:
377
datasette_event_playback(offset, event_list->current->data);
379
case EVENT_ATTACHIMAGE:
380
event_playback_attach_image(event_list->current->data,
381
event_list->current->size);
383
case EVENT_ATTACHDISK:
384
case EVENT_ATTACHTAPE:
386
/* old style attach via absolute filename and detach*/
388
const char *filename;
390
unit = (unsigned int)((char*)event_list->current->data)[0];
391
filename = &((char*)event_list->current->data)[1];
394
tape_image_event_playback(unit, filename);
396
file_system_event_playback(unit, filename);
400
machine_reset_event_playback(offset, event_list->current->data);
402
case EVENT_TIMESTAMP:
403
ui_display_event_time(current_timestamp++, playback_time);
406
event_playback_stop();
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);
373
case EVENT_KEYBOARD_RESTORE:
374
keyboard_restore_event_playback(offset, event_list->current->data);
376
case EVENT_JOYSTICK_VALUE:
377
joystick_event_playback(offset, event_list->current->data);
379
case EVENT_DATASETTE:
380
datasette_event_playback(offset, event_list->current->data);
382
case EVENT_ATTACHIMAGE:
383
event_playback_attach_image(event_list->current->data,
384
event_list->current->size);
386
case EVENT_ATTACHDISK:
387
case EVENT_ATTACHTAPE:
389
/* old style attach via absolute filename and detach*/
391
const char *filename;
393
unit = (unsigned int)((char*)event_list->current->data)[0];
394
filename = &((char*)event_list->current->data)[1];
397
tape_image_event_playback(unit, filename);
399
file_system_event_playback(unit, filename);
404
machine_reset_event_playback(offset, event_list->current->data);
406
case EVENT_TIMESTAMP:
407
ui_display_event_time(current_timestamp++, playback_time);
410
event_playback_stop();
415
log_error(event_log, "Unknow event type %i.", event_list->current->type);
414
418
if (event_list->current->type != EVENT_LIST_END
426
430
while (current->type != EVENT_LIST_END) {
427
431
switch (current->type) {
428
case EVENT_SYNC_TEST:
430
case EVENT_KEYBOARD_DELAY:
431
keyboard_register_delay(*(unsigned int*)current->data);
433
case EVENT_KEYBOARD_MATRIX:
434
keyboard_event_delayed_playback(current->data);
436
case EVENT_KEYBOARD_RESTORE:
437
keyboard_restore_event_playback(0, current->data);
439
case EVENT_KEYBOARD_CLEAR:
440
keyboard_register_clear();
442
case EVENT_JOYSTICK_DELAY:
443
joystick_register_delay(*(unsigned int*)current->data);
445
case EVENT_JOYSTICK_VALUE:
446
joystick_event_delayed_playback(current->data);
448
case EVENT_DATASETTE:
449
datasette_event_playback(0, current->data);
452
machine_reset_event_playback(0, current->data);
454
case EVENT_ATTACHDISK:
455
case EVENT_ATTACHTAPE:
457
/* in fact this is only for detaching */
460
unit = (unsigned int)((char*)current->data)[0];
463
tape_image_event_playback(1, NULL);
465
file_system_event_playback(unit, NULL);
468
case EVENT_ATTACHIMAGE:
469
event_playback_attach_image(current->data, current->size);
472
resources_set_value_event(current->data, current->size);
475
log_error(event_log, "Unknow event type %i.", current->type);
432
case EVENT_SYNC_TEST:
434
case EVENT_KEYBOARD_DELAY:
435
keyboard_register_delay(*(unsigned int*)current->data);
437
case EVENT_KEYBOARD_MATRIX:
438
keyboard_event_delayed_playback(current->data);
440
case EVENT_KEYBOARD_RESTORE:
441
keyboard_restore_event_playback(0, current->data);
443
case EVENT_KEYBOARD_CLEAR:
444
keyboard_register_clear();
446
case EVENT_JOYSTICK_DELAY:
447
joystick_register_delay(*(unsigned int*)current->data);
449
case EVENT_JOYSTICK_VALUE:
450
joystick_event_delayed_playback(current->data);
452
case EVENT_DATASETTE:
453
datasette_event_playback(0, current->data);
456
machine_reset_event_playback(0, current->data);
458
case EVENT_ATTACHDISK:
459
case EVENT_ATTACHTAPE:
461
/* in fact this is only for detaching */
464
unit = (unsigned int)((char*)current->data)[0];
467
tape_image_event_playback(1, NULL);
469
file_system_event_playback(unit, NULL);
473
case EVENT_ATTACHIMAGE:
474
event_playback_attach_image(current->data, current->size);
477
resources_set_value_event(current->data, current->size);
480
log_error(event_log, "Unknow event type %i.", current->type);
477
482
current = current->next;
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);
615
case EVENT_START_MODE_RESET:
617
data = lib_malloc(len);
618
data[0] = EVENT_START_MODE_RESET;
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);
622
case EVENT_START_MODE_RESET:
624
data = lib_malloc(len);
625
data[0] = EVENT_START_MODE_RESET;
622
629
event_record(EVENT_INITIAL, (void *)data, (unsigned int)len);
631
638
static void event_record_start_trap(WORD addr, void *data)
633
640
switch (event_start_mode) {
634
case EVENT_START_MODE_FILE_SAVE:
635
if (machine_write_snapshot(event_snapshot_path(event_start_snapshot),
637
ui_error(translate_text(IDGS_CANT_CREATE_START_SNAP_S),
638
event_snapshot_path(event_start_snapshot));
639
ui_display_recording(0);
645
event_initial_write();
646
next_timestamp_clk = maincpu_clk;
647
current_timestamp = 0;
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));
658
next_timestamp_clk = maincpu_clk;
659
current_timestamp = playback_time;
661
case EVENT_START_MODE_RESET:
662
machine_trigger_reset(MACHINE_RESET_MODE_HARD);
666
event_initial_write();
667
next_timestamp_clk = 0;
668
current_timestamp = 0;
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();
677
next_timestamp_clk = maincpu_clk;
680
log_error(event_log, "Unknown event start mode %i", event_start_mode);
641
case EVENT_START_MODE_FILE_SAVE:
642
if (machine_write_snapshot(event_snapshot_path(event_start_snapshot),
644
ui_error(translate_text(IDGS_CANT_CREATE_START_SNAP_S),
645
event_snapshot_path(event_start_snapshot));
646
ui_display_recording(0);
652
event_initial_write();
653
next_timestamp_clk = maincpu_clk;
654
current_timestamp = 0;
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));
665
next_timestamp_clk = maincpu_clk;
666
current_timestamp = playback_time;
668
case EVENT_START_MODE_RESET:
669
machine_trigger_reset(MACHINE_RESET_MODE_HARD);
673
event_initial_write();
674
next_timestamp_clk = 0;
675
current_timestamp = 0;
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();
684
next_timestamp_clk = maincpu_clk;
687
log_error(event_log, "Unknown event start mode %i", event_start_mode);
749
757
void event_reset_ack(void)
751
if (event_list == NULL)
759
if (event_list == NULL) {
754
763
if (playback_reset_ack) {
755
764
playback_reset_ack = 0;
756
765
next_alarm_set();
759
if (event_list->current
760
&& event_list->current->type == EVENT_RESETCPU)
768
if (event_list->current && event_list->current->type == EVENT_RESETCPU) {
762
769
next_current_list();
763
770
next_alarm_set();
766
773
/* timestamp alarm needs to be set */
768
775
alarm_set(event_alarm, next_timestamp_clk);
771
779
static void event_playback_start_trap(WORD addr, void *data)
779
787
event_snapshot_path(event_end_snapshot), &major, &minor, machine_name);
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);
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)
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));
816
ui_display_playback(0, NULL);
820
if (event_list->current->size > strlen((char *)&data[1]) + 2)
821
strncpy(event_version, (char *)(&data[strlen((char *)&data[1]) + 2]), 15);
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);
832
/* Alarm will be set if reset is ack'ed. */
833
playback_reset_ack = 1;
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));
823
ui_display_playback(0, NULL);
827
if (event_list->current->size > strlen((char *)&data[1]) + 2) {
828
strncpy(event_version, (char *)(&data[strlen((char *)&data[1]) + 2]), 15);
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);
841
/* Alarm will be set if reset is ack'ed. */
842
playback_reset_ack = 1;
837
846
if (machine_read_snapshot(
887
896
static void event_record_set_milestone_trap(WORD addr, void *data)
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));
894
902
milestone_timestamp_alarm = next_timestamp_clk;
895
903
milestone_timestamp = current_timestamp;
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;
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;
1038
1051
next_timestamp_clk = clk;
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))
1044
1057
curr->type = EVENT_TIMESTAMP;
1045
1058
curr->clk = next_timestamp_clk;
1059
1073
curr->size = size;
1060
1074
curr->data = (size > 0 ? data : NULL);
1062
if (type == EVENT_LIST_END)
1076
if (type == EVENT_LIST_END) {
1065
if (type == EVENT_RESETCPU)
1080
if (type == EVENT_RESETCPU) {
1066
1081
next_timestamp_clk -= clk;
1068
1084
curr->next = lib_calloc(1, sizeof(event_list_t));
1069
1085
curr = curr->next;
1072
if (num_of_timestamps > 0)
1088
if (num_of_timestamps > 0) {
1073
1089
playback_time = num_of_timestamps - 1;
1075
1092
snapshot_module_close(m);
1082
1099
snapshot_module_t *m;
1083
1100
event_list_t *curr;
1085
if (event_mode == 0)
1102
if (event_mode == 0) {
1088
1106
m = snapshot_module_create(s, "EVENT", 0, 0);
1093
1112
curr = event_list->base;
1095
1114
while (curr != NULL) {
1096
1115
if (curr->type != EVENT_TIMESTAMP
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);
1105
1124
curr = curr->next;
1108
if (snapshot_module_close(m) < 0)
1127
if (snapshot_module_close(m) < 0) {
1131
1151
static int set_event_start_snapshot(const char *val, void *param)
1133
if (util_string_set(&event_start_snapshot, val))
1153
if (util_string_set(&event_start_snapshot, val)) {
1139
1160
static int set_event_end_snapshot(const char *val, void *param)
1141
if (util_string_set(&event_end_snapshot, val))
1162
if (util_string_set(&event_end_snapshot, val)) {
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,
1226
1250
static void clk_overflow_callback(CLOCK sub, void *data)
1228
if (event_record_active())
1252
if (event_record_active()) {
1229
1253
event_record(EVENT_OVERFLOW, NULL, 0);
1231
if (next_timestamp_clk)
1256
if (next_timestamp_clk) {
1232
1257
next_timestamp_clk -= sub;