summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/machine/6821pia.h
blob: 0f05acd72ed70e7ee267bba1b71869e10326e53e (plain) (blame)
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
/**********************************************************************

    Motorola 6821 PIA interface and emulation

    Notes:
        * get_port_b_z_mask() gives the caller the bitmask that shows
          which bits are high-impendance when reading port B, and thus
          neither 0 or 1. get_output_cb2_z() returns the same info
          for the CB2 pin.
        * set_port_a_z_mask allows the input callback to indicate
          which port A bits are disconnected. For these bits, the
          read operation will return the output buffer's contents.
        * The 'alt' interface functions are used when the A0 and A1
          address bits are swapped.
        * All 'int' data or return values are bool, and should be
          converted to bool at some point.

**********************************************************************/

#pragma once

#ifndef __6821PIA_H__
#define __6821PIA_H__

#include "emu.h"



/***************************************************************************
    DEVICE CONFIGURATION MACROS
***************************************************************************/

#define MDRV_PIA6821_ADD(_tag, _intrf) \
    MDRV_DEVICE_ADD(_tag, PIA6821, 0) \
    MDRV_DEVICE_CONFIG(_intrf)

#define MDRV_PIA6821_MODIFY(_tag, _intrf) \
    MDRV_DEVICE_MODIFY(_tag) \
    MDRV_DEVICE_CONFIG(_intrf)

#define MDRV_PIA6822_ADD(_tag, _intrf) \
    MDRV_DEVICE_ADD(_tag, PIA6822, 0) \
    MDRV_DEVICE_CONFIG(_intrf)

#define MDRV_PIA6822_MODIFY(_tag, _intrf) \
    MDRV_DEVICE_MODIFY(_tag) \
    MDRV_DEVICE_CONFIG(_intrf)



/***************************************************************************
    TYPE DEFINITIONS
***************************************************************************/


// ======================> pia6821_interface

struct pia6821_interface
{
    devcb_read8 m_in_a_func;
    devcb_read8 m_in_b_func;
    devcb_read_line m_in_ca1_func;
    devcb_read_line m_in_cb1_func;
    devcb_read_line m_in_ca2_func;
    devcb_read_line m_in_cb2_func;
    devcb_write8 m_out_a_func;
    devcb_write8 m_out_b_func;
    devcb_write_line m_out_ca2_func;
    devcb_write_line m_out_cb2_func;
    devcb_write_line m_irq_a_func;
    devcb_write_line m_irq_b_func;
};



// ======================> pia6821_device_config

class pia6821_device_config : public device_config,
                              public pia6821_interface
{
    friend class pia6821_device;

    // construction/destruction
    pia6821_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);

public:
    // allocators
    static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
    virtual device_t *alloc_device(running_machine &machine) const;

protected:
    // device_config overrides
    virtual void device_config_complete();
};



// ======================> pia6821_device

class pia6821_device :  public device_t
{
    friend class pia6821_device_config;

    // construction/destruction
    pia6821_device(running_machine &_machine, const pia6821_device_config &_config);

public:

    UINT8 reg_r(UINT8 offset);
    void reg_w(UINT8 offset, UINT8 data);

    UINT8 alt_r(UINT8 offset);
    void alt_w(UINT8 offset, UINT8 data);

    UINT8 get_port_b_z_mask();          /* see first note in .c */
    void set_port_a_z_mask(UINT8 data); /* see second note in .c */

    UINT8 porta_r();
    void porta_w(UINT8 data);
    void set_input_a(UINT8 data, UINT8 z_mask);
    UINT8 get_output_a();

    UINT8 ca1_r();
    void ca1_w(UINT8 state);

    UINT8 ca2_r();
    void ca2_w(UINT8 state);
    int get_output_ca2();
    int get_output_ca2_z();

    UINT8 portb_r();
    void portb_w(UINT8 data);
    UINT8 get_output_b();

    UINT8 cb1_r();
    void cb1_w(UINT8 state);

    UINT8 cb2_r();
    void cb2_w(UINT8 state);
    int get_output_cb2();
    int get_output_cb2_z();

    int get_irq_a();
    int get_irq_b();

protected:
    // device-level overrides
    virtual void device_start();
    virtual void device_reset();
    virtual void device_post_load() { }
    virtual void device_clock_changed() { }

private:

    void update_interrupts();

    UINT8 get_in_a_value();
    UINT8 get_in_b_value();

    UINT8 get_out_a_value();
    UINT8 get_out_b_value();

    void set_out_ca2(int data);
    void set_out_cb2(int data);

    UINT8 port_a_r();
    UINT8 ddr_a_r();
    UINT8 control_a_r();

    UINT8 port_b_r();
    UINT8 ddr_b_r();
    UINT8 control_b_r();

    void send_to_out_a_func(const char* message);
    void send_to_out_b_func(const char* message);

