~ubuntu-branches/ubuntu/vivid/vice/vivid-proposed

« back to all changes in this revision

Viewing changes to src/autostart.c

  • Committer: Package Import Robot
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2014-10-19 08:05:48 UTC
  • mfrom: (17.1.7 sid)
  • Revision ID: package-import@ubuntu.com-20141019080548-mb75mi9i7d3k7ui3
Tags: 2.4.dfsg+2.4.9-2
Re-try to fix build race with building in po/ first.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * autostart.c - Automatic image loading and starting.
3
 
 *
4
 
 * Written by
5
 
 *  Teemu Rantanen <tvr@cs.hut.fi>
6
 
 *  Ettore Perazzoli <ettore@comm2000.it>
7
 
 *  Andr� Fachat <a.fachat@physik.tu-chemnitz.de>
8
 
 *  Andreas Boose <viceteam@t-online.de>
9
 
 *  Thomas Bretz <tbretz@ph.tum.de>
10
 
 *
11
 
 * This file is part of VICE, the Versatile Commodore Emulator.
12
 
 * See README for copyright notice.
13
 
 *
14
 
 *  This program is free software; you can redistribute it and/or modify
15
 
 *  it under the terms of the GNU General Public License as published by
16
 
 *  the Free Software Foundation; either version 2 of the License, or
17
 
 *  (at your option) any later version.
18
 
 *
19
 
 *  This program is distributed in the hope that it will be useful,
20
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 
 *  GNU General Public License for more details.
23
 
 *
24
 
 *  You should have received a copy of the GNU General Public License
25
 
 *  along with this program; if not, write to the Free Software
26
 
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27
 
 *  02111-1307  USA.
28
 
 *
29
 
 */
30
 
 
31
 
/* #define DEBUG_AUTOSTART */
32
 
 
33
 
#include "vice.h"
34
 
 
35
 
#include <stdio.h>
36
 
#include <stdlib.h>
37
 
#include <string.h>
38
 
 
39
 
#include "archapi.h"
40
 
#include "archdep.h"
41
 
#include "autostart.h"
42
 
#include "autostart-prg.h"
43
 
#include "attach.h"
44
 
#include "charset.h"
45
 
#include "cmdline.h"
46
 
#include "datasette.h"
47
 
#include "drive.h"
48
 
#include "fileio.h"
49
 
#include "fsdevice.h"
50
 
#include "imagecontents.h"
51
 
#include "tapecontents.h"
52
 
#include "diskcontents.h"
53
 
#include "interrupt.h"
54
 
#include "kbdbuf.h"
55
 
#include "lib.h"
56
 
#include "log.h"
57
 
#include "machine-bus.h"
58
 
#include "machine.h"
59
 
#include "maincpu.h"
60
 
#include "mem.h"
61
 
#include "monitor.h"
62
 
#include "network.h"
63
 
#include "resources.h"
64
 
#include "snapshot.h"
65
 
#include "tape.h"
66
 
#include "translate.h"
67
 
#include "types.h"
68
 
#include "uiapi.h"
69
 
#include "util.h"
70
 
#include "vdrive.h"
71
 
#include "vdrive-bam.h"
72
 
#include "vice-event.h"
73
 
 
74
 
#ifdef DEBUG_AUTOSTART
75
 
#define DBG(_x_)        log_debug _x_
76
 
#else
77
 
#define DBG(_x_)
78
 
#endif
79
 
 
80
 
static void autostart_done(void);
81
 
static void autostart_finish(void);
82
 
 
83
 
/* Kernal addresses.  Set by `autostart_init()'.  */
84
 
 
85
 
static WORD blnsw;           /* Cursor Blink enable: 0 = Flash Cursor */
86
 
static int pnt;                 /* Pointer: Current Screen Line Address */
87
 
static int pntr;                /* Cursor Column on Current Line */
88
 
static int lnmx;                /* Physical Screen Line Length */
89
 
 
90
 
/* Current state of the autostart routine.  */
91
 
static enum {
92
 
    AUTOSTART_NONE,
93
 
    AUTOSTART_ERROR,
94
 
    AUTOSTART_HASTAPE,
95
 
    AUTOSTART_PRESSPLAYONTAPE,
96
 
    AUTOSTART_LOADINGTAPE,
97
 
    AUTOSTART_HASDISK,
98
 
    AUTOSTART_LOADINGDISK,
99
 
    AUTOSTART_HASSNAPSHOT,
100
 
    AUTOSTART_WAITLOADREADY,
101
 
    AUTOSTART_WAITLOADING,
102
 
    AUTOSTART_WAITSEARCHINGFOR,
103
 
    AUTOSTART_INJECT,
104
 
    AUTOSTART_DONE
105
 
} autostartmode = AUTOSTART_NONE;
106
 
 
107
 
#define AUTOSTART_WAIT_BLINK   0
108
 
#define AUTOSTART_NOWAIT_BLINK 1
109
 
 
110
 
/* Log descriptor.  */
111
 
static log_t autostart_log = LOG_ERR;
112
 
 
113
 
/* Flag: was true drive emulation turned on when we started booting the disk
114
 
   image?  */
115
 
static int orig_drive_true_emulation_state = -1;
116
 
 
117
 
/* Flag: warp mode state before booting */
118
 
static int orig_warp_mode = -1;
119
 
 
120
 
/* PETSCII name of the program to load. NULL if default */
121
 
static char *autostart_program_name = NULL;
122
 
 
123
 
/* Minimum number of cycles before we feed BASIC with commands.  */
124
 
static CLOCK min_cycles;
125
 
static CLOCK autostart_initial_delay_cycles;
126
 
 
127
 
/* Flag: Do we want to switch true drive emulation on/off during autostart?
128
 
 * Normally, this is the same as handle_drive_true_emulation_by_machine;
129
 
 * however, the user can override this decision by specifying
130
 
 * -autostart-no-true-drive-emulation
131
 
 */
132
 
static int handle_drive_true_emulation_overridden;
133
 
 
134
 
/* Flag: Does the machine want us to switch true drive emulation on/off during autostart? */
135
 
static int handle_drive_true_emulation_by_machine;
136
 
 
137
 
/* Flag: autostart is initialized.  */
138
 
static int autostart_enabled = 0;
139
 
 
140
 
/* Flag: Autostart the file or just load it?  */
141
 
static unsigned int autostart_run_mode;
142
 
 
143
 
/* Flag: maincpu_clk isn't resetted yet */
144
 
static int autostart_wait_for_reset;
145
 
 
146
 
/* Flag: load stage after LOADING enters ROM area */
147
 
static int entered_rom = 0;
148
 
 
149
 
/* Flag: trap monitor after done */
150
 
static int trigger_monitor = 0;
151
 
 
152
 
int autostart_ignore_reset = 0; /* FIXME: only used by datasette.c, does it really have to be global? */
153
 
 
154
 
/* additional random delay of up to 10 frames */
155
 
#define AUTOSTART_RAND() (1 + (int)(((float)machine_get_cycles_per_frame()) * 10.0f * rand() / (RAND_MAX + 1.0)))
156
 
 
157
 
/* flag for special case handling of C128 80 columns mode */
158
 
static int c128_column4080_key;
159
 
 
160
 
/* ------------------------------------------------------------------------- */
161
 
 
162
 
static int autostart_basic_load = 0;
163
 
 
164
 
static int AutostartRunWithColon = 0;
165
 
 
166
 
static int AutostartHandleTrueDriveEmulation = 0;
167
 
 
168
 
static int AutostartWarp = 0;
169
 
 
170
 
static int AutostartDelay = 0;
171
 
static int AutostartDelayRandom = 0;
172
 
 
173
 
static int AutostartPrgMode = AUTOSTART_PRG_MODE_VFS;
174
 
 
175
 
static char *AutostartPrgDiskImage = NULL;
176
 
 
177
 
static const char * const AutostartRunCommandsAvailable[] = {
178
 
    "RUN\r", "RUN:\r"
179
 
};
180
 
 
181
 
static const char * AutostartRunCommand = NULL;
182
 
 
183
 
static void set_handle_true_drive_emulation_state(void)
184
 
{
185
 
    handle_drive_true_emulation_overridden =
186
 
        AutostartHandleTrueDriveEmulation ?
187
 
        handle_drive_true_emulation_by_machine : 0;
188
 
}
189
 
 
190
 
/*! \internal \brief set if autostart should use LOAD ... ,1 */
191
 
static int set_autostart_basic_load(int val, void *param)
192
 
{
193
 
    autostart_basic_load = val ? 1 : 0;
194
 
 
195
 
    return 0;
196
 
}
197
 
 
198
 
/*! \internal \brief set if autostart should execute with a colon or not
199
 
 
200
 
 \param val
201
 
   if 0, the "RUN" command at the end of autostart is executed without
202
 
   a colon; else, it will be executed with a colon.
203
 
 
204
 
 \param param
205
 
   unused
206
 
 
207
 
 \return
208
 
   0 on success. else -1.
209
 
*/
210
 
static int set_autostart_run_with_colon(int val, void *param)
211
 
{
212
 
    AutostartRunWithColon = val ? 1 : 0;
213
 
 
214
 
    AutostartRunCommand = AutostartRunCommandsAvailable[AutostartRunWithColon];
215
 
 
216
 
    return 0;
217
 
}
218
 
 
219
 
/*! \internal \brief set if autostart should handle TDE or not
220
 
 
221
 
 \param val
222
 
   if 0, autostart does not handle TDE even if the machine says it can
223
 
   handle it.
224
 
 
225
 
 \param param
226
 
   unused
227
 
 
228
 
 \return
229
 
   0 on success. else -1.
230
 
*/
231
 
static int set_autostart_handle_tde(int val, void *param)
232
 
{
233
 
    AutostartHandleTrueDriveEmulation = val ? 1 : 0;
234
 
 
235
 
    set_handle_true_drive_emulation_state();
236
 
 
237
 
    return 0;
238
 
}
239
 
 
240
 
/*! \internal \brief set if autostart should enable warp mode */
241
 
static int set_autostart_warp(int val, void *param)
242
 
{
243
 
    AutostartWarp = val ? 1 : 0;
244
 
 
245
 
    return 0;
246
 
}
247
 
 
248
 
/*! \internal \brief set initial autostart delay. 0 means default. */
249
 
static int set_autostart_delay(int val, void *param)
250
 
{
251
 
    if ((val < 0) || (val > 1000)) {
252
 
        val = 0;
253
 
    }
254
 
    AutostartDelay = val;
255
 
    return 0;
256
 
}
257
 
 
258
 
/*! \internal \brief set initial autostart random delay. 0 means off, 1 means on. */
259
 
static int set_autostart_delayrandom(int val, void *param)
260
 
{
261
 
    AutostartDelayRandom = val ? 1 : 0;
262
 
    return 0;
263
 
}
264
 
 
265
 
/*! \internal \brief set autostart prg mode */
266
 
static int set_autostart_prg_mode(int val, void *param)
267
 
{
268
 
    AutostartPrgMode = val;
269
 
    if ((val < 0) || (val > AUTOSTART_PRG_MODE_LAST)) {
270
 
        val = 0;
271
 
    }
272
 
 
273
 
    return 0;
274
 
}
275
 
 
276
 
/*! \internal \brief set disk image name of autostart prg mode */
277
 
 
278
 
static int set_autostart_prg_disk_image(const char *val, void *param)
279
 
{
280
 
    if (util_string_set(&AutostartPrgDiskImage, val)) {
281
 
        return 0;
282
 
    }
283
 
 
284
 
    return 0;
285
 
}
286
 
 
287
 
/*! \brief string resources used by autostart */
288
 
static resource_string_t resources_string[] = {
289
 
    { "AutostartPrgDiskImage", NULL, RES_EVENT_NO, NULL,
290
 
      &AutostartPrgDiskImage, set_autostart_prg_disk_image, NULL },
291
 
    { NULL }
292
 
};
293
 
 
294
 
/*! \brief integer resources used by autostart */
295
 
static const resource_int_t resources_int[] = {
296
 
    { "AutostartBasicLoad", 0, RES_EVENT_NO, (resource_value_t)0,
297
 
      &autostart_basic_load, set_autostart_basic_load, NULL },
298
 
    { "AutostartRunWithColon", 0, RES_EVENT_NO, (resource_value_t)0,
299
 
      &AutostartRunWithColon, set_autostart_run_with_colon, NULL },
300
 
    { "AutostartHandleTrueDriveEmulation", 0, RES_EVENT_NO, (resource_value_t)0,
301
 
      &AutostartHandleTrueDriveEmulation, set_autostart_handle_tde, NULL },
302
 
    { "AutostartWarp", 1, RES_EVENT_NO, (resource_value_t)0,
303
 
      &AutostartWarp, set_autostart_warp, NULL },
304
 
    { "AutostartPrgMode", 0, RES_EVENT_NO, (resource_value_t)0,
305
 
      &AutostartPrgMode, set_autostart_prg_mode, NULL },
306
 
    { "AutostartDelay", 0, RES_EVENT_NO, (resource_value_t)0,
307
 
      &AutostartDelay, set_autostart_delay, NULL },
308
 
    { "AutostartDelayRandom", 1, RES_EVENT_NO, (resource_value_t)0,
309
 
      &AutostartDelayRandom, set_autostart_delayrandom, NULL },
310
 
    { NULL }
311
 
};
312
 
 
313
 
/*! \brief initialize the resources
314
 
 \return
315
 
   0 on success, else -1.
316
 
 
317
 
 \remark
318
 
   Registers the integer resources
319
 
*/
320
 
int autostart_resources_init(void)
321
 
{
322
 
    resources_string[0].factory_value = archdep_default_autostart_disk_image_file_name();
323
 
 
324
 
    if (resources_register_string(resources_string) < 0) {
325
 
        return -1;
326
 
    }
327
 
 
328
 
    return resources_register_int(resources_int);
329
 
}
330
 
 
331
 
void autostart_resources_shutdown(void)
332
 
{
333
 
    lib_free(AutostartPrgDiskImage);
334
 
    lib_free(resources_string[0].factory_value);
335
 
}
336
 
 
337
 
/* ------------------------------------------------------------------------- */
338
 
 
339
 
static const cmdline_option_t cmdline_options[] =
340
 
