File: plus4parallel.c

package info (click to toggle)
vice 3.7.1%2Bdfsg1-2
  • links: PTS
  • area: contrib
  • in suites: bookworm
  • size: 49,876 kB
  • sloc: ansic: 431,530; cpp: 35,357; sh: 9,747; makefile: 7,010; perl: 1,822; yacc: 1,197; lex: 589; sed: 184; objc: 115; xml: 36
file content (140 lines) | stat: -rw-r--r-- 4,798 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
 * plus4parallel.c - Parallel cable handling for the Plus4.
 *
 * Written by
 *  Andreas Boose <viceteam@t-online.de>
 *
 * This file is part of VICE, the Versatile Commodore Emulator.
 * See README for copyright notice.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 *  02111-1307  USA.
 *
 */

#include "vice.h"

#include "drive.h"
#include "drivetypes.h"
#include "iecdrive.h"
#include "joyport.h"
#include "maincpu.h"
#include "plus4parallel.h"
#include "ted.h"
#include "types.h"
#include "userport.h"

static uint8_t parallel_cable_cpu_value = 0xff;
static uint8_t parallel_cable_drive_value[NUM_DISK_UNITS] = { 0xff, 0xff, 0xff, 0xff };

static int parallel_cable_enabled = 0;

void parallel_cable_drive_write(int port, uint8_t data, int handshake, unsigned int dnr)
{
    parallel_cable_drive_value[dnr] = data;
}

uint8_t parallel_cable_drive_read(int type, int handshake)
{
    return parallel_cable_cpu_value & parallel_cable_drive_value[0] & parallel_cable_drive_value[1];
}

/* ------------------------------------------------------------------------- */

/* Some prototypes are needed */
static void parallel_cable_cpu_write(int type, uint8_t data);
static uint8_t parallel_cable_cpu_read(int type, uint8_t orig);
static void userport_par_cable_store_pbx(uint8_t data, int pulse);
static uint8_t userport_par_cable_read_pbx(uint8_t orig);
static int userport_par_cable_enable(int value);

static userport_device_t par_cable_device = {
    "Userport parallel drive cable",      /* device name */
    JOYSTICK_ADAPTER_ID_NONE,             /* NOT a joystick adapter */
    USERPORT_DEVICE_TYPE_DRIVE_PAR_CABLE, /* device is a parallel drive cable */
    userport_par_cable_enable,            /* enable function */
    userport_par_cable_read_pbx,          /* read pb0-pb7 function */
    userport_par_cable_store_pbx,         /* NO store pb0-pb7 function */
    NULL,                                 /* NO read pa2 pin function */
    NULL,                                 /* NO store pa2 pin function */
    NULL,                                 /* NO read pa3 pin function */
    NULL,                                 /* NO store pa3 pin function */
    0,                                    /* pc pin is NOT needed */
    NULL,                                 /* NO store sp1 pin function */
    NULL,                                 /* NO read sp1 pin function */
    NULL,                                 /* NO store sp2 pin function */
    NULL,                                 /* NO read sp2 pin function */
    NULL,                                 /* NO reset pin function */
    NULL,                                 /* NO power toggle function */
    NULL,                                 /* NO snapshot write function */
    NULL                                  /* NO snapshot read function */
};

static int userport_par_cable_enable(int value)
{
    int val = value ? 1 : 0;

    parallel_cable_enabled = val;

    return 0;
}

static void userport_par_cable_store_pbx(uint8_t data, int pulse)
{
    parallel_cable_cpu_write(DRIVE_PC_STANDARD, data);
}

static uint8_t userport_par_cable_read_pbx(uint8_t orig)
{
    return parallel_cable_cpu_read(DRIVE_PC_STANDARD, orig);
}

int parallel_cable_cpu_resources_init(void)
{
    return userport_device_register(USERPORT_DEVICE_DRIVE_PAR_CABLE, &par_cable_device);
}

/* ------------------------------------------------------------------------- */

static void parallel_cable_cpu_write(int type, uint8_t data)
{
    if (!(diskunit_context[0]->enable)
        && !(diskunit_context[1]->enable)) {
        return;
    }

    drive_cpu_execute_all(last_write_cycle);

    parallel_cable_cpu_value = data;
}

static uint8_t parallel_cable_cpu_read(int type, uint8_t orig)
{
    uint8_t data = 0xff;

    if (!(diskunit_context[0]->enable)
        && !(diskunit_context[1]->enable)) {
        return orig;
    }

    drive_cpu_execute_all(maincpu_clk);

    return data & (parallel_cable_cpu_value & parallel_cable_drive_value[0] & parallel_cable_drive_value[1]);
}

void parallel_cable_cpu_undump(int type, uint8_t data)
{
    parallel_cable_cpu_value = data;
}