37 | 37 |
bit5 C2_INPUT C2_OUTPUT
|
38 | 38 |
*/
|
39 | 39 |
#define PIA_IRQ1 0x80
|
40 | |
#define PIA_IRQ2 0x40
|
|
40 |
#define PIA_IRQ2 0x40
|
41 | 41 |
#define SET_IRQ1(c) c |= PIA_IRQ1;
|
42 | 42 |
#define SET_IRQ2(c) c |= PIA_IRQ2;
|
43 | 43 |
#define CLEAR_IRQ1(c) c &= ~PIA_IRQ1;
|
|
119 | 119 |
{
|
120 | 120 |
BYTE retval = 0;
|
121 | 121 |
byRS &= 3;
|
122 | |
switch ( byRS )
|
123 | |
{
|
|
122 |
switch (byRS) {
|
124 | 123 |
/******************* port A output/DDR read *******************/
|
125 | |
case PIA_DDRA:
|
126 | |
// read output register
|
127 | |
if ( OUTPUT_SELECTED(m_byCTLA) )
|
128 | |
{
|
129 | |
// combine input and output values
|
130 | |
retval = ( m_byOA & m_byDDRA ) | ( m_byIA & ~m_byDDRA );
|
131 | |
// IRQ flags implicitly cleared by a read
|
132 | |
CLEAR_IRQ1( m_byCTLA );
|
133 | |
CLEAR_IRQ1( m_byCTLB );
|
|
124 |
case PIA_DDRA:
|
|
125 |
// read output register
|
|
126 |
if (OUTPUT_SELECTED(m_byCTLA)) {
|
|
127 |
// combine input and output values
|
|
128 |
retval = (m_byOA & m_byDDRA) | (m_byIA & ~m_byDDRA);
|
|
129 |
// IRQ flags implicitly cleared by a read
|
|
130 |
CLEAR_IRQ1(m_byCTLA);
|
|
131 |
CLEAR_IRQ1(m_byCTLB);
|
|
132 |
UpdateInterrupts();
|
|
133 |
// CA2 is configured as output and in read strobe mode
|
|
134 |
if (C2_OUTPUT(m_byCTLA) && C2_STROBE_MODE(m_byCTLA)) {
|
|
135 |
// this will cause a transition low; call the output function if we're currently high
|
|
136 |
if (m_byOCA2)
|
|
137 |
PIA_W_CALLBACK(m_stOutCA2, 0);
|
|
138 |
m_byOCA2 = 0;
|
|
139 |
|
|
140 |
// if the CA2 strobe is cleared by the E, reset it right away
|
|
141 |
if (STROBE_E_RESET(m_byCTLA)) {
|
|
142 |
PIA_W_CALLBACK(m_stOutCA2, 1);
|
|
143 |
m_byOCA2 = 1;
|
|
144 |
}
|
|
145 |
}
|
|
146 |
}
|
|
147 |
// read DDR register
|
|
148 |
else {
|
|
149 |
retval = m_byDDRA;
|
|
150 |
}
|
|
151 |
break;
|
|
152 |
|
|
153 |
/******************* port B output/DDR read *******************/
|
|
154 |
case PIA_DDRB:
|
|
155 |
|
|
156 |
// read output register
|
|
157 |
if (OUTPUT_SELECTED(m_byCTLB)) {
|
|
158 |
// combine input and output values
|
|
159 |
retval = (m_byOB & m_byDDRB) + (m_byIB & ~m_byDDRB);
|
|
160 |
|
|
161 |
// IRQ flags implicitly cleared by a read
|
|
162 |
CLEAR_IRQ2(m_byCTLA);
|
|
163 |
CLEAR_IRQ2(m_byCTLB);
|
|
164 |
UpdateInterrupts();
|
|
165 |
}
|
|
166 |
/* read DDR register */
|
|
167 |
else {
|
|
168 |
retval = m_byDDRB;
|
|
169 |
}
|
|
170 |
break;
|
|
171 |
|
|
172 |
/******************* port A control read *******************/
|
|
173 |
case PIA_CTLA:
|
|
174 |
// read control register
|
|
175 |
retval = m_byCTLA;
|
|
176 |
// when CA2 is an output, IRQA2 = 0, and is not affected by CA2 transitions.
|
|
177 |
if (C2_OUTPUT(m_byCTLA))
|
|
178 |
retval &= ~PIA_IRQ2;
|
|
179 |
break;
|
|
180 |
|
|
181 |
/******************* port B control read *******************/
|
|
182 |
case PIA_CTLB:
|
|
183 |
retval = m_byCTLB;
|
|
184 |
// when CB2 is an output, IRQB2 = 0, and is not affected by CB2 transitions.
|
|
185 |
if (C2_OUTPUT(m_byCTLB))
|
|
186 |
retval &= ~PIA_IRQ2;
|
|
187 |
break;
|
|
188 |
|
|
189 |
}
|
|
190 |
|
|
191 |
return retval;
|
|
192 |
}
|
|
193 |
|
|
194 |
void C6821::Write(BYTE byRS, BYTE byData)
|
|
195 |
{
|
|
196 |
byRS &= 3;
|
|
197 |
|
|
198 |
switch( byRS ) {
|
|
199 |
/******************* port A output/DDR write *******************/
|
|
200 |
case PIA_DDRA:
|
|
201 |
|
|
202 |
// write output register
|
|
203 |
if (OUTPUT_SELECTED(m_byCTLA)) {
|
|
204 |
// update the output value
|
|
205 |
m_byOA = byData;
|
|
206 |
|
|
207 |
// send it to the output function
|
|
208 |
if (m_byDDRA)
|
|
209 |
PIA_W_CALLBACK(m_stOutA, m_byOA & m_byDDRA);
|
|
210 |
}
|
|
211 |
|
|
212 |
// write DDR register
|
|
213 |
else {
|
|
214 |
if (m_byDDRA != byData) {
|
|
215 |
m_byDDRA = byData;
|
|
216 |
|
|
217 |
// send it to the output function
|
|
218 |
if (m_byDDRA)
|
|
219 |
PIA_W_CALLBACK(m_stOutA, m_byOA & m_byDDRA);
|
|
220 |
}
|
|
221 |
}
|
|
222 |
break;
|
|
223 |
|
|
224 |
/******************* port B output/DDR write *******************/
|
|
225 |
case PIA_DDRB:
|
|
226 |
|
|
227 |
// write output register
|
|
228 |
if (OUTPUT_SELECTED(m_byCTLB)) {
|
|
229 |
// update the output value
|
|
230 |
m_byOB = byData;
|
|
231 |
|
|
232 |
// send it to the output function
|
|
233 |
if (m_byDDRB)
|
|
234 |
PIA_W_CALLBACK(m_stOutB, m_byOB & m_byDDRB);
|
|
235 |
|
|
236 |
// CB2 is configured as output and in write strobe mode
|
|
237 |
if (C2_OUTPUT(m_byCTLB) && C2_STROBE_MODE(m_byCTLB)) {
|
|
238 |
// this will cause a transition low; call the output function if we're currently high
|
|
239 |
if (m_byOCB2)
|
|
240 |
PIA_W_CALLBACK(m_stOutCB2, 0);
|
|
241 |
m_byOCB2 = 0;
|
|
242 |
|
|
243 |
// if the CB2 strobe is cleared by the E, reset it right away
|
|
244 |
if (STROBE_E_RESET(m_byCTLB)) {
|
|
245 |
PIA_W_CALLBACK(m_stOutCB2, 1);
|
|
246 |
m_byOCB2 = 1;
|
|
247 |
}
|
|
248 |
}
|
|
249 |
}
|
|
250 |
// write DDR register
|
|
251 |
else {
|
|
252 |
if (m_byDDRB != byData) {
|
|
253 |
m_byDDRB = byData;
|
|
254 |
|
|
255 |
// send it to the output function
|
|
256 |
if (m_byDDRB)
|
|
257 |
PIA_W_CALLBACK(m_stOutB, m_byOB & m_byDDRB);
|
|
258 |
}
|
|
259 |
}
|
|
260 |
break;
|
|
261 |
|
|
262 |
/******************* port A control write *******************/
|
|
263 |
case PIA_CTLA:
|
|
264 |
// Bit 7 and 6 read only
|
|
265 |
byData &= 0x3f;
|
|
266 |
|
|
267 |
// CA2 is configured as output and in set/reset mode
|
|
268 |
if (C2_OUTPUT(byData)) {
|
|
269 |
// determine the new value
|
|
270 |
int temp = SET_C2(byData) ? 1 : 0;
|
|
271 |
|
|
272 |
// if this creates a transition, call the CA2 output function
|
|
273 |
if (m_byOCA2 ^ temp)
|
|
274 |
PIA_W_CALLBACK(m_stOutCA2, temp);
|
|
275 |
|
|
276 |
// set the new value
|
|
277 |
m_byOCA2 = temp;
|
|
278 |
}
|
|
279 |
|
|
280 |
// update the control register
|
|
281 |
m_byCTLA = (m_byCTLA & ~0x3F) | byData;
|
|
282 |
|
|
283 |
// update externals
|
134 | 284 |
UpdateInterrupts();
|
135 | |
// CA2 is configured as output and in read strobe mode
|
136 | |
if ( C2_OUTPUT(m_byCTLA) && C2_STROBE_MODE(m_byCTLA) )
|
137 | |
{
|
138 | |
// this will cause a transition low; call the output function if we're currently high
|
139 | |
if ( m_byOCA2 )
|
140 | |
PIA_W_CALLBACK( m_stOutCA2, 0 );
|
141 | |
m_byOCA2 = 0;
|
142 | |
|
143 | |
// if the CA2 strobe is cleared by the E, reset it right away
|
144 | |
if ( STROBE_E_RESET( m_byCTLA ) )
|
145 | |
{
|
146 | |
PIA_W_CALLBACK( m_stOutCA2, 1 );
|
147 | |
m_byOCA2 = 1;
|
148 | |
}
|
149 | |
}
|
150 | |
}
|
151 | |
// read DDR register
|
152 | |
else
|
153 | |
{
|
154 | |
retval = m_byDDRA;
|
155 | |
}
|
156 | |
break;
|
157 | |
|
158 | |
/******************* port B output/DDR read *******************/
|
159 | |
case PIA_DDRB:
|
160 | |
|
161 | |
// read output register
|
162 | |
if ( OUTPUT_SELECTED( m_byCTLB ) )
|
163 | |
{
|
164 | |
// combine input and output values
|
165 | |
retval = ( m_byOB & m_byDDRB ) + ( m_byIB & ~m_byDDRB );
|
166 | |
|
167 | |
// IRQ flags implicitly cleared by a read
|
168 | |
CLEAR_IRQ2( m_byCTLA );
|
169 | |
CLEAR_IRQ2( m_byCTLB );
|
|
285 |
break;
|
|
286 |
|
|
287 |
/******************* port B control write *******************/
|
|
288 |
case PIA_CTLB:
|
|
289 |
|
|
290 |
/* Bit 7 and 6 read only - PD 16/01/00 */
|
|
291 |
|
|
292 |
byData &= 0x3f;
|
|
293 |
|
|
294 |
// CB2 is configured as output and in set/reset mode
|
|
295 |
if (C2_OUTPUT(byData)) {
|
|
296 |
// determine the new value
|
|
297 |
int temp = SET_C2(byData) ? 1 : 0;
|
|
298 |
|
|
299 |
// if this creates a transition, call the CA2 output function
|
|
300 |
if (m_byOCB2 ^ temp)
|
|
301 |
PIA_W_CALLBACK(m_stOutCB2, temp);
|
|
302 |
|
|
303 |
// set the new value
|
|
304 |
m_byOCB2 = temp;
|
|
305 |
}
|
|
306 |
|
|
307 |
// update the control register
|
|
308 |
m_byCTLB = (m_byCTLB & ~0x3F) | byData;
|
|
309 |
|
|
310 |
// update externals
|
170 | 311 |
UpdateInterrupts();
|
171 | |
}
|
172 | |
/* read DDR register */
|
173 | |
else
|
174 | |
{
|
175 | |
retval = m_byDDRB;
|
176 | |
}
|
177 | |
break;
|
178 | |
|
179 | |
/******************* port A control read *******************/
|
180 | |
case PIA_CTLA:
|
181 | |
// read control register
|
182 | |
retval = m_byCTLA;
|
183 | |
// when CA2 is an output, IRQA2 = 0, and is not affected by CA2 transitions.
|
184 | |
if ( C2_OUTPUT( m_byCTLA ) )
|
185 | |
retval &= ~PIA_IRQ2;
|
186 | |
break;
|
187 | |
|
188 | |
/******************* port B control read *******************/
|
189 | |
case PIA_CTLB:
|
190 | |
retval = m_byCTLB;
|
191 | |
// when CB2 is an output, IRQB2 = 0, and is not affected by CB2 transitions.
|
192 | |
if ( C2_OUTPUT( m_byCTLB ) )
|
193 | |
retval &= ~PIA_IRQ2;
|
194 | |
break;
|
195 | |
|
196 | |
}
|
197 | |
|
198 | |
return retval;
|
199 | |
}
|
200 | |
|
201 | |
void C6821::Write(BYTE byRS, BYTE byData)
|
202 | |
{
|
203 | |
byRS &= 3;
|
204 | |
|
205 | |
switch( byRS )
|
206 | |
{
|
207 | |
/******************* port A output/DDR write *******************/
|
208 | |
case PIA_DDRA:
|
209 | |
|
210 | |
// write output register
|
211 | |
if ( OUTPUT_SELECTED( m_byCTLA ) )
|
212 | |
{
|
213 | |
// update the output value
|
214 | |
m_byOA = byData;
|
215 | |
|
216 | |
// send it to the output function
|
217 | |
if ( m_byDDRA )
|
218 | |
PIA_W_CALLBACK( m_stOutA, m_byOA & m_byDDRA );
|
219 | |
}
|
220 | |
|
221 | |
// write DDR register
|
222 | |
else
|
223 | |
{
|
224 | |
if ( m_byDDRA != byData )
|
225 | |
{
|
226 | |
m_byDDRA = byData;
|
227 | |
|
228 | |
// send it to the output function
|
229 | |
if ( m_byDDRA )
|
230 | |
PIA_W_CALLBACK( m_stOutA, m_byOA & m_byDDRA );
|
231 | |
}
|
232 | |
}
|
233 | |
break;
|
234 | |
|
235 | |
/******************* port B output/DDR write *******************/
|
236 | |
case PIA_DDRB:
|
237 | |
|
238 | |
// write output register
|
239 | |
if ( OUTPUT_SELECTED( m_byCTLB ) )
|
240 | |
{
|
241 | |
// update the output value
|
242 | |
m_byOB = byData;
|
243 | |
|
244 | |
// send it to the output function
|
245 | |
if ( m_byDDRB )
|
246 | |
PIA_W_CALLBACK( m_stOutB, m_byOB & m_byDDRB );
|
247 | |
|
248 | |
// CB2 is configured as output and in write strobe mode
|
249 | |
if ( C2_OUTPUT( m_byCTLB ) && C2_STROBE_MODE( m_byCTLB ) )
|
250 | |
{
|
251 | |
// this will cause a transition low; call the output function if we're currently high
|
252 | |
if ( m_byOCB2 )
|
253 | |
PIA_W_CALLBACK( m_stOutCB2, 0 );
|
254 | |
m_byOCB2 = 0;
|
255 | |
|
256 | |
// if the CB2 strobe is cleared by the E, reset it right away
|
257 | |
if ( STROBE_E_RESET( m_byCTLB ) )
|
258 | |
{
|
259 | |
PIA_W_CALLBACK( m_stOutCB2, 1 );
|
260 | |
m_byOCB2 = 1;
|
261 | |
}
|
262 | |
}
|
263 | |
}
|
264 | |
// write DDR register
|
265 | |
else
|
266 | |
{
|
267 | |
if ( m_byDDRB != byData )
|
268 | |
{
|
269 | |
m_byDDRB = byData;
|
270 | |
|
271 | |
// send it to the output function
|
272 | |
if ( m_byDDRB )
|
273 | |
PIA_W_CALLBACK( m_stOutB, m_byOB & m_byDDRB );
|
274 | |
}
|
275 | |
}
|
276 | |
break;
|
277 | |
|
278 | |
/******************* port A control write *******************/
|
279 | |
case PIA_CTLA:
|
280 | |
// Bit 7 and 6 read only
|
281 | |
byData &= 0x3f;
|
282 | |
|
283 | |
// CA2 is configured as output and in set/reset mode
|
284 | |
if ( C2_OUTPUT( byData ) )
|
285 | |
{
|
286 | |
// determine the new value
|
287 | |
int temp = SET_C2( byData ) ? 1 : 0;
|
288 | |
|
289 | |
// if this creates a transition, call the CA2 output function
|
290 | |
if ( m_byOCA2 ^ temp)
|
291 | |
PIA_W_CALLBACK( m_stOutCA2, temp );
|
292 | |
|
293 | |
// set the new value
|
294 | |
m_byOCA2 = temp;
|
295 | |
}
|
296 | |
|
297 | |
// update the control register
|
298 | |
m_byCTLA = ( m_byCTLA & ~0x3F ) | byData;
|
299 | |
|
300 | |
// update externals
|
301 | |
UpdateInterrupts();
|
302 | |
break;
|
303 | |
|
304 | |
/******************* port B control write *******************/
|
305 | |
case PIA_CTLB:
|
306 | |
|
307 | |
/* Bit 7 and 6 read only - PD 16/01/00 */
|
308 | |
|
309 | |
byData &= 0x3f;
|
310 | |
|
311 | |
// CB2 is configured as output and in set/reset mode
|
312 | |
if ( C2_OUTPUT( byData ) )
|
313 | |
{
|
314 | |
// determine the new value
|
315 | |
int temp = SET_C2( byData ) ? 1 : 0;
|
316 | |
|
317 | |
// if this creates a transition, call the CA2 output function
|
318 | |
if ( m_byOCB2 ^ temp)
|
319 | |
PIA_W_CALLBACK( m_stOutCB2, temp );
|
320 | |
|
321 | |
// set the new value
|
322 | |
m_byOCB2 = temp;
|
323 | |
}
|
324 | |
|
325 | |
// update the control register
|
326 | |
m_byCTLB = ( m_byCTLB & ~0x3F ) | byData;
|
327 | |
|
328 | |
// update externals
|
329 | |
UpdateInterrupts();
|
330 | |
break;
|
|
312 |
break;
|
331 | 313 |
}
|
332 | 314 |
|
333 | 315 |
}
|
|
427 | 409 |
if ( m_byICA2 ^ byData )
|
428 | 410 |
{
|
429 | 411 |
// handle the active transition
|
430 | |
if ( ( byData && C2_LOW_TO_HIGH( m_byCTLA ) ) ||
|
431 | |
( !byData && C2_HIGH_TO_LOW( m_byCTLA ) ) )
|
432 | |
{
|
|
412 |
if ((byData && C2_LOW_TO_HIGH(m_byCTLA)) ||
|
|
413 |
(!byData && C2_HIGH_TO_LOW(m_byCTLA))) {
|
433 | 414 |
// mark the IRQ
|
434 | |
SET_IRQ2( m_byCTLA );
|
|
415 |
SET_IRQ2(m_byCTLA);
|
435 | 416 |
|
436 | 417 |
// update externals
|
437 | 418 |
UpdateInterrupts();
|