{
341
 
    { "-basicload", SET_RESOURCE, 0,
342
 
      NULL, NULL, "AutostartBasicLoad", (resource_value_t)1,
343
 
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
344
 
      IDCLS_UNUSED, IDCLS_AUTOSTART_LOAD_TO_BASIC_START,
345
 
      NULL, NULL },
346
 
    { "+basicload", SET_RESOURCE, 0,
347
 
      NULL, NULL, "AutostartBasicLoad", (resource_value_t)0,
348
 
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
349
 
      IDCLS_UNUSED, IDCLS_AUTOSTART_LOAD_WITH_1,
350
 
      NULL, NULL },
351
 
    { "-autostartwithcolon", SET_RESOURCE, 0,
352
 
      NULL, NULL, "AutostartRunWithColon", (resource_value_t)1,
353
 
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
354
 
      IDCLS_UNUSED, IDCLS_ENABLE_AUTOSTARTWITHCOLON,
355
 
      NULL, NULL },
356
 
    { "+autostartwithcolon", SET_RESOURCE, 0,
357
 
      NULL, NULL, "AutostartRunWithColon", (resource_value_t)0,
358
 
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
359
 
      IDCLS_UNUSED, IDCLS_DISABLE_AUTOSTARTWITHCOLON,
360
 
      NULL, NULL },
361
 
    { "-autostart-handle-tde", SET_RESOURCE, 0,
362
 
      NULL, NULL, "AutostartHandleTrueDriveEmulation", (resource_value_t)1,
363
 
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
364
 
      IDCLS_UNUSED, IDCLS_ENABLE_AUTOSTART_HANDLE_TDE,
365
 
      NULL, NULL },
366
 
    { "+autostart-handle-tde", SET_RESOURCE, 0,
367
 
      NULL, NULL, "AutostartHandleTrueDriveEmulation", (resource_value_t)0,
368
 
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
369
 
      IDCLS_UNUSED, IDCLS_DISABLE_AUTOSTART_HANDLE_TDE,
370
 
      NULL, NULL },
371
 
    { "-autostart-warp", SET_RESOURCE, 0,
372
 
      NULL, NULL, "AutostartWarp", (resource_value_t)1,
373
 
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
374
 
      IDCLS_UNUSED, IDCLS_ENABLE_WARP_MODE_AUTOSTART,
375
 
      NULL, NULL },
376
 
    { "+autostart-warp", SET_RESOURCE, 0,
377
 
      NULL, NULL, "AutostartWarp", (resource_value_t)0,
378
 
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
379
 
      IDCLS_UNUSED, IDCLS_DISABLE_WARP_MODE_AUTOSTART,
380
 
      NULL, NULL },
381
 
    { "-autostartprgmode", SET_RESOURCE, 1,
382
 
      NULL, NULL, "AutostartPrgMode", NULL,
383
 
      USE_PARAM_ID, USE_DESCRIPTION_ID,
384
 
      IDCLS_UNUSED, IDCLS_SET_AUTOSTART_MODE_FOR_PRG,
385
 
      NULL, NULL },
386
 
    { "-autostartprgdiskimage", SET_RESOURCE, 1,
387
 
      NULL, NULL, "AutostartPrgDiskImage", NULL,
388
 
      USE_PARAM_ID, USE_DESCRIPTION_ID,
389
 
      IDCLS_UNUSED, IDCLS_SET_DISK_IMAGE_FOR_AUTOSTART_PRG,
390
 
      NULL, NULL },
391
 
    { "-autostart-delay", SET_RESOURCE, 1,
392
 
      NULL, NULL, "AutostartDelay", NULL,
393
 
      USE_PARAM_ID, USE_DESCRIPTION_ID,
394
 
      IDCLS_UNUSED, IDCLS_SET_AUTOSTART_DELAY,
395
 
      NULL, NULL },
396
 
    { "-autostart-delay-random", SET_RESOURCE, 0,
397
 
      NULL, NULL, "AutostartDelayRandom", (resource_value_t)1,
398
 
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
399
 
      IDCLS_UNUSED, IDCLS_ENABLE_AUTOSTART_RANDOM_DELAY,
400
 
      NULL, NULL },
401
 
    { "+autostart-delay-random", SET_RESOURCE, 0,
402
 
      NULL, NULL, "AutostartDelayRandom", (resource_value_t)0,
403
 
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
404
 
      IDCLS_UNUSED, IDCLS_DISABLE_AUTOSTART_RANDOM_DELAY,
405
 
      NULL, NULL },
406
 
    { NULL }
407
 
};
408
 
 
409
 
/*! \brief initialize the command-line options
410
 
 
411
 
 \return
412
 
   0 on success, else -1.
413
 
 
414
 
 \remark
415
 
   Registers the command-line options
416
 
*/
417
 
int autostart_cmdline_options_init(void)
418
 
{
419
 
    return cmdline_register_options(cmdline_options);
420
 
}
421
 
 
422
 
/* ------------------------------------------------------------------------- */
423
 
 
424
 
/* Deallocate program name if we have one */
425
 
static void deallocate_program_name(void)
426
 
{
427
 
    lib_free(autostart_program_name);
428
 
    autostart_program_name = NULL;
429
 
}
430
 
 
431
 
static enum { YES, NO, NOT_YET } check(const char *s, unsigned int blink_mode)
432
 
{
433
 
    int screen_addr, line_length, cursor_column, addr, i;
434
 
 
435
 
    screen_addr = (int)(mem_read((WORD)(pnt)) | (mem_read((WORD)(pnt + 1)) << 8));
436
 
    cursor_column = (int)mem_read((WORD)(pntr));
437
 
 
438
 
    line_length = (int)(lnmx < 0 ? -lnmx : mem_read((WORD)(lnmx)) + 1);
439
 
 
440
 
    DBG(("check(%s) addr:%04x column:%d, linelen:%d blnsw:%04x(%d)", s, screen_addr, cursor_column, line_length, blnsw, mem_read(blnsw)));
441
 
 
442
 
    if (!kbdbuf_is_empty()) {
443
 
        return NOT_YET;
444
 
    }
445
 
 
446
 
    if (blink_mode == AUTOSTART_WAIT_BLINK && cursor_column != 0) {
447
 
        return NOT_YET;
448
 
    }
449
 
 
450
 
    if (blink_mode == AUTOSTART_WAIT_BLINK && blnsw != 0 && mem_read(blnsw) != 0) {
451
 
        return NOT_YET;
452
 
    }
453
 
 
454
 
    if (blink_mode == AUTOSTART_WAIT_BLINK) {
455
 
        addr = screen_addr - line_length;
456
 
    } else {
457
 
        addr = screen_addr;
458
 
    }
459
 
 
460
 
    for (i = 0; s[i] != '\0'; i++) {
461
 
        if (mem_read((WORD)(addr + i)) != s[i] % 64) {
462
 
            if (mem_read((WORD)(addr + i)) != (BYTE)32) {
463
 
                return NO;
464
 
            }
465
 
            return NOT_YET;
466
 
        }
467
 
    }
468
 
    return YES;
469
 
}
470
 
 
471
 
static void set_true_drive_emulation_mode(int on)
472
 
{
473
 
    resources_set_int("DriveTrueEmulation", on);
474
 
    ui_update_menus();
475
 
}
476
 
 
477
 
static int get_true_drive_emulation_state(void)
478
 
{
479
 
    int value;
480
 
 
481
 
    if (resources_get_int("DriveTrueEmulation", &value) < 0) {
482
 
        return 0;
483
 
    }
484
 
 
485
 
    return value;
486
 
}
487
 
 
488
 
static void set_warp_mode(int on)
489
 
{
490
 
    resources_set_int("WarpMode", on);
491
 
    ui_update_menus();
492
 
}
493
 
 
494
 
static int get_warp_mode(void)
495
 
{
496
 
    int value;
497
 
 
498
 
    if (resources_get_int("WarpMode", &value) < 0) {
499
 
        return 0;
500
 
    }
501
 
 
502
 
    return value;
503
 
}
504
 
 
505
 
static void enable_warp_if_requested(void)
506
 
{
507
 
    /* enable warp mode? */
508
 
    if (AutostartWarp) {
509
 
        orig_warp_mode = get_warp_mode();
510
 
        if (!orig_warp_mode) {
511
 
            log_message(autostart_log, "Turning Warp mode on");
512
 
            set_warp_mode(1);
513
 
        }
514
 
    }
515
 
}
516
 
 
517
 
static void disable_warp_if_was_requested(void)
518
 
{
519
 
    /* disable warp mode */
520
 
    if (AutostartWarp) {
521
 
        if (!orig_warp_mode) {
522
 
            log_message(autostart_log, "Turning Warp mode off");
523
 
            set_warp_mode(0);
524
 
        }
525
 
    }
526
 
}
527
 
 
528
 
static void check_rom_area(void)
529
 
{
530
 
    /* enter ROM ? */
531
 
    if (!entered_rom) {
532
 
        if (reg_pc >= 0xe000) {
533
 
            log_message(autostart_log, "Entered ROM at $%04x", reg_pc);
534
 
            entered_rom = 1;
535
 
        }
536
 
    } else {
537
 
        /* special case for auto-starters: ROM left. We also consider
538
 
         * BASIC area to be ROM, because it's responsible for writing "READY."
539
 
         */
540
 
        if (machine_addr_in_ram(reg_pc)) {
541
 
            log_message(autostart_log, "Left ROM for $%04x", reg_pc);
542
 
            disable_warp_if_was_requested();
543
 
            autostart_done();
544
 
        }
545
 
    }
546
 
}
547
 
 
548
 
/* ------------------------------------------------------------------------- */
549
 
 
550
 
static void load_snapshot_trap(WORD unused_addr, void *unused_data)
551
 
{
552
 
    if (autostart_program_name
553
 
        && machine_read_snapshot((char *)autostart_program_name, 0) < 0) {
554
 
        ui_error(translate_text(IDGS_CANNOT_LOAD_SNAPSHOT_FILE));
555
 
    }
556
 
 
557
 
    ui_update_menus();
558
 
}
559
 
 
560
 
/* ------------------------------------------------------------------------- */
561
 
 
562
 
/* Reset autostart.  */
563
 
void autostart_reinit(CLOCK _min_cycles, int _handle_drive_true_emulation,
564
 
                      int _blnsw, int _pnt, int _pntr, int _lnmx)
565
 
{
566
 
    blnsw = (WORD)(_blnsw);
567
 
    pnt = _pnt;
568
 
    pntr = _pntr;
569
 
    lnmx = _lnmx;
570
 
 
571
 
    min_cycles = _min_cycles;
572
 
 
573
 
    handle_drive_true_emulation_by_machine = _handle_drive_true_emulation;
574
 
 
575
 
    set_handle_true_drive_emulation_state();
576
 
 
577
 
    if (_min_cycles) {
578
 
        autostart_enabled = 1;
579
 
    } else {
580
 
        autostart_enabled = 0;
581
 
    }
582
 
}
583
 
 
584
 
/* Initialize autostart.  */
585
 
int autostart_init(CLOCK _min_cycles, int handle_drive_true_emulation,
586
 
                   int blnsw, int pnt, int pntr, int lnmx)
587
 
{
588
 
    autostart_prg_init();
589
 
 
590
 
    autostart_reinit(_min_cycles, handle_drive_true_emulation, blnsw, pnt,
591
 
                     pntr, lnmx);
592
 
 
593
 
    if (autostart_log == LOG_ERR) {
594
 
        autostart_log = log_open("AUTOSTART");
595
 
        if (autostart_log == LOG_ERR) {
596
 
            return -1;
597
 
        }
598
 
    }
599
 
 
600
 
    return 0;
601
 
}
602
 
 
603
 
void autostart_disable(void)
604
 
{
605
 
    if (!autostart_enabled) {
606
 
        return;
607
 
    }
608
 
 
609
 
    autostartmode = AUTOSTART_ERROR;
610
 
    trigger_monitor = 0;
611
 
    deallocate_program_name();
612
 
    log_error(autostart_log, "Turned off.");
613
 
}
614
 
 
615
 
/* Control if the monitor will be triggered after an autostart */
616
 
void autostart_trigger_monitor(int enable)
617
 
{
618
 
    trigger_monitor = enable;
619
 
}
620
 
 
621
 
/* this is called after successful loading */
622
 
static void autostart_finish(void)
623
 
{
624
 
    if (autostart_run_mode == AUTOSTART_MODE_RUN) {
625
 
        log_message(autostart_log, "Starting program.");
626
 
        if ((machine_class == VICE_MACHINE_C128) && (c128_column4080_key == 0)) {
627
 
            kbdbuf_feed("GRAPHIC5:");
628
 
        }
629
 
        kbdbuf_feed(AutostartRunCommand);
630
 
    } else {
631
 
        log_message(autostart_log, "Program loaded.");
632
 
        if ((machine_class == VICE_MACHINE_C128) && (c128_column4080_key == 0)) {
633
 
            kbdbuf_feed("GRAPHIC5\x0d");
634
 
        }
635
 
    }
636
 
}
637
 
 
638
 
/* This is called if all steps of an autostart operation were passed successfully */
639
 
static void autostart_done(void)
640
 
{
641
 
    autostartmode = AUTOSTART_DONE;
642
 
 
643
 
    if (machine_class == VICE_MACHINE_C128) {
644
 
        /* restore original state of key */
645
 
        resources_set_int("40/80ColumnKey", c128_column4080_key);
646
 
    }
647
 
 
648
 
    /* Enter monitor after done */
649
 
    if (trigger_monitor) {
650
 
        trigger_monitor = 0;
651
 
        monitor_startup_trap();
652
 
        log_message(autostart_log, "Done. Returning to Monitor.");
653
 
    } else {
654
 
        log_message(autostart_log, "Done.");
655
 
    }
656
 
}
657
 
 
658
 
/* ------------------------------------------------------------------------- */
659
 
 
660
 
/* This function is called by the `serialreceivebyte()' trap as soon as EOF
661
 
   is reached.  */
662
 
static void disk_eof_callback(void)
663
 