    void port_a_w(UINT8 data);
    void ddr_a_w(UINT8 data);

    void port_b_w(UINT8 data);
    void ddr_b_w(UINT8 data);

    void control_a_w(UINT8 data);
    void control_b_w(UINT8 data);

    devcb_resolved_read8 m_in_a_func;
    devcb_resolved_read8 m_in_b_func;
    devcb_resolved_read_line m_in_ca1_func;
    devcb_resolved_read_line m_in_cb1_func;
    devcb_resolved_read_line m_in_ca2_func;
    devcb_resolved_read_line m_in_cb2_func;
    devcb_resolved_write8 m_out_a_func;
    devcb_resolved_write8 m_out_b_func;
    devcb_resolved_write_line m_out_ca2_func;
    devcb_resolved_write_line m_out_cb2_func;
    devcb_resolved_write_line m_irq_a_func;
    devcb_resolved_write_line m_irq_b_func;

    UINT8 m_in_a;
    UINT8 m_in_ca1;
    UINT8 m_in_ca2;
    UINT8 m_out_a;
    UINT8 m_out_ca2;
    UINT8 m_port_a_z_mask;
    UINT8 m_ddr_a;
    UINT8 m_ctl_a;
    UINT8 m_irq_a1;
    UINT8 m_irq_a2;
    UINT8 m_irq_a_state;

    UINT8 m_in_b;
    UINT8 m_in_cb1;
    UINT8 m_in_cb2;
    UINT8 m_out_b;
    UINT8 m_out_cb2;
    UINT8 m_last_out_cb2_z;
    UINT8 m_ddr_b;
    UINT8 m_ctl_b;
    UINT8 m_irq_b1;
    UINT8 m_irq_b2;
    UINT8 m_irq_b_state;

    /* variables that indicate if access a line externally -
       used to for logging purposes ONLY */
    UINT8 m_in_a_pushed;
    UINT8 m_out_a_needs_pulled;
    UINT8 m_in_ca1_pushed;
    UINT8 m_in_ca2_pushed;
    UINT8 m_out_ca2_needs_pulled;
    UINT8 m_in_b_pushed;
    UINT8 m_out_b_needs_pulled;
    UINT8 m_in_cb1_pushed;
    UINT8 m_in_cb2_pushed;
    UINT8 m_out_cb2_needs_pulled;
    UINT8 m_logged_port_a_not_connected;
    UINT8 m_logged_port_b_not_connected;
    UINT8 m_logged_ca1_not_connected;
    UINT8 m_logged_ca2_not_connected;
    UINT8 m_logged_cb1_not_connected;
    UINT8 m_logged_cb2_not_connected;

    const pia6821_device_config &m_config;
};


// device type definition
extern const device_type PIA6821;



/***************************************************************************
    PROTOTYPES
***************************************************************************/

READ8_DEVICE_HANDLER( pia6821_r );
WRITE8_DEVICE_HANDLER( pia6821_w );

READ8_DEVICE_HANDLER( pia6821_alt_r );
WRITE8_DEVICE_HANDLER( pia6821_alt_w );

UINT8 pia6821_get_port_b_z_mask(running_device *device);  /* see first note */
void pia6821_set_port_a_z_mask(running_device *device, UINT8 data);  /* see second note */

READ8_DEVICE_HANDLER( pia6821_porta_r );
WRITE8_DEVICE_HANDLER( pia6821_porta_w );
void pia6821_set_input_a(running_device *device, UINT8 data, UINT8 z_mask);
UINT8 pia6821_get_output_a(running_device *device);

READ_LINE_DEVICE_HANDLER( pia6821_ca1_r );
WRITE_LINE_DEVICE_HANDLER( pia6821_ca1_w );

READ_LINE_DEVICE_HANDLER( pia6821_ca2_r );
WRITE_LINE_DEVICE_HANDLER( pia6821_ca2_w );
int pia6821_get_output_ca2(running_device *device);
int pia6821_get_output_ca2_z(running_device *device);

READ8_DEVICE_HANDLER( pia6821_portb_r );
WRITE8_DEVICE_HANDLER( pia6821_portb_w );
UINT8 pia6821_get_output_b(running_device *device);

READ_LINE_DEVICE_HANDLER( pia6821_cb1_r );
WRITE_LINE_DEVICE_HANDLER( pia6821_cb1_w );

READ_LINE_DEVICE_HANDLER( pia6821_cb2_r );
WRITE_LINE_DEVICE_HANDLER( pia6821_cb2_w );
int pia6821_get_output_cb2(running_device *device);
int pia6821_get_output_cb2_z(running_device *device);

int pia6821_get_irq_a(running_device *device);
int pia6821_get_irq_b(running_device *device);


#endif /* __6821PIA_H__ */