1 // license:BSD-3-Clause
2 // copyright-holders:F. Ulivi
3 /*********************************************************************
4
5 tms9914.cpp
6
7 Texas Instruments TMS9914(A) GPIB Controller
8
9 TODO:
10 - A few interface commands
11 - A few auxiliary commands
12
13 Main reference for this IC:
14 TI, jun 89, TMS9914A GPIB Controller - Data Manual
15
16 **********************************************************************/
17
18 #include "emu.h"
19 #include "tms9914.h"
20
21 // Debugging
22 #define LOG_NOISY_MASK (LOG_GENERAL << 1)
23 #define LOG_NOISY(...) LOGMASKED(LOG_NOISY_MASK, __VA_ARGS__)
24 #define LOG_REG_MASK (LOG_NOISY_MASK << 1)
25 #define LOG_REG(...) LOGMASKED(LOG_REG_MASK, __VA_ARGS__)
26 #define LOG_INT_MASK (LOG_REG_MASK << 1)
27 #define LOG_INT(...) LOGMASKED(LOG_INT_MASK, __VA_ARGS__)
28 //#define VERBOSE (LOG_GENERAL)
29 #include "logmacro.h"
30
31 // Bit manipulation
32 namespace {
BIT_MASK(unsigned n)33 template<typename T> constexpr T BIT_MASK(unsigned n)
34 {
35 return (T)1U << n;
36 }
37
BIT_CLR(T & w,unsigned n)38 template<typename T> void BIT_CLR(T& w , unsigned n)
39 {
40 w &= ~BIT_MASK<T>(n);
41 }
42
BIT_SET(T & w,unsigned n)43 template<typename T> void BIT_SET(T& w , unsigned n)
44 {
45 w |= BIT_MASK<T>(n);
46 }
47 }
48
49 // Registers
50 enum {
51 REG_R_INT_STAT0 = 0, // R 0: Interrupt status 0
52 REG_R_INT_STAT1 = 1, // R 1: Interrupt status 1
53 REG_R_ADDR_STAT = 2, // R 2: Address status
54 REG_R_BUS_STAT = 3, // R 3: Bus status
55 REG_R_CMD_PT = 6, // R 6: Command pass-through
56 REG_R_DI = 7, // R 7: Data input
57 REG_W_INT_MASK0 = 0, // W 0: Interrupt mask 0
58 REG_W_INT_MASK1 = 1, // W 1: Interrupt mask 1
59 REG_W_AUX_CMD = 3, // W 3: Auxiliary command
60 REG_W_ADDRESS = 4, // W 4: Address
61 REG_W_SERIAL_P = 5, // W 5: Serial poll
62 REG_W_PARALLEL_P = 6, // W 6: Parallel poll
63 REG_W_DO = 7 // W 7: Data output
64 };
65
66 // Interrupt status/mask 0
67 constexpr unsigned REG_INT0_MAC_BIT = 0; // My Address status Changed
68 constexpr unsigned REG_INT0_RLC_BIT = 1; // Remote/Local status Changed
69 constexpr unsigned REG_INT0_SPAS_BIT = 2; // Polled by serial poll
70 constexpr unsigned REG_INT0_END_BIT = 3; // EOI received
71 constexpr unsigned REG_INT0_BO_BIT = 4; // Byte Out interrupt
72 constexpr unsigned REG_INT0_BI_BIT = 5; // Byte In interrupt
73 constexpr unsigned REG_INT0_INT1_BIT = 6; // Interrupt(s) pending from INT1 register
74 constexpr unsigned REG_INT0_INT0_BIT = 7; // Interrupt(s) pending from INT0 register
75 constexpr uint8_t REG_INT0_INT_MASK = 0x3f; // Mask of actual interrupt bits
76
77 // Interrupt status/mask 1
78 constexpr unsigned REG_INT1_IFC_BIT = 0; // IFC received
79 constexpr unsigned REG_INT1_SRQ_BIT = 1; // SRQ asserted
80 constexpr unsigned REG_INT1_MA_BIT = 2; // My address received
81 constexpr unsigned REG_INT1_DCAS_BIT = 3; // DCAS state active
82 constexpr unsigned REG_INT1_APT_BIT = 4; // Address Pass-Through
83 constexpr unsigned REG_INT1_UNC_BIT = 5; // Unrecognized command
84 constexpr unsigned REG_INT1_ERR_BIT = 6; // Source handshake error
85 constexpr unsigned REG_INT1_GET_BIT = 7; // Group Execute Trigger
86
87 // Address status register
88 constexpr unsigned REG_AS_ULPA_BIT = 0; // LSB of last recognized address
89 constexpr unsigned REG_AS_TADS_BIT = 1; // Addressed to talk
90 constexpr unsigned REG_AS_LADS_BIT = 2; // Addressed to listen
91 constexpr unsigned REG_AS_TPAS_BIT = 3; // TPAS state active
92 constexpr unsigned REG_AS_LPAS_BIT = 4; // LPAS state active
93 constexpr unsigned REG_AS_ATN_BIT = 5; // ATN asserted
94 constexpr unsigned REG_AS_LLO_BIT = 6; // Local lockout enabled
95 constexpr unsigned REG_AS_REM_BIT = 7; // Remote state enabled
96
97 // Bus status register
98 constexpr unsigned REG_BS_REN_BIT = 0;
99 constexpr unsigned REG_BS_IFC_BIT = 1;
100 constexpr unsigned REG_BS_SRQ_BIT = 2;
101 constexpr unsigned REG_BS_EOI_BIT = 3;
102 constexpr unsigned REG_BS_NRFD_BIT = 4;
103 constexpr unsigned REG_BS_NDAC_BIT = 5;
104 constexpr unsigned REG_BS_DAV_BIT = 6;
105 constexpr unsigned REG_BS_ATN_BIT = 7;
106
107 // Auxiliary command register
108 constexpr uint8_t REG_AUXCMD_CMD_MASK = 0x1f; // Mask of auxiliary command
109 constexpr unsigned REG_AUXCMD_CS_BIT = 7; // Clear/set bit
110
111 // Auxiliary commands
112 enum {
113 AUXCMD_SWRST = 0x00,
114 AUXCMD_DACR = 0x01,
115 AUXCMD_RHDF = 0x02,
116 AUXCMD_HDFA = 0x03,
117 AUXCMD_HDFE = 0x04,
118 AUXCMD_NBAF = 0x05,
119 AUXCMD_FGET = 0x06,
120 AUXCMD_RTL = 0x07,
121 AUXCMD_FEOI = 0x08,
122 AUXCMD_LON = 0x09,
123 AUXCMD_TON = 0x0a,
124 AUXCMD_GTS = 0x0b,
125 AUXCMD_TCA = 0x0c,
126 AUXCMD_TCS = 0x0d,
127 AUXCMD_RPP = 0x0e,
128 AUXCMD_SIC = 0x0f,
129 AUXCMD_SRE = 0x10,
130 AUXCMD_RQC = 0x11,
131 AUXCMD_RLC = 0x12,
132 AUXCMD_DAI = 0x13,
133 AUXCMD_PTS = 0x14,
134 AUXCMD_STDL = 0x15,
135 AUXCMD_SHDW = 0x16,
136 AUXCMD_VSTDL = 0x17,
137 AUXCMD_RSV2 = 0x18
138 };
139
140 // Address register
141 constexpr uint8_t REG_ADDR_ADDR_MASK = 0x1f; // Address mask
142 constexpr unsigned REG_ADDR_DAT_BIT = 5; // Disable talker
143 constexpr unsigned REG_ADDR_DAL_BIT = 6; // Disable listener
144 constexpr unsigned REG_ADDR_EDPA_BIT = 7; // Dual primary address mode
145
146 // Serial poll register
147 constexpr uint8_t REG_SERIAL_P_MASK = 0xbf; // Serial status mask
148 constexpr unsigned REG_SERIAL_P_RSV1_BIT = 6; // Request service 1
149
150 // Interface commands
151 constexpr uint8_t IFCMD_MASK = 0x7f; // Mask of valid bits in if. commands
152 constexpr uint8_t IFCMD_ACG_MASK = 0x70; // Mask of ACG commands
153 constexpr uint8_t IFCMD_ACG_VALUE = 0x00; // Value of ACG commands
154 constexpr uint8_t IFCMD_UCG_MASK = 0x70; // Mask of UCG commands
155 constexpr uint8_t IFCMD_UCG_VALUE = 0x10; // Value of UCG commands
156 constexpr uint8_t IFCMD_GROUP_MASK = 0x60; // Mask of group id
157 constexpr uint8_t IFCMD_LAG_VALUE = 0x20; // Value of LAG commands
158 constexpr uint8_t IFCMD_TAG_VALUE = 0x40; // Value of TAG commands
159 constexpr uint8_t IFCMD_SCG_VALUE = 0x60; // Value of SCG commands
160 constexpr uint8_t IFCMD_GTL = 0x01; // Go to local
161 constexpr uint8_t IFCMD_SDC = 0x04; // Selected device clear
162 constexpr uint8_t IFCMD_GET = 0x08; // Group execute trigger
163 constexpr uint8_t IFCMD_TCT = 0x09; // Take control
164 constexpr uint8_t IFCMD_LLO = 0x11; // Local lock-out
165 constexpr uint8_t IFCMD_DCL = 0x14; // Device clear
166 constexpr uint8_t IFCMD_SPE = 0x18; // Serial poll enable
167 constexpr uint8_t IFCMD_SPD = 0x19; // Serial poll disable
168 constexpr uint8_t IFCMD_UNL = 0x3f; // Unlisten
169 constexpr uint8_t IFCMD_UNT = 0x5f; // Untalk
170
171 // Device type definition
172 DEFINE_DEVICE_TYPE(TMS9914, tms9914_device, "tms9914", "TMS9914 GPIB Controller")
173
174 // Constructors
tms9914_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)175 tms9914_device::tms9914_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
176 : device_t(mconfig , TMS9914 , tag , owner , clock),
177 m_dio_read_func(*this),
178 m_dio_write_func(*this),
179 m_signal_wr_fns(*this),
180 m_int_write_func(*this),
181 m_accrq_write_func(*this)
182 {
183 // Silence compiler complaints about unused variables
184 (void)REG_INT1_IFC_BIT;
185 (void)REG_INT1_GET_BIT;
186 }
187
188 // Signal inputs
WRITE_LINE_MEMBER(tms9914_device::eoi_w)189 WRITE_LINE_MEMBER(tms9914_device::eoi_w)
190 {
191 set_ext_signal(IEEE_488_EOI , state);
192 }
193
WRITE_LINE_MEMBER(tms9914_device::dav_w)194 WRITE_LINE_MEMBER(tms9914_device::dav_w)
195 {
196 set_ext_signal(IEEE_488_DAV , state);
197 }
198
WRITE_LINE_MEMBER(tms9914_device::nrfd_w)199 WRITE_LINE_MEMBER(tms9914_device::nrfd_w)
200 {
201 set_ext_signal(IEEE_488_NRFD , state);
202 }
203
WRITE_LINE_MEMBER(tms9914_device::ndac_w)204 WRITE_LINE_MEMBER(tms9914_device::ndac_w)
205 {
206 set_ext_signal(IEEE_488_NDAC , state);
207 }
208
WRITE_LINE_MEMBER(tms9914_device::ifc_w)209 WRITE_LINE_MEMBER(tms9914_device::ifc_w)
210 {
211 set_ext_signal(IEEE_488_IFC , state);
212 }
213
WRITE_LINE_MEMBER(tms9914_device::srq_w)214 WRITE_LINE_MEMBER(tms9914_device::srq_w)
215 {
216 bool prev_srq = get_signal(IEEE_488_SRQ);
217 set_ext_signal(IEEE_488_SRQ , state);
218 if (cont_r() && !prev_srq && get_signal(IEEE_488_SRQ)) {
219 set_int1_bit(REG_INT1_SRQ_BIT);
220 }
221 }
222
WRITE_LINE_MEMBER(tms9914_device::atn_w)223 WRITE_LINE_MEMBER(tms9914_device::atn_w)
224 {
225 set_ext_signal(IEEE_488_ATN , state);
226 }
227
WRITE_LINE_MEMBER(tms9914_device::ren_w)228 WRITE_LINE_MEMBER(tms9914_device::ren_w)
229 {
230 set_ext_signal(IEEE_488_REN , state);
231 }
232
233 // Register I/O
write(offs_t offset,uint8_t data)234 void tms9914_device::write(offs_t offset, uint8_t data)
235 {
236 LOG_REG("W %u=%02x\n" , offset , data);
237
238 switch (offset) {
239 case REG_W_INT_MASK0:
240 m_reg_int0_mask = data & REG_INT0_INT_MASK;
241 update_int();
242 break;
243
244 case REG_W_INT_MASK1:
245 m_reg_int1_mask = data;
246 update_int();
247 break;
248
249 case REG_W_AUX_CMD:
250 do_aux_cmd(data & REG_AUXCMD_CMD_MASK , BIT(data , REG_AUXCMD_CS_BIT));
251 break;
252
253 case REG_W_ADDRESS:
254 {
255 uint8_t diff = m_reg_address ^ data;
256 m_reg_address = data;
257 if (BIT(diff , REG_ADDR_DAT_BIT) || BIT(diff , REG_ADDR_DAL_BIT)) {
258 update_fsm();
259 }
260 }
261 break;
262
263 case REG_W_SERIAL_P:
264 {
265 uint8_t diff = m_reg_2nd_serial_p ^ data;
266 m_reg_2nd_serial_p = data;
267 if (BIT(diff , REG_SERIAL_P_RSV1_BIT)) {
268 update_fsm();
269 }
270 }
271 break;
272
273 case REG_W_PARALLEL_P:
274 m_reg_2nd_parallel_p = data;
275 break;
276
277 case REG_W_DO:
278 m_reg_do = data;
279
280 if (m_next_eoi) {
281 m_next_eoi = false;
282 if (!m_swrst) {
283 if (m_t_eoi_state == FSM_T_ENIS) {
284 m_t_eoi_state = FSM_T_ENRS;
285 } else if (m_t_eoi_state == FSM_T_ENAS) {
286 m_t_eoi_state = FSM_T_ERAS;
287 }
288 }
289
290 }
291
292 set_accrq(false);
293 if (!m_swrst) {
294 BIT_CLR(m_reg_int0_status , REG_INT0_BO_BIT);
295 update_int();
296 if (m_t_eoi_state == FSM_T_ENRS) {
297 m_t_eoi_state = FSM_T_ERAS;
298 } else if (m_t_eoi_state == FSM_T_ENAS) {
299 m_t_eoi_state = FSM_T_ENIS;
300 }
301 bool update = sh_active();
302 if (m_sh_shfs) {
303 m_sh_shfs = false;
304 update = true;
305 }
306 if (update) {
307 update_fsm();
308 }
309 }
310 break;
311
312 default:
313 LOG("Write to unmapped reg %u\n" , offset);
314 break;
315 }
316 }
317
read(offs_t offset)318 uint8_t tms9914_device::read(offs_t offset)
319 {
320 uint8_t res;
321
322 switch (offset) {
323 case REG_R_INT_STAT0:
324 res = m_reg_int0_status;
325 m_reg_int0_status = 0;
326 update_int();
327 break;
328
329 case REG_R_INT_STAT1:
330 res = m_reg_int1_status;
331 m_reg_int1_status = 0;
332 update_int();
333 break;
334
335 case REG_R_ADDR_STAT:
336 res = 0;
337 if (m_reg_ulpa) {
338 BIT_SET(res , REG_AS_ULPA_BIT);
339 }
340 if (m_t_state != FSM_T_TIDS) {
341 BIT_SET(res , REG_AS_TADS_BIT);
342 }
343 if (m_l_state != FSM_L_LIDS) {
344 BIT_SET(res , REG_AS_LADS_BIT);
345 }
346 if (m_t_tpas) {
347 BIT_SET(res , REG_AS_TPAS_BIT);
348 }
349 if (m_l_lpas) {
350 BIT_SET(res , REG_AS_LPAS_BIT);
351 }
352 if (get_signal(IEEE_488_ATN)) {
353 BIT_SET(res , REG_AS_ATN_BIT);
354 }
355 if (m_rl_state == FSM_RL_RWLS || m_rl_state == FSM_RL_LWLS) {
356 BIT_SET(res , REG_AS_LLO_BIT);
357 }
358 if (m_rl_state == FSM_RL_REMS || m_rl_state == FSM_RL_RWLS) {
359 BIT_SET(res , REG_AS_REM_BIT);
360 }
361 break;
362
363 case REG_R_BUS_STAT:
364 res = 0;
365 if (get_signal(IEEE_488_REN)) {
366 BIT_SET(res , REG_BS_REN_BIT);
367 }
368 if (get_ifcin()) {
369 BIT_SET(res , REG_BS_IFC_BIT);
370 }
371 if (get_signal(IEEE_488_SRQ)) {
372 BIT_SET(res , REG_BS_SRQ_BIT);
373 }
374 if (get_signal(IEEE_488_EOI)) {
375 BIT_SET(res , REG_BS_EOI_BIT);
376 }
377 if (get_signal(IEEE_488_NRFD)) {
378 BIT_SET(res , REG_BS_NRFD_BIT);
379 }
380 if (get_signal(IEEE_488_NDAC)) {
381 BIT_SET(res , REG_BS_NDAC_BIT);
382 }
383 if (get_signal(IEEE_488_DAV)) {
384 BIT_SET(res , REG_BS_DAV_BIT);
385 }
386 if (get_signal(IEEE_488_ATN)) {
387 BIT_SET(res , REG_BS_ATN_BIT);
388 }
389 break;
390
391 case REG_R_CMD_PT:
392 res = get_dio();
393 break;
394
395 case REG_R_DI:
396 res = m_reg_di;
397 BIT_CLR(m_reg_int0_status , REG_INT0_BI_BIT);
398 update_int();
399 set_accrq(false);
400 if (!m_hdfa && m_ah_anhs) {
401 m_ah_anhs = false;
402 update_fsm();
403 }
404 // TODO: ACRS -> ANRS ?
405 break;
406
407 default:
408 LOG("Read from unmapped reg %u\n" , offset);
409 res = 0;
410 break;
411 }
412
413 LOG_REG("R %u=%02x\n" , offset , res);
414 return res;
415 }
416
READ_LINE_MEMBER(tms9914_device::cont_r)417 READ_LINE_MEMBER(tms9914_device::cont_r)
418 {
419 return m_c_state != FSM_C_CIDS && m_c_state != FSM_C_CADS;
420 }
421
422 // device-level overrides
device_start()423 void tms9914_device::device_start()
424 {
425 save_item(NAME(m_int_line));
426 save_item(NAME(m_accrq_line));
427 save_item(NAME(m_dio));
428 save_item(NAME(m_signals));
429 save_item(NAME(m_ext_signals));
430 save_item(NAME(m_no_reflection));
431 save_item(NAME(m_ext_state_change));
432 save_item(NAME(m_reg_int0_status));
433 save_item(NAME(m_reg_int0_mask));
434 save_item(NAME(m_reg_int1_status));
435 save_item(NAME(m_reg_int1_mask));
436 save_item(NAME(m_reg_address));
437 save_item(NAME(m_reg_serial_p));
438 save_item(NAME(m_reg_2nd_serial_p));
439 save_item(NAME(m_reg_parallel_p));
440 save_item(NAME(m_reg_2nd_parallel_p));
441 save_item(NAME(m_reg_di));
442 save_item(NAME(m_reg_do));
443 save_item(NAME(m_reg_ulpa));
444 save_item(NAME(m_swrst));
445 save_item(NAME(m_hdfa));
446 save_item(NAME(m_hdfe));
447 save_item(NAME(m_rtl));
448 save_item(NAME(m_gts));
449 save_item(NAME(m_rpp));
450 save_item(NAME(m_sic));
451 save_item(NAME(m_sre));
452 save_item(NAME(m_dai));
453 save_item(NAME(m_pts));
454 save_item(NAME(m_stdl));
455 save_item(NAME(m_shdw));
456 save_item(NAME(m_vstdl));
457 save_item(NAME(m_rsvd2));
458 save_item(NAME(m_ah_state));
459 save_item(NAME(m_ah_adhs));
460 save_item(NAME(m_ah_anhs));
461 save_item(NAME(m_sh_state));
462 save_item(NAME(m_sh_shfs));
463 save_item(NAME(m_sh_vsts));
464 save_item(NAME(m_t_state));
465 save_item(NAME(m_t_tpas));
466 save_item(NAME(m_t_spms));
467 save_item(NAME(m_t_eoi_state));
468 save_item(NAME(m_l_state));
469 save_item(NAME(m_l_lpas));
470 save_item(NAME(m_sr_state));
471 save_item(NAME(m_rl_state));
472 save_item(NAME(m_pp_ppas));
473 save_item(NAME(m_c_state));
474 save_item(NAME(m_next_eoi));
475
476 m_dio_read_func.resolve_safe(0xff);
477 m_dio_write_func.resolve_safe();
478 m_signal_wr_fns.resolve_all_safe();
479 m_int_write_func.resolve_safe();
480 m_accrq_write_func.resolve_safe();
481
482 m_sh_dly_timer = timer_alloc(SH_DELAY_TMR_ID);
483 m_ah_dly_timer = timer_alloc(AH_DELAY_TMR_ID);
484 m_c_dly_timer = timer_alloc(C_DELAY_TMR_ID);
485 }
486
device_reset()487 void tms9914_device::device_reset()
488 {
489 m_no_reflection = false;
490 m_ext_state_change = false;
491 m_swrst = true;
492 m_hdfa = false;
493 m_hdfe = false;
494 m_rtl = false;
495 m_rpp = false;
496 m_sic = false;
497 m_sre = false;
498 m_dai = false;
499 m_pts = false;
500 m_stdl = false;
501 m_shdw = false;
502 m_vstdl = false;
503 m_accrq_line = true; // Ensure change is propagated
504
505 m_reg_serial_p = 0;
506 m_reg_2nd_serial_p = 0;
507 m_reg_parallel_p = 0;
508 m_reg_2nd_parallel_p = 0;
509
510 m_reg_ulpa = false;
511 std::fill(std::begin(m_ext_signals), std::end(m_ext_signals), false);
512
513 do_swrst();
514 update_fsm();
515 update_int();
516 update_ifc();
517 update_ren();
518 }
519
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)520 void tms9914_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
521 {
522 LOG_NOISY("tmr %d\n" , id);
523 update_fsm();
524 }
525
get_dio()526 uint8_t tms9914_device::get_dio()
527 {
528 return ~m_dio_read_func();
529 }
530
set_dio(uint8_t data)531 void tms9914_device::set_dio(uint8_t data)
532 {
533 if (data != m_dio) {
534 LOG_NOISY("DIO=%02x\n" , data);
535 m_dio = data;
536 m_dio_write_func(~data);
537 }
538 }
539
get_signal(ieee_488_signal_t signal) const540 bool tms9914_device::get_signal(ieee_488_signal_t signal) const
541 {
542 return m_ext_signals[ signal ];
543 }
544
get_ifcin() const545 bool tms9914_device::get_ifcin() const
546 {
547 return get_signal(IEEE_488_IFC) && !m_sic;
548 }
549
set_ext_signal(ieee_488_signal_t signal,int state)550 void tms9914_device::set_ext_signal(ieee_488_signal_t signal , int state)
551 {
552 state = !state;
553 if (m_ext_signals[ signal ] != state) {
554 m_ext_signals[ signal ] = state;
555 LOG_NOISY("EXT EOI %d DAV %d NRFD %d NDAC %d IFC %d SRQ %d ATN %d REN %d\n" ,
556 m_ext_signals[ IEEE_488_EOI ] ,
557 m_ext_signals[ IEEE_488_DAV ] ,
558 m_ext_signals[ IEEE_488_NRFD ] ,
559 m_ext_signals[ IEEE_488_NDAC ] ,
560 m_ext_signals[ IEEE_488_IFC ] ,
561 m_ext_signals[ IEEE_488_SRQ ] ,
562 m_ext_signals[ IEEE_488_ATN ] ,
563 m_ext_signals[ IEEE_488_REN ]);
564 update_fsm();
565 }
566 }
567
set_signal(ieee_488_signal_t signal,bool state)568 void tms9914_device::set_signal(ieee_488_signal_t signal , bool state)
569 {
570 if (state != m_signals[ signal ]) {
571 m_signals[ signal ] = state;
572 LOG_NOISY("INT EOI %d DAV %d NRFD %d NDAC %d IFC %d SRQ %d ATN %d REN %d\n" ,
573 m_signals[ IEEE_488_EOI ] ,
574 m_signals[ IEEE_488_DAV ] ,
575 m_signals[ IEEE_488_NRFD ] ,
576 m_signals[ IEEE_488_NDAC ] ,
577 m_signals[ IEEE_488_IFC ] ,
578 m_signals[ IEEE_488_SRQ ] ,
579 m_signals[ IEEE_488_ATN ] ,
580 m_signals[ IEEE_488_REN ]);
581 m_signal_wr_fns[ signal ](!state);
582 }
583 }
584
do_swrst()585 void tms9914_device::do_swrst()
586 {
587 m_reg_int0_status = 0;
588 m_reg_int1_status = 0;
589
590 m_ah_state = FSM_AH_AIDS;
591 m_ah_adhs = false;
592 m_ah_anhs = false;
593 m_ah_aehs = false;
594 m_sh_state = FSM_SH_SIDS;
595 m_sh_shfs = true;
596 m_sh_vsts = false;
597 m_t_state = FSM_T_TIDS;
598 m_t_tpas = false;
599 m_t_spms = false;
600 m_t_eoi_state = FSM_T_ENIS;
601 m_l_state = FSM_L_LIDS;
602 m_l_lpas = false;
603 m_sr_state = FSM_SR_NPRS;
604 m_rl_state = FSM_RL_LOCS;
605 m_pp_ppas = false;
606 m_c_state = FSM_C_CIDS;
607 m_gts = false;
608
609 update_int();
610 set_accrq(false);
611 }
612
listener_reset() const613 bool tms9914_device::listener_reset() const
614 {
615 return m_swrst || BIT(m_reg_address , REG_ADDR_DAL_BIT) || m_sic || get_ifcin();
616 }
617
talker_reset() const618 bool tms9914_device::talker_reset() const
619 {
620 return m_swrst || BIT(m_reg_address , REG_ADDR_DAT_BIT) || m_sic || get_ifcin();
621 }
622
controller_reset() const623 bool tms9914_device::controller_reset() const
624 {
625 return m_swrst || get_ifcin();
626 }
627
sh_active() const628 bool tms9914_device::sh_active() const
629 {
630 return m_sh_state == FSM_SH_SDYS || m_sh_state == FSM_SH_STRS || m_sh_state == FSM_SH_SERS;
631 }
632
update_fsm()633 void tms9914_device::update_fsm()
634 {
635 if (m_no_reflection) {
636 return;
637 }
638
639 m_no_reflection = true;
640
641 bool changed = true;
642 int prev_state;
643 // Loop until all changes settle
644 while (changed) {
645 LOG_NOISY("SH %d SHFS %d AH %d T %d TPAS %d L %d LPAS %d PP %d C %d\n" ,
646 m_sh_state , m_sh_shfs , m_ah_state , m_t_state , m_t_tpas ,
647 m_l_state , m_l_lpas , m_pp_ppas , m_c_state);
648 changed = m_ext_state_change;
649 m_ext_state_change = false;
650
651 // SH FSM
652 prev_state = m_sh_state;
653 bool sh_reset = m_swrst ||
654 (get_signal(IEEE_488_ATN) && m_c_state != FSM_C_CACS) ||
655 (!get_signal(IEEE_488_ATN) && !(m_t_state == FSM_T_TACS || m_t_state == FSM_T_SPAS));
656
657 if (get_signal(IEEE_488_ATN) || !m_vstdl) {
658 m_sh_vsts = false;
659 }
660 if (sh_reset) {
661 m_sh_state = FSM_SH_SIDS;
662 m_sh_dly_timer->reset();
663 } else {
664 switch (m_sh_state) {
665 case FSM_SH_SIDS:
666 if (m_t_state == FSM_T_TACS ||
667 m_t_state == FSM_T_SPAS ||
668 m_c_state == FSM_C_CACS) {
669 m_sh_state = FSM_SH_SGNS;
670 }
671 break;
672
673 case FSM_SH_SGNS:
674 if (!m_sh_shfs || m_t_state == FSM_T_SPAS) {
675 m_sh_state = FSM_SH_SDYS;
676 unsigned clocks = m_sh_vsts ? 4 : (m_stdl ? 8 : 12);
677 m_sh_dly_timer->adjust(clocks_to_attotime(clocks));
678 LOG_NOISY("SH DLY %u\n" , clocks);
679 }
680 break;
681
682 case FSM_SH_SDYS:
683 if (!m_t_spms) {
684 if (m_t_eoi_state == FSM_T_ENRS) {
685 m_t_eoi_state = FSM_T_ENIS;
686 } else if (m_t_eoi_state == FSM_T_ERAS) {
687 m_t_eoi_state = FSM_T_ENAS;
688 }
689 }
690 if (!m_sh_dly_timer->enabled() && !get_signal(IEEE_488_NRFD)) {
691 if (get_signal(IEEE_488_NDAC)) {
692 m_sh_state = FSM_SH_STRS;
693 } else {
694 m_sh_state = FSM_SH_SERS;
695 set_int1_bit(REG_INT1_ERR_BIT);
696 }
697 }
698 break;
699
700 case FSM_SH_SERS:
701 if (get_signal(IEEE_488_NDAC)) {
702 m_sh_state = FSM_SH_STRS;
703 }
704 break;
705
706 case FSM_SH_STRS:
707 if (m_t_state != FSM_T_SPAS) {
708 m_sh_shfs = true;
709 }
710 if (!get_signal(IEEE_488_ATN) && m_vstdl) {
711 m_sh_vsts = true;
712 }
713 if (!get_signal(IEEE_488_NDAC)) {
714 if (VERBOSE & LOG_GENERAL) {
715 bool const iscmd = m_signals[IEEE_488_ATN];
716 char cmd[16] = "";
717 if (iscmd) {
718 uint8_t tmp = m_dio & 0x7f;
719 if (tmp >= 0x20 && tmp <= 0x3f)
720 snprintf(cmd, 16, "MLA%d", tmp & 0x1f);
721 else if (tmp >= 0x40 && tmp <= 0x5f)
722 snprintf(cmd, 16, "MTA%d", tmp & 0x1f);
723 else if (tmp >= 0x60 && tmp <= 0x7f)
724 snprintf(cmd, 16, "MSA%d", tmp & 0x1f);
725 }
726 LOG("%.6f TX %s %02X/%d %s\n" , machine().time().as_double() , m_signals[IEEE_488_ATN] ? "C" : "D", m_dio , m_signals[ IEEE_488_EOI ], cmd);
727 }
728 m_sh_state = FSM_SH_SGNS;
729 }
730 break;
731
732 default:
733 LOG("Invalid SH state %d\n" , m_sh_state);
734 m_sh_state = FSM_SH_SIDS;
735 }
736 }
737 if (m_sh_state != prev_state) {
738 changed = true;
739 if (m_sh_state == FSM_SH_SGNS && m_sh_shfs &&
740 m_t_state != FSM_T_SPAS) {
741 // BO interrupt is raised when SGNS state is entered
742 set_int0_bit(REG_INT0_BO_BIT);
743 }
744 if (prev_state == FSM_SH_STRS && m_t_state == FSM_T_SPAS &&
745 (m_sr_state == FSM_SR_APRS1 || m_sr_state == FSM_SR_APRS2)) {
746 set_int0_bit(REG_INT0_SPAS_BIT);
747 }
748 }
749 // SH outputs
750 // EOI is controlled by SH & C FSMs
751 // DIO is controlled by SH & PP FSMs
752 bool eoi_signal = false;
753 uint8_t dio_byte = 0;
754 set_signal(IEEE_488_DAV , m_sh_state == FSM_SH_STRS);
755 if (sh_active()) {
756 if (m_t_state == FSM_T_SPAS) {
757 dio_byte = m_reg_serial_p & REG_SERIAL_P_MASK;
758 if (m_sr_state == FSM_SR_APRS1 || m_sr_state == FSM_SR_APRS2) {
759 // Set RQS
760 BIT_SET(dio_byte , 6);
761 }
762 } else {
763 dio_byte = m_reg_do;
764 }
765 eoi_signal = m_t_eoi_state == FSM_T_ERAS || m_t_eoi_state == FSM_T_ENAS;
766 }
767
768 // AH FSM
769 prev_state = m_ah_state;
770 bool ah_reset = m_swrst ||
771 (get_signal(IEEE_488_ATN) && cont_r()) ||
772 (!get_signal(IEEE_488_ATN) && m_l_state != FSM_L_LADS && m_l_state != FSM_L_LACS);
773 if (ah_reset) {
774 m_ah_state = FSM_AH_AIDS;
775 m_ah_dly_timer->reset();
776 } else {
777 switch (m_ah_state) {
778 case FSM_AH_AIDS:
779 m_ah_state = FSM_AH_ANRS;
780 break;
781
782 case FSM_AH_ANRS:
783 // See also the reading of DI register & RHDF command
784 if (m_c_state != FSM_C_CWAS &&
785 !get_signal(IEEE_488_DAV) &&
786 (get_signal(IEEE_488_ATN) ||
787 (!m_ah_anhs && !m_ah_aehs))) {
788 m_ah_state = FSM_AH_ACRS;
789 m_ah_dly_timer->adjust(clocks_to_attotime(1));
790 } else if (get_signal(IEEE_488_DAV)) {
791 m_ah_state = FSM_AH_AWNS;
792 }
793 break;
794
795 case FSM_AH_ACRS:
796 if (!get_signal(IEEE_488_ATN) &&
797 (m_ah_anhs || m_ah_aehs)) {
798 m_ah_state = FSM_AH_ANRS;
799 m_ah_dly_timer->reset();
800 } else if (!m_ah_dly_timer->enabled() && get_signal(IEEE_488_DAV)) {
801 m_ah_state = FSM_AH_ACDS1;
802 m_ah_dly_timer->adjust(clocks_to_attotime(get_signal(IEEE_488_ATN) ? 5 : 1));
803 }
804 break;
805
806 case FSM_AH_ACDS1:
807 if (!get_signal(IEEE_488_DAV)) {
808 m_ah_state = FSM_AH_ACRS;
809 m_ah_dly_timer->adjust(clocks_to_attotime(1));
810 } else if (!m_ah_dly_timer->enabled()) {
811 m_ah_state = FSM_AH_ACDS2;
812 if (get_signal(IEEE_488_ATN)) {
813 // Got a command
814 uint8_t if_cmd = get_dio();
815 if_cmd_received(if_cmd & IFCMD_MASK);
816 } else {
817 // Got a DAB
818 dab_received(get_dio() , get_signal(IEEE_488_EOI));
819 }
820 }
821 break;
822
823 case FSM_AH_ACDS2:
824 if (!m_ah_adhs || !get_signal(IEEE_488_ATN)) {
825 m_ah_state = FSM_AH_AWNS;
826 } else if (!get_signal(IEEE_488_DAV)) {
827 m_ah_state = FSM_AH_ANRS;
828 }
829 break;
830
831 case FSM_AH_AWNS:
832 if (!get_signal(IEEE_488_DAV)) {
833 m_ah_state = FSM_AH_ANRS;
834 }
835 break;
836
837 default:
838 LOG("Invalid AH state %d\n" , m_ah_state);
839 m_ah_state = FSM_AH_AIDS;
840 }
841 }
842 if (m_ah_state != prev_state) {
843 changed = true;
844 }
845 // AH outputs
846 set_signal(IEEE_488_NRFD , m_ah_state == FSM_AH_ANRS || m_ah_state == FSM_AH_ACDS1 || m_ah_state == FSM_AH_ACDS2 || m_ah_state == FSM_AH_AWNS);
847 set_signal(IEEE_488_NDAC , m_ah_state == FSM_AH_ANRS || m_ah_state == FSM_AH_ACRS || m_ah_state == FSM_AH_ACDS1 || m_ah_state == FSM_AH_ACDS2);
848
849 // T FSM
850 prev_state = m_t_state;
851 if (talker_reset()) {
852 m_t_state = FSM_T_TIDS;
853 } else {
854 switch (m_t_state) {
855 case FSM_T_TIDS:
856 break;
857
858 case FSM_T_TADS:
859 if (!get_signal(IEEE_488_ATN)) {
860 if (m_t_spms) {
861 m_t_state = FSM_T_SPAS;
862 // When entering SPAS, serial poll register is copied into the
863 // register that is actually output (as it's double buffered)
864 m_reg_serial_p = m_reg_2nd_serial_p;
865 } else {
866 m_t_state = FSM_T_TACS;
867 }
868 }
869 break;
870
871 case FSM_T_TACS:
872 case FSM_T_SPAS:
873 if (get_signal(IEEE_488_ATN)) {
874 m_t_state = FSM_T_TADS;
875 }
876 break;
877
878 default:
879 LOG("Invalid T state %d\n" , m_t_state);
880 m_t_state = FSM_T_TIDS;
881 }
882 }
883 if (m_t_state != prev_state) {
884 changed = true;
885 }
886 if (m_t_spms && (m_swrst || get_ifcin() || cont_r())) {
887 m_t_spms = false;
888 changed = true;
889 }
890 // No direct T outputs
891
892 // L FSM
893 prev_state = m_l_state;
894 if (listener_reset()) {
895 m_l_state = FSM_L_LIDS;
896 } else {
897 switch (m_l_state) {
898 case FSM_L_LIDS:
899 break;
900
901 case FSM_L_LADS:
902 if (!get_signal(IEEE_488_ATN)) {
903 m_l_state = FSM_L_LACS;
904 }
905 break;
906
907 case FSM_L_LACS:
908 if (get_signal(IEEE_488_ATN)) {
909 m_l_state = FSM_L_LADS;
910 }
911 break;
912
913 default:
914 LOG("Invalid L state %d\n" , m_l_state);
915 m_l_state = FSM_L_LIDS;
916 }
917 }
918 if (m_l_state != prev_state) {
919 changed = true;
920 }
921 // No direct L outputs
922
923 // PP FSM
924 if (!m_pp_ppas) {
925 // PPSS
926 if (!m_swrst && get_signal(IEEE_488_ATN) && get_signal(IEEE_488_EOI) && !cont_r()) {
927 m_pp_ppas = true;
928 changed = true;
929 // Copy m_reg_2nd_parallel_p when entering PPAS
930 m_reg_parallel_p = m_reg_2nd_parallel_p;
931 }
932 } else {
933 // PPAS
934 if (m_swrst || !get_signal(IEEE_488_ATN) || !get_signal(IEEE_488_EOI) || cont_r()) {
935 m_pp_ppas = false;
936 changed = true;
937 }
938 }
939 // PP output
940 if (m_pp_ppas) {
941 dio_byte |= m_reg_parallel_p;
942 }
943
944 // SR FSM
945 prev_state = m_sr_state;
946 if (m_swrst) {
947 m_sr_state = FSM_SR_NPRS;
948 } else {
949 switch (m_sr_state) {
950 case FSM_SR_NPRS:
951 if (m_t_state != FSM_T_SPAS &&
952 (BIT(m_reg_2nd_serial_p , REG_SERIAL_P_RSV1_BIT) || m_rsvd2)) {
953 m_sr_state = FSM_SR_SRQS;
954 }
955 break;
956
957 case FSM_SR_SRQS:
958 if (m_t_state == FSM_T_SPAS) {
959 m_sr_state = FSM_SR_APRS1;
960 } else if (!BIT(m_reg_2nd_serial_p , REG_SERIAL_P_RSV1_BIT) && !m_rsvd2) {
961 m_sr_state = FSM_SR_NPRS;
962 }
963 break;
964
965 case FSM_SR_APRS1:
966 if (m_t_state == FSM_T_SPAS && m_sh_state == FSM_SH_STRS) {
967 m_rsvd2 = false;
968 }
969 if (!BIT(m_reg_2nd_serial_p , REG_SERIAL_P_RSV1_BIT) && !m_rsvd2) {
970 m_sr_state = FSM_SR_APRS2;
971 }
972 break;
973
974 case FSM_SR_APRS2:
975 if (m_t_state == FSM_T_SPAS) {
976 if (m_sh_state == FSM_SH_STRS) {
977 m_rsvd2 = false;
978 }
979 } else {
980 m_sr_state = FSM_SR_NPRS;
981 }
982 break;
983
984 default:
985 LOG("Invalid SR state %d\n" , m_sr_state);
986 m_sr_state = FSM_SR_NPRS;
987 }
988 }
989 if (m_sr_state != prev_state) {
990 changed = true;
991 }
992 // SR outputs
993 set_signal(IEEE_488_SRQ , m_sr_state == FSM_SR_SRQS);
994
995 // RL FSM
996 if (m_rl_state != FSM_RL_LOCS && (m_swrst || !get_signal(IEEE_488_REN))) {
997 m_rl_state = FSM_RL_LOCS;
998 changed = true;
999 }
1000 // No direct RL outputs
1001
1002 // C outputs
1003 prev_state = m_c_state;
1004 if (controller_reset()) {
1005 m_c_state = FSM_C_CIDS;
1006 m_gts = false;
1007 m_c_dly_timer->reset();
1008 } else {
1009 switch (m_c_state) {
1010 case FSM_C_CIDS:
1011 // See also sic & rqc aux commands
1012 if (m_sic) {
1013 m_c_state = FSM_C_CADS;
1014 }
1015 break;
1016
1017 case FSM_C_CADS:
1018 if (!get_signal(IEEE_488_ATN)) {
1019 m_c_state = FSM_C_CACS;
1020 }
1021 break;
1022
1023 case FSM_C_CACS:
1024 if (m_rpp) {
1025 m_c_state = FSM_C_CPWS;
1026 m_gts = false;
1027 } else if (m_gts && !sh_active()) {
1028 m_c_state = FSM_C_CSBS;
1029 m_gts = false;
1030 // This ensures a BO interrupt is generated if TACS is active
1031 m_sh_state = FSM_SH_SIDS;
1032 }
1033 break;
1034
1035 case FSM_C_CSBS:
1036 // tcs -> CWAS
1037 // tca -> CSHS
1038 break;
1039
1040 case FSM_C_CWAS:
1041 if (m_ah_state == FSM_AH_ANRS) {
1042 m_c_state = FSM_C_CSHS;
1043 m_c_dly_timer->adjust(clocks_to_attotime(8));
1044 }
1045 break;
1046
1047 case FSM_C_CSHS:
1048 if (!m_c_dly_timer->enabled()) {
1049 m_c_state = FSM_C_CSWS;
1050 m_c_dly_timer->adjust(clocks_to_attotime(2));
1051 }
1052 break;
1053
1054 case FSM_C_CSWS:
1055 if (!m_c_dly_timer->enabled()) {
1056 m_c_state = FSM_C_CAWS;
1057 m_c_dly_timer->adjust(clocks_to_attotime(8));
1058 }
1059 break;
1060
1061 case FSM_C_CAWS:
1062 if (!m_c_dly_timer->enabled()) {
1063 m_c_state = FSM_C_CACS;
1064 }
1065 break;
1066
1067 case FSM_C_CPWS:
1068 if (!m_rpp) {
1069 m_c_state = FSM_C_CAWS;
1070 m_c_dly_timer->adjust(clocks_to_attotime(8));
1071 }
1072 break;
1073
1074 default:
1075 LOG("Invalid C state %d\n" , m_c_state);
1076 m_c_state = FSM_C_CIDS;
1077 }
1078 }
1079 if (m_c_state != prev_state) {
1080 changed = true;
1081 }
1082 set_signal(IEEE_488_ATN , m_c_state == FSM_C_CACS ||
1083 m_c_state == FSM_C_CSWS || m_c_state == FSM_C_CAWS ||
1084 m_c_state == FSM_C_CPWS);
1085 eoi_signal = eoi_signal || m_c_state == FSM_C_CPWS;
1086 set_signal(IEEE_488_EOI , eoi_signal);
1087 set_dio(dio_byte);
1088 }
1089
1090 m_no_reflection = false;
1091 }
1092
is_my_address(uint8_t addr)1093 bool tms9914_device::is_my_address(uint8_t addr)
1094 {
1095 uint8_t diff = (addr ^ m_reg_address) & REG_ADDR_ADDR_MASK;
1096 if (BIT(m_reg_address , REG_ADDR_EDPA_BIT)) {
1097 // If dual-address mode is enabled, difference in LSB of address is ignored
1098 BIT_CLR(diff , 0);
1099 }
1100 if (diff == 0) {
1101 m_reg_ulpa = BIT(addr , 0);
1102 }
1103 return diff == 0;
1104 }
1105
do_LAF()1106 void tms9914_device::do_LAF()
1107 {
1108 if (m_l_state == FSM_L_LIDS) {
1109 m_l_state = FSM_L_LADS;
1110 m_ext_state_change = true;
1111 }
1112 if (m_t_state != FSM_T_TIDS) {
1113 m_t_state = FSM_T_TIDS;
1114 m_ext_state_change = true;
1115 }
1116 if (m_rl_state == FSM_RL_LWLS) {
1117 m_rl_state = FSM_RL_RWLS;
1118 set_int0_bit(REG_INT0_RLC_BIT);
1119 } else if (m_rl_state == FSM_RL_LOCS && !m_rtl && get_signal(IEEE_488_REN)) {
1120 m_rl_state = FSM_RL_REMS;
1121 set_int0_bit(REG_INT0_RLC_BIT);
1122 }
1123 }
1124
do_TAF()1125 void tms9914_device::do_TAF()
1126 {
1127 if (m_t_state == FSM_T_TIDS) {
1128 m_t_state = FSM_T_TADS;
1129 m_ext_state_change = true;
1130 }
1131 if (m_l_state != FSM_L_LIDS) {
1132 m_l_state = FSM_L_LIDS;
1133 m_ext_state_change = true;
1134 }
1135 }
1136
if_cmd_received(uint8_t if_cmd)1137 void tms9914_device::if_cmd_received(uint8_t if_cmd)
1138 {
1139 LOG("%.6f RX cmd:%02x\n" , machine().time().as_double() , if_cmd);
1140
1141 bool sahf = false;
1142
1143 // Any PCG command that is not MLA nor MTA clears LPAS & TPAS
1144 if ((if_cmd & IFCMD_GROUP_MASK) != IFCMD_SCG_VALUE) {
1145 m_l_lpas = false;
1146 m_t_tpas = false;
1147 }
1148
1149 switch (if_cmd) {
1150 case IFCMD_GTL:
1151 if (m_l_state == FSM_L_LADS) {
1152 if (m_rl_state == FSM_RL_REMS) {
1153 m_rl_state = FSM_RL_LOCS;
1154 set_int0_bit(REG_INT0_RLC_BIT);
1155 } else if (m_rl_state == FSM_RL_RWLS) {
1156 m_rl_state = FSM_RL_LWLS;
1157 set_int0_bit(REG_INT0_RLC_BIT);
1158 }
1159 }
1160 break;
1161
1162 case IFCMD_SDC:
1163 if (m_l_state == FSM_L_LADS) {
1164 set_int1_bit(REG_INT1_DCAS_BIT);
1165 sahf = BIT(m_reg_int1_mask , REG_INT1_DCAS_BIT);
1166 }
1167 break;
1168
1169 case IFCMD_GET:
1170 // TODO:
1171 break;
1172
1173 case IFCMD_TCT:
1174 if (m_t_state == FSM_T_TADS) {
1175 set_int1_bit(REG_INT1_UNC_BIT);
1176 sahf = BIT(m_reg_int1_mask , REG_INT1_UNC_BIT);
1177 }
1178 break;
1179
1180 case IFCMD_LLO:
1181 if (m_rl_state == FSM_RL_LOCS && get_signal(IEEE_488_REN)) {
1182 m_rl_state = FSM_RL_LWLS;
1183 } else if (m_rl_state == FSM_RL_REMS) {
1184 m_rl_state = FSM_RL_RWLS;
1185 }
1186 break;
1187
1188 case IFCMD_DCL:
1189 set_int1_bit(REG_INT1_DCAS_BIT);
1190 sahf = BIT(m_reg_int1_mask , REG_INT1_DCAS_BIT);
1191 break;
1192
1193 case IFCMD_SPE:
1194 if (!get_ifcin() && !m_t_spms) {
1195 m_t_spms = true;
1196 m_ext_state_change = true;
1197 }
1198 break;
1199
1200 case IFCMD_SPD:
1201 if (m_t_spms) {
1202 m_t_spms = false;
1203 m_ext_state_change = true;
1204 }
1205 break;
1206
1207 case IFCMD_UNL:
1208 if (m_l_state != FSM_L_LIDS) {
1209 m_l_state = FSM_L_LIDS;
1210 set_int0_bit(REG_INT0_MAC_BIT);
1211 }
1212 break;
1213
1214 case IFCMD_UNT:
1215 if (m_t_state != FSM_T_TIDS) {
1216 m_t_state = FSM_T_TIDS;
1217 set_int0_bit(REG_INT0_MAC_BIT);
1218 }
1219 break;
1220
1221 default:
1222 if ((if_cmd & IFCMD_ACG_MASK) == IFCMD_ACG_VALUE) {
1223 // ACG
1224 if (m_l_state == FSM_L_LADS) {
1225 set_int1_bit(REG_INT1_UNC_BIT);
1226 sahf = BIT(m_reg_int1_mask , REG_INT1_UNC_BIT);
1227 }
1228 } else if ((if_cmd & IFCMD_UCG_MASK) == IFCMD_UCG_VALUE) {
1229 // UCG
1230 set_int1_bit(REG_INT1_UNC_BIT);
1231 sahf = BIT(m_reg_int1_mask , REG_INT1_UNC_BIT);
1232 } else if ((if_cmd & IFCMD_GROUP_MASK) == IFCMD_LAG_VALUE) {
1233 // LAG
1234 if (is_my_address(if_cmd)) {
1235 // MLA
1236 m_l_lpas = true;
1237 if (!BIT(m_reg_int1_mask , REG_INT1_APT_BIT)) {
1238 // Not using secondary addressing
1239 if (!listener_reset()) {
1240 if (m_l_state != FSM_L_LADS) {
1241 set_int0_bit(REG_INT0_MAC_BIT);
1242 }
1243 do_LAF();
1244 }
1245 if (!m_t_spms) {
1246 set_int1_bit(REG_INT1_MA_BIT);
1247 sahf = BIT(m_reg_int1_mask , REG_INT1_MA_BIT);
1248 }
1249 }
1250 }
1251 } else if ((if_cmd & IFCMD_GROUP_MASK) == IFCMD_TAG_VALUE) {
1252 // TAG
1253 if (is_my_address(if_cmd)) {
1254 // MTA
1255 m_t_tpas = true;
1256 if (!BIT(m_reg_int1_mask , REG_INT1_APT_BIT)) {
1257 // Not using secondary addressing
1258 if (!talker_reset()) {
1259 if (m_t_state != FSM_T_TADS) {
1260 set_int0_bit(REG_INT0_MAC_BIT);
1261 }
1262 do_TAF();
1263 }
1264 if (!m_t_spms) {
1265 set_int1_bit(REG_INT1_MA_BIT);
1266 sahf = BIT(m_reg_int1_mask , REG_INT1_MA_BIT);
1267 }
1268 }
1269 } else {
1270 // OTA
1271 if (m_t_state != FSM_T_TIDS) {
1272 set_int0_bit(REG_INT0_MAC_BIT);
1273 }
1274 m_t_state = FSM_T_TIDS;
1275 }
1276 } else {
1277 // SCG
1278 if (m_pts) {
1279 set_int1_bit(REG_INT1_UNC_BIT);
1280 sahf = BIT(m_reg_int1_mask , REG_INT1_UNC_BIT);
1281 m_pts = false;
1282 } else if (m_l_lpas || m_t_tpas) {
1283 set_int1_bit(REG_INT1_APT_BIT);
1284 sahf = BIT(m_reg_int1_mask , REG_INT1_APT_BIT);
1285 }
1286 }
1287 break;
1288 }
1289
1290 if (sahf) {
1291 m_ah_adhs = true;
1292 }
1293 }
1294
dab_received(uint8_t dab,bool eoi)1295 void tms9914_device::dab_received(uint8_t dab , bool eoi)
1296 {
1297 LOG("%.6f RX DAB:%02x/%d\n" , machine().time().as_double() , dab , eoi);
1298 m_reg_di = dab;
1299 if (!m_shdw) {
1300 m_ah_anhs = true;
1301 set_int0_bit(REG_INT0_BI_BIT);
1302 if (eoi) {
1303 set_int0_bit(REG_INT0_END_BIT);
1304 }
1305 }
1306 if (m_hdfe && eoi) {
1307 m_ah_aehs = true;
1308 }
1309 }
1310
do_aux_cmd(unsigned cmd,bool set_bit)1311 void tms9914_device::do_aux_cmd(unsigned cmd , bool set_bit)
1312 {
1313 switch (cmd) {
1314 case AUXCMD_SWRST:
1315 if (set_bit && !m_swrst) {
1316 do_swrst();
1317 }
1318 if (m_swrst != set_bit) {
1319 m_swrst = set_bit;
1320 update_fsm();
1321 }
1322 break;
1323
1324 case AUXCMD_DACR:
1325 if (m_ah_adhs) {
1326 m_ah_adhs = false;
1327 if (BIT(m_reg_int1_mask , REG_INT1_APT_BIT)) {
1328 // Using secondary addressing
1329 if (set_bit && !listener_reset() && m_l_lpas) {
1330 do_LAF();
1331 }
1332 if (!set_bit && m_t_state == FSM_T_TADS && m_t_tpas) {
1333 m_t_state = FSM_T_TIDS;
1334 m_ext_state_change = true;
1335 }
1336 if (set_bit && !talker_reset() && m_t_tpas) {
1337 do_TAF();
1338 }
1339 }
1340 update_fsm();
1341 }
1342 break;
1343
1344 case AUXCMD_RHDF:
1345 // TODO: ACRS -> ANRS
1346 if (m_ah_anhs || m_ah_aehs) {
1347 m_ah_anhs = false;
1348 m_ah_aehs = false;
1349 update_fsm();
1350 }
1351 break;
1352
1353 case AUXCMD_HDFA:
1354 if (!m_swrst) {
1355 m_hdfa = set_bit;
1356 }
1357 break;
1358
1359 case AUXCMD_HDFE:
1360 if (!m_swrst) {
1361 m_hdfe = set_bit;
1362 }
1363 break;
1364
1365 case AUXCMD_NBAF:
1366 m_t_eoi_state = FSM_T_ENIS;
1367 if (!m_sh_shfs) {
1368 m_sh_shfs = true;
1369 update_fsm();
1370 }
1371 break;
1372
1373 case AUXCMD_FGET:
1374 LOG("Unimplemented FGET cmd\n");
1375 break;
1376
1377 case AUXCMD_RTL:
1378 m_rtl = set_bit;
1379 if (m_rtl && m_rl_state == FSM_RL_REMS) {
1380 m_rl_state = FSM_RL_LOCS;
1381 set_int0_bit(REG_INT0_RLC_BIT);
1382 }
1383 break;
1384
1385 case AUXCMD_FEOI:
1386 m_next_eoi = true;
1387 break;
1388
1389 case AUXCMD_LON:
1390 if (set_bit) {
1391 if (!listener_reset()) {
1392 do_LAF();
1393 }
1394 } else {
1395 m_l_state = FSM_L_LIDS;
1396 m_ext_state_change = true;
1397 }
1398 update_fsm();
1399 break;
1400
1401 case AUXCMD_TON:
1402 if (set_bit) {
1403 if (!talker_reset()) {
1404 do_TAF();
1405 }
1406 } else {
1407 m_t_state = FSM_T_TIDS;
1408 m_ext_state_change = true;
1409 }
1410 update_fsm();
1411 break;
1412
1413 case AUXCMD_GTS:
1414 if (m_c_state == FSM_C_CACS) {
1415 m_gts = true;
1416 update_fsm();
1417 }
1418 break;
1419
1420 case AUXCMD_TCA:
1421 if (m_c_state == FSM_C_CSBS) {
1422 m_c_state = FSM_C_CSHS;
1423 m_ext_state_change = true;
1424 // Manual says delay is 8 clock cycles, but 10 at least are needed
1425 // to pass diagb hpib diagnostic
1426 //m_c_dly_timer->adjust(clocks_to_attotime(8));
1427 m_c_dly_timer->adjust(clocks_to_attotime(10));
1428 update_fsm();
1429 }
1430 break;
1431
1432 case AUXCMD_TCS:
1433 if (m_c_state == FSM_C_CSBS) {
1434 m_c_state = FSM_C_CWAS;
1435 m_ext_state_change = true;
1436 update_fsm();
1437 }
1438 break;
1439
1440 case AUXCMD_RPP:
1441 if (!m_swrst && m_rpp != set_bit) {
1442 m_rpp = set_bit;
1443 update_fsm();
1444 }
1445 break;
1446
1447 case AUXCMD_SIC:
1448 if (m_sic != set_bit) {
1449 m_sic = set_bit;
1450 update_ifc();
1451 if (!controller_reset() && m_sic && m_c_state == FSM_C_CIDS) {
1452 m_c_state = FSM_C_CADS;
1453 m_ext_state_change = true;
1454 }
1455 update_fsm();
1456 }
1457 break;
1458
1459 case AUXCMD_SRE:
1460 m_sre = set_bit;
1461 update_ren();
1462 break;
1463
1464 case AUXCMD_RQC:
1465 if (!controller_reset() && m_c_state == FSM_C_CIDS) {
1466 m_c_state = FSM_C_CADS;
1467 m_ext_state_change = true;
1468 update_fsm();
1469 }
1470 break;
1471
1472 case AUXCMD_RLC:
1473 if (m_c_state != FSM_C_CIDS) {
1474 m_c_state = FSM_C_CIDS;
1475 m_ext_state_change = true;
1476 update_fsm();
1477 }
1478 break;
1479
1480 case AUXCMD_DAI:
1481 m_dai = set_bit;
1482 update_int();
1483 break;
1484
1485 case AUXCMD_PTS:
1486 m_pts = true;
1487 break;
1488
1489 case AUXCMD_STDL:
1490 LOG("Unimplemented STDL=%d cmd\n" , set_bit);
1491 break;
1492
1493 case AUXCMD_SHDW:
1494 if (!m_swrst) {
1495 m_shdw = set_bit;
1496 if (m_shdw && m_ah_anhs) {
1497 m_ah_anhs = false;
1498 update_fsm();
1499 }
1500 }
1501 break;
1502
1503 case AUXCMD_VSTDL:
1504 LOG("Unimplemented VSTDL=%d cmd\n" , set_bit);
1505 break;
1506
1507 case AUXCMD_RSV2:
1508 if (set_bit != m_rsvd2) {
1509 m_rsvd2 = set_bit;
1510 update_fsm();
1511 }
1512 break;
1513
1514 default:
1515 LOG("Unrecognized aux cmd %u\n" , cmd);
1516 break;
1517 }
1518 }
1519
set_int0_bit(unsigned bit_no)1520 void tms9914_device::set_int0_bit(unsigned bit_no)
1521 {
1522 BIT_SET(m_reg_int0_status , bit_no);
1523 update_int();
1524 if (bit_no == REG_INT0_BI_BIT || (bit_no == REG_INT0_BO_BIT && m_c_state != FSM_C_CACS)) {
1525 set_accrq(true);
1526 }
1527 }
1528
set_int1_bit(unsigned bit_no)1529 void tms9914_device::set_int1_bit(unsigned bit_no)
1530 {
1531 BIT_SET(m_reg_int1_status , bit_no);
1532 update_int();
1533 }
1534
update_int()1535 void tms9914_device::update_int()
1536 {
1537 bool new_int_line = false;
1538 m_reg_int0_status &= REG_INT0_INT_MASK;
1539 if (m_reg_int0_status & m_reg_int0_mask) {
1540 BIT_SET(m_reg_int0_status , REG_INT0_INT0_BIT);
1541 new_int_line = true;
1542 }
1543 if (m_reg_int1_status & m_reg_int1_mask) {
1544 BIT_SET(m_reg_int0_status , REG_INT0_INT1_BIT);
1545 new_int_line = true;
1546 }
1547 if (m_dai) {
1548 new_int_line = false;
1549 }
1550 if (new_int_line != m_int_line) {
1551 LOG_INT("INT=%d\n" , new_int_line);
1552 m_int_line = new_int_line;
1553 m_int_write_func(m_int_line);
1554 }
1555 }
1556
update_ifc()1557 void tms9914_device::update_ifc()
1558 {
1559 set_signal(IEEE_488_IFC , m_sic);
1560 }
1561
update_ren()1562 void tms9914_device::update_ren()
1563 {
1564 set_signal(IEEE_488_REN , m_sre);
1565 }
1566
set_accrq(bool state)1567 void tms9914_device::set_accrq(bool state)
1568 {
1569 if (state != m_accrq_line) {
1570 LOG_INT("ACCRQ=%d\n" , state);
1571 m_accrq_line = state;
1572 m_accrq_write_func(m_accrq_line);
1573 }
1574 }
1575