{
664
 
    if (handle_drive_true_emulation_overridden) {
665
 
        BYTE id[2], *buffer = NULL;
666
 
        unsigned int track, sector;
667
 
        /* FIXME: shouldnt this loop over all drives? */
668
 
        if (orig_drive_true_emulation_state) {
669
 
            log_message(autostart_log, "Turning true drive emulation on.");
670
 
            if (vdrive_bam_get_disk_id(8, id) == 0) {
671
 
                vdrive_get_last_read(&track, &sector, &buffer);
672
 
            }
673
 
        }
674
 
        set_true_drive_emulation_mode(orig_drive_true_emulation_state);
675
 
        if (orig_drive_true_emulation_state) {
676
 
            if (buffer) {
677
 
                log_message(autostart_log, "Restoring true drive state of drive 8.");
678
 
                drive_set_disk_memory(id, track, sector, drive_context[0]);
679
 
                drive_set_last_read(track, sector, buffer, drive_context[0]);
680
 
            } else {
681
 
                log_message(autostart_log, "No Disk Image in drive 8.");
682
 
            }
683
 
        }
684
 
    }
685
 
 
686
 
    if (autostartmode != AUTOSTART_NONE) {
687
 
        autostart_finish();
688
 
    }
689
 
 
690
 
    autostart_done();
691
 
 
692
 
    machine_bus_eof_callback_set(NULL);
693
 
 
694
 
    disable_warp_if_was_requested();
695
 
}
696
 
 
697
 
/* This function is called by the `serialattention()' trap before
698
 
   returning.  */
699
 
static void disk_attention_callback(void)
700
 
{
701
 
    machine_bus_attention_callback_set(NULL);
702
 
 
703
 
    /* Next step is waiting for end of loading, to turn true drive emulation
704
 
       on.  */
705
 
    machine_bus_eof_callback_set(disk_eof_callback);
706
 
}
707
 
 
708
 
/* ------------------------------------------------------------------------- */
709
 
 
710
 
static void advance_hastape(void)
711
 
{
712
 
    char *tmp;
713
 
 
714
 
    switch (check("READY.", AUTOSTART_WAIT_BLINK)) {
715
 
        case YES:
716
 
            log_message(autostart_log, "Loading file.");
717
 
            if (autostart_program_name) {
718
 
                tmp = util_concat("LOAD\"", autostart_program_name, "\":\r", NULL);
719
 
                kbdbuf_feed(tmp);
720
 
                lib_free(tmp);
721
 
            } else {
722
 
                kbdbuf_feed("LOAD:\r");
723
 
            }
724
 
            autostartmode = AUTOSTART_PRESSPLAYONTAPE;
725
 
            entered_rom = 0;
726
 
            deallocate_program_name();
727
 
            break;
728
 
        case NO:
729
 
            disable_warp_if_was_requested();
730
 
            autostart_disable();
731
 
            break;
732
 
        case NOT_YET:
733
 
            break;
734
 
    }
735
 
}
736
 
 
737
 
static void advance_pressplayontape(void)
738
 
{
739
 
    switch (check("PRESS PLAY ON TAPE", AUTOSTART_NOWAIT_BLINK)) {
740
 
        case YES:
741
 
            autostartmode = AUTOSTART_LOADINGTAPE;
742
 
            datasette_control(DATASETTE_CONTROL_START);
743
 
            break;
744
 
        case NO:
745
 
            disable_warp_if_was_requested();
746
 
            autostart_disable();
747
 
            break;
748
 
        case NOT_YET:
749
 
            break;
750
 
    }
751
 
}
752
 
 
753
 
static void advance_loadingtape(void)
754
 
{
755
 
    switch (check("READY.", AUTOSTART_WAIT_BLINK)) {
756
 
        case YES:
757
 
            disable_warp_if_was_requested();
758
 
            autostart_finish();
759
 
            autostart_done();
760
 
            break;
761
 
        case NO:
762
 
            disable_warp_if_was_requested();
763
 
            autostart_disable();
764
 
            break;
765
 
        case NOT_YET:
766
 
            /* leave autostart and disable warp if ROM area was left */
767
 
            check_rom_area();
768
 
            break;
769
 
    }
770
 
}
771
 
 
772
 
static void advance_hasdisk(void)
773
 
{
774
 
    char *tmp;
775
 
    int traps;
776
 
 
777
 
    switch (check("READY.", AUTOSTART_WAIT_BLINK)) {
778
 
        case YES:
779
 
            if (autostart_program_name) {
780
 
                log_message(autostart_log, "Loading program '%s'",
781
 
                            autostart_program_name);
782
 
            } else {
783
 
                log_message(autostart_log, "Loading program '*'");
784
 
            }
785
 
            orig_drive_true_emulation_state = get_true_drive_emulation_state();
786
 
            if (handle_drive_true_emulation_overridden) {
787
 
                resources_get_int("VirtualDevices", &traps);
788
 
                if (traps) {
789
 
                    if (orig_drive_true_emulation_state) {
790
 
                        log_message(autostart_log,
791
 
                                    "Turning true drive emulation off.");
792
 
                    }
793
 
                    set_true_drive_emulation_mode(0);
794
 
                } else {
795
 
                    if (!orig_drive_true_emulation_state) {
796
 
                        log_message(autostart_log,
797
 
                                    "Turning true drive emulation on.");
798
 
                    }
799
 
                    set_true_drive_emulation_mode(1);
800
 
                }
801
 
            } else {
802
 
                if (!orig_drive_true_emulation_state) {
803
 
                    traps = 1;
804
 
                } else {
805
 
                    traps = 0;
806
 
                }
807
 
            }
808
 
 
809
 
            tmp = lib_msprintf("LOAD\"%s\",8%s:\r",
810
 
                               autostart_program_name ?
811
 
                               autostart_program_name : "*",
812
 
                               autostart_basic_load ? "" : ",1");
813
 
            DBG(("advance_hasdisk '%s'", tmp));
814
 
            kbdbuf_feed(tmp);
815
 
            lib_free(tmp);
816
 
 
817
 
            if (!traps) {
818
 
                if (AutostartWarp) {
819
 
                    autostartmode = AUTOSTART_WAITSEARCHINGFOR;
820
 
                } else {
821
 
                    /* be most compatible if warp is disabled */
822
 
                    autostart_finish();
823
 
                    autostart_done();
824
 
                }
825
 
            } else {
826
 
                autostartmode = AUTOSTART_LOADINGDISK;
827
 
                machine_bus_attention_callback_set(disk_attention_callback);
828
 
            }
829
 
 
830
 
            deallocate_program_name();
831
 
            break;
832
 
        case NO:
833
 
            orig_drive_true_emulation_state = get_true_drive_emulation_state();
834
 
            disable_warp_if_was_requested();
835
 
            autostart_disable();
836
 
            break;
837
 
        case NOT_YET:
838
 
            break;
839
 
    }
840
 
}
841
 
 
842
 
static void advance_hassnapshot(void)
843
 
{
844
 
    switch (check("READY.", AUTOSTART_WAIT_BLINK)) {
845
 
        case YES:
846
 
            autostart_done();
847
 
            log_message(autostart_log, "Restoring snapshot.");
848
 
            interrupt_maincpu_trigger_trap(load_snapshot_trap, 0);
849
 
            break;
850
 
        case NO:
851
 
            autostart_disable();
852
 
            break;
853
 
        case NOT_YET:
854
 
            break;
855
 
    }
856
 
}
857
 
 
858
 
/* ----- stages for tde disk loading with warp --------------------------- */
859
 
 
860
 
static void advance_waitsearchingfor(void)
861
 
{
862
 
    switch (check("SEARCHING FOR", AUTOSTART_NOWAIT_BLINK)) {
863
 
        case YES:
864
 
            log_message(autostart_log, "Searching for ...");
865
 
            autostartmode = AUTOSTART_WAITLOADING;
866
 
            break;
867
 
        case NO:
868
 
            log_message(autostart_log, "NO Searching for ...");
869
 
            disable_warp_if_was_requested();
870
 
            autostart_disable();
871
 
            break;
872
 
        case NOT_YET:
873
 
            break;
874
 
    }
875
 
}
876
 
 
877
 
static void advance_waitloading(void)
878
 
{
879
 
    switch (check("LOADING", AUTOSTART_NOWAIT_BLINK)) {
880
 
        case YES:
881
 
            log_message(autostart_log, "Loading");
882
 
            entered_rom = 0;
883
 
            autostartmode = AUTOSTART_WAITLOADREADY;
884
 
            break;
885
 
        case NO:
886
 
            /* still showing SEARCHING FOR ? */
887
 
            if (check("SEARCHING FOR", AUTOSTART_NOWAIT_BLINK) == YES) {
888
 
                return;
889
 
            }
890
 
            /* no something else is shown -> error! */
891
 
            log_message(autostart_log, "NO Loading");
892
 
            disable_warp_if_was_requested();
893
 
            autostart_disable();
894
 
            break;
895
 
        case NOT_YET:
896
 
            break;
897
 
    }
898
 
}
899
 
 
900
 
static void advance_waitloadready(void)
901
 
{
902
 
    switch (check("READY.", AUTOSTART_WAIT_BLINK)) {
903
 
        case YES:
904
 
            log_message(autostart_log, "Ready");
905
 
            disable_warp_if_was_requested();
906
 
            autostart_finish();
907
 
            autostart_done();
908
 
            break;
909
 
        case NO:
910
 
            log_message(autostart_log, "NO Ready");
911
 
            disable_warp_if_was_requested();
912
 
            autostart_disable();
913
 
            break;
914
 
        case NOT_YET:
915
 
            /* leave autostart and disable warp if ROM area was left */
916
 
            check_rom_area();
917
 
            break;
918
 
    }
919
 
}
920
 
 
921
 
/* After a reset a PRG file has to be injected into RAM */
922
 
static void advance_inject(void)
923
 
{
924
 
    if (autostart_prg_perform_injection(autostart_log) < 0) {
925
 
        disable_warp_if_was_requested();
926
 
        autostart_disable();
927
 
    } else {
928
 
        /* wait for ready cursor and type RUN */
929
 
        autostartmode = AUTOSTART_WAITLOADREADY;
930
 
    }
931
 
}
932
 
 
933
 
/* Execute the actions for the current `autostartmode', advancing to the next
934
 
   mode if necessary.  */
935
 
void autostart_advance(void)
936
 
{
937
 
    if (!autostart_enabled) {
938
 
        return;
939
 
    }
940
 
 
941
 
    if (orig_drive_true_emulation_state == -1) {
942
 
        orig_drive_true_emulation_state = get_true_drive_emulation_state();
943
 
    }
944
 
 
945
 
    if (maincpu_clk < autostart_initial_delay_cycles) {
946
 
        autostart_wait_for_reset = 0;
947
 
        return;
948
 
    }
949
 
 
950
 
    if (autostart_wait_for_reset) {
951
 
        return;
952
 
    }
953
 
 
954
 
    switch (autostartmode) {
955
 
        case AUTOSTART_HASTAPE:
956
 
            advance_hastape();
957
 
            break;
958
 
        case AUTOSTART_PRESSPLAYONTAPE:
959
 
            advance_pressplayontape();
960
 
            break;
961
 
        case AUTOSTART_LOADINGTAPE:
962
 
            advance_loadingtape();
963
 
            break;
964
 
        case AUTOSTART_HASDISK:
965
 
            advance_hasdisk();
966
 
            break;
967
 
        case AUTOSTART_HASSNAPSHOT:
968
 
            advance_hassnapshot();
969
 
            break;
970
 
        case AUTOSTART_WAITLOADREADY:
971
 
            advance_waitloadready();
972
 
            break;
973
 
        case AUTOSTART_WAITLOADING:
974
 
            advance_waitloading();
975
 
            break;
976
 
        case AUTOSTART_WAITSEARCHINGFOR:
977
 
            advance_waitsearchingfor();
978
 
            break;
979
 
        case AUTOSTART_INJECT:
980
 
            advance_inject();
981
 
            break;
982
 
        default:
983
 
            return;
984
 
    }
985
 
 
986
 
    if (autostartmode == AUTOSTART_ERROR && handle_drive_true_emulation_overridden) {
987
 
        log_message(autostart_log, "Now turning true drive emulation %s.",
988
 
                    orig_drive_true_emulation_state ? "on" : "off");
989
 
        set_true_drive_emulation_mode(orig_drive_true_emulation_state);
990
 
    }
991
 
}
992
 
 
993
 
/* Clean memory and reboot for autostart.  */
994
 
static void reboot_for_autostart(const char *program_name, unsigned int mode,
995
 
                                 unsigned int runmode)
996
 
{
997
 
    int rnd;
998
 
 
999
 
    if (!autostart_enabled) {
1000
 
        return;
1001
 
    }
1002
 
 
1003
 
    log_message(autostart_log, "Resetting the machine to autostart '%s'",
1004
 
                program_name ? program_name : "*");
1005
 
 
1006
 
    /* on x128 autostart will only work in 40 columns mode (and can not be fixed
1007
 
       easily for VDC mode). We work around that by switching to 40 columns and
1008
 
       back if needed */
1009
 
    if (machine_class == VICE_MACHINE_C128) {
1010
 
        resources_get_int("40/80ColumnKey", &c128_column4080_key);
1011
 
        resources_set_int("40/80ColumnKey", 1);
1012
 
    }
1013
 
 
1014
 
    mem_powerup();
1015
 
 
1016
 
    autostart_ignore_reset = 1;
1017
 
    deallocate_program_name();
1018
 
    if (program_name && program_name[0]) {
1019
 
        autostart_program_name = lib_stralloc(program_name);
1020
 
    }
1021
 
 
1022
 
    autostart_initial_delay_cycles = min_cycles;
1023
 
    resources_get_int("AutostartDelayRandom", &rnd);
1024
 
    if (rnd) {
1025
 
        autostart_initial_delay_cycles += AUTOSTART_RAND();
1026
 
    }
1027
 
    DBG(("autostart_initial_delay_cycles: %d", autostart_initial_delay_cycles));
1028
 
 
1029
 
    machine_trigger_reset(MACHINE_RESET_MODE_SOFT);
1030
 
 
1031
 
    /* The autostartmode must be set AFTER the shutdown to make the autostart
1032
 
       threadsafe for OS/2 */
1033
 
    autostartmode = mode;
1034
 
    autostart_run_mode = runmode;
1035
 
    autostart_wait_for_reset = 1;
1036
 
 
1037
 
    /* enable warp before reset */
1038
 
    if (mode != AUTOSTART_HASSNAPSHOT) {
1039
 
        enable_warp_if_requested();
1040
 
    }
1041
 
}
1042
 
 
1043
 
/* ------------------------------------------------------------------------- */
1044
 
 
1045
 
/* Autostart snapshot file `file_name'.  */
1046
 
int autostart_snapshot(const char *file_name, const char *program_name)
1047
 
{
1048
 
    BYTE vmajor, vminor;
1049
 
    snapshot_t *snap;
1050
 
 
1051
 
    if (network_connected() || event_record_active() || event_playback_active()
1052
 
        || file_name == NULL || !autostart_enabled) {
1053
 
        return -1;
1054
 
    }
1055
 
 
1056
 
    deallocate_program_name();  /* not needed at all */
1057
 
 
1058
 
    if (!(snap = snapshot_open(file_name, &vmajor, &vminor, machine_get_name()))) {
1059
 
        autostartmode = AUTOSTART_ERROR;
1060
 
        return -1;
1061
 
    }
1062
 
 
1063
 
    log_message(autostart_log, "Loading snapshot file `%s'.", file_name);
1064
 
    snapshot_close(snap);
1065
 
 
1066
 
    /*autostart_program_name = lib_stralloc(file_name);
1067
 
    interrupt_maincpu_trigger_trap(load_snapshot_trap, 0);*/
1068
 
    /* use for snapshot */
1069
 
    reboot_for_autostart(file_name, AUTOSTART_HASSNAPSHOT, AUTOSTART_MODE_RUN);
1070
 
 
1071
 
    return 0;
1072
 
}
1073
 
 
1074
 
/* Autostart tape image `file_name'.  */
1075
 
int autostart_tape(const char *file_name, const char *program_name,
1076
 
                   unsigned int program_number, unsigned int runmode)
1077
 
{
1078
 
    BYTE do_seek = 1;
1079
 
 
1080
 
    if (network_connected() || event_record_active() || event_playback_active()
1081
 
        || !file_name || !autostart_enabled) {
1082
 
        return -1;
1083
 
    }
1084
 
 
1085
 
    if (!(tape_image_attach(1, file_name) < 0)) {
1086
 
        log_message(autostart_log,
1087
 
                    "Attached file `%s' as a tape image.", file_name);
1088
 
        if (!tape_tap_attached()) {
1089
 
            if (program_number == 0 || program_number == 1) {
1090
 
                do_seek = 0;
1091
 
            }
1092
 
            program_number -= 1;
1093
 
        }
1094
 
        if (do_seek) {
1095
 
            if (program_number > 0) {
1096
 
                /* program numbers in tape_seek_to_file() start at 0 */
1097
 
                tape_seek_to_file(tape_image_dev1, program_number - 1);
1098
 
            } else {
1099
 
                tape_seek_start(tape_image_dev1);
1100
 
            }
1101
 
        }
1102
 
        resources_set_int("VirtualDevices", 1); /* Kludge: iAN CooG - for t64 images we need devtraps ON */
1103
 
        reboot_for_autostart(program_name, AUTOSTART_HASTAPE, runmode);
1104
 
 
1105
 
        return 0;
1106
 
    }
1107
 
 
1108
 
    autostartmode = AUTOSTART_ERROR;
1109
 
    deallocate_program_name();
1110
 
 
1111
 
    return -1;
1112
 
}
1113
 
 
1114
 
/* Cope with 0xa0 padded file names.  */
1115
 
static void autostart_disk_cook_name(char **name)
1116
 
{
1117
 
    unsigned int pos;
1118
 
 
1119
 
    pos = 0;
1120
 
 
1121
 
    while ((*name)[pos] != '\0') {
1122
 
        if (((unsigned char)((*name)[pos])) == 0xa0) {
1123
 
            char *ptr;
1124
 
 
1125
 
            ptr = lib_malloc(pos + 1);
1126
 
            memcpy(ptr, *name, pos);
1127
 
            ptr[pos] = '\0';
1128
 
            lib_free(*name);
1129
 
            *name = ptr;
1130
 
            break;
1131
 
        }
1132
 
        pos++;
1133
 
    }
1134
 
}
1135
 
 
1136
 
/* Autostart disk image `file_name'.  */
1137
 
int autostart_disk(const char *file_name, const char *program_name,
1138
 
                   unsigned int program_number, unsigned int runmode)
1139
 
{
1140
 
    char *name = NULL;
1141
 
 
1142
 
    if (network_connected() || event_record_active() || event_playback_active()
1143
 
        || !file_name || !autostart_enabled) {
1144
 
        return -1;
1145
 
    }
1146
 
 
1147
 
    /* Get program name first to avoid more than one file handle open on
1148
 
       image.  */
1149
 
    if (!program_name && program_number > 0) {
1150
 
        name = image_contents_filename_by_number(diskcontents_filesystem_read(file_name), program_number);
1151
 
    } else {
1152
 
        name = lib_stralloc(program_name ? program_name : "*");
1153
 
    }
1154
 
 
1155
 
    if (name) {
1156
 
        autostart_disk_cook_name(&name);
1157
 
        if (!(file_system_attach_disk(8, file_name) < 0)) {
1158
 
            log_message(autostart_log,
1159
 
                        "Attached file `%s' as a disk image.", file_name);
1160
 
            reboot_for_autostart(name, AUTOSTART_HASDISK, runmode);
1161
 
            lib_free(name);
1162
 
 
1163
 
            return 0;
1164
 
        }
1165
 
    }
1166
 
 
1167
 
    autostartmode = AUTOSTART_ERROR;
1168
 
    deallocate_program_name();
1169
 
    lib_free(name);
1170
 
 
1171
 
    return -1;
1172
 
}
1173
 
 
1174
 
/* Autostart PRG file `file_name'.  The PRG file can either be a raw CBM file
1175
 
   or a P00 file */
1176
 
int autostart_prg(const char *file_name, unsigned int runmode)
1177
 
{
1178
 
    fileio_info_t *finfo;
1179
 
    int result;
1180
 
    const char *boot_file_name;
1181
 
    int mode;
1182
 
 
1183
 
    if (network_connected() || event_record_active() || event_playback_active()) {
1184
 
        return -1;
1185
 
    }
1186
 
 
1187
 
    /* open prg file */
1188
 
    finfo = fileio_open(file_name, NULL, FILEIO_FORMAT_RAW | FILEIO_FORMAT_P00,
1189
 
                        FILEIO_COMMAND_READ | FILEIO_COMMAND_FSNAME,
1190
 
                        FILEIO_TYPE_PRG);
1191
 
 
1192
 
    /* can't open file */
1193
 
    if (finfo == NULL) {
1194
 
        log_error(autostart_log, "Cannot open `%s'.", file_name);
1195
 
        return -1;
1196
 
    }
1197
 
 
1198
 
    /* determine how to load file */
1199
 
    switch (AutostartPrgMode) {
1200
 
        case AUTOSTART_PRG_MODE_VFS:
1201
 
            log_message(autostart_log, "Loading PRG file `%s' with virtual FS on unit #8.", file_name);
1202
 
            result = autostart_prg_with_virtual_fs(file_name, finfo, autostart_log);
1203
 
            mode = AUTOSTART_HASDISK;
1204
 
            boot_file_name = (const char *)finfo->name;
1205
 
            break;
1206
 
        case AUTOSTART_PRG_MODE_INJECT:
1207
 
            log_message(autostart_log, "Loading PRG file `%s' with direct RAM injection.", file_name);
1208
 
            result = autostart_prg_with_ram_injection(file_name, finfo, autostart_log);
1209
 
            mode = AUTOSTART_INJECT;
1210
 
            boot_file_name = NULL;
1211
 
            break;
1212
 
        case AUTOSTART_PRG_MODE_DISK:
1213
 
            log_message(autostart_log, "Loading PRG file `%s' with autostart disk image.", file_name);
1214
 
            result = autostart_prg_with_disk_image(file_name, finfo, autostart_log, AutostartPrgDiskImage);
1215
 
            mode = AUTOSTART_HASDISK;
1216
 
            boot_file_name = "*";
1217
 
            break;
1218
 
        default:
1219
 
            log_error(autostart_log, "Invalid PRG autostart mode: %d", AutostartPrgMode);
1220
 
            result = -1;
1221
 
            break;
1222
 
    }
1223
 
 
1224
 
    /* Now either proceed with disk image booting or prg injection after reset */
1225
 
    if (result >= 0) {
1226
 
        ui_update_menus();
1227
 
        reboot_for_autostart(boot_file_name, mode, runmode);
1228
 
    }
1229
 
 
1230
 
    /* close prg file */
1231
 
    fileio_close(finfo);
1232
 
 
1233
 
    return result;
1234
 
}
1235
 
 
1236
 
/* ------------------------------------------------------------------------- */
1237
 
 
1238
 
int autostart_autodetect_opt_prgname(const char *file_prog_name,
1239
 
                                     unsigned int alt_prg_number,
1240
 
                                     unsigned int runmode)
1241
 
{
1242
 
    char *tmp;
1243
 
    int result;
1244
 
 
1245
 
    /* Check for image:prg -format.  */
1246
 
    tmp = strrchr(file_prog_name, ':');
1247
 
    if (tmp) {
1248
 
        char *autostart_prg_name;
1249
 
        char *autostart_file;
1250
 
 
1251
 
        autostart_file = lib_stralloc(file_prog_name);
1252
 
        autostart_prg_name = strrchr(autostart_file, ':');
1253
 
        *autostart_prg_name++ = '\0';
1254
 
        /* Does the image exist?  */
1255
 
        if (util_file_exists(autostart_file)) {
1256
 
            char *name;
1257
 
 
1258
 
            charset_petconvstring((BYTE *)autostart_prg_name, 0);
1259
 
            name = charset_replace_hexcodes(autostart_prg_name);
1260
 
            result = autostart_autodetect(autostart_file, name, 0,
1261
 
                                          runmode);
1262
 
            lib_free(name);
1263
 
        } else {
1264
 
            result = autostart_autodetect(file_prog_name, NULL, alt_prg_number,
1265
 
                                          runmode);
1266
 
        }
1267
 
        lib_free(autostart_file);
1268
 
    } else {
1269
 
        result = autostart_autodetect(file_prog_name, NULL, alt_prg_number,
1270
 
                                      runmode);
1271
 
    }
1272
 
    return result;
1273
 
}
1274
 
 
1275
 
/* Autostart `file_name', trying to auto-detect its type.  */
1276
 
int autostart_autodetect(const char *file_name, const char *program_name,
1277
 
                         unsigned int program_number, unsigned int runmode)
1278
 
{
1279
 
    if (network_connected() || event_record_active() || event_playback_active()
1280
 
        || file_name == NULL) {
1281
 
        return -1;
1282
 
    }
1283
 
 
1284
 
    if (!autostart_enabled) {
1285
 
        log_error(autostart_log,
1286
 
                  "Autostart is not available on this setup.");
1287
 
        return -1;
1288
 
    }
1289
 
 
1290
 
    log_message(autostart_log, "Autodetecting image type of `%s'.", file_name);
1291
 
 
1292
 
    if (autostart_disk(file_name, program_name, program_number, runmode) == 0) {
1293
 
        log_message(autostart_log, "`%s' recognized as disk image.", file_name);
1294
 
        return 0;
1295
 
    }
1296
 
 
1297
 
    if (machine_class != VICE_MACHINE_C64DTV && machine_class != VICE_MACHINE_SCPU64) {
1298
 
        if (autostart_tape(file_name, program_name, program_number, runmode) == 0) {
1299
 
            log_message(autostart_log, "`%s' recognized as tape image.", file_name);
1300
 
            return 0;
1301
 
        }
1302
 
    }
1303
 
 
1304
 
    if (autostart_snapshot(file_name, program_name) == 0) {
1305
 
        log_message(autostart_log, "`%s' recognized as snapshot image.",
1306
 
                    file_name);
1307
 
        return 0;
1308
 
    }
1309
 
    if (autostart_prg(file_name, runmode) == 0) {
1310
 
        log_message(autostart_log, "`%s' recognized as program/p00 file.",
1311
 
                    file_name);
1312
 
        return 0;
1313
 
    }
1314
 
 
1315
 
    log_error(autostart_log, "`%s' is not a valid file.", file_name);
1316
 
    return -1;
1317
 
}
1318
 
 
1319
 
/* Autostart the image attached to device `num'.  */
1320
 
int autostart_device(int num)
1321
 
{
1322
 
    if (network_connected() || event_playback_active() || event_record_active()
1323
 
        || !autostart_enabled) {
1324
 
        return -1;
1325
 
    }
1326
 
 
1327
 
    switch (num) {
1328
 
        case 8:
1329
 
            reboot_for_autostart(NULL, AUTOSTART_HASDISK, AUTOSTART_MODE_RUN);
1330
 
            return 0;
1331
 
        case 1:
1332
 
            reboot_for_autostart(NULL, AUTOSTART_HASTAPE, AUTOSTART_MODE_RUN);
1333
 
            return 0;
1334
 
    }
1335
 
    return -1;
1336
 
}
1337
 
 
1338
 
int autostart_in_progress(void)
1339
 
{
1340
 
    return (autostartmode != AUTOSTART_NONE && autostartmode != AUTOSTART_DONE);
1341
 
}
1342
 
 
1343
 
/* Disable autostart on reset.  */
1344
 
void autostart_reset(void)
1345
 
{
1346
 
    int oldmode;
1347
 
 
1348
 
    if (!autostart_enabled) {
1349
 
        return;
1350
 
    }
1351
 
 
1352
 
    if (!autostart_ignore_reset
1353
 
        && autostartmode != AUTOSTART_NONE
1354
 
        && autostartmode != AUTOSTART_ERROR) {
1355
 
        oldmode = autostartmode;
1356
 
        autostartmode = AUTOSTART_NONE;
1357
 
        if (oldmode != AUTOSTART_DONE) {
1358
 
            disk_eof_callback();
1359
 
        }
1360
 
        autostartmode = AUTOSTART_NONE;
1361
 
        trigger_monitor = 0;
1362
 
        deallocate_program_name();
1363
 
        log_message(autostart_log, "Turned off.");
1364
 
    }
1365
 
    autostart_ignore_reset = 0;
1366
 
}
1367
 
 
1368
 
void autostart_shutdown(void)
1369
 
{
1370
 
    deallocate_program_name();
1371
 
 
1372
 
    autostart_prg_shutdown();
1373
 
}
1374
 
 
1375
 
#ifdef ANDROID_COMPILE
1376
 
void loader_set_warpmode(int on)
1377
 
{
1378
 
    set_warp_mode(on);
1379
 
}
1380
 
#endif
 
1
/*
 
2
 * autostart.c - Automatic image loading and starting.
 
3
 *
 
4
 * Written by
 
5
 *  Teemu Rantanen <tvr@cs.hut.fi>
 
6
 *  Ettore Perazzoli <ettore@comm2000.it>
 
7
 *  Andr� Fachat <a.fachat@physik.tu-chemnitz.de>
 
8
 *  Andreas Boose <viceteam@t-online.de>
 
9
 *  Thomas Bretz <tbretz@ph.tum.de>
 
10
 *
 
11
 * This file is part of VICE, the Versatile Commodore Emulator.
 
12
 * See README for copyright notice.
 
13
 *
 
14
 *  This program is free software; you can redistribute it and/or modify
 
15
 *  it under the terms of the GNU General Public License as published by
 
16
 *  the Free Software Foundation; either version 2 of the License, or
 
17
 *  (at your option) any later version.
 
18
 *
 
19
 *  This program is distributed in the hope that it will be useful,
 
20
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
21
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
22
 *  GNU General Public License for more details.
 
23
 *
 
24
 *  You should have received a copy of the GNU General Public License
 
25
 *  along with this program; if not, write to the Free Software
 
26
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 
27
 *  02111-1307  USA.
 
28
 *
 
29
 */
 
30
 
 
31
/* #define DEBUG_AUTOSTART */
 
32
 
 
33
#include "vice.h"
 
34
 
 
35
#include <stdio.h>
 
36
#include <stdlib.h>
 
37
#include <string.h>
 
38
 
 
39
#include "archapi.h"
 
40
#include "archdep.h"
 
41
#include "autostart.h"
 
42
#include "autostart-prg.h"
 
43
#include "attach.h"
 
44
#include "charset.h"
 
45
#include "cmdline.h"
 
46
#include "datasette.h"
 
47
#include "drive.h"
 
48
#include "fileio.h"
 
49
#include "fsdevice.h"
 
50
#include "imagecontents.h"
 
51
#include "tapecontents.h"
 
52
#include "diskcontents.h"
 
53
#include "interrupt.h"
 
54
#include "kbdbuf.h"
 
55
#include "lib.h"
 
56
#include "log.h"
 
57
#include "machine-bus.h"
 
58
#include "machine.h"
 
59
#include "maincpu.h"
 
60
#include "mem.h"
 
61
#include "monitor.h"
 
62
#include "network.h"
 
63
#include "resources.h"
 
64
#include "snapshot.h"
 
65
#include "tape.h"
 
66
#include "translate.h"
 
67
#include "types.h"
 
68
#include "uiapi.h"
 
69
#include "util.h"
 
70
#include "vdrive.h"
 
71
#include "vdrive-bam.h"
 
72
#include "vice-event.h"
 
73
 
 
74
#ifdef DEBUG_AUTOSTART
 
75
#define DBG(_x_)        log_debug _x_
 
76
#else
 
77
#define DBG(_x_)
 
78
#endif
 
79
 
 
80
static void autostart_done(void);
 
81
static void autostart_finish(void);
 
82
 
 
83
/* Kernal addresses.  Set by `autostart_init()'.  */
 
84
 
 
85
static WORD blnsw;           /* Cursor Blink enable: 0 = Flash Cursor */
 
86
static int pnt;                 /* Pointer: Current Screen Line Address */
 
87
static int pntr;                /* Cursor Column on Current Line */
 
88
static int lnmx;                /* Physical Screen Line Length */
 
89
 
 
90
/* Current state of the autostart routine.  */
 
91
static enum {
 
92
    AUTOSTART_NONE,
 
93
    AUTOSTART_ERROR,
 
94
    AUTOSTART_HASTAPE,
 
95
    AUTOSTART_PRESSPLAYONTAPE,
 
96
    AUTOSTART_LOADINGTAPE,
 
97
    AUTOSTART_HASDISK,
 
98
    AUTOSTART_LOADINGDISK,
 
99
    AUTOSTART_HASSNAPSHOT,
 
100
    AUTOSTART_WAITLOADREADY,
 
101
    AUTOSTART_WAITLOADING,
 
102
    AUTOSTART_WAITSEARCHINGFOR,
 
103
    AUTOSTART_INJECT,
 
104
    AUTOSTART_DONE
 
105
} autostartmode = AUTOSTART_NONE;
 
106
 
 
107
#define AUTOSTART_WAIT_BLINK   0
 
108
#define AUTOSTART_NOWAIT_BLINK 1
 
109
 
 
110
/* Log descriptor.  */
 
111
static log_t autostart_log = LOG_ERR;
 
112
 
 
113
/* Flag: was true drive emulation turned on when we started booting the disk
 
114
   image?  */
 
115
static int orig_drive_true_emulation_state = -1;
 
116
 
 
117
/* Flag: warp mode state before booting */
 
118
static int orig_warp_mode = -1;
 
119
 
 
120
/* PETSCII name of the program to load. NULL if default */
 
121
static char *autostart_program_name = NULL;
 
122
 
 
123
/* Minimum number of cycles before we feed BASIC with commands.  */
 
124
static CLOCK min_cycles;
 
125
static CLOCK autostart_initial_delay_cycles;
 
126
 
 
127
/* Flag: Do we want to switch true drive emulation on/off during autostart?
 
128
 * Normally, this is the same as handle_drive_true_emulation_by_machine;
 
129
 * however, the user can override this decision by specifying
 
130
 * -autostart-no-true-drive-emulation
 
131
 */
 
132
static int handle_drive_true_emulation_overridden;
 
133
 
 
134
/* Flag: Does the machine want us to switch true drive emulation on/off during autostart? */
 
135
static int handle_drive_true_emulation_by_machine;
 
136
 
 
137
/* Flag: autostart is initialized.  */
 
138
static int autostart_enabled = 0;
 
139
 
 
140
/* Flag: Autostart the file or just load it?  */
 
141
static unsigned int autostart_run_mode;
 
142
 
 
143
/* Flag: maincpu_clk isn't resetted yet */
 
144
static int autostart_wait_for_reset;
 
145
 
 
146
/* Flag: load stage after LOADING enters ROM area */
 
147
static int entered_rom = 0;
 
148
 
 
149
/* Flag: trap monitor after done */
 
150
static int trigger_monitor = 0;
 
151
 
 
152
int autostart_ignore_reset = 0; /* FIXME: only used by datasette.c, does it really have to be global? */
 
153
 
 
154
/* additional random delay of up to 10 frames */
 
155
#define AUTOSTART_RAND() (1 + (int)(((float)machine_get_cycles_per_frame()) * 10.0f * rand() / (RAND_MAX + 1.0)))
 
156
 
 
157
/* flag for special case handling of C128 80 columns mode */
 
158
static int c128_column4080_key;
 
159
 
 
160
/* ------------------------------------------------------------------------- */
 
161
 
 
162
static int autostart_basic_load = 0;
 
163
 
 
164
static int AutostartRunWithColon = 0;
 
165
 
 
166
static int AutostartHandleTrueDriveEmulation = 0;
 
167
 
 
168
static int AutostartWarp = 0;
 
169
 
 
170
static int AutostartDelay = 0;
 
171
static int AutostartDelayRandom = 0;
 
172
 
 
173
static int AutostartPrgMode = AUTOSTART_PRG_MODE_VFS;
 
174
 
 
175
static char *AutostartPrgDiskImage = NULL;
 
176
 
 
177
static const char * const AutostartRunCommandsAvailable[] = {
 
178
    "RUN\r", "RUN:\r"
 
179
};
 
180
 
 
181
static const char * AutostartRunCommand = NULL;
 
182
 
 
183
static void set_handle_true_drive_emulation_state(void)
 
184
{
 
185
    handle_drive_true_emulation_overridden =
 
186
        AutostartHandleTrueDriveEmulation ?
 
187
        handle_drive_true_emulation_by_machine : 0;
 
188
}
 
189
 
 
190
/*! \internal \brief set if autostart should use LOAD ... ,1 */
 
191
static int set_autostart_basic_load(int val, void *param)
 
192
{
 
193
    autostart_basic_load = val ? 1 : 0;
 
194
 
 
195
    return 0;
 
196
}
 
197
 
 
198
/*! \internal \brief set if autostart should execute with a colon or not
 
199
 
 
200
 \param val
 
201
   if 0, the "RUN" command at the end of autostart is executed without
 
202
   a colon; else, it will be executed with a colon.
 
203
 
 
204
 \param param
 
205
   unused
 
206
 
 
207
 \return
 
208
   0 on success. else -1.
 
209
*/
 
210
static int set_autostart_run_with_colon(int val, void *param)
 
211
{
 
212
    AutostartRunWithColon = val ? 1 : 0;
 
213
 
 
214
    AutostartRunCommand = AutostartRunCommandsAvailable[AutostartRunWithColon];
 
215
 
 
216
    return 0;
 
217
}
 
218
 
 
219
/*! \internal \brief set if autostart should handle TDE or not
 
220
 
 
221
 \param val
 
222
   if 0, autostart does not handle TDE even if the machine says it can
 
223
   handle it.
 
224
 
 
225
 \param param
 
226
   unused
 
227
 
 
228
 \return
 
229
   0 on success. else -1.
 
230
*/
 
231
static int set_autostart_handle_tde(int val, void *param)
 
232
{
 
233
    AutostartHandleTrueDriveEmulation = val ? 1 : 0;
 
234
 
 
235
    set_handle_true_drive_emulation_state();
 
236
 
 
237
    return 0;
 
238
}
 
239
 
 
240
/*! \internal \brief set if autostart should enable warp mode */
 
241
static int set_autostart_warp(int val, void *param)
 
242
{
 
243
    AutostartWarp = val ? 1 : 0;
 
244
 
 
245
    return 0;
 
246
}
 
247
 
 
248
/*! \internal \brief set initial autostart delay. 0 means default. */
 
249
static int set_autostart_delay(int val, void *param)
 
250
{
 
251
    if ((val < 0) || (val > 1000)) {
 
252
        val = 0;
 
253
    }
 
254
    AutostartDelay = val;
 
255
    return 0;
 
256
}
 
257
 
 
258
/*! \internal \brief set initial autostart random delay. 0 means off, 1 means on. */
 
259
static int set_autostart_delayrandom(int val, void *param)
 
260
{
 
261
    AutostartDelayRandom = val ? 1 : 0;
 
262
    return 0;
 
263
}
 
264
 
 
265
/*! \internal \brief set autostart prg mode */
 
266
static int set_autostart_prg_mode(int val, void *param)
 
267
{
 
268
    if ((val < 0) || (val > AUTOSTART_PRG_MODE_LAST)) {
 
269
        val = AUTOSTART_PRG_MODE_DEFAULT;
 
270
    }
 
271
    AutostartPrgMode = val;
 
272
 
 
273
    return 0;
 
274
}
 
275
 
 
276
/*! \internal \brief set disk image name of autostart prg mode */
 
277
 
 
278
static int set_autostart_prg_disk_image(const char *val, void *param)
 
279
{
 
280
    if (util_string_set(&AutostartPrgDiskImage, val)) {
 
281
        return 0;
 
282
    }
 
283
 
 
284
    return 0;
 
285
}
 
286
 
 
287
/*! \brief string resources used by autostart */
 
288
static resource_string_t resources_string[] = {
 
289
    { "AutostartPrgDiskImage", NULL, RES_EVENT_NO, NULL,
 
290
      &AutostartPrgDiskImage, set_autostart_prg_disk_image, NULL },
 
291
    { NULL }
 
292
};
 
293
 
 
294
/*! \brief integer resources used by autostart */
 
295
static const resource_int_t resources_int[] = {
 
296
    { "AutostartBasicLoad", 0, RES_EVENT_NO, (resource_value_t)0,
 
297
      &autostart_basic_load, set_autostart_basic_load, NULL },
 
298
    { "AutostartRunWithColon", 0, RES_EVENT_NO, (resource_value_t)0,
 
299
      &AutostartRunWithColon, set_autostart_run_with_colon, NULL },
 
300
    { "AutostartHandleTrueDriveEmulation", 0, RES_EVENT_NO, (resource_value_t)0,
 
301
      &AutostartHandleTrueDriveEmulation, set_autostart_handle_tde, NULL },
 
302
    { "AutostartWarp", 1, RES_EVENT_NO, (resource_value_t)0,
 
303
      &AutostartWarp, set_autostart_warp, NULL },
 
304
    { "AutostartPrgMode", AUTOSTART_PRG_MODE_DEFAULT, RES_EVENT_NO, (resource_value_t)0,
 
305
      &AutostartPrgMode, set_autostart_prg_mode, NULL },
 
306
    { "AutostartDelay", 0, RES_EVENT_NO, (resource_value_t)0,
 
307
      &AutostartDelay, set_autostart_delay, NULL },
 
308
    { "AutostartDelayRandom", 1, RES_EVENT_NO, (resource_value_t)0,
 
309
      &AutostartDelayRandom, set_autostart_delayrandom, NULL },
 
310
    { NULL }
 
311
};
 
312
 
 
313
/*! \brief initialize the resources
 
314
 \return
 
315
   0 on success, else -1.
 
316
 
 
317
 \remark
 
318
   Registers the integer resources
 
319
*/
 
320
int autostart_resources_init(void)
 
321
{
 
322
    resources_string[0].factory_value = archdep_default_autostart_disk_image_file_name();
 
323
 
 
324
    if (resources_register_string(resources_string) < 0) {
 
325
        return -1;
 
326
    }
 
327
 
 
328
    return resources_register_int(resources_int);
 
329
}
 
330
 
 
331
void autostart_resources_shutdown(void)
 
332
{
 
333
    lib_free(AutostartPrgDiskImage);
 
334
    lib_free(resources_string[0].factory_value);
 
335
}
 
336
 
 
337
/* ------------------------------------------------------------------------- */
 
338
 
 
339
static const cmdline_option_t cmdline_options[] =
 
340
{
 
341
    { "-basicload", SET_RESOURCE, 0,
 
342
      NULL, NULL, "AutostartBasicLoad", (resource_value_t)1,
 
343
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
 
344
      IDCLS_UNUSED, IDCLS_AUTOSTART_LOAD_TO_BASIC_START,
 
345
      NULL, NULL },
 
346
    { "+basicload", SET_RESOURCE, 0,
 
347
      NULL, NULL, "AutostartBasicLoad", (resource_value_t)0,
 
348
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
 
349
      IDCLS_UNUSED, IDCLS_AUTOSTART_LOAD_WITH_1,
 
350
      NULL, NULL },
 
351
    { "-autostartwithcolon", SET_RESOURCE, 0,
 
352
      NULL, NULL, "AutostartRunWithColon", (resource_value_t)1,
 
353
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
 
354
      IDCLS_UNUSED, IDCLS_ENABLE_AUTOSTARTWITHCOLON,
 
355
      NULL, NULL },
 
356
    { "+autostartwithcolon", SET_RESOURCE, 0,
 
357
      NULL, NULL, "AutostartRunWithColon", (resource_value_t)0,
 
358
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
 
359
      IDCLS_UNUSED, IDCLS_DISABLE_AUTOSTARTWITHCOLON,
 
360
      NULL, NULL },
 
361
    { "-autostart-handle-tde", SET_RESOURCE, 0,
 
362
      NULL, NULL, "AutostartHandleTrueDriveEmulation", (resource_value_t)1,
 
363
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
 
364
      IDCLS_UNUSED, IDCLS_ENABLE_AUTOSTART_HANDLE_TDE,
 
365
      NULL, NULL },
 
366
    { "+autostart-handle-tde", SET_RESOURCE, 0,
 
367
      NULL, NULL, "AutostartHandleTrueDriveEmulation", (resource_value_t)0,
 
368
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
 
369
      IDCLS_UNUSED, IDCLS_DISABLE_AUTOSTART_HANDLE_TDE,
 
370
      NULL, NULL },
 
371
    { "-autostart-warp", SET_RESOURCE, 0,
 
372
      NULL, NULL, "AutostartWarp", (resource_value_t)1,
 
373
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
 
374
      IDCLS_UNUSED, IDCLS_ENABLE_WARP_MODE_AUTOSTART,
 
375
      NULL, NULL },
 
376
    { "+autostart-warp", SET_RESOURCE, 0,
 
377
      NULL, NULL, "AutostartWarp", (resource_value_t)0,
 
378
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
 
379
      IDCLS_UNUSED, IDCLS_DISABLE_WARP_MODE_AUTOSTART,
 
380
      NULL, NULL },
 
381
    { "-autostartprgmode", SET_RESOURCE, 1,
 
382
      NULL, NULL, "AutostartPrgMode", NULL,
 
383
      USE_PARAM_ID, USE_DESCRIPTION_ID,
 
384
      IDCLS_P_MODE, IDCLS_SET_AUTOSTART_MODE_FOR_PRG,
 
385
      NULL, NULL },
 
386
    { "-autostartprgdiskimage", SET_RESOURCE, 1,
 
387
      NULL, NULL, "AutostartPrgDiskImage", NULL,
 
388
      USE_PARAM_ID, USE_DESCRIPTION_ID,
 
389
      IDCLS_P_NAME, IDCLS_SET_DISK_IMAGE_FOR_AUTOSTART_PRG,
 
390
      NULL, NULL },
 
391
    { "-autostart-delay", SET_RESOURCE, 1,
 
392
      NULL, NULL, "AutostartDelay", NULL,
 
393
      USE_PARAM_ID, USE_DESCRIPTION_ID,
 
394
      IDCLS_P_SECONDS, IDCLS_SET_AUTOSTART_DELAY,
 
395
      NULL, NULL },
 
396
    { "-autostart-delay-random", SET_RESOURCE, 0,
 
397
      NULL, NULL, "AutostartDelayRandom", (resource_value_t)1,
 
398
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
 
399
      IDCLS_UNUSED, IDCLS_ENABLE_AUTOSTART_RANDOM_DELAY,
 
400
      NULL, NULL },
 
401
    { "+autostart-delay-random", SET_RESOURCE, 0,
 
402
      NULL, NULL, "AutostartDelayRandom", (resource_value_t)0,
 
403
      USE_PARAM_STRING, USE_DESCRIPTION_ID,
 
404
      IDCLS_UNUSED, IDCLS_DISABLE_AUTOSTART_RANDOM_DELAY,
 
405
      NULL, NULL },
 
406
    { NULL }
 
407
};
 
408
 
 
409
/*! \brief initialize the command-line options
 
410
 
 
411
 \return
 
412
   0 on success, else -1.
 
413
 
 
414
 \remark
 
415
   Registers the command-line options
 
416
*/
 
417
int autostart_cmdline_options_init(void)
 
418
{
 
419
    return cmdline_register_options(cmdline_options);
 
420
}
 
421
 
 
422
/* ------------------------------------------------------------------------- */
 
423
 
 
424
/* Deallocate program name if we have one */
 
425
static void deallocate_program_name(void)
 
426
{
 
427
    lib_free(autostart_program_name);
 
428
    autostart_program_name = NULL;
 
429
}
 
430
 
 
431
static enum { YES, NO, NOT_YET } check(const char *s, unsigned int blink_mode)
 
432
{
 
433
    int screen_addr, line_length, cursor_column, addr, i;
 
434
 
 
435
    screen_addr = (int)(mem_read((WORD)(pnt)) | (mem_read((WORD)(pnt + 1)) << 8));
 
436
    cursor_column = (int)mem_read((WORD)(pntr));
 
437
 
 
438
    line_length = (int)(lnmx < 0 ? -lnmx : mem_read((WORD)(lnmx)) + 1);
 
439
 
 
440
    DBG(("check(%s) addr:%04x column:%d, linelen:%d blnsw:%04x(%d)", s, screen_addr, cursor_column, line_length, blnsw, mem_read(blnsw)));
 
441
 
 
442
    if (!kbdbuf_is_empty()) {
 
443
        return NOT_YET;
 
444
    }
 
445
 
 
446
    if (blink_mode == AUTOSTART_WAIT_BLINK && cursor_column != 0) {
 
447
        return NOT_YET;
 
448
    }
 
449
 
 
450
    if (blink_mode == AUTOSTART_WAIT_BLINK && blnsw != 0 && mem_read(blnsw) != 0) {
 
451
        return NOT_YET;
 
452
    }
 
453
 
 
454
    if (blink_mode == AUTOSTART_WAIT_BLINK) {
 
455
        addr = screen_addr - line_length;
 
456
    } else {
 
457
        addr = screen_addr;
 
458
    }
 
459
 
 
460
    for (i = 0; s[i] != '\0'; i++) {
 
461
        if (mem_read((WORD)(addr + i)) != s[i] % 64) {
 
462
            if (mem_read((WORD)(addr + i)) != (BYTE)32) {
 
463
                return NO;
 
464
            }
 
465
            return NOT_YET;
 
466
        }
 
467
    }
 
468
    return YES;
 
469
}
 
470
 
 
471
static void set_true_drive_emulation_mode(int on)
 
472
{
 
473
    resources_set_int("DriveTrueEmulation", on);
 
474
    ui_update_menus();
 
475
}
 
476
 
 
477
static int get_true_drive_emulation_state(void)
 
478
{
 
479
    int value;
 
480
 
 
481
    if (resources_get_int("DriveTrueEmulation", &value) < 0) {
 
482
        return 0;
 
483
    }
 
484
 
 
485
    return value;
 
486
}
 
487
 
 
488
static void set_warp_mode(int on)
 
489
{
 
490
    resources_set_int("WarpMode", on);
 
491
    ui_update_menus();
 
492
}
 
493
 
 
494
static int get_warp_mode(void)
 
495
{
 
496
    int value;
 
497
 
 
498
    if (resources_get_int("WarpMode", &value) < 0) {
 
499
        return 0;
 
500
    }
 
501
 
 
502
    return value;
 
503
}
 
504
 
 
505
static void enable_warp_if_requested(void)
 
506
{
 
507
    /* enable warp mode? */
 
508
    if (AutostartWarp) {
 
509
        orig_warp_mode = get_warp_mode();
 
510
        if (!orig_warp_mode) {
 
511
            log_message(autostart_log, "Turning Warp mode on");
 
512
            set_warp_mode(1);
 
513
        }
 
514
    }
 
515
}
 
516
 
 
517
static void disable_warp_if_was_requested(void)
 
518
{
 
519
    /* disable warp mode */
 
520
    if (AutostartWarp) {
 
521
        if (!orig_warp_mode) {
 
522
            log_message(autostart_log, "Turning Warp mode off");
 
523
            set_warp_mode(0);
 
524
        }
 
525
    }
 
526
}
 
527
 
 
528
static void check_rom_area(void)
 
529
{
 
530
    /* enter ROM ? */
 
531
    if (!entered_rom) {
 
532
        if (reg_pc >= 0xe000) {
 
533
            log_message(autostart_log, "Entered ROM at $%04x", reg_pc);
 
534
            entered_rom = 1;
 
535
        }
 
536
    } else {
 
537
        /* special case for auto-starters: ROM left. We also consider
 
538
         * BASIC area to be ROM, because it's responsible for writing "READY."
 
539
         */
 
540
        if (machine_addr_in_ram(reg_pc)) {
 
541
            log_message(autostart_log, "Left ROM for $%04x", reg_pc);
 
542
            disable_warp_if_was_requested();
 
543
            autostart_done();
 
544
        }
 
545
    }
 
546
}
 
547
 
 
548
/* ------------------------------------------------------------------------- */
 
549
 
 
550
static void load_snapshot_trap(WORD unused_addr, void *unused_data)
 
551
{
 
552
    if (autostart_program_name
 
553
        && machine_read_snapshot((char *)autostart_program_name, 0) < 0) {
 
554
        ui_error(translate_text(IDGS_CANNOT_LOAD_SNAPSHOT_FILE));
 
555
    }
 
556
 
 
557
    ui_update_menus();
 
558
}
 
559
 
 
560
/* ------------------------------------------------------------------------- */
 
561
 
 
562
/* Reset autostart.  */
 
563
void autostart_reinit(CLOCK _min_cycles, int _handle_drive_true_emulation,
 
564
                      int _blnsw, int _pnt, int _pntr, int _lnmx)
 
565
{
 
566
    blnsw = (WORD)(_blnsw);
 
567
    pnt = _pnt;
 
568
    pntr = _pntr;
 
569
    lnmx = _lnmx;
 
570
 
 
571
    min_cycles = _min_cycles;
 
572
 
 
573
    handle_drive_true_emulation_by_machine = _handle_drive_true_emulation;
 
574
 
 
575
    set_handle_true_drive_emulation_state();
 
576
 
 
577
    if (_min_cycles) {
 
578
        autostart_enabled = 1;
 
579
    } else {
 
580
        autostart_enabled = 0;
 
581
    }
 
582
}
 
583
 
 
584
/* Initialize autostart.  */
 
585
int autostart_init(CLOCK _min_cycles, int handle_drive_true_emulation,
 
586
                   int blnsw, int pnt, int pntr, int lnmx)
 
587
{
 
588
    autostart_prg_init();
 
589
 
 
590
    autostart_reinit(_min_cycles, handle_drive_true_emulation, blnsw, pnt,
 
591
                     pntr, lnmx);
 
592
 
 
593
    if (autostart_log == LOG_ERR) {
 
594
        autostart_log = log_open("AUTOSTART");
 
595
        if (autostart_log == LOG_ERR) {
 
596
            return -1;
 
597
        }
 
598
    }
 
599
 
 
600
    return 0;
 
601
}
 
602
 
 
603
void autostart_disable(void)
 
604
{
 
605
    if (!autostart_enabled) {
 
606
        return;
 
607
    }
 
608
 
 
609
    autostartmode = AUTOSTART_ERROR;
 
610
    trigger_monitor = 0;
 
611
    deallocate_program_name();
 
612
    log_error(autostart_log, "Turned off.");
 
613
}
 
614
 
 
615
/* Control if the monitor will be triggered after an autostart */
 
616
void autostart_trigger_monitor(int enable)
 
617
{
 
618
    trigger_monitor = enable;
 
619
}
 
620
 
 
621
/* this is called after successful loading */
 
622
static void autostart_finish(void)
 
623
{
 
624
    if (autostart_run_mode == AUTOSTART_MODE_RUN) {
 
625
        log_message(autostart_log, "Starting program.");
 
626
        if ((machine_class == VICE_MACHINE_C128) && (c128_column4080_key == 0)) {
 
627
            kbdbuf_feed("GRAPHIC5:");
 
628
        }
 
629
        kbdbuf_feed(AutostartRunCommand);
 
630
    } else {
 
631
        log_message(autostart_log, "Program loaded.");
 
632
        if ((machine_class == VICE_MACHINE_C128) && (c128_column4080_key == 0)) {
 
633
            kbdbuf_feed("GRAPHIC5\x0d");
 
634
        }
 
635
    }
 
636
}
 
637
 
 
638
/* This is called if all steps of an autostart operation were passed successfully */
 
639
static void autostart_done(void)
 
640
{
 
641
    autostartmode = AUTOSTART_DONE;
 
642
 
 
643
    if (machine_class == VICE_MACHINE_C128) {
 
644
        /* restore original state of key */
 
645
        resources_set_int("40/80ColumnKey", c128_column4080_key);
 
646
    }
 
647
 
 
648
    /* Enter monitor after done */
 
649
    if (trigger_monitor) {
 
650
        trigger_monitor = 0;
 
651
        monitor_startup_trap();
 
652
        log_message(autostart_log, "Done. Returning to Monitor.");
 
653
    } else {
 
654
        log_message(autostart_log, "Done.");
 
655
    }
 
656
}
 
657
 
 
658
/* ------------------------------------------------------------------------- */
 
659
 
 
660
/* This function is called by the `serialreceivebyte()' trap as soon as EOF
 
661
   is reached.  */
 
662
static void disk_eof_callback(void)
 
663
{
 
664
    if (handle_drive_true_emulation_overridden) {
 
665
        BYTE id[2], *buffer = NULL;
 
666
        unsigned int track, sector;
 
667
        /* FIXME: shouldnt this loop over all drives? */
 
668
        if (orig_drive_true_emulation_state) {
 
669
            log_message(autostart_log, "Turning true drive emulation on.");
 
670
            if (vdrive_bam_get_disk_id(8, id) == 0) {
 
671
                vdrive_get_last_read(&track, &sector, &buffer);
 
672
            }
 
673
        }
 
674
        set_true_drive_emulation_mode(orig_drive_true_emulation_state);
 
675
        if (orig_drive_true_emulation_state) {
 
676
            if (buffer) {
 
677
                log_message(autostart_log, "Restoring true drive state of drive 8.");
 
678
                drive_set_disk_memory(id, track, sector, drive_context[0]);
 
679
                drive_set_last_read(track, sector, buffer, drive_context[0]);
 
680
            } else {
 
681
                log_message(autostart_log, "No Disk Image in drive 8.");
 
682
            }
 
683
        }
 
684
    }
 
685
 
 
686
    if (autostartmode != AUTOSTART_NONE) {
 
687
        autostart_finish();
 
688
    }
 
689
 
 
690
    autostart_done();
 
691
 
 
692
    machine_bus_eof_callback_set(NULL);
 
693
 
 
694
    disable_warp_if_was_requested();
 
695
}
 
696
 
 
697
/* This function is called by the `serialattention()' trap before
 
698
   returning.  */
 
699
static void disk_attention_callback(void)
 
700
{
 
701
    machine_bus_attention_callback_set(NULL);
 
702
 
 
703
    /* Next step is waiting for end of loading, to turn true drive emulation
 
704
       on.  */
 
705
    machine_bus_eof_callback_set(disk_eof_callback);
 
706
}
 
707
 
 
708
/* ------------------------------------------------------------------------- */
 
709
 
 
710
static void advance_hastape(void)
 
711
{
 
712
    char *tmp;
 
713
 
 
714
    switch (check("READY.", AUTOSTART_WAIT_BLINK)) {
 
715
        case YES:
 
716
            log_message(autostart_log, "Loading file.");
 
717
            if (autostart_program_name) {
 
718
                tmp = util_concat("LOAD\"", autostart_program_name, "\":\r", NULL);
 
719
                kbdbuf_feed(tmp);
 
720
                lib_free(tmp);
 
721
            } else {
 
722
                kbdbuf_feed("LOAD:\r");
 
723
            }
 
724
            autostartmode = AUTOSTART_PRESSPLAYONTAPE;
 
725
            entered_rom = 0;
 
726
            deallocate_program_name();
 
727
            break;
 
728
        case NO:
 
729
            disable_warp_if_was_requested();
 
730
            autostart_disable();
 
731
            break;
 
732
        case NOT_YET:
 
733
            break;
 
734
    }
 
735
}
 
736
 
 
737
static void advance_pressplayontape(void)
 
738
{
 
739
    switch (check("PRESS PLAY ON TAPE", AUTOSTART_NOWAIT_BLINK)) {
 
740
        case YES:
 
741
            autostartmode = AUTOSTART_LOADINGTAPE;
 
742
            datasette_control(DATASETTE_CONTROL_START);
 
743
            break;
 
744
        case NO:
 
745
            disable_warp_if_was_requested();
 
746
            autostart_disable();
 
747
            break;
 
748
        case NOT_YET:
 
749
            break;
 
750
    }
 
751
}
 
752
 
 
753
static void advance_loadingtape(void)
 
754
{
 
755
    switch (check("READY.", AUTOSTART_WAIT_BLINK)) {
 
756
        case YES:
 
757
            disable_warp_if_was_requested();
 
758
            autostart_finish();
 
759
            autostart_done();
 
760
            break;
 
761
        case NO:
 
762
            disable_warp_if_was_requested();
 
763
            autostart_disable();
 
764
            break;
 
765
        case NOT_YET:
 
766
            /* leave autostart and disable warp if ROM area was left */
 
767
            check_rom_area();
 
768
            break;
 
769
    }
 
770
}
 
771
 
 
772
static void advance_hasdisk(void)
 
773
{
 
774
    char *tmp;
 
775
    int traps;
 
776
 
 
777
    switch (check("READY.", AUTOSTART_WAIT_BLINK)) {
 
778
        case YES:
 
779
            if (autostart_program_name) {
 
780
                log_message(autostart_log, "Loading program '%s'",
 
781
                            autostart_program_name);
 
782
            } else {
 
783
                log_message(autostart_log, "Loading program '*'");
 
784
            }
 
785
            orig_drive_true_emulation_state = get_true_drive_emulation_state();
 
786
            if (handle_drive_true_emulation_overridden) {
 
787
                resources_get_int("VirtualDevices", &traps);
 
788
                if (traps) {
 
789
                    if (orig_drive_true_emulation_state) {
 
790
                        log_message(autostart_log,
 
791
                                    "Turning true drive emulation off.");
 
792
                    }
 
793
                    set_true_drive_emulation_mode(0);
 
794
                } else {
 
795
                    if (!orig_drive_true_emulation_state) {
 
796
                        log_message(autostart_log,
 
797
                                    "Turning true drive emulation on.");
 
798
                    }
 
799
                    set_true_drive_emulation_mode(1);
 
800
                }
 
801
            } else {
 
802
                if (!orig_drive_true_emulation_state) {
 
803
                    traps = 1;
 
804
                } else {
 
805
                    traps = 0;
 
806
                }
 
807
            }
 
808
 
 
809
            tmp = lib_msprintf("LOAD\"%s\",8%s:\r",
 
810
                               autostart_program_name ?
 
811
                               autostart_program_name : "*",
 
812
                               autostart_basic_load ? "" : ",1");
 
813
            DBG(("advance_hasdisk '%s'", tmp));
 
814
            kbdbuf_feed(tmp);
 
815
            lib_free(tmp);
 
816
 
 
817
            if (!traps) {
 
818
                if (AutostartWarp) {
 
819
                    autostartmode = AUTOSTART_WAITSEARCHINGFOR;
 
820
                } else {
 
821
                    /* be most compatible if warp is disabled */
 
822
                    autostart_finish();
 
823
                    autostart_done();
 
824
                }
 
825
            } else {
 
826
                autostartmode = AUTOSTART_LOADINGDISK;
 
827
                machine_bus_attention_callback_set(disk_attention_callback);
 
828
            }
 
829
 
 
830
            deallocate_program_name();
 
831
            break;
 
832
        case NO:
 
833
            orig_drive_true_emulation_state = get_true_drive_emulation_state();
 
834
            disable_warp_if_was_requested();
 
835
            autostart_disable();
 
836
            break;
 
837
        case NOT_YET:
 
838
            break;
 
839
    }
 
840
}
 
841
 
 
842
static void advance_hassnapshot(void)
 
843
{
 
844
    switch (check("READY.", AUTOSTART_WAIT_BLINK)) {
 
845
        case YES:
 
846
            autostart_done();
 
847
            log_message(autostart_log, "Restoring snapshot.");
 
848
            interrupt_maincpu_trigger_trap(load_snapshot_trap, 0);
 
849
            break;
 
850
        case NO:
 
851
            autostart_disable();
 
852
            break;
 
853
        case NOT_YET:
 
854
            break;
 
855
    }
 
856
}
 
857
 
 
858
/* ----- stages for tde disk loading with warp --------------------------- */
 
859
 
 
860
static void advance_waitsearchingfor(void)
 
861
{
 
862
    switch (check("SEARCHING FOR", AUTOSTART_NOWAIT_BLINK)) {
 
863
        case YES:
 
864
            log_message(autostart_log, "Searching for ...");
 
865
            autostartmode = AUTOSTART_WAITLOADING;
 
866
            break;
 
867
        case NO:
 
868
            log_message(autostart_log, "NO Searching for ...");
 
869
            disable_warp_if_was_requested();
 
870
            autostart_disable();
 
871
            break;
 
872
        case NOT_YET:
 
873
            break;
 
874
    }
 
875
}
 
876
 
 
877
static void advance_waitloading(void)
 
878
{
 
879
    switch (check("LOADING", AUTOSTART_NOWAIT_BLINK)) {
 
880
        case YES:
 
881
            log_message(autostart_log, "Loading");
 
882
            entered_rom = 0;
 
883
            autostartmode = AUTOSTART_WAITLOADREADY;
 
884
            break;
 
885
        case NO:
 
886
            /* still showing SEARCHING FOR ? */
 
887
            if (check("SEARCHING FOR", AUTOSTART_NOWAIT_BLINK) == YES) {
 
888
                return;
 
889
            }
 
890
            /* no something else is shown -> error! */
 
891
            log_message(autostart_log, "NO Loading");
 
892
            disable_warp_if_was_requested();
 
893
            autostart_disable();
 
894
            break;
 
895
        case NOT_YET:
 
896
            break;
 
897
    }
 
898
}
 
899
 
 
900
static void advance_waitloadready(void)
 
901
{
 
902
    switch (check("READY.", AUTOSTART_WAIT_BLINK)) {
 
903
        case YES:
 
904
            log_message(autostart_log, "Ready");
 
905
            disable_warp_if_was_requested();
 
906
            autostart_finish();
 
907
            autostart_done();
 
908
            break;
 
909
        case NO:
 
910
            log_message(autostart_log, "NO Ready");
 
911
            disable_warp_if_was_requested();
 
912
            autostart_disable();
 
913
            break;
 
914
        case NOT_YET:
 
915
            /* leave autostart and disable warp if ROM area was left */
 
916
            check_rom_area();
 
917
            break;
 
918
    }
 
919
}
 
920
 
 
921
/* After a reset a PRG file has to be injected into RAM */
 
922
static void advance_inject(void)
 
923
{
 
924
    if (autostart_prg_perform_injection(autostart_log) < 0) {
 
925
        disable_warp_if_was_requested();
 
926
        autostart_disable();
 
927
    } else {
 
928
        /* wait for ready cursor and type RUN */
 
929
        autostartmode = AUTOSTART_WAITLOADREADY;
 
930
    }
 
931
}
 
932
 
 
933
/* Execute the actions for the current `autostartmode', advancing to the next
 
934
   mode if necessary.  */
 
935
void autostart_advance(void)
 
936
{
 
937
    if (!autostart_enabled) {
 
938
        return;
 
939
    }
 
940
 
 
941
    if (orig_drive_true_emulation_state == -1) {
 
942
        orig_drive_true_emulation_state = get_true_drive_emulation_state();
 
943
    }
 
944
 
 
945
    if (maincpu_clk < autostart_initial_delay_cycles) {
 
946
        autostart_wait_for_reset = 0;
 
947
        return;
 
948
    }
 
949
 
 
950
    if (autostart_wait_for_reset) {
 
951
        return;
 
952
    }
 
953
 
 
954
    switch (autostartmode) {
 
955
        case AUTOSTART_HASTAPE:
 
956
            advance_hastape();
 
957
            break;
 
958
        case AUTOSTART_PRESSPLAYONTAPE:
 
959
            advance_pressplayontape();
 
960
            break;
 
961
        case AUTOSTART_LOADINGTAPE:
 
962
            advance_loadingtape();
 
963
            break;
 
964
        case AUTOSTART_HASDISK:
 
965
            advance_hasdisk();
 
966
            break;
 
967
        case AUTOSTART_HASSNAPSHOT:
 
968
            advance_hassnapshot();
 
969
            break;
 
970
        case AUTOSTART_WAITLOADREADY:
 
971
            advance_waitloadready();
 
972
            break;
 
973
        case AUTOSTART_WAITLOADING:
 
974
            advance_waitloading();
 
975
            break;
 
976
        case AUTOSTART_WAITSEARCHINGFOR:
 
977
            advance_waitsearchingfor();
 
978
            break;
 
979
        case AUTOSTART_INJECT:
 
980
            advance_inject();
 
981
            break;
 
982
        default:
 
983
            return;
 
984
    }
 
985
 
 
986
    if (autostartmode == AUTOSTART_ERROR && handle_drive_true_emulation_overridden) {
 
987
        log_message(autostart_log, "Now turning true drive emulation %s.",
 
988
                    orig_drive_true_emulation_state ? "on" : "off");
 
989
        set_true_drive_emulation_mode(orig_drive_true_emulation_state);
 
990
    }
 
991
}
 
992
 
 
993
/* Clean memory and reboot for autostart.  */
 
994
static void reboot_for_autostart(const char *program_name, unsigned int mode,
 
995
                                 unsigned int runmode)
 
996
{
 
997
    int rnd;
 
998
 
 
999
    if (!autostart_enabled) {
 
1000
        return;
 
1001
    }
 
1002
 
 
1003
    log_message(autostart_log, "Resetting the machine to autostart '%s'",
 
1004
                program_name ? program_name : "*");
 
1005
 
 
1006
    /* on x128 autostart will only work in 40 columns mode (and can not be fixed
 
1007
       easily for VDC mode). We work around that by switching to 40 columns and
 
1008
       back if needed */
 
1009
    if (machine_class == VICE_MACHINE_C128) {
 
1010
        resources_get_int("40/80ColumnKey", &c128_column4080_key);
 
1011
        resources_set_int("40/80ColumnKey", 1);
 
1012
    }
 
1013
 
 
1014
    mem_powerup();
 
1015
 
 
1016
    autostart_ignore_reset = 1;
 
1017
    deallocate_program_name();
 
1018
    if (program_name && program_name[0]) {
 
1019
        autostart_program_name = lib_stralloc(program_name);
 
1020
    }
 
1021
 
 
1022
    autostart_initial_delay_cycles = min_cycles;
 
1023
    resources_get_int("AutostartDelayRandom", &rnd);
 
1024
    if (rnd) {
 
1025
        autostart_initial_delay_cycles += AUTOSTART_RAND();
 
1026
    }
 
1027
    DBG(("autostart_initial_delay_cycles: %d", autostart_initial_delay_cycles));
 
1028
 
 
1029
    machine_trigger_reset(MACHINE_RESET_MODE_SOFT);
 
1030
 
 
1031
    /* The autostartmode must be set AFTER the shutdown to make the autostart
 
1032
       threadsafe for OS/2 */
 
1033
    autostartmode = mode;
 
1034
    autostart_run_mode = runmode;
 
1035
    autostart_wait_for_reset = 1;
 
1036
 
 
1037
    /* enable warp before reset */
 
1038
    if (mode != AUTOSTART_HASSNAPSHOT) {
 
1039
        enable_warp_if_requested();
 
1040
    }
 
1041
}
 
1042
 
 
1043
/* ------------------------------------------------------------------------- */
 
1044
 
 
1045
/* Autostart snapshot file `file_name'.  */
 
1046
int autostart_snapshot(const char *file_name, const char *program_name)
 
1047
{
 
1048
    BYTE vmajor, vminor;
 
1049
    snapshot_t *snap;
 
1050
 
 
1051
    if (network_connected() || event_record_active() || event_playback_active()
 
1052
        || file_name == NULL || !autostart_enabled) {
 
1053
        return -1;
 
1054
    }
 
1055
 
 
1056
    deallocate_program_name();  /* not needed at all */
 
1057
 
 
1058
    if (!(snap = snapshot_open(file_name, &vmajor, &vminor, machine_get_name()))) {
 
1059
        autostartmode = AUTOSTART_ERROR;
 
1060
        return -1;
 
1061
    }
 
1062
 
 
1063
    log_message(autostart_log, "Loading snapshot file `%s'.", file_name);
 
1064
    snapshot_close(snap);
 
1065
 
 
1066
    /*autostart_program_name = lib_stralloc(file_name);
 
1067
    interrupt_maincpu_trigger_trap(load_snapshot_trap, 0);*/
 
1068
    /* use for snapshot */
 
1069
    reboot_for_autostart(file_name, AUTOSTART_HASSNAPSHOT, AUTOSTART_MODE_RUN);
 
1070
 
 
1071
    return 0;
 
1072
}
 
1073
 
 
1074
/* Autostart tape image `file_name'.  */
 
1075
int autostart_tape(const char *file_name, const char *program_name,
 
1076
                   unsigned int program_number, unsigned int runmode)
 
1077
{
 
1078
    BYTE do_seek = 1;
 
1079
 
 
1080
    if (network_connected() || event_record_active() || event_playback_active()
 
1081
        || !file_name || !autostart_enabled) {
 
1082
        return -1;
 
1083
    }
 
1084
 
 
1085
    if (!(tape_image_attach(1, file_name) < 0)) {
 
1086
        log_message(autostart_log,
 
1087
                    "Attached file `%s' as a tape image.", file_name);
 
1088
        if (!tape_tap_attached()) {
 
1089
            if (program_number == 0 || program_number == 1) {
 
1090
                do_seek = 0;
 
1091
            }
 
1092
            program_number -= 1;
 
1093
        }
 
1094
        if (do_seek) {
 
1095
            if (program_number > 0) {
 
1096
                /* program numbers in tape_seek_to_file() start at 0 */
 
1097
                tape_seek_to_file(tape_image_dev1, program_number - 1);
 
1098
            } else {
 
1099
                tape_seek_start(tape_image_dev1);
 
1100
            }
 
1101
        }
 
1102
        resources_set_int("VirtualDevices", 1); /* Kludge: iAN CooG - for t64 images we need devtraps ON */
 
1103
        reboot_for_autostart(program_name, AUTOSTART_HASTAPE, runmode);
 
1104
 
 
1105
        return 0;
 
1106
    }
 
1107
 
 
1108
    autostartmode = AUTOSTART_ERROR;
 
1109
    deallocate_program_name();
 
1110
 
 
1111
    return -1;
 
1112
}
 
1113
 
 
1114
/* Cope with 0xa0 padded file names.  */
 
1115
static void autostart_disk_cook_name(char **name)
 
1116
{
 
1117
    unsigned int pos;
 
1118
 
 
1119
    pos = 0;
 
1120
 
 
1121
    while ((*name)[pos] != '\0') {
 
1122
        if (((unsigned char)((*name)[pos])) == 0xa0) {
 
1123
            char *ptr;
 
1124
 
 
1125
            ptr = lib_malloc(pos + 1);
 
1126
            memcpy(ptr, *name, pos);
 
1127
            ptr[pos] = '\0';
 
1128
            lib_free(*name);
 
1129
            *name = ptr;
 
1130
            break;
 
1131
        }
 
1132
        pos++;
 
1133
    }
 
1134
}
 
1135
 
 
1136
/* Autostart disk image `file_name'.  */
 
1137
int autostart_disk(const char *file_name, const char *program_name,
 
1138
                   unsigned int program_number, unsigned int runmode)
 
1139
{
 
1140
    char *name = NULL;
 
1141
 
 
1142
    if (network_connected() || event_record_active() || event_playback_active()
 
1143
        || !file_name || !autostart_enabled) {
 
1144
        return -1;
 
1145
    }
 
1146
 
 
1147
    /* Get program name first to avoid more than one file handle open on
 
1148
       image.  */
 
1149
    if (!program_name && program_number > 0) {
 
1150
        name = image_contents_filename_by_number(diskcontents_filesystem_read(file_name), program_number);
 
1151
    } else {
 
1152
        name = lib_stralloc(program_name ? program_name : "*");
 
1153
    }
 
1154
 
 
1155
    if (name) {
 
1156
        autostart_disk_cook_name(&name);
 
1157
        if (!(file_system_attach_disk(8, file_name) < 0)) {
 
1158
            log_message(autostart_log,
 
1159
                        "Attached file `%s' as a disk image.", file_name);
 
1160
            reboot_for_autostart(name, AUTOSTART_HASDISK, runmode);
 
1161
            lib_free(name);
 
1162
 
 
1163
            return 0;
 
1164
        }
 
1165
    }
 
1166
 
 
1167
    autostartmode = AUTOSTART_ERROR;
 
1168
    deallocate_program_name();
 
1169
    lib_free(name);
 
1170
 
 
1171
    return -1;
 
1172
}
 
1173
 
 
1174
/* Autostart PRG file `file_name'.  The PRG file can either be a raw CBM file
 
1175
   or a P00 file */
 
1176
int autostart_prg(const char *file_name, unsigned int runmode)
 
1177
{
 
1178
    fileio_info_t *finfo;
 
1179
    int result;
 
1180
    const char *boot_file_name;
 
1181
    int mode;
 
1182
 
 
1183
    if (network_connected() || event_record_active() || event_playback_active()) {
 
1184
        return -1;
 
1185
    }
 
1186
 
 
1187
    /* open prg file */
 
1188
    finfo = fileio_open(file_name, NULL, FILEIO_FORMAT_RAW | FILEIO_FORMAT_P00,
 
1189
                        FILEIO_COMMAND_READ | FILEIO_COMMAND_FSNAME,
 
1190
                        FILEIO_TYPE_PRG);
 
1191
 
 
1192
    /* can't open file */
 
1193
    if (finfo == NULL) {
 
1194
        log_error(autostart_log, "Cannot open `%s'.", file_name);
 
1195
        return -1;
 
1196
    }
 
1197
 
 
1198
    /* determine how to load file */
 
1199
    switch (AutostartPrgMode) {
 
1200
        case AUTOSTART_PRG_MODE_VFS:
 
1201
            log_message(autostart_log, "Loading PRG file `%s' with virtual FS on unit #8.", file_name);
 
1202
            result = autostart_prg_with_virtual_fs(file_name, finfo, autostart_log);
 
1203
            mode = AUTOSTART_HASDISK;
 
1204
            boot_file_name = (const char *)finfo->name;
 
1205
            break;
 
1206
        case AUTOSTART_PRG_MODE_INJECT:
 
1207
            log_message(autostart_log, "Loading PRG file `%s' with direct RAM injection.", file_name);
 
1208
            result = autostart_prg_with_ram_injection(file_name, finfo, autostart_log);
 
1209
            mode = AUTOSTART_INJECT;
 
1210
            boot_file_name = NULL;
 
1211
            break;
 
1212
        case AUTOSTART_PRG_MODE_DISK:
 
1213
            log_message(autostart_log, "Loading PRG file `%s' with autostart disk image.", file_name);
 
1214
            result = autostart_prg_with_disk_image(file_name, finfo, autostart_log, AutostartPrgDiskImage);
 
1215
            mode = AUTOSTART_HASDISK;
 
1216
            boot_file_name = "*";
 
1217
            break;
 
1218
        default:
 
1219
            log_error(autostart_log, "Invalid PRG autostart mode: %d", AutostartPrgMode);
 
1220
            result = -1;
 
1221
            break;
 
1222
    }
 
1223
 
 
1224
    /* Now either proceed with disk image booting or prg injection after reset */
 
1225
    if (result >= 0) {
 
1226
        ui_update_menus();
 
1227
        reboot_for_autostart(boot_file_name, mode, runmode);
 
1228
    }
 
1229
 
 
1230
    /* close prg file */
 
1231
    fileio_close(finfo);
 
1232
 
 
1233
    return result;
 
1234
}
 
1235
 
 
1236
/* ------------------------------------------------------------------------- */
 
1237
 
 
1238
int autostart_autodetect_opt_prgname(const char *file_prog_name,
 
1239
                                     unsigned int alt_prg_number,
 
1240
                                     unsigned int runmode)
 
1241
{
 
1242
    char *tmp;
 
1243
    int result;
 
1244
 
 
1245
    /* Check for image:prg -format.  */
 
1246
    tmp = strrchr(file_prog_name, ':');
 
1247
    if (tmp) {
 
1248
        char *autostart_prg_name;
 
1249
        char *autostart_file;
 
1250
 
 
1251
        autostart_file = lib_stralloc(file_prog_name);
 
1252
        autostart_prg_name = strrchr(autostart_file, ':');
 
1253
        *autostart_prg_name++ = '\0';
 
1254
        /* Does the image exist?  */
 
1255
        if (util_file_exists(autostart_file)) {
 
1256
            char *name;
 
1257
 
 
1258
            charset_petconvstring((BYTE *)autostart_prg_name, 0);
 
1259
            name = charset_replace_hexcodes(autostart_prg_name);
 
1260
            result = autostart_autodetect(autostart_file, name, 0,
 
1261
                                          runmode);
 
1262
            lib_free(name);
 
1263
        } else {
 
1264
            result = autostart_autodetect(file_prog_name, NULL, alt_prg_number,
 
1265
                                          runmode);
 
1266
        }
 
1267
        lib_free(autostart_file);
 
1268
    } else {
 
1269
        result = autostart_autodetect(file_prog_name, NULL, alt_prg_number,
 
1270
                                      runmode);
 
1271
    }
 
1272
    return result;
 
1273
}
 
1274
 
 
1275
/* Autostart `file_name', trying to auto-detect its type.  */
 
1276
int autostart_autodetect(const char *file_name, const char *program_name,
 
1277
                         unsigned int program_number, unsigned int runmode)
 
1278
{
 
1279
    if (network_connected() || event_record_active() || event_playback_active()
 
1280
        || file_name == NULL) {
 
1281
        return -1;
 
1282
    }
 
1283
 
 
1284
    if (!autostart_enabled) {
 
1285
        log_error(autostart_log,
 
1286
                  "Autostart is not available on this setup.");
 
1287
        return -1;
 
1288
    }
 
1289
 
 
1290
    log_message(autostart_log, "Autodetecting image type of `%s'.", file_name);
 
1291
 
 
1292
    if (autostart_disk(file_name, program_name, program_number, runmode) == 0) {
 
1293
        log_message(autostart_log, "`%s' recognized as disk image.", file_name);
 
1294
        return 0;
 
1295
    }
 
1296
 
 
1297
    if (machine_class != VICE_MACHINE_C64DTV && machine_class != VICE_MACHINE_SCPU64) {
 
1298
        if (autostart_tape(file_name, program_name, program_number, runmode) == 0) {
 
1299
            log_message(autostart_log, "`%s' recognized as tape image.", file_name);
 
1300
            return 0;
 
1301
        }
 
1302
    }
 
1303
 
 
1304
    if (autostart_snapshot(file_name, program_name) == 0) {
 
1305
        log_message(autostart_log, "`%s' recognized as snapshot image.",
 
1306
                    file_name);
 
1307
        return 0;
 
1308
    }
 
1309
    if (autostart_prg(file_name, runmode) == 0) {
 
1310
        log_message(autostart_log, "`%s' recognized as program/p00 file.",
 
1311
                    file_name);
 
1312
        return 0;
 
1313
    }
 
1314
 
 
1315
    log_error(autostart_log, "`%s' is not a valid file.", file_name);
 
1316
    return -1;
 
1317
}
 
1318
 
 
1319
/* Autostart the image attached to device `num'.  */
 
1320
int autostart_device(int num)
 
1321
{
 
1322
    if (network_connected() || event_playback_active() || event_record_active()
 
1323
        || !autostart_enabled) {
 
1324
        return -1;
 
1325
    }
 
1326
 
 
1327
    switch (num) {
 
1328
        case 8:
 
1329
            reboot_for_autostart(NULL, AUTOSTART_HASDISK, AUTOSTART_MODE_RUN);
 
1330
            return 0;
 
1331
        case 1:
 
1332
            reboot_for_autostart(NULL, AUTOSTART_HASTAPE, AUTOSTART_MODE_RUN);
 
1333
            return 0;
 
1334
    }
 
1335
    return -1;
 
1336
}
 
1337
 
 
1338
int autostart_in_progress(void)
 
1339
{
 
1340
    return (autostartmode != AUTOSTART_NONE && autostartmode != AUTOSTART_DONE);
 
1341
}
 
1342
 
 
1343
/* Disable autostart on reset.  */
 
1344
void autostart_reset(void)
 
1345
{
 
1346
    int oldmode;
 
1347
 
 
1348
    if (!autostart_enabled) {
 
1349
        return;
 
1350
    }
 
1351
 
 
1352
    if (!autostart_ignore_reset
 
1353
        && autostartmode != AUTOSTART_NONE
 
1354
        && autostartmode != AUTOSTART_ERROR) {
 
1355
        oldmode = autostartmode;
 
1356
        autostartmode = AUTOSTART_NONE;
 
1357
        if (oldmode != AUTOSTART_DONE) {
 
1358
            disk_eof_callback();
 
1359
        }
 
1360
        autostartmode = AUTOSTART_NONE;
 
1361
        trigger_monitor = 0;
 
1362
        deallocate_program_name();
 
1363
        log_message(autostart_log, "Turned off.");
 
1364
    }
 
1365
    autostart_ignore_reset = 0;
 
1366
}
 
1367
 
 
1368
void autostart_shutdown(void)
 
1369
{
 
1370
    deallocate_program_name();
 
1371
 
 
1372
    autostart_prg_shutdown();
 
1373
}
 
1374
 
 
1375
#ifdef ANDROID_COMPILE
 
1376
void loader_set_warpmode(int on)
 
1377
{
 
1378
    set_warp_mode(on);
 
1379
}
 
1380
#endif