1 // license:BSD-3-Clause
2 // copyright-holders:Michael Zapf
3 /*
4     Texas Instruments TMS9900
5 
6                     +--------------------+
7                V_BB | 1  o             64| /HOLD
8                V_CC | 2                63| /MEMEN
9                WAIT | 3                62| READY
10               /LOAD | 4                61| /WE
11               HOLDA | 5                60| CRUCLK
12              /RESET | 6                59| V_CC
13                 IAQ | 7                58| -
14                PHI1 | 8                57| -
15                PHI2 | 9                56| D15   -+  LSB
16      LSB  +-    A14 |10                55| D14    |
17           |     A13 |11                54| D13    |
18           |     A12 |12                53| D12    |
19           |     A11 |13                52| D11    |
20   Address |     A10 |14   +--------+   51| D10    | Data
21     bus   |      A9 |15   |        |   50| D9     | bus
22    32K *  |      A8 |16   |        |   49| D8     | 16 bit
23    16bit  |      A7 |17   |        |   48| D7     |
24           |      A6 |18   |        |   47| D6     |
25           |      A5 |19   +--------+   46| D5     |
26           |      A4 |20                45| D4     |
27           |      A3 |21                44| D3     |
28           |      A2 |22                43| D2     |
29           |      A1 |23                42| D1     |
30      MSB  +-     A0 |24                41| D0    -+  MSB
31                PHI4 |25                40| V_SS
32                V_SS |26                39| -
33                V_DD |27                38| -
34                PHI3 |28                37| -
35                DBIN |29                36| IC0   -+ MSB
36              CRUOUT |30                35| IC1    | Interrupt
37               CRUIN |31                34| IC2    | level
38             /INTREQ |32                33| IC3   -+ LSB
39                     +--------------------+
40 
41        WAIT   out   Processor in wait state
42       /LOAD    in   Non-maskable interrupt
43       HOLDA   out   Hold acknowledge
44      /RESET    in   Reset
45         IAQ   out   Instruction acquisition
46      PHI1-4    in   Clock phase inputs
47        DBIN   out   Data bus in input mode
48      CRUOUT   out   Communication register unit data output
49       CRUIN    in   Communication register unit data input
50     /INTREQ    in   Interrupt request
51      CRUCLK   out   Communication register unit clock output
52         /WE   out   Data available for memory write
53       READY    in   Memory ready for access
54      /MEMEN   out   Address bus contains memory address
55       /HOLD    in   External device acquires address and data bus lines
56 
57       V_BB     -5V  supply
58       V_CC     +5V  supply (pins 2 and 59 connected in parallel)
59       V_DD    +12V  supply
60       V_SS      0V  Ground reference (pins 26 and 40 connected in parallel)
61 
62       A0-A14  out   Address bus (32768 words of 16 bit width)
63       D0-A15  i/o   Data bus
64      IC0-IC3   in   Interrupt level (0-15)
65 
66      Note that Texas Instruments' bit numberings define bit 0 as the
67      most significant bit (different to most other systems). Also, the
68      system uses big-endian memory organisation: Storing the word 0x1234 at
69      address 0x0000 means that the byte 0x12 is stored at 0x0000 and byte 0x34
70      is stored at 0x0001.
71 
72      The processor also knows byte-oriented operations (like add byte (AB),
73      move byte (MOVB)). This makes it necessary for the CPU to read the word
74      from the target memory location first, change the respective byte, and
75      write it back.
76 
77      See the TI-99/4A driver for an application of the TMS9900 processor
78      within an 8-bit data bus board layout (using a data bus multiplexer).
79 
80      Subcycle handling
81 
82      In this implementation we try to emulate the internal operations as
83      precisely as possible, following the technical specifications. We need
84      not try to be clock-precise with every tick; it suffices to perform
85      the proper number of operations within a given time span.
86 
87      For each command the CPU executes a microprogram which requires some
88      amount of cycles to complete. During this time the external clock continues
89      to issue pulses which can be used to control wait state creation. As we
90      do not emulate external clocks this implementation offers an extra output
91      "clock_out" (which, however, is available for the TMS9995) which pulses
92      at a rate of 3 MHz. External devices (e.g. memory controllers) may count
93      the pulses and pull down the READY line (with set_ready) as needed.
94 
95      Another possibility for creating wait states is to pull down the line
96      for some time set by a timer. This is done, for example, by circuits like
97      GROMs or speech synthesis processors (TMS52xx).
98 
99     Michael Zapf, June 2012
100 */
101 
102 #include "emu.h"
103 #include "tms9900.h"
104 #include "9900dasm.h"
105 
106 #define NOPRG -1
107 
108 constexpr int tms99xx_device::AS_SETADDRESS;
109 
110 /* tms9900 ST register bits. */
111 enum
112 {
113 	ST_LH = 0x8000,     // Logical higher (unsigned comparison)
114 	ST_AGT = 0x4000,    // Arithmetical greater than (signed comparison)
115 	ST_EQ = 0x2000,     // Equal
116 	ST_C = 0x1000,      // Carry
117 	ST_OV = 0x0800,     // Overflow (when using signed operations)
118 	ST_OP = 0x0400,     // Odd parity (used with byte operations)
119 	ST_X = 0x0200,      // XOP
120 	ST_IM = 0x000f      // Interrupt mask
121 };
122 
123 /*
124     The following defines can be set to 0 or 1 to disable or enable certain
125     output in the log.
126 */
127 #define LOG_OP         (1U<<1)   // Current instruction
128 #define LOG_EXEC       (1U<<2)   // Address of current instruction
129 #define LOG_CYCLES     (1U<<4)   // Cycles
130 #define LOG_WARN       (1U<<5)   // Illegal operation or other condition
131 #define LOG_MEM        (1U<<6)   // Memory access
132 #define LOG_CONTEXT    (1U<<7)   // Context switch
133 #define LOG_INT        (1U<<8)   // Interrupts
134 #define LOG_READY      (1U<<9)   // READY line input
135 #define LOG_CLOCK      (1U<<10)  // Clock pulses
136 #define LOG_ADDRESSBUS (1U<<11)  // Address bus operation
137 #define LOG_STATUS     (1U<<12)  // Status register
138 #define LOG_CRU        (1U<<13)  // CRU operations
139 #define LOG_WAIT       (1U<<15)  // Wait states
140 #define LOG_HOLD       (1U<<16)  // Hold states
141 #define LOG_IDLE       (1U<<17)  // Idle states
142 #define LOG_EMU        (1U<<18)  // Emulation details
143 #define LOG_MICRO      (1U<<19)  // Microinstruction processing
144 #define LOG_INTD       (1U<<20)  // Interrupts (detailed phases)
145 #define LOG_LOAD       (1U<<21)  // LOAD interrupt
146 #define LOG_DETAIL     (1U<<31)  // Increased detail
147 
148 // Minimum log should be warnings
149 #define VERBOSE ( LOG_GENERAL | LOG_WARN )
150 
151 #include "logmacro.h"
152 
153 /****************************************************************************
154     Common constructor for TMS9900 and TMS9980A
155     The CRU mask is related to the bits, not to their addresses which are
156     twice their number. Accordingly, the TMS9900 has a CRU bitmask 0x0fff.
157 ****************************************************************************/
158 
tms99xx_device(const machine_config & mconfig,device_type type,const char * tag,int data_width,int prg_addr_bits,int cru_addr_bits,device_t * owner,uint32_t clock)159 tms99xx_device::tms99xx_device(const machine_config &mconfig, device_type type, const char *tag, int data_width, int prg_addr_bits, int cru_addr_bits, device_t *owner, uint32_t clock)
160 	: cpu_device(mconfig, type, tag, owner, clock),
161 		m_program_config("program", ENDIANNESS_BIG, data_width, prg_addr_bits),
162 		m_setaddress_config("setaddress", ENDIANNESS_BIG, data_width, prg_addr_bits), // choose the same width as the program space
163 		m_io_config("cru", ENDIANNESS_LITTLE, 8, cru_addr_bits + 1, 1),
164 		m_prgspace(nullptr),
165 		m_cru(nullptr),
166 		m_prgaddr_mask((1<<prg_addr_bits)-2),  // fffe for 16 bits, 3ffe for 14 bits (only even addresses)
167 		m_cruaddr_mask((2<<cru_addr_bits)-2),  // Address is shifted left by one
168 		m_iaq(false),
169 		m_clock_out_line(*this),
170 		m_wait_line(*this),
171 		m_holda_line(*this),
172 		m_get_intlevel(*this),
173 		m_external_operation(*this),
174 		m_ready_bufd(true),
175 		m_program_index(NOPRG),
176 		m_caller_index(NOPRG)
177 {
178 }
179 
~tms99xx_device()180 tms99xx_device::~tms99xx_device()
181 {
182 }
183 
184 /****************************************************************************
185     Constructor for TMS9900
186 ****************************************************************************/
187 
tms9900_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)188 tms9900_device::tms9900_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
189 	: tms99xx_device(mconfig, TMS9900, tag, 16, 16, 12, owner, clock)
190 {
191 }
192 
193 enum
194 {
195 	TMS9900_PC=0, TMS9900_WP, TMS9900_STATUS, TMS9900_IR,
196 	TMS9900_R0, TMS9900_R1, TMS9900_R2, TMS9900_R3,
197 	TMS9900_R4, TMS9900_R5, TMS9900_R6, TMS9900_R7,
198 	TMS9900_R8, TMS9900_R9, TMS9900_R10, TMS9900_R11,
199 	TMS9900_R12, TMS9900_R13, TMS9900_R14, TMS9900_R15
200 };
201 
device_start()202 void tms99xx_device::device_start()
203 {
204 	// TODO: Restore state save feature
205 	resolve_lines();
206 	m_prgspace = &space(AS_PROGRAM);
207 	m_setaddr = has_space(AS_SETADDRESS) ? &space(AS_SETADDRESS) : nullptr;
208 	m_cru = &space(AS_IO);
209 
210 	// set our instruction counter
211 	set_icountptr(m_icount);
212 
213 	m_state_any = 0;
214 	PC = 0;
215 	m_hold_state = false;
216 
217 	// add the states for the debugger
218 	for (int i=0; i < 20; i++)
219 	{
220 		// callimport = need to use the state_import method to write to the state variable
221 		// callexport = need to use the state_export method to read the state variable
222 		state_add(i, s_statename[i], m_state_any).callimport().callexport().formatstr("%04X");
223 	}
224 	state_add(STATE_GENPC, "GENPC", PC).formatstr("%4s").noshow();
225 	state_add(STATE_GENPCBASE, "CURPC", PC).formatstr("%4s").noshow();
226 	state_add(STATE_GENFLAGS, "status", m_state_any).callimport().callexport().formatstr("%16s").noshow();
227 
228 	build_command_lookup_table();
229 
230 	// Register persistable state variables
231 	save_item(NAME(m_icount));
232 	save_item(NAME(WP));
233 	save_item(NAME(PC));
234 	save_item(NAME(ST));
235 	save_item(NAME(IR));
236 	save_item(NAME(m_address));
237 	save_item(NAME(m_current_value));
238 	save_item(NAME(m_command));
239 	save_item(NAME(m_byteop));
240 	save_item(NAME(m_pass));
241 	save_item(NAME(m_check_ready));
242 	save_item(NAME(m_mem_phase));
243 	save_item(NAME(m_load_state));
244 	save_item(NAME(m_irq_state));
245 	save_item(NAME(m_log_interrupt));
246 	save_item(NAME(m_reset));
247 	save_item(NAME(m_irq_level));
248 	// save_item(NAME(m_first_cycle)); // only for log output
249 	save_item(NAME(m_idle_state));
250 	save_item(NAME(m_ready_bufd));
251 	save_item(NAME(m_ready));
252 	save_item(NAME(m_wait_state));
253 	save_item(NAME(m_hold_state));
254 	// save_item(NAME(m_state_any)); // only for debugger output
255 	save_item(NAME(MPC));
256 	save_item(NAME(m_program_index));
257 	save_item(NAME(m_caller_index));
258 	save_item(NAME(m_caller_MPC));
259 	save_item(NAME(m_state));
260 	save_item(NAME(m_hold_acknowledged));
261 	save_item(NAME(m_source_even));
262 	save_item(NAME(m_destination_even));
263 	save_item(NAME(m_source_address));
264 	save_item(NAME(m_source_value));
265 	save_item(NAME(m_address_saved));
266 	save_item(NAME(m_address_copy));
267 	save_item(NAME(m_register_contents));
268 	save_item(NAME(m_regnumber));
269 	save_item(NAME(m_cru_address));
270 	save_item(NAME(m_count));
271 	save_item(NAME(m_value_copy));
272 	save_item(NAME(m_value));
273 	save_item(NAME(m_get_destination));
274 }
275 
device_stop()276 void tms99xx_device::device_stop()
277 {
278 }
279 
280 /*
281     External connections
282 */
resolve_lines()283 void tms99xx_device::resolve_lines()
284 {
285 	// Resolve our external connections
286 	m_external_operation.resolve();
287 	m_get_intlevel.resolve();
288 	m_clock_out_line.resolve();
289 	m_wait_line.resolve();
290 	m_holda_line.resolve();
291 }
292 
293 /*
294     TMS9900 hard reset
295     The device reset is just the emulator's trigger for the reset procedure
296     which is invoked via the main loop.
297 */
device_reset()298 void tms99xx_device::device_reset()
299 {
300 	LOGMASKED(LOG_EMU, "Device reset by emulator\n");
301 	m_reset = true;
302 	m_check_ready = false;
303 	m_wait_state = false;
304 	ST = 0;
305 	m_irq_state = false;
306 	m_log_interrupt = false;   // only for debugging
307 }
308 
309 char const *const tms99xx_device::s_statename[20] =
310 {
311 	"PC", "WP", "ST", "IR",
312 	"R0", "R1", "R2", "R3",
313 	"R4", "R5", "R6", "R7",
314 	"R8", "R9", "R10","R11",
315 	"R12","R13","R14","R15"
316 };
317 
318 /*
319     Write the contents of a register by external input (debugger)
320 */
state_import(const device_state_entry & entry)321 void tms99xx_device::state_import(const device_state_entry &entry)
322 {
323 	int index = entry.index();
324 	switch (entry.index())
325 	{
326 		case STATE_GENFLAGS:
327 			// no action here; we do not allow import, as the flags are all
328 			// bits of the STATUS register
329 			break;
330 		case TMS9900_PC:
331 			PC = (uint16_t)(m_state_any & m_prgaddr_mask);
332 			break;
333 		case TMS9900_WP:
334 			WP = (uint16_t)(m_state_any & m_prgaddr_mask);
335 			break;
336 		case TMS9900_STATUS:
337 			ST = (uint16_t)m_state_any;
338 			break;
339 		case TMS9900_IR:
340 			IR = (uint16_t)m_state_any;
341 			break;
342 		default:
343 			// Workspace registers
344 			if (index <= TMS9900_R15)
345 				write_workspace_register_debug(index-TMS9900_R0, (uint16_t)m_state_any);
346 			break;
347 	}
348 }
349 
350 /*
351     Reads the contents of a register for display in the debugger.
352 */
state_export(const device_state_entry & entry)353 void tms99xx_device::state_export(const device_state_entry &entry)
354 {
355 	int index = entry.index();
356 	switch (entry.index())
357 	{
358 		case STATE_GENFLAGS:
359 			m_state_any = ST;
360 			break;
361 		case TMS9900_PC:
362 			m_state_any = PC;
363 			break;
364 		case TMS9900_WP:
365 			m_state_any = WP;
366 			break;
367 		case TMS9900_STATUS:
368 			m_state_any = ST;
369 			break;
370 		case TMS9900_IR:
371 			m_state_any = IR;
372 			break;
373 		default:
374 			// Workspace registers
375 			if (index <= TMS9900_R15)
376 				m_state_any = read_workspace_register_debug(index-TMS9900_R0);
377 			break;
378 	}
379 }
380 
381 /*
382     state_string_export - export state as a string for the debugger
383 */
state_string_export(const device_state_entry & entry,std::string & str) const384 void tms99xx_device::state_string_export(const device_state_entry &entry, std::string &str) const
385 {
386 	static char const statestr[] = "LAECOPX-----IIII";
387 	char flags[17];
388 	for (auto &flag : flags) flag = 0x00;
389 	uint16_t val = 0x8000;
390 	if (entry.index()==STATE_GENFLAGS)
391 	{
392 		for (int i=0; i < 16; i++)
393 		{
394 			flags[i] = ((val & ST)!=0)? statestr[i] : '.';
395 			val = (val >> 1) & 0x7fff;
396 		}
397 	}
398 	str.assign(flags);
399 }
400 
401 /**************************************************************************/
402 
read_workspace_register_debug(int reg)403 uint16_t tms99xx_device::read_workspace_register_debug(int reg)
404 {
405 	int temp = m_icount;
406 	auto dis = machine().disable_side_effects();
407 	uint16_t value = m_prgspace->read_word((WP+(reg<<1)) & m_prgaddr_mask);
408 	m_icount = temp;
409 	return value;
410 }
411 
write_workspace_register_debug(int reg,uint16_t data)412 void tms99xx_device::write_workspace_register_debug(int reg, uint16_t data)
413 {
414 	int temp = m_icount;
415 	auto dis = machine().disable_side_effects();
416 	m_prgspace->write_word((WP+(reg<<1)) & m_prgaddr_mask, data);
417 	m_icount = temp;
418 }
419 
420 /*
421     The setaddress space is used to implement a split-phase memory access
422     where the address bus is first set, then the CPU samples the READY line,
423     (when low, enters wait states,) then the CPU reads the address bus. For
424     writing, setting the address and setting the data bus is done in direct
425     succession.
426 
427     It is an optional feature, where drivers may connect to this space to
428     make use of it, or to completely ignore it when there is no need for
429     waitstate control.
430 
431     In order to allow for using address maps, the setaddress space shows the
432     same widths as the normal program space. Its values are the levels of
433     certains lines that are set or reset during the memory access, in
434     particular DBIN and IAQ.
435 */
memory_space_config() const436 device_memory_interface::space_config_vector tms99xx_device::memory_space_config() const
437 {
438 	if (has_configured_map(AS_SETADDRESS))
439 		return space_config_vector {
440 			std::make_pair(AS_PROGRAM,   &m_program_config),
441 			std::make_pair(AS_SETADDRESS, &m_setaddress_config),
442 			std::make_pair(AS_IO,        &m_io_config)
443 		};
444 	else
445 		return space_config_vector {
446 			std::make_pair(AS_PROGRAM,   &m_program_config),
447 			std::make_pair(AS_IO,        &m_io_config)
448 		};
449 }
450 
451 /**************************************************************************
452     Microprograms for the CPU instructions
453 
454     The actions which are specific to the respective instruction are
455     invoked by repeated calls of ALU_xxx; each call increases a state
456     variable so that on the next call, the next part can be processed.
457     This saves us a lot of additional functions.
458 **************************************************************************/
459 
460 /*
461     Define the indices for the micro-operation table. This is done for the sake
462     of a simpler microprogram definition as an uint8_t[].
463 */
464 enum
465 {
466 	IAQ = 0,
467 	MEMORY_READ,
468 	MEMORY_WRITE,
469 	REG_READ,
470 	REG_WRITE,
471 	CRU_INPUT,
472 	CRU_OUTPUT,
473 	DATA_DERIVE,
474 	RET,
475 	ABORT,
476 	END,
477 
478 	ALU_NOP,
479 	ALU_CLR,
480 	ALU_SETADDR,
481 	ALU_ADDONE,
482 	ALU_SETADDR_ADDONE,
483 	ALU_PCADDR_ADVANCE,
484 	ALU_SOURCE,
485 	ALU_ADDREG,
486 	ALU_IMM,
487 	ALU_REG,
488 	ALU_F1,
489 	ALU_COMP,
490 	ALU_F3,
491 	ALU_MPY,
492 	ALU_DIV,
493 	ALU_XOP,
494 	ALU_CLR_SWPB,
495 	ALU_ABS,
496 	ALU_X,
497 	ALU_B,
498 	ALU_BLWP,
499 	ALU_LDCR,
500 	ALU_STCR,
501 	ALU_SBZ_SBO,
502 	ALU_TB,
503 	ALU_JMP,
504 	ALU_SHIFT,
505 	ALU_AI_ORI,
506 	ALU_CI,
507 	ALU_LI,
508 	ALU_LWPI,
509 	ALU_LIMI,
510 	ALU_STWP_STST,
511 	ALU_EXT,
512 	ALU_RTWP,
513 	ALU_INT
514 };
515 
516 
517 #define MICROPROGRAM(_MP) \
518 	static const uint8_t _MP[] =
519 
520 /*
521     This is a kind of subroutine with 6 variants. Might be done in countless
522     better ways, but will suffice for now. Each variant has at most 8 steps
523     RET will return to the caller.
524     The padding simplifies the calculation of the start address: We just
525     take the Ts field as an index. In the last two cases we add an offset of 8
526     if we have an indexed (resp. a byte) operation.
527 */
MICROPROGRAM(data_derivation)528 MICROPROGRAM(data_derivation)
529 {
530 	REG_READ, RET, 0, 0, 0, 0, 0, 0,                                                // Rx           (00)
531 	0, 0, 0, 0, 0, 0, 0, 0,
532 	REG_READ, ALU_SETADDR, MEMORY_READ, RET, 0, 0, 0, 0,                            // *Rx          (01)
533 	0, 0, 0, 0, 0, 0, 0, 0,
534 	ALU_CLR, ALU_PCADDR_ADVANCE, MEMORY_READ, ALU_ADDREG, MEMORY_READ, RET, 0, 0,   // @sym         (10)
535 	REG_READ, ALU_PCADDR_ADVANCE, MEMORY_READ, ALU_ADDREG, MEMORY_READ, RET, 0, 0,  // @sym(Rx)     (10)
536 	REG_READ, ALU_SETADDR_ADDONE, ALU_ADDONE, REG_WRITE, MEMORY_READ, RET, 0, 0,    // *Rx+ (word)  (11)
537 	REG_READ, ALU_SETADDR_ADDONE, REG_WRITE, MEMORY_READ, RET, 0, 0, 0              // *Rx+ (byte)  (11)
538 };
539 
MICROPROGRAM(f1_mp)540 MICROPROGRAM(f1_mp)
541 {
542 	ALU_NOP,
543 	DATA_DERIVE,
544 	ALU_SOURCE,         // Store the word
545 	DATA_DERIVE,
546 	ALU_F1,
547 	MEMORY_WRITE,
548 	END
549 };
550 
MICROPROGRAM(comp_mp)551 MICROPROGRAM(comp_mp)
552 {
553 	ALU_NOP,
554 	DATA_DERIVE,
555 	ALU_SOURCE,
556 	DATA_DERIVE,
557 	ALU_COMP,
558 	ALU_NOP,        // Compare operations do not write back any data
559 	END
560 };
561 
MICROPROGRAM(f3_mp)562 MICROPROGRAM(f3_mp)
563 {
564 	ALU_NOP,
565 	DATA_DERIVE,
566 	ALU_F3,
567 	MEMORY_READ,    // We have to distinguish this from the C/CB microprogram above
568 	ALU_F3,
569 	ALU_NOP,        // Compare operations do not write back any data
570 	END
571 };
572 
MICROPROGRAM(xor_mp)573 MICROPROGRAM(xor_mp)
574 {
575 	ALU_NOP,
576 	DATA_DERIVE,
577 	ALU_F3,
578 	MEMORY_READ,
579 	ALU_F3,
580 	MEMORY_WRITE,   // XOR again must write back data, cannot reuse f3_mp
581 	END
582 };
583 
MICROPROGRAM(mult_mp)584 MICROPROGRAM(mult_mp)
585 {
586 	ALU_NOP,
587 	DATA_DERIVE,
588 	ALU_MPY,        // Save the value; put register number in m_regnumber
589 	MEMORY_READ,
590 	ALU_MPY,        // 18 cycles for multiplication
591 	MEMORY_WRITE,       // Write the high word
592 	ALU_MPY,        // Get low word, increase m_address
593 	MEMORY_WRITE,
594 	END
595 };
596 
MICROPROGRAM(div_mp)597 MICROPROGRAM(div_mp)
598 {
599 	ALU_NOP,
600 	DATA_DERIVE,    // Get divisor
601 	ALU_DIV,        // 0 Store divisor and get register number
602 	MEMORY_READ,    // Read register
603 	ALU_DIV,        // 1 Check overflow, increase address (or abort here)
604 	ABORT,
605 	MEMORY_READ,    // Read subsequent word (if reg=15 this is behind the workspace)
606 	ALU_DIV,        // 2 Calculate quotient (takes variable amount of cycles; at least 32 machine cycles), set register number
607 	MEMORY_WRITE,   // Write quotient into register
608 	ALU_DIV,        // 3 Get remainder
609 	MEMORY_WRITE,   // Write remainder
610 	END
611 };
612 
MICROPROGRAM(xop_mp)613 MICROPROGRAM(xop_mp)
614 {
615 	ALU_NOP,
616 	DATA_DERIVE,    // Get argument
617 	ALU_XOP,        // 0 Save the address of the source operand, set address = 0x0040 + xopNr*4, 6 cycles
618 	MEMORY_READ,    // Read the new WP
619 	ALU_XOP,        // 1 Save old WP, set new WP, get the source operand address
620 	MEMORY_WRITE,   // Write the address of the source operand into the new R11
621 	ALU_XOP,        // 2
622 	MEMORY_WRITE,   // Write the ST into the new R15
623 	ALU_XOP,        // 3
624 	MEMORY_WRITE,   // Write the PC into the new R14
625 	ALU_XOP,        // 4
626 	MEMORY_WRITE,   // Write the WP into the new R13
627 	ALU_XOP,        // 5 Set the X bit in the ST
628 	MEMORY_READ,    // Read the new PC
629 	ALU_XOP,        // 6 Set the new PC
630 	END
631 };
632 
MICROPROGRAM(clr_swpb_mp)633 MICROPROGRAM(clr_swpb_mp)
634 {
635 	ALU_NOP,
636 	DATA_DERIVE,
637 	ALU_CLR_SWPB,
638 	MEMORY_WRITE,
639 	END
640 };
641 
MICROPROGRAM(abs_mp)642 MICROPROGRAM(abs_mp)
643 {
644 	ALU_NOP,
645 	DATA_DERIVE,
646 	ALU_ABS,        // two cycles
647 	MEMORY_WRITE,   // skipped when ABS is not performed
648 	ALU_NOP,
649 	END
650 };
651 
MICROPROGRAM(x_mp)652 MICROPROGRAM(x_mp)
653 {
654 	ALU_NOP,
655 	DATA_DERIVE,
656 	ALU_X,
657 	END
658 };
659 
MICROPROGRAM(b_mp)660 MICROPROGRAM(b_mp)      // Branch
661 {
662 	ALU_NOP,
663 	DATA_DERIVE,
664 	ALU_B,
665 	END
666 };
667 
MICROPROGRAM(bl_mp)668 MICROPROGRAM(bl_mp)     // Branch and Link
669 {
670 	ALU_NOP,
671 	DATA_DERIVE,
672 	ALU_B,
673 	ALU_NOP,
674 	MEMORY_WRITE,
675 	END
676 };
677 
MICROPROGRAM(blwp_mp)678 MICROPROGRAM(blwp_mp)       // Branch and Load WP
679 {
680 	ALU_NOP,
681 	DATA_DERIVE,            // Get argument
682 	ALU_BLWP,               // 0 Save old WP, set new WP, save position
683 	ALU_NOP,
684 	MEMORY_WRITE,           // write ST to R15
685 	ALU_BLWP,               // 1
686 	MEMORY_WRITE,           // write PC to R14
687 	ALU_BLWP,               // 2
688 	MEMORY_WRITE,           // write WP to R13
689 	ALU_BLWP,               // 3 Get saved position
690 	MEMORY_READ,            // Read new PC
691 	ALU_BLWP,               // 4 Set new PC
692 	END
693 };
694 
MICROPROGRAM(ldcr_mp)695 MICROPROGRAM(ldcr_mp)
696 {
697 	ALU_NOP,
698 	DATA_DERIVE,
699 	ALU_SOURCE,
700 	ALU_NOP,
701 	ALU_LDCR,
702 	ALU_NOP,
703 	MEMORY_READ,
704 	ALU_LDCR,
705 	CRU_OUTPUT,
706 	ALU_NOP,
707 	END
708 };
709 
MICROPROGRAM(stcr_mp)710 MICROPROGRAM(stcr_mp)
711 {
712 	ALU_NOP,
713 	DATA_DERIVE,
714 	ALU_SOURCE,         // Store address and value
715 	ALU_STCR,           // 0 Set register_number = 12; 0 cycles (already done before)
716 	MEMORY_READ,
717 	ALU_STCR,           // 1 Prepare CRU access
718 	ALU_NOP,
719 	CRU_INPUT,
720 	ALU_STCR,           // 2 Create result; Cycles = 5 + (8-#C-1) or + (16-#C)
721 	ALU_NOP,
722 	ALU_NOP,
723 	ALU_NOP,
724 	MEMORY_WRITE,
725 	END
726 };
727 
MICROPROGRAM(sbz_sbo_mp)728 MICROPROGRAM(sbz_sbo_mp)
729 {
730 	ALU_SBZ_SBO,
731 	ALU_NOP,
732 	MEMORY_READ,
733 	ALU_SBZ_SBO,
734 	CRU_OUTPUT,
735 	END
736 };
737 
MICROPROGRAM(tb_mp)738 MICROPROGRAM(tb_mp)
739 {
740 	ALU_TB,
741 	MEMORY_READ,
742 	ALU_TB,
743 	CRU_INPUT,
744 	ALU_TB,
745 	END
746 };
747 
MICROPROGRAM(jmp_mp)748 MICROPROGRAM(jmp_mp)
749 {
750 	ALU_NOP,
751 	ALU_JMP,
752 	ALU_JMP,
753 	ALU_NOP,
754 	END
755 };
756 
MICROPROGRAM(shift_mp)757 MICROPROGRAM(shift_mp)
758 {
759 	ALU_SHIFT,
760 	MEMORY_READ,
761 	ALU_SHIFT,              // 2 cycles if count != 0, else 4
762 	MEMORY_READ,            // skipped if count != 0
763 	ALU_SHIFT,              // skipped if count != 0  (4 cycles)
764 	ALU_SHIFT,
765 	MEMORY_WRITE,
766 	ALU_NOP,
767 	END
768 };
769 
MICROPROGRAM(ai_ori_mp)770 MICROPROGRAM(ai_ori_mp)
771 {
772 	ALU_REG,
773 	MEMORY_READ,
774 	ALU_IMM,
775 	MEMORY_READ,
776 	ALU_AI_ORI,
777 	MEMORY_WRITE,
778 	END
779 };
780 
MICROPROGRAM(ci_mp)781 MICROPROGRAM(ci_mp)
782 {
783 	ALU_REG,
784 	MEMORY_READ,
785 	ALU_IMM,
786 	MEMORY_READ,
787 	ALU_CI,
788 	ALU_NOP,
789 	END
790 };
791 
MICROPROGRAM(li_mp)792 MICROPROGRAM(li_mp)
793 {
794 	ALU_IMM,
795 	MEMORY_READ,
796 	ALU_LI,             // sets status bits
797 	ALU_REG,            // set register number
798 	MEMORY_WRITE,
799 	END
800 };
801 
MICROPROGRAM(lwpi_mp)802 MICROPROGRAM(lwpi_mp)
803 {
804 	ALU_IMM,
805 	MEMORY_READ,
806 	ALU_NOP,
807 	ALU_LWPI,               // sets WP
808 	END
809 };
810 
MICROPROGRAM(limi_mp)811 MICROPROGRAM(limi_mp)
812 {
813 	ALU_IMM,
814 	MEMORY_READ,
815 	ALU_NOP,
816 	ALU_LIMI,               // sets interrupt mask in ST
817 	ALU_NOP,
818 	ALU_NOP,
819 	END
820 };
821 
MICROPROGRAM(stwp_stst_mp)822 MICROPROGRAM(stwp_stst_mp)
823 {
824 	ALU_STWP_STST,
825 	ALU_REG,
826 	MEMORY_WRITE,
827 	END
828 };
829 
MICROPROGRAM(external_mp)830 MICROPROGRAM(external_mp)
831 {
832 	ALU_NOP,
833 	ALU_NOP,
834 	ALU_EXT,
835 	ALU_NOP,
836 	ALU_NOP,
837 	END
838 };
839 
MICROPROGRAM(rtwp_mp)840 MICROPROGRAM(rtwp_mp)
841 {
842 	ALU_NOP,
843 	ALU_RTWP,
844 	MEMORY_READ,
845 	ALU_RTWP,               // no cycles
846 	MEMORY_READ,
847 	ALU_RTWP,               // no cycles
848 	MEMORY_READ,
849 	ALU_RTWP,
850 	END
851 };
852 
MICROPROGRAM(int_mp)853 MICROPROGRAM(int_mp)
854 {
855 	ALU_NOP,
856 	ALU_INT,                // 0 Set address = 0
857 	MEMORY_READ,
858 	ALU_INT,                // 1 Save old WP, set new WP, save position
859 	MEMORY_WRITE,           // write ST to R15
860 	ALU_INT,                // 2
861 	MEMORY_WRITE,           // write PC to R14
862 	ALU_INT,                // 3
863 	MEMORY_WRITE,           // write WP to R13
864 	ALU_INT,                // 4 Get saved position
865 	MEMORY_READ,            // Read new PC
866 	ALU_INT,                // 5 Set new PC
867 	END
868 };
869 
870 const tms99xx_device::ophandler tms99xx_device::s_microoperation[] =
871 {
872 	&tms99xx_device::acquire_instruction,
873 	&tms99xx_device::mem_read,
874 	&tms99xx_device::mem_write,
875 	&tms99xx_device::register_read,
876 	&tms99xx_device::register_write,
877 	&tms99xx_device::cru_input_operation,
878 	&tms99xx_device::cru_output_operation,
879 	&tms99xx_device::data_derivation_subprogram,
880 	&tms99xx_device::return_from_subprogram,
881 	&tms99xx_device::abort_operation,
882 	&tms99xx_device::command_completed,
883 
884 	&tms99xx_device::alu_nop,
885 	&tms99xx_device::alu_clear,
886 	&tms99xx_device::alu_setaddr,
887 	&tms99xx_device::alu_addone,
888 	&tms99xx_device::alu_setaddr_addone,
889 	&tms99xx_device::alu_pcaddr_advance,
890 	&tms99xx_device::alu_source,
891 	&tms99xx_device::alu_add_register,
892 	&tms99xx_device::alu_imm,
893 	&tms99xx_device::alu_reg,
894 
895 	&tms99xx_device::alu_f1,
896 	&tms99xx_device::alu_comp,
897 	&tms99xx_device::alu_f3,
898 	&tms99xx_device::alu_multiply,
899 	&tms99xx_device::alu_divide,
900 	&tms99xx_device::alu_xop,
901 	&tms99xx_device::alu_clr_swpb,
902 	&tms99xx_device::alu_abs,
903 	&tms99xx_device::alu_x,
904 	&tms99xx_device::alu_b,
905 	&tms99xx_device::alu_blwp,
906 	&tms99xx_device::alu_ldcr,
907 	&tms99xx_device::alu_stcr,
908 	&tms99xx_device::alu_sbz_sbo,
909 	&tms99xx_device::alu_tb,
910 	&tms99xx_device::alu_jmp,
911 	&tms99xx_device::alu_shift,
912 	&tms99xx_device::alu_ai_ori,
913 	&tms99xx_device::alu_ci,
914 	&tms99xx_device::alu_li,
915 	&tms99xx_device::alu_lwpi,
916 	&tms99xx_device::alu_limi,
917 	&tms99xx_device::alu_stwp_stst,
918 	&tms99xx_device::alu_external,
919 	&tms99xx_device::alu_rtwp,
920 	&tms99xx_device::alu_int
921 };
922 
923 /*****************************************************************************
924     CPU instructions
925 *****************************************************************************/
926 
927 /*
928     Available instructions
929 */
930 enum
931 {
932 	ILL=0, A, AB, ABS, AI, ANDI, B, BL, BLWP, C,
933 	CB, CI, CKOF, CKON, CLR, COC, CZC, DEC, DECT, DIV,
934 	IDLE, INC, INCT, INV, JEQ, JGT, JH, JHE, JL, JLE,
935 	JLT, JMP, JNC, JNE, JNO, JOC, JOP, LDCR, LI, LIMI,
936 	LREX, LWPI, MOV, MOVB, MPY, NEG, ORI, RSET, RTWP, S,
937 	SB, SBO, SBZ, SETO, SLA, SOC, SOCB, SRA, SRC, SRL,
938 	STCR, STST, STWP, SWPB, SZC, SZCB, TB, X, XOP, XOR,
939 	INTR
940 };
941 
942 /*
943     Formats:
944 
945           0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
946     ----+------------------------------------------------+
947     1   | Opcode | B | Td |  RegNr     | Ts |    RegNr   |
948         +--------+---+----+------------+----+------------+
949     2   |  Opcode               |      Displacement      |
950         +-----------------------+------------------------+
951     3   |  Opcode         |  RegNr     | Ts |    RegNr   |
952         +-----------------+------------+----+------------+
953     4   |  Opcode         |  Count     | Ts |    RegNr   |
954         +-----------------+------------+----+------------+
955     5   |  Opcode               |  Count    |    RegNr   |
956         +-----------------------+-----------+------------+
957     6   |  Opcode                      | Ts |    RegNr   |
958         +------------------------------+----+------------+
959     7   |  Opcode                         |0| 0| 0| 0| 0 |
960         +---------------------------------+-+--+--+--+---+
961     8   |  Opcode                         |0|    RegNr   |
962         +---------------------------------+-+------------+
963     9   |  Opcode         |   Reg/Nr   | Ts |    RegNr   |
964         +-----------------+------------+----+------------+
965 */
966 
967 /*
968     Defines the number of bits from the left which are significant for the
969     command in the respective format.
970 */
971 static const int format_mask_len[] =
972 {
973 	0, 4, 8, 6, 6, 8, 10, 16, 12, 6
974 };
975 
976 const tms99xx_device::tms_instruction tms99xx_device::s_command[] =
977 {
978 	// Opcode, ID, format, microprg
979 	{ 0x0200, LI, 8, li_mp },
980 	{ 0x0220, AI, 8, ai_ori_mp },
981 	{ 0x0240, ANDI, 8, ai_ori_mp },
982 	{ 0x0260, ORI, 8, ai_ori_mp },
983 	{ 0x0280, CI, 8, ci_mp },
984 	{ 0x02a0, STWP, 8, stwp_stst_mp },
985 	{ 0x02c0, STST, 8, stwp_stst_mp },
986 	{ 0x02e0, LWPI, 8, lwpi_mp },
987 	{ 0x0300, LIMI, 8, limi_mp },
988 	{ 0x0340, IDLE, 7, external_mp },
989 	{ 0x0360, RSET, 7, external_mp },
990 	{ 0x0380, RTWP, 7, rtwp_mp },
991 	{ 0x03a0, CKON, 7, external_mp },
992 	{ 0x03c0, CKOF, 7, external_mp },
993 	{ 0x03e0, LREX, 7, external_mp },
994 	{ 0x0400, BLWP, 6, blwp_mp },
995 	{ 0x0440, B, 6, b_mp },
996 	{ 0x0480, X, 6, x_mp },
997 	{ 0x04c0, CLR, 6, clr_swpb_mp },
998 	{ 0x0500, NEG, 6, clr_swpb_mp },
999 	{ 0x0540, INV, 6, clr_swpb_mp },
1000 	{ 0x0580, INC, 6, clr_swpb_mp },
1001 	{ 0x05c0, INCT, 6, clr_swpb_mp },
1002 	{ 0x0600, DEC, 6, clr_swpb_mp },
1003 	{ 0x0640, DECT, 6, clr_swpb_mp },
1004 	{ 0x0680, BL, 6, bl_mp },
1005 	{ 0x06c0, SWPB, 6, clr_swpb_mp },
1006 	{ 0x0700, SETO, 6, clr_swpb_mp },
1007 	{ 0x0740, ABS, 6, abs_mp },
1008 	{ 0x0800, SRA, 5, shift_mp },
1009 	{ 0x0900, SRL, 5, shift_mp },
1010 	{ 0x0a00, SLA, 5, shift_mp },
1011 	{ 0x0b00, SRC, 5, shift_mp },
1012 	{ 0x1000, JMP, 2, jmp_mp },
1013 	{ 0x1100, JLT, 2, jmp_mp },
1014 	{ 0x1200, JLE, 2, jmp_mp },
1015 	{ 0x1300, JEQ, 2, jmp_mp },
1016 	{ 0x1400, JHE, 2, jmp_mp },
1017 	{ 0x1500, JGT, 2, jmp_mp },
1018 	{ 0x1600, JNE, 2, jmp_mp },
1019 	{ 0x1700, JNC, 2, jmp_mp },
1020 	{ 0x1800, JOC, 2, jmp_mp },
1021 	{ 0x1900, JNO, 2, jmp_mp },
1022 	{ 0x1a00, JL, 2, jmp_mp },
1023 	{ 0x1b00, JH, 2, jmp_mp },
1024 	{ 0x1c00, JOP, 2, jmp_mp },
1025 	{ 0x1d00, SBO, 2, sbz_sbo_mp },
1026 	{ 0x1e00, SBZ, 2, sbz_sbo_mp },
1027 	{ 0x1f00, TB, 2, tb_mp },
1028 	{ 0x2000, COC, 3, f3_mp },
1029 	{ 0x2400, CZC, 3, f3_mp },
1030 	{ 0x2800, XOR, 3, xor_mp },
1031 	{ 0x2c00, XOP, 3, xop_mp },
1032 	{ 0x3000, LDCR, 4, ldcr_mp },
1033 	{ 0x3400, STCR, 4, stcr_mp },
1034 	{ 0x3800, MPY, 9, mult_mp },
1035 	{ 0x3c00, DIV, 9, div_mp },
1036 	{ 0x4000, SZC, 1, f1_mp },
1037 	{ 0x5000, SZCB, 1, f1_mp },
1038 	{ 0x6000, S, 1, f1_mp },
1039 	{ 0x7000, SB, 1, f1_mp },
1040 	{ 0x8000, C, 1, comp_mp },
1041 	{ 0x9000, CB, 1, comp_mp },
1042 	{ 0xa000, A, 1, f1_mp },
1043 	{ 0xb000, AB, 1, f1_mp },
1044 	{ 0xc000, MOV, 1, f1_mp },
1045 	{ 0xd000, MOVB, 1, f1_mp },
1046 	{ 0xe000, SOC, 1, f1_mp },
1047 	{ 0xf000, SOCB, 1, f1_mp },
1048 	{ 0x0000, INTR, 1, int_mp}      // special entry for the interrupt microprogram, not in lookup table
1049 };
1050 
1051 /*
1052     Create a B-tree for looking up the commands. Each node can carry up to
1053     16 entries, indexed by 4 consecutive bits in the opcode.
1054 
1055     Works as follows:
1056 
1057     Opcode = 0201 (Load immediate value into register 1)
1058     Opcode = 0284 (Compare immediate value with register 4)
1059 
1060     Table: [ Table0, table1, table2, ... tableF ]
1061                |
1062        +-------+
1063        v
1064     table0: [ table00, table01, table02, ... table0f ]
1065                                   |
1066         +-------------------------+
1067         v
1068     table02: [ table020, table021, ... table028, ... table02f ]
1069                    |         |             |
1070                    v         v             v
1071                  Entry      NULL          Entry
1072                 for LI                   for CI
1073 
1074     For each level in the tree, four more bits are compared. The search
1075     terminates when the number of compared bits is equal or higher than
1076     the number of significant bits of the format of this opcode. The entry
1077     points to the respective line in s_command.
1078 
1079     This way we can decode all format 1 commands by a single pass (including the
1080     most frequent command MOV), and almost all commands by less than four passes.
1081 
1082     The disadvantage is that we have to build these tables from the opcode
1083     list at runtime, and many positions are empty. But we do not need more
1084     than 20 tables for the TMS command set.
1085 */
build_command_lookup_table()1086 void tms99xx_device::build_command_lookup_table()
1087 {
1088 	int i = 0;
1089 	int cmdindex;
1090 	int bitcount;
1091 	const tms_instruction *inst;
1092 	uint16_t opcode;
1093 
1094 	m_command_lookup_table = std::make_unique<lookup_entry[]>(16);
1095 
1096 	lookup_entry* table = m_command_lookup_table.get();
1097 	for (int j=0; j < 16; j++)
1098 	{
1099 		table[j].next_digit = nullptr;
1100 		table[j].index = NOPRG;
1101 	}
1102 
1103 	do
1104 	{
1105 		inst = &s_command[i];
1106 		table = m_command_lookup_table.get();
1107 		LOGMASKED(LOG_EMU, "=== opcode=%04x, len=%d\n", inst->opcode, format_mask_len[inst->format]);
1108 		bitcount = 4;
1109 		opcode = inst->opcode;
1110 		cmdindex = (opcode>>12) & 0x000f;
1111 
1112 		while (bitcount < format_mask_len[inst->format])
1113 		{
1114 			// Descend
1115 			if (table[cmdindex].next_digit == nullptr)
1116 			{
1117 				LOGMASKED(LOG_EMU, "create new table at bitcount=%d for index=%d\n", bitcount, cmdindex);
1118 				table[cmdindex].next_digit = std::make_unique<lookup_entry[]>(16);
1119 				for (int j=0; j < 16; j++)
1120 				{
1121 					table[cmdindex].next_digit[j].next_digit = nullptr;
1122 					table[cmdindex].next_digit[j].index = NOPRG;
1123 				}
1124 			}
1125 			else
1126 			{
1127 				LOGMASKED(LOG_EMU, "found a table at bitcount=%d\n", bitcount);
1128 			}
1129 
1130 			table = table[cmdindex].next_digit.get();
1131 
1132 			bitcount = bitcount+4;
1133 			opcode <<= 4;
1134 			cmdindex = (opcode>>12) & 0x000f;
1135 			LOGMASKED(LOG_EMU, "next index=%x\n", cmdindex);
1136 		}
1137 
1138 		LOGMASKED(LOG_EMU, "bitcount=%d\n", bitcount);
1139 		// We are at the target level
1140 		// Need to fill in the same entry for all values in the bitcount
1141 		// (if a command needs 10 bits we have to copy it four
1142 		// times for all combinations with 12 bits)
1143 		for (int j=0; j < (1<<(bitcount-format_mask_len[inst->format])); j++)
1144 		{
1145 			LOGMASKED(LOG_EMU, "opcode=%04x at position %d\n", inst->opcode, cmdindex+j);
1146 			table[cmdindex+j].index = i;
1147 		}
1148 		i++;
1149 	} while (inst->opcode != 0xf000);
1150 
1151 	m_interrupt_mp_index = i;
1152 }
1153 
1154 /*
1155     Main execution loop
1156 
1157     For each invocation of execute_run, a number of loop iterations has been
1158     calculated before (m_icount). Each loop iteration is one clock cycle.
1159     The loop must be executed for the number of times that corresponds to the
1160     time until the next timer event.
1161 
1162     In this implementation, each loop iteration also causes the clock line to
1163     pulse once. External devices may use this pulse to decrement counters
1164     which control the READY line.
1165 
1166     Machine cycles to clock input:
1167 
1168       +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+
1169       | | | | | | | | | | | | | | | | | |  clock (1 of 4 phases)
1170     +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +
1171     |-------|-------|-------|-------|----  cycles (2 clock pulses each)
1172 
1173     Wait states only have effect for memory operations. They are processed as
1174     follows:
1175 
1176     1) The CPU sets the address bus for reading. If READY is low, the CPU
1177     waits for the next clock tick repeatedly until READY is high again.
1178     When this is the case, the data bus is sampled on the next clock tick
1179     and the read operation is complete.
1180 
1181     As we do not have a split-phase read operation in this emulation
1182     we actually read the data bus instantly but wait for the READY line to
1183     be high again.
1184 
1185     2) The CPU sets the address bus for writing. In the same moment, the data
1186     bus is loaded with the word to be written. On the next clock tick,
1187     the CPU checks the READY line and waits until it is high. When READY
1188     is high at a clock tick, the operation is complete on the next clock tick.
1189 */
execute_run()1190 void tms99xx_device::execute_run()
1191 {
1192 	if (m_reset) service_interrupt();
1193 
1194 	LOGMASKED(LOG_EMU, "calling execute_run for %d cycles\n", m_icount);
1195 	do
1196 	{
1197 		// Only when last instruction has completed
1198 		if (m_program_index == NOPRG)
1199 		{
1200 			if (m_load_state)
1201 			{
1202 				m_irq_level = LOAD_INT;
1203 				m_irq_state = false;
1204 				service_interrupt();
1205 			}
1206 			else
1207 			{
1208 				// Interrupts are serviced when
1209 				// - an interrupt condition is signaled over INTREQ and
1210 				// - the level indicated by IC0-IC3 is lower than the interrupt mask value and
1211 				// - the previous instruction is not an XOP or BLWP
1212 				if (m_irq_state && (m_irq_level <= (ST & 0x000f)) && (m_command != XOP && m_command != BLWP))
1213 					service_interrupt();
1214 			}
1215 		}
1216 
1217 		if (m_program_index == NOPRG && m_idle_state)
1218 		{
1219 			LOGMASKED(LOG_IDLE, "IDLE state\n");
1220 			pulse_clock(1);
1221 			if (!m_external_operation.isnull())
1222 			{
1223 				m_external_operation(IDLE_OP, 0, 0xff);
1224 				m_external_operation(IDLE_OP, 1, 0xff);
1225 			}
1226 		}
1227 		else
1228 		{
1229 			const uint8_t* program = nullptr;
1230 			// When we are in the data derivation sequence, the caller_index is set
1231 			if (m_program_index != NOPRG)
1232 				program = (m_caller_index == NOPRG)? (uint8_t*)s_command[m_program_index].prog : data_derivation;
1233 
1234 			// Handle HOLD
1235 			// A HOLD request is signalled through the input line HOLD.
1236 			// The hold state will be entered with the next non-memory access cycle.
1237 			if (m_hold_state &&
1238 				(m_program_index == NOPRG ||
1239 				(program[MPC] != IAQ &&
1240 				program[MPC] != MEMORY_READ && program[MPC] != MEMORY_WRITE &&
1241 				program[MPC] != REG_READ && program[MPC] != REG_WRITE)))
1242 			{
1243 				LOGMASKED(LOG_HOLD, "HOLD state\n");
1244 				if (!m_hold_acknowledged) acknowledge_hold();
1245 				pulse_clock(1);
1246 			}
1247 			else
1248 			{
1249 				// Normal operation
1250 				if (m_check_ready && m_ready == false)
1251 				{
1252 					// We are in a wait state
1253 					set_wait_state(true);
1254 					LOGMASKED(LOG_WAIT, "wait state\n");
1255 					// The clock output should be used to change the state of an outer
1256 					// device which operates the READY line
1257 					pulse_clock(1);
1258 				}
1259 				else
1260 				{
1261 					set_wait_state(false);
1262 					m_check_ready = false;
1263 					// If we don't have a microprogram, acquire the next instruction
1264 					uint8_t op = (m_program_index==NOPRG)? IAQ : program[MPC];
1265 
1266 					LOGMASKED(LOG_MICRO, "MPC = %d, op = %d\n", MPC, op);
1267 					// Call the operation of the microprogram
1268 					(this->*s_microoperation[op])();
1269 					// If we have multiple passes (as in the TMS9980)
1270 					m_pass--;
1271 					if (m_pass<=0)
1272 					{
1273 						m_pass = 1;
1274 						MPC++;
1275 						m_mem_phase = 1;
1276 						m_iaq = false;
1277 					}
1278 				}
1279 			}
1280 		}
1281 	} while (m_icount>0 && !m_reset);
1282 	LOGMASKED(LOG_EMU, "cycles expired; will return soon.\n");
1283 }
1284 
1285 /**************************************************************************/
1286 
1287 /*
1288     Interrupt input
1289 */
execute_set_input(int irqline,int state)1290 void tms99xx_device::execute_set_input(int irqline, int state)
1291 {
1292 	if (irqline==INT_9900_RESET && state==ASSERT_LINE)
1293 	{
1294 		m_reset = true;
1295 	}
1296 	else
1297 	{
1298 		if (irqline == INT_9900_LOAD)
1299 		{
1300 			m_load_state = (state==ASSERT_LINE);
1301 			m_irq_level = LOAD_INT;
1302 			m_reset = false;
1303 		}
1304 		else
1305 		{
1306 			m_irq_state = (state==ASSERT_LINE);
1307 			if (state==ASSERT_LINE)
1308 			{
1309 				m_irq_level = get_intlevel(state);
1310 				LOGMASKED(LOG_INT, "/INT asserted, level=%d, ST=%04x\n", m_irq_level, ST);
1311 			}
1312 			else
1313 			{
1314 				LOGMASKED(LOG_INT, "/INT cleared\n");
1315 			}
1316 		}
1317 	}
1318 }
1319 
1320 /*
1321     This can be overloaded by variants of TMS99xx.
1322 */
get_intlevel(int state)1323 int tms99xx_device::get_intlevel(int state)
1324 {
1325 	if (!m_get_intlevel.isnull()) return m_get_intlevel(0);
1326 	return 0;
1327 }
1328 
service_interrupt()1329 void tms99xx_device::service_interrupt()
1330 {
1331 	m_program_index = m_interrupt_mp_index;
1332 
1333 	m_command = INTR;
1334 	m_idle_state = false;
1335 	if (!m_external_operation.isnull()) m_external_operation(IDLE_OP, 0, 0xff);
1336 
1337 	m_state = 0;
1338 
1339 	// If reset, we just start with execution, otherwise we put the MPC
1340 	// on the first microinstruction, which also means that the main loop shall
1341 	// leave it where it is. So we pretend we have another pass to do.
1342 	m_pass = m_reset? 1 : 2;
1343 
1344 	// just for debugging purposes
1345 	if (!m_reset) m_log_interrupt = true;
1346 
1347 	if (m_reset)
1348 	{
1349 		m_irq_level = RESET_INT;
1350 
1351 		m_ready_bufd = true;
1352 		m_ready = true;
1353 		m_load_state = false;
1354 		m_hold_state = false;
1355 		m_hold_acknowledged = false;
1356 		m_wait_state = false;
1357 		IR = 0;
1358 		ST = 0;
1359 		m_mem_phase = 1;
1360 
1361 		m_reset = false;
1362 		LOG("** RESET triggered\n");
1363 	}
1364 	else
1365 	{
1366 		if (m_irq_level==LOAD_INT)
1367 			LOGMASKED(LOG_LOAD, "** LOAD interrupt triggered\n");
1368 		else
1369 			LOGMASKED(LOG_INTD, "** Interrupt on level %d\n", m_irq_level);
1370 	}
1371 
1372 	MPC = 0;
1373 	m_first_cycle = m_icount;
1374 }
1375 
1376 /*
1377     Issue a pulse on the clock line.
1378 */
pulse_clock(int count)1379 void tms99xx_device::pulse_clock(int count)
1380 {
1381 	for (int i=0; i < count; i++)
1382 	{
1383 		if (!m_clock_out_line.isnull()) m_clock_out_line(ASSERT_LINE);
1384 		m_ready = m_ready_bufd;              // get the latched READY state
1385 		if (!m_clock_out_line.isnull()) m_clock_out_line(CLEAR_LINE);
1386 		m_icount--;                         // This is the only location where we count down the cycles.
1387 		if (m_check_ready) LOGMASKED(LOG_CLOCK, "pulse_clock, READY=%d\n", m_ready? 1:0);
1388 		else LOGMASKED(LOG_CLOCK, "pulse_clock\n");
1389 	}
1390 }
1391 
1392 /*
1393     Enter the hold state.
1394 */
set_hold(int state)1395 void tms99xx_device::set_hold(int state)
1396 {
1397 	m_hold_state = (state==ASSERT_LINE);
1398 	if (!m_hold_state)
1399 	{
1400 		m_hold_acknowledged = false;
1401 		if (!m_holda_line.isnull()) m_holda_line(CLEAR_LINE);
1402 	}
1403 }
1404 
1405 /*
1406     Acknowledge the HOLD request.
1407 */
acknowledge_hold()1408 inline void tms99xx_device::acknowledge_hold()
1409 {
1410 	m_hold_acknowledged = true;
1411 	if (!m_holda_line.isnull()) m_holda_line(ASSERT_LINE);
1412 }
1413 
1414 /*
1415     Signal READY to the CPU. When cleared, the CPU enters wait states. This
1416     becomes effective on a clock pulse.
1417 */
set_ready(int state)1418 void tms99xx_device::set_ready(int state)
1419 {
1420 	bool newready = (state==ASSERT_LINE);
1421 
1422 	if (newready != m_ready_bufd)
1423 	{
1424 		if (m_reset)
1425 		{
1426 			LOGMASKED(LOG_WARN, "Ignoring READY=%d change due to pending RESET\n", state);
1427 		}
1428 		else
1429 		{
1430 			m_ready_bufd = newready;
1431 			LOGMASKED(LOG_READY, "set READY = %d\n", m_ready_bufd? 1 : 0);
1432 		}
1433 	}
1434 }
1435 
abort_operation()1436 void tms99xx_device::abort_operation()
1437 {
1438 	command_completed();
1439 }
1440 
1441 /*
1442     Enter or leave the wait state. We only operate the WAIT line when there is a change.
1443 */
set_wait_state(bool state)1444 inline void tms99xx_device::set_wait_state(bool state)
1445 {
1446 	if (m_wait_state != state)
1447 		if (!m_wait_line.isnull()) m_wait_line(state? ASSERT_LINE : CLEAR_LINE);
1448 	m_wait_state = state;
1449 }
1450 
1451 /*
1452     Acquire the next word as an instruction. The program counter advances by
1453     one word.
1454 */
decode(uint16_t inst)1455 void tms99xx_device::decode(uint16_t inst)
1456 {
1457 	int ix = 0;
1458 	lookup_entry* table = m_command_lookup_table.get();
1459 	uint16_t opcode = inst;
1460 	bool complete = false;
1461 
1462 	m_state = 0;
1463 	IR = inst;
1464 	m_get_destination = false;
1465 	m_byteop = false;
1466 
1467 	while (!complete)
1468 	{
1469 		ix = (opcode >> 12) & 0x000f;
1470 		LOGMASKED(LOG_MICRO, "Check next hex digit of instruction %x\n", ix);
1471 		if (table[ix].next_digit != nullptr)
1472 		{
1473 			table = table[ix].next_digit.get();
1474 			opcode = opcode << 4;
1475 		}
1476 		else complete = true;
1477 	}
1478 	m_program_index = table[ix].index;
1479 	if (m_program_index == NOPRG)
1480 	{
1481 		// not found
1482 		LOGMASKED(LOG_WARN, "** %04x: Illegal opcode %04x\n", PC, inst);
1483 		IR = 0;
1484 		// This will cause another instruction acquisition in the next machine cycle
1485 		// with an asserted IAQ line (can be used to indicate this illegal opcode detection).
1486 	}
1487 	else
1488 	{
1489 		const tms_instruction decoded = s_command[m_program_index];
1490 		MPC = -1;
1491 		m_command = decoded.id;
1492 		LOGMASKED(LOG_OP, "=== %04x: Op=%04x (%s)\n", PC, IR, opname[m_command]);
1493 
1494 		// Byte operations are either format 1 with the byte flag set
1495 		// or format 4 (CRU multi bit operations) with 1-8 bits to transfer.
1496 		// Used by the data derivation sequence.
1497 		m_byteop = ((decoded.format==1 && ((IR & 0x1000)!=0))
1498 				|| (decoded.format==4 && (((IR >> 6)&0x000f) > 0) && (((IR >> 6)&0x000f) < 9)));
1499 	}
1500 	m_pass = 1;
1501 }
1502 
byte_operation()1503 inline bool tms99xx_device::byte_operation()
1504 {
1505 	return (IR & 0x1000)!=0;
1506 }
1507 
acquire_instruction()1508 void tms99xx_device::acquire_instruction()
1509 {
1510 	if (m_mem_phase == 1)
1511 	{
1512 		m_iaq = true;
1513 		m_address = PC;
1514 		m_first_cycle = m_icount;
1515 	}
1516 
1517 	mem_read();
1518 
1519 	if (m_mem_phase == 1)
1520 	{
1521 		decode(m_current_value);
1522 
1523 		// Mark logged address as interrupt service
1524 		if (m_log_interrupt)
1525 			LOGMASKED(LOG_EXEC, "i%04x\n", PC);
1526 		else
1527 			LOGMASKED(LOG_EXEC, "%04x\n", PC);
1528 
1529 		debugger_instruction_hook(PC);
1530 		PC = (PC + 2) & m_prgaddr_mask;
1531 		// IAQ will be cleared in the main loop
1532 	}
1533 }
1534 
1535 /*
1536     Memory read
1537     Clock cycles: 2 + W, W = number of wait states
1538 */
mem_read()1539 void tms99xx_device::mem_read()
1540 {
1541 	// After set_address, any device attached to the address bus may pull down
1542 	// READY in order to put the CPU into wait state before the read_word
1543 	// operation will be performed
1544 	// set_address and read_word should pass the same address as argument
1545 	if (m_mem_phase==1)
1546 	{
1547 		LOGMASKED(LOG_ADDRESSBUS, "set address (r) %04x\n", m_address);
1548 		if (m_setaddr)
1549 			m_setaddr->write_word(m_address & m_prgaddr_mask, (TMS99xx_BUS_DBIN | (m_iaq? TMS99xx_BUS_IAQ : 0)));
1550 		m_check_ready = true;
1551 		m_mem_phase = 2;
1552 		m_pass = 2;
1553 		pulse_clock(1); // Concludes the first cycle
1554 		// If READY has been found to be low, the CPU will now stay in the wait state loop
1555 	}
1556 	else
1557 	{
1558 		// Second phase (after READY was raised again)
1559 		m_current_value = m_prgspace->read_word(m_address & m_prgaddr_mask);
1560 		pulse_clock(1);
1561 		m_mem_phase = 1;        // reset to phase 1
1562 		LOGMASKED(LOG_MEM, "mem r %04x -> %04x\n", m_address, m_current_value);
1563 	}
1564 }
1565 
mem_write()1566 void tms99xx_device::mem_write()
1567 {
1568 	if (m_mem_phase==1)
1569 	{
1570 		LOGMASKED(LOG_ADDRESSBUS, "set address (w) %04x\n", m_address);
1571 		// When writing, the data bus is asserted immediately after the address bus
1572 		if (m_setaddr)
1573 			m_setaddr->write_word(m_address & m_prgaddr_mask, TMS99xx_BUS_WRITE);
1574 		LOGMASKED(LOG_MEM, "mem w %04x <- %04x\n",  m_address, m_current_value);
1575 		m_prgspace->write_word(m_address & m_prgaddr_mask, m_current_value);
1576 		m_check_ready = true;
1577 		m_mem_phase = 2;
1578 		m_pass = 2;
1579 		pulse_clock(1);
1580 	}
1581 	else
1582 	{
1583 		// Second phase (we arrive here when the wait states are over)
1584 		pulse_clock(1);
1585 	}
1586 }
1587 
register_read()1588 void tms99xx_device::register_read()
1589 {
1590 	// Need to set m_address for F1/F3 (we don't know what the data_derive did)
1591 	if (m_mem_phase==1)
1592 	{
1593 		m_address = WP + (m_regnumber<<1);
1594 	}
1595 
1596 	mem_read();
1597 
1598 	if (m_mem_phase==1)
1599 	{
1600 		m_register_contents = m_current_value;
1601 	}
1602 }
1603 
1604 /*
1605     Memory write:
1606 
1607     Clock cycles: 2 + W, W = number of wait states
1608 */
register_write()1609 void tms99xx_device::register_write()
1610 {
1611 	// This will be called twice; m_pass is set by the embedded mem_write
1612 	uint16_t addr_save = m_address;
1613 	m_address = (WP + (m_regnumber<<1)) & m_prgaddr_mask;
1614 	mem_write();
1615 	m_address = addr_save;
1616 }
1617 
1618 /*
1619     CRU support code
1620 
1621     The CRU bus is a 1-bit-wide I/O bus.  The CPU can read or write bits at random address.
1622     Special instructions are dedicated to reading and writing one or several consecutive bits.
1623 
1624     The CRU uses the same address bus as the normal memory access. For writing,
1625     the CRUCLK line is pulsed, but not for reading where CRUCLK stays cleared.
1626     This means that each normal memory access also causes read accesses on the
1627     CRU side. The /MEMEN line may be used to distinguish the kinds of accesses
1628     as it stays cleared during CRU operations.
1629 
1630     We do not emulate this here as it seems there are no real applications of
1631     this side effect. Real designs must ensure that CRU read operations are
1632     idempotent (i.e. they must not change the state of the queried device).
1633 
1634     Read returns the number of consecutive CRU bits, with increasing CRU address
1635     from the least significant to the most significant bit; right-aligned (in
1636     other words, little-endian as opposed to the big-endian order of memory words).
1637 
1638     There seems to be no handling of wait states during CRU operations on the
1639     TMS9900. The TMS9995, in contrast, respects wait states during the transmission
1640     of each single bit.
1641 
1642     The current emulation of the CRU space involves a 1-bit address shift,
1643     reflecting the one-to-one correspondence between CRU bits and words (not
1644     bytes) in the lower part of the memory space. (On the TMS9980A and TMS9995,
1645     CRUOUT is multiplexed with the least significant address line.) Thus, what
1646     TI's documentation calls the software address (the R12 base value plus the
1647     bit offset multiplied by 2) is used in address maps and CPU-side operations.
1648     MAME's memory architecture automatically translates these to right-justified
1649     hardware addresses in the process of decoding offsets for read/write handlers,
1650     which is more typical of what peripheral devices expect. (Note also that
1651     address spaces do not support data widths narrower than 8 bits, so these
1652     handlers must specify 8-bit types despite only one bit being useful.)
1653 
1654     Usage of this method:
1655        CRU write: First bit is at rightmost position of m_value.
1656 */
1657 
cru_input_operation()1658 void tms99xx_device::cru_input_operation()
1659 {
1660 	offs_t cruaddr = m_cru_address & m_cruaddr_mask;
1661 	uint16_t value = 0;
1662 
1663 	for (int i = 0; i < m_count; i++)
1664 	{
1665 		// Poll one bit at a time
1666 		bool cruin = BIT(m_cru->read_byte(cruaddr), 0);
1667 		if (cruin)
1668 			value |= 1 << i;
1669 
1670 		LOGMASKED(LOG_CRU, "CRU input operation, address %04x, value %d\n", cruaddr, cruin ? 1 : 0);
1671 
1672 		// Increment the CRU address
1673 		cruaddr = (cruaddr + 2) & m_cruaddr_mask;
1674 
1675 		// On each machine cycle (2 clocks) only one CRU bit is transmitted
1676 		pulse_clock(2);
1677 	}
1678 
1679 	m_value = value;
1680 }
1681 
cru_output_operation()1682 void tms99xx_device::cru_output_operation()
1683 {
1684 	offs_t cruaddr = m_cru_address & m_cruaddr_mask;
1685 	uint16_t value = m_value;
1686 
1687 	// Write m_count bits from cru_address
1688 	for (int i = 0; i < m_count; i++)
1689 	{
1690 		LOGMASKED(LOG_CRU, "CRU output operation, address %04x, value %d\n", cruaddr, BIT(value, 0));
1691 
1692 		// Write one bit at a time
1693 		m_cru->write_byte(cruaddr, BIT(value, 0));
1694 		value >>= 1;
1695 
1696 		// Increment the CRU address
1697 		cruaddr = (cruaddr + 2) & m_cruaddr_mask;
1698 
1699 		pulse_clock(2);
1700 	}
1701 }
1702 
return_from_subprogram()1703 void tms99xx_device::return_from_subprogram()
1704 {
1705 	// Return from data derivation
1706 	// The result should be in m_current_value
1707 	// and the address in m_address
1708 	m_program_index = m_caller_index;
1709 	m_caller_index = NOPRG;
1710 	MPC = m_caller_MPC; // will be increased on return
1711 }
1712 
command_completed()1713 void tms99xx_device::command_completed()
1714 {
1715 	// Pseudo state at the end of the current instruction cycle sequence
1716 	if (LOG_CYCLES & VERBOSE)
1717 	{
1718 		logerror("+++ Instruction %04x (%s) completed", IR, opname[m_command]);
1719 		int cycles =  m_first_cycle - m_icount;
1720 		// Avoid nonsense values due to expired and resumed main loop
1721 		if (cycles > 0 && cycles < 10000) logerror(", %d cycles", cycles);
1722 		logerror("+++\n");
1723 	}
1724 	m_program_index = NOPRG;
1725 }
1726 
1727 /*
1728     This is a switch to a subprogram; there is only one, the data
1729     derivation. In terms of cycles, it does not take any time; execution
1730     continues with the first instruction of the subprogram.
1731 */
data_derivation_subprogram()1732 void tms99xx_device::data_derivation_subprogram()
1733 {
1734 	uint16_t ircopy = IR;
1735 
1736 	// Save the return program and position
1737 	m_caller_index = m_program_index;
1738 	m_caller_MPC = MPC;
1739 
1740 	// Source or destination argument?
1741 	if (m_get_destination) ircopy >>= 6;
1742 
1743 	m_regnumber = ircopy & 0x000f;
1744 
1745 	MPC = ircopy & 0x0030;
1746 
1747 	if (((MPC == 0x0020) && (m_regnumber != 0))         // indexed
1748 		|| ((MPC == 0x0030) && m_byteop))       // byte operation
1749 	{
1750 		MPC += 8;   // the second option
1751 	}
1752 	m_get_destination = true;   // when we call this the second time before END it's the destination
1753 	m_pass = 2;
1754 }
1755 
1756 
1757 /**************************************************************************
1758     Status bit operations
1759 **************************************************************************/
1760 
set_status_bit(int bit,bool state)1761 inline void tms99xx_device::set_status_bit(int bit, bool state)
1762 {
1763 	if (state) ST |= bit;
1764 	else ST &= ~bit;
1765 }
1766 
set_status_parity(uint8_t value)1767 void tms99xx_device::set_status_parity(uint8_t value)
1768 {
1769 	int count = 0;
1770 	for (int i=0; i < 8; i++)
1771 	{
1772 		if ((value & 0x80)!=0) count++;
1773 		value <<= 1;
1774 	}
1775 	set_status_bit(ST_OP, (count & 1)!=0);
1776 }
1777 
compare_and_set_lae(uint16_t value1,uint16_t value2)1778 inline void tms99xx_device::compare_and_set_lae(uint16_t value1, uint16_t value2)
1779 {
1780 	set_status_bit(ST_EQ, value1 == value2);
1781 	set_status_bit(ST_LH, value1 > value2);
1782 	set_status_bit(ST_AGT, (int16_t)value1 > (int16_t)value2);
1783 	LOGMASKED(LOG_STATUS, "ST = %04x (val1=%04x, val2=%04x)\n", ST, value1, value2);
1784 }
1785 
1786 /**************************************************************************
1787     ALU operations
1788 **************************************************************************/
1789 
alu_nop()1790 void tms99xx_device::alu_nop()
1791 {
1792 	// Do nothing (or nothing that is externally visible)
1793 	pulse_clock(2);
1794 	return;
1795 }
1796 
alu_source()1797 void tms99xx_device::alu_source()
1798 {
1799 	// Copy the current value into the source data register
1800 	m_source_even = ((m_address & 1)==0);
1801 	m_source_value = m_current_value;
1802 	m_source_address = m_address;
1803 	pulse_clock(2);
1804 }
1805 
alu_clear()1806 void tms99xx_device::alu_clear()
1807 {
1808 	// Clears the register contents
1809 	m_register_contents = 0;
1810 	pulse_clock(2);
1811 }
1812 
alu_setaddr()1813 void tms99xx_device::alu_setaddr()
1814 {
1815 	// Load the current value into the address register
1816 	m_address = m_current_value;
1817 	pulse_clock(2);
1818 }
1819 
alu_addone()1820 void tms99xx_device::alu_addone()
1821 {
1822 	m_current_value++;
1823 	pulse_clock(2);
1824 }
1825 
alu_setaddr_addone()1826 void tms99xx_device::alu_setaddr_addone()
1827 {
1828 	// Set the address register and increase the recent value
1829 	m_address = m_current_value;
1830 	m_current_value++;
1831 	pulse_clock(2);
1832 }
1833 
alu_pcaddr_advance()1834 void tms99xx_device::alu_pcaddr_advance()
1835 {
1836 	// Set PC as new read address, increase by 2
1837 	m_address = PC;
1838 	PC = (PC + 2) & m_prgaddr_mask;
1839 	pulse_clock(2);
1840 }
1841 
alu_add_register()1842 void tms99xx_device::alu_add_register()
1843 {
1844 	// Add the register contents to the current value and set as address
1845 	m_address = m_current_value + m_register_contents;
1846 	pulse_clock(2);
1847 }
1848 
alu_imm()1849 void tms99xx_device::alu_imm()
1850 {
1851 	m_value_copy = m_current_value;
1852 	m_address_copy = m_address;
1853 	m_address = PC;
1854 	PC = (PC + 2) & m_prgaddr_mask;
1855 	pulse_clock(2);
1856 }
1857 
alu_reg()1858 void tms99xx_device::alu_reg()
1859 {
1860 	m_address = (WP + ((IR & 0x000f)<<1)) & m_prgaddr_mask;
1861 	pulse_clock(2);
1862 }
1863 
alu_f1()1864 void tms99xx_device::alu_f1()
1865 {
1866 	uint32_t dest_new = 0;
1867 
1868 	// Save the destination value
1869 	uint16_t prev_dest_value = m_current_value;
1870 
1871 	m_destination_even = ((m_address & 1)==0);  // this is the destination address; the source address has already been saved
1872 	bool byteop = byte_operation();
1873 
1874 	if (byteop)
1875 	{
1876 		if (!m_destination_even) m_current_value <<= 8;
1877 		if (!m_source_even) m_source_value <<= 8;
1878 		// We have to strip away the low byte, or byte operations may fail
1879 		// e.g. 0x10ff + 0x0101 = 0x1200
1880 		// or   0x2000 - 0x0101 = 0x1eff
1881 		m_source_value &= 0xff00;
1882 		m_current_value &= 0xff00;
1883 	}
1884 
1885 	switch (m_command)
1886 	{
1887 		case A:
1888 		case AB:
1889 			// Add the contents of the source data to the destination data
1890 			// May exceed 0xffff (for carry check)
1891 			dest_new = m_current_value + m_source_value;
1892 
1893 			// 1000 + e000 = f000 (L)
1894 			// c000 + c000 = 8000 (LC)
1895 			// 7000 + 4000 = b000 (LO)
1896 			// 2000 + f000 = 1000 (LAC)
1897 			// c000 + b000 = 7000 (LACO)
1898 			// 2000 + e000 = 0000 (EC)
1899 			// 8000 + 8000 = 0000 (ECO)
1900 
1901 			// When adding, a carry occurs when we exceed the 0xffff value.
1902 			set_status_bit(ST_C, (dest_new & 0x10000) != 0);
1903 			// If the result has a sign bit that is different from both arguments, we have an overflow
1904 			// (i.e. getting a negative value from two positive values and vice versa)
1905 			set_status_bit(ST_OV, ((dest_new ^ m_current_value) & (dest_new ^ m_source_value) & 0x8000)!=0);
1906 			break;
1907 
1908 		case S:
1909 		case SB:
1910 			// Subtract the contents of the source data from the destination data
1911 			dest_new = m_current_value + ((~m_source_value) & 0xffff) + 1;
1912 			// LAECO(P)
1913 			// 8000 - 8000 = 0000 (EC)
1914 			// 2000 - 8000 = a000 (LO)
1915 			// 8000 - 2000 = 6000 (LACO)
1916 			// 2000 - 1000 = 1000 (LAC)
1917 			// 1000 - 2000 = f000 (L)
1918 			// 1000 - 1000 = 0000 (EC)
1919 			// 1000 - f000 = 2000 (LA)
1920 			// f000 - 2000 = d000 (LC)
1921 
1922 			// Subtraction means adding the 2s complement, so the carry bit
1923 			// is set whenever adding the 2s complement exceeds ffff
1924 			// In fact the CPU adds the one's complement, then adds a one. This
1925 			// explains why subtracting 0 sets the carry bit.
1926 			set_status_bit(ST_C, (dest_new & 0x10000) != 0);
1927 
1928 			// If the arguments have different sign bits and the result has a
1929 			// sign bit different from the destination value, we have an overflow
1930 			// e.g. value1 = 0x7fff, value2 = 0xffff; value1-value2 = 0x8000
1931 			// or   value1 = 0x8000, value2 = 0x0001; value1-value2 = 0x7fff
1932 			// value1 is the destination value
1933 			set_status_bit(ST_OV, (m_current_value ^ m_source_value) & (m_current_value ^ dest_new) & 0x8000);
1934 			break;
1935 
1936 		case SOC:
1937 		case SOCB:
1938 			// OR the contents of the source data on the destination data
1939 			dest_new = m_current_value | m_source_value;
1940 			break;
1941 
1942 		case SZC:
1943 		case SZCB:
1944 			// AND the one's complement of the contents of the source data on the destination data
1945 			dest_new = m_current_value & ~m_source_value;
1946 			break;
1947 
1948 		case MOV:
1949 		case MOVB:
1950 			// Copy the source data to the destination data
1951 			dest_new = m_source_value;
1952 			break;
1953 	}
1954 
1955 	if (byteop)
1956 	{
1957 		set_status_parity((uint8_t)(dest_new>>8));
1958 
1959 		// destnew is the new value to be written (high byte); needs to be
1960 		// merged with the existing word
1961 		if (m_destination_even)
1962 			m_current_value = (prev_dest_value & 0x00ff) | (dest_new & 0xff00);
1963 		else
1964 			m_current_value = (prev_dest_value & 0xff00) | ((dest_new >> 8) & 0x00ff);
1965 		compare_and_set_lae((uint16_t)(dest_new & 0xff00), 0);
1966 	}
1967 	else
1968 	{
1969 		m_current_value = (uint16_t)(dest_new & 0xffff);
1970 		compare_and_set_lae((uint16_t)(dest_new & 0xffff), 0);
1971 	}
1972 
1973 	pulse_clock(2);
1974 }
1975 
alu_comp()1976 void tms99xx_device::alu_comp()
1977 {
1978 	m_destination_even = ((m_address & 1)==0);  // this is the destination address; the source address has already been saved
1979 	if (byte_operation())
1980 	{
1981 		if (!m_destination_even) m_current_value <<= 8;
1982 		if (!m_source_even) m_source_value <<= 8;
1983 		set_status_parity((uint8_t)(m_source_value>>8));
1984 		compare_and_set_lae(m_source_value & 0xff00, m_current_value & 0xff00);
1985 	}
1986 	else
1987 		compare_and_set_lae(m_source_value, m_current_value);
1988 
1989 	pulse_clock(2);
1990 }
1991 
alu_f3()1992 void tms99xx_device::alu_f3()
1993 {
1994 	switch (m_state)
1995 	{
1996 	case 0:
1997 		// Get register address
1998 		m_address = WP + ((IR >> 5) & 0x001e);
1999 		m_source_value = m_current_value;
2000 		break;
2001 	case 1:
2002 		if (m_command == COC)
2003 		{
2004 			set_status_bit(ST_EQ, (m_current_value & m_source_value) == m_source_value);
2005 		}
2006 		else
2007 		{
2008 			if (m_command == CZC)
2009 			{
2010 				set_status_bit(ST_EQ, (~m_current_value & m_source_value) == m_source_value);
2011 			}
2012 			else
2013 			{
2014 				// XOR
2015 				// The workspace register address is still in m_address
2016 				m_current_value = (m_current_value ^ m_source_value);
2017 				compare_and_set_lae(m_current_value, 0);
2018 			}
2019 		}
2020 		LOGMASKED(LOG_STATUS, "ST = %04x\n", ST);
2021 		break;
2022 	}
2023 
2024 	m_state++;
2025 	pulse_clock(2);
2026 }
2027 
alu_multiply()2028 void tms99xx_device::alu_multiply()
2029 {
2030 	uint32_t result;
2031 
2032 	switch (m_state)
2033 	{
2034 	case 0: // After data derivation
2035 		m_source_value = m_current_value;
2036 		m_address = ((IR >> 5) & 0x001e) + WP;
2037 		break;
2038 	case 1: // After reading the register (multiplier)
2039 		result = (m_source_value & 0x0000ffff) * (m_current_value & 0x0000ffff);
2040 		m_current_value = (result >> 16) & 0xffff;
2041 		m_value_copy = result & 0xffff;
2042 		pulse_clock(34);                                // add 36 clock cycles (18 machine cycles); last one in main loop
2043 		break;
2044 	case 2: // After writing the high word to the destination register
2045 		m_current_value = m_value_copy;                     // Prepare to save low word
2046 		m_address = (m_address + 2) & m_prgaddr_mask;
2047 		break;
2048 	}
2049 	pulse_clock(2);
2050 	m_state++;
2051 }
2052 
alu_divide()2053 void tms99xx_device::alu_divide()
2054 {
2055 	// Format is DIV Divisor,REG(dividend)
2056 	uint32_t uval32;
2057 	bool overflow = true;
2058 	uint16_t value1;
2059 
2060 	switch (m_state)
2061 	{
2062 	case 0:
2063 		m_source_value = m_current_value;   // store divisor
2064 		// Set address of register
2065 		m_address = WP + ((IR >> 5) & 0x001e);
2066 		m_address_copy = m_address;
2067 		break;
2068 	case 1:
2069 		// We have an overflow when the quotient cannot be stored in 16 bits
2070 		// This is the case when the dividend / divisor >= 0x10000,
2071 		// or equivalently, dividend / 0x10000 >= divisor
2072 
2073 		if (m_current_value < m_source_value)   // also if source=0
2074 		{
2075 			MPC++;  // skip the abort
2076 			overflow = false;
2077 		}
2078 		set_status_bit(ST_OV, overflow);
2079 		m_value_copy = m_current_value;         // Save the high word
2080 		m_address = (m_address + 2) & m_prgaddr_mask;       // Read next word
2081 		break;
2082 	case 2:
2083 		// W2 is in m_current_value
2084 		// Create full word and perform division
2085 		uval32 = (m_value_copy << 16) | m_current_value;
2086 
2087 		m_current_value = uval32 / m_source_value;
2088 		m_value_copy = uval32 % m_source_value;
2089 		m_address = m_address_copy;
2090 
2091 		// The number of ALU cycles depends on the number of steps in
2092 		// the division algorithm. The number of cycles is between 32 and
2093 		// 48 (*2 for clock cycles)
2094 		// As I don't have a description of the actual algorithm, I'll use
2095 		// the following heuristic: We use 32 ALU cycles in general, then
2096 		// we need as many cycles as it takes to
2097 		// shift away the dividend. Thus, bigger dividends need more cycles.
2098 
2099 		pulse_clock(62);    // one pulse is at the start, one at the end
2100 		value1 = m_value_copy & 0xffff;
2101 
2102 		while (value1 != 0)
2103 		{
2104 			value1 = (value1 >> 1) & 0xffff;
2105 			pulse_clock(2);
2106 		}
2107 		// We still have m_regnumber; this is where m_current_value will go to
2108 		break;
2109 	case 3:
2110 		// Prepare to write the remainder
2111 		m_current_value = m_value_copy;
2112 		m_address = m_address + 2;
2113 		LOGMASKED(LOG_STATUS, "ST = %04x (div)\n", ST);
2114 		break;
2115 	}
2116 	pulse_clock(2);
2117 	m_state++;
2118 }
2119 
alu_xop()2120 void tms99xx_device::alu_xop()
2121 {
2122 	switch (m_state)
2123 	{
2124 	case 0:
2125 		// We have the effective address of the source operand in m_address
2126 		m_address_saved = m_address;
2127 		// Now we take the XOP number from the instruction register
2128 		// and calculate the vector location
2129 		// [0010 11xx xx tt SSSS]  shift 6 right, then *4 => shift 4 right
2130 		m_address = 0x0040 + ((IR >> 4) & 0x003c);
2131 		// Takes some additional cycles
2132 		pulse_clock(4);
2133 		break;
2134 	case 1:
2135 		m_value_copy = WP;                      // save the old WP
2136 		WP = m_current_value & m_prgaddr_mask;  // the new WP has been read in the previous microoperation
2137 		m_current_value = m_address_saved;      // we saved the address of the source operand; retrieve it
2138 		m_address = WP + 0x0016;                // Next register is R11
2139 		break;
2140 	case 2:
2141 		m_address = WP + 0x001e;
2142 		m_current_value = ST;
2143 		break;
2144 	case 3:
2145 		m_address = WP + 0x001c;
2146 		m_current_value = PC;
2147 		break;
2148 	case 4:
2149 		m_address = WP + 0x001a;
2150 		m_current_value = m_value_copy;         // old WP into new R13
2151 		break;
2152 	case 5:
2153 		m_address =  0x0042 + ((IR >> 4) & 0x003c);     // location of new PC
2154 		set_status_bit(ST_X, true);
2155 		break;
2156 	case 6:
2157 		PC = m_current_value & m_prgaddr_mask;
2158 		break;
2159 	}
2160 	pulse_clock(2);
2161 	m_state++;
2162 }
2163 
alu_clr_swpb()2164 void tms99xx_device::alu_clr_swpb()
2165 {
2166 	uint32_t dest_new = 0;
2167 	uint32_t src_val = m_current_value & 0x0000ffff;
2168 	uint16_t sign = 0;
2169 
2170 	bool setstatus = true;
2171 	bool check_ov = true;
2172 	bool check_c = true;
2173 
2174 	switch (m_command)
2175 	{
2176 	case CLR:
2177 		// no status bits
2178 		m_current_value = 0x0000;
2179 		setstatus = false;
2180 		break;
2181 	case SETO:
2182 		// no status bits
2183 		m_current_value = 0xffff;
2184 		setstatus = false;
2185 		break;
2186 	case INV:
2187 		// LAE
2188 		dest_new = ~src_val & 0xffff;
2189 		check_ov = false;
2190 		check_c = false;
2191 		break;
2192 	case NEG:
2193 		// LAECO
2194 		// Overflow occurs for value=0x8000
2195 		dest_new = ((~src_val) & 0x0000ffff) + 1;
2196 		check_ov = false;
2197 		set_status_bit(ST_OV, src_val == 0x8000);
2198 		break;
2199 	case INC:
2200 		// LAECO
2201 		// Overflow for result value = 0x8000
2202 		// Carry for result value = 0x0000
2203 		dest_new = src_val + 1;
2204 		break;
2205 	case INCT:
2206 		// LAECO
2207 		// Overflow for result value = 0x8000 / 0x8001
2208 		// Carry for result value = 0x0000 / 0x0001
2209 		dest_new = src_val + 2;
2210 		break;
2211 	case DEC:
2212 		// LAECO
2213 		// Carry for result value != 0xffff
2214 		// Overflow for result value == 0x7fff
2215 		dest_new = src_val + 0xffff;
2216 		sign = 0x8000;
2217 		break;
2218 	case DECT:
2219 		// Carry for result value != 0xffff / 0xfffe
2220 		// Overflow for result value = 0x7fff / 0x7ffe
2221 		dest_new = src_val + 0xfffe;
2222 		sign = 0x8000;
2223 		break;
2224 	case SWPB:
2225 		m_current_value = ((m_current_value << 8) | (m_current_value >> 8)) & 0xffff;
2226 		setstatus = false;
2227 		break;
2228 	}
2229 
2230 	if (setstatus)
2231 	{
2232 		if (check_ov) set_status_bit(ST_OV, ((src_val & 0x8000)==sign) && ((dest_new & 0x8000)!=sign));
2233 		if (check_c) set_status_bit(ST_C, (dest_new & 0x10000) != 0);
2234 		m_current_value = dest_new & 0xffff;
2235 		compare_and_set_lae(m_current_value, 0);
2236 	}
2237 
2238 	pulse_clock(2);
2239 	// No states here
2240 }
2241 
alu_abs()2242 void tms99xx_device::alu_abs()
2243 {
2244 	// LAECO (from original word!)
2245 	// O if >8000
2246 	// C is alwas reset
2247 	set_status_bit(ST_OV, m_current_value == 0x8000);
2248 	set_status_bit(ST_C, false);
2249 	compare_and_set_lae(m_current_value, 0);
2250 
2251 	if ((m_current_value & 0x8000)!=0)
2252 	{
2253 		m_current_value = (((~m_current_value) & 0x0000ffff) + 1) & 0xffff;
2254 		pulse_clock(2);     // If ABS is performed it takes one machine cycle more
2255 	}
2256 	else
2257 	{
2258 		MPC++; // skips over the next micro operation (MEMORY_WRITE)
2259 	}
2260 	pulse_clock(2);
2261 }
2262 
alu_x()2263 void tms99xx_device::alu_x()
2264 {
2265 	decode(m_current_value);
2266 	pulse_clock(2);
2267 }
2268 
2269 /*
2270     Used by B and BL
2271 */
alu_b()2272 void tms99xx_device::alu_b()
2273 {
2274 	// no status bits
2275 	// Although we got the contents of the source data, we do not use them
2276 	// but directly branch there. That is, we are only interested in the
2277 	// address of the source data.
2278 	// If we have a B *R5 and R5 contains the value 0xa000, the CPU actually
2279 	// retrieves the value at 0xa000, but in fact it will load the PC
2280 	// with the address 0xa000
2281 	m_current_value = PC;
2282 	PC = m_address & m_prgaddr_mask;
2283 	m_address = WP + 22;
2284 	pulse_clock(2);
2285 }
2286 
alu_blwp()2287 void tms99xx_device::alu_blwp()
2288 {
2289 	switch (m_state)
2290 	{
2291 	case 0:
2292 		m_value_copy = WP;
2293 		WP = m_current_value & m_prgaddr_mask;              // set new WP (*m_destination)
2294 		m_address_saved = (m_address + 2) & m_prgaddr_mask; // Save the location of the WP
2295 		m_address = WP + 30;
2296 		m_current_value = ST;                           // get status register
2297 		break;
2298 	case 1:
2299 		m_current_value = PC;                           // get program counter
2300 		m_address = m_address - 2;
2301 		break;
2302 	case 2:
2303 		m_current_value = m_value_copy;                 // retrieve the old WP
2304 		m_address = m_address - 2;
2305 		break;
2306 	case 3:
2307 		m_address = m_address_saved;                    // point to PC component of branch vector
2308 		break;
2309 	case 4:
2310 		PC = m_current_value & m_prgaddr_mask;
2311 		LOGMASKED(LOG_CONTEXT, "Context switch (blwp): WP=%04x, PC=%04x, ST=%04x\n", WP, PC, ST);
2312 		break;
2313 	}
2314 	pulse_clock(2);
2315 	m_state++;
2316 }
2317 
alu_ldcr()2318 void tms99xx_device::alu_ldcr()
2319 {
2320 	uint16_t value;
2321 
2322 	// Spec: "If the source operand address is odd, the address is truncated
2323 	//        to an even address prior to data transfer."
2324 	// (Editor/Assembler, page 151)
2325 	// This refers to transfers with more than 8 bits. In this case, for
2326 	// LDCR the first bit is taken from the least significant bit of the
2327 	// source word. If the address is odd (e.g. 0x1001), it is
2328 	// treated as 0x1000, that is, truncated to an even address.
2329 	// For transfers with 1-8 bits, the first bit is the least significant
2330 	// bit of the source byte (any address).
2331 
2332 	if (m_state == 0)
2333 	{
2334 		m_address = WP + 24;
2335 	}
2336 	else
2337 	{
2338 		value = m_source_value; // copied by ALU_SOURCE
2339 		m_count = (IR >> 6) & 0x000f;
2340 		if (m_count == 0) m_count = 16;
2341 		if (m_count <= 8)
2342 		{
2343 			if (m_source_even) value>>=8;
2344 			set_status_parity((uint8_t)(value & 0xff));
2345 			compare_and_set_lae(value<<8, 0);
2346 		}
2347 		else
2348 		{
2349 			compare_and_set_lae(value, 0);
2350 		}
2351 		m_cru_address = m_current_value;
2352 		m_value = value;
2353 		LOGMASKED(LOG_CRU, "Load CRU address %04x (%d bits), value = %04x\n", m_cru_address, m_count, m_value);
2354 	}
2355 	m_state++;
2356 	pulse_clock(2);
2357 }
2358 
alu_stcr()2359 void tms99xx_device::alu_stcr()
2360 {
2361 	uint16_t value;
2362 	int n = 2;
2363 	// For STCR transfers with more than 8 bits, the first CRU bit is
2364 	// always put into the least significant bit of the destination word.
2365 	// If the address is odd (e.g. 0x1001), it is treated as 0x1000, that is,
2366 	// truncated to an even boundary.
2367 	// For transfers with 1-8 bits, the destination address is handled as
2368 	// in MOVB operations, i.e. the other byte of the word is kept unchanged.
2369 
2370 	switch (m_state)
2371 	{
2372 	case 0: // After getting the destination operand and saving the address/value
2373 		m_address = WP + 24;
2374 		n = 0;
2375 		break;
2376 	case 1: // After getting R12
2377 		m_cru_address = m_current_value;
2378 		m_count = (IR >> 6) & 0x000f;
2379 		if (m_count == 0) m_count = 16;
2380 		break;
2381 	case 2: // After the cru operation; value starts at LSB of m_value
2382 		value = m_value & 0xffff;
2383 		if (m_count < 9)
2384 		{
2385 			LOGMASKED(LOG_CRU, "Store CRU at %04x (%d bits) in %04x, result = %02x\n", m_cru_address, m_count, m_source_address, value);
2386 			set_status_parity((uint8_t)(value & 0xff));
2387 			compare_and_set_lae(value<<8, 0);
2388 			if (m_source_even)
2389 				m_current_value = (m_source_value & 0x00ff) | (value<<8);
2390 			else
2391 				m_current_value = (m_source_value & 0xff00) | (value & 0xff);
2392 
2393 			pulse_clock(2*(5 + (8-m_count)));
2394 		}
2395 		else
2396 		{
2397 			LOGMASKED(LOG_CRU, "Store CRU at %04x (%d bits) in %04x, result = %04x\n", m_cru_address, m_count, m_source_address, value);
2398 			m_current_value = value;
2399 			compare_and_set_lae(value, 0);
2400 			pulse_clock(2*(5 + (16-m_count)));
2401 		}
2402 		m_address = m_source_address;
2403 		break;
2404 	}
2405 
2406 	m_state++;
2407 	pulse_clock(n);
2408 }
2409 
alu_sbz_sbo()2410 void tms99xx_device::alu_sbz_sbo()
2411 {
2412 	int8_t displacement;
2413 	if (m_state==0)
2414 	{
2415 		m_address = WP + 24;
2416 	}
2417 	else
2418 	{
2419 		m_value = (m_command==SBO)? 1 : 0;
2420 		displacement = (int8_t)(IR & 0xff);
2421 		m_cru_address = m_current_value + (displacement<<1);
2422 		m_count = 1;
2423 	}
2424 	m_state++;
2425 	pulse_clock(2);
2426 }
2427 
alu_tb()2428 void tms99xx_device::alu_tb()
2429 {
2430 	int8_t displacement;
2431 	switch (m_state)
2432 	{
2433 	case 0:
2434 		m_address = WP + 24;
2435 		break;
2436 	case 1:
2437 		displacement = (int8_t)(IR & 0xff);
2438 		m_cru_address = m_current_value + (displacement<<1);
2439 		m_count = 1;
2440 		break;
2441 	case 2:
2442 		set_status_bit(ST_EQ, m_value!=0);
2443 		LOGMASKED(LOG_STATUS, "ST = %04x\n", ST);
2444 		break;
2445 	}
2446 	m_state++;
2447 	pulse_clock(2);
2448 }
2449 
alu_jmp()2450 void tms99xx_device::alu_jmp()
2451 {
2452 	int8_t displacement;
2453 	bool cond = false;
2454 
2455 	if (m_state==0)
2456 	{
2457 		switch (m_command)
2458 		{
2459 		case JMP:
2460 			cond = true;
2461 			break;
2462 		case JLT:   // LAECOP == x00xxx
2463 			cond = ((ST & (ST_AGT | ST_EQ))==0);
2464 			break;
2465 		case JLE:   // LAECOP == 0xxxxx
2466 			cond = ((ST & ST_LH)==0);
2467 			break;
2468 		case JEQ:   // LAECOP == xx1xxx
2469 			cond = ((ST & ST_EQ)!=0);
2470 			break;
2471 		case JHE:   // LAECOP == 1x0xxx, 0x1xxx
2472 			cond = ((ST & (ST_LH | ST_EQ)) != 0);
2473 			break;
2474 		case JGT:   // LAECOP == x1xxxx
2475 			cond = ((ST & ST_AGT)!=0);
2476 			break;
2477 		case JNE:   // LAECOP == xx0xxx
2478 			cond = ((ST & ST_EQ)==0);
2479 			break;
2480 		case JNC:   // LAECOP == xxx0xx
2481 			cond = ((ST & ST_C)==0);
2482 			break;
2483 		case JOC:   // LAECOP == xxx1xx
2484 			cond = ((ST & ST_C)!=0);
2485 			break;
2486 		case JNO:   // LAECOP == xxxx0x
2487 			cond = ((ST & ST_OV)==0);
2488 			break;
2489 		case JL:    // LAECOP == 0x0xxx
2490 			cond = ((ST & (ST_LH | ST_EQ)) == 0);
2491 			break;
2492 		case JH:    // LAECOP == 1xxxxx
2493 			cond = ((ST & ST_LH)!=0);
2494 			break;
2495 		case JOP:   // LAECOP == xxxxx1
2496 			cond = ((ST & ST_OP)!=0);
2497 			break;
2498 		}
2499 		if (!cond)
2500 		{
2501 			LOGMASKED(LOG_DETAIL, "Jump condition false\n");
2502 			MPC+=1; // skip next ALU call
2503 		}
2504 		else
2505 			LOGMASKED(LOG_DETAIL, "Jump condition true\n");
2506 	}
2507 	else
2508 	{
2509 		displacement = (IR & 0xff);
2510 		PC = (PC + (displacement<<1)) & m_prgaddr_mask;
2511 	}
2512 	m_state++;
2513 	pulse_clock(2);
2514 }
2515 
alu_shift()2516 void tms99xx_device::alu_shift()
2517 {
2518 	bool carry = false;
2519 	bool overflow = false;
2520 	uint16_t sign = 0;
2521 	uint32_t value;
2522 	int count;
2523 	bool check_ov = false;
2524 
2525 	switch (m_state)
2526 	{
2527 	case 0:
2528 		m_address = WP + ((IR & 0x000f)<<1);
2529 		pulse_clock(2);
2530 		break;
2531 	case 1:
2532 		// we have the value of the register in m_current_value
2533 		// Save it (we may have to read R0)
2534 		m_value_copy = m_current_value;
2535 		m_address_saved = m_address;
2536 		m_address = WP;
2537 		m_current_value = (IR >> 4) & 0x000f;
2538 
2539 		if (m_current_value != 0)
2540 		{
2541 			// skip the next read and ALU operation
2542 			MPC = MPC+2;
2543 			m_state++;
2544 		}
2545 		else
2546 		{
2547 			LOGMASKED(LOG_DETAIL, "Shift operation gets count from R0\n");
2548 			pulse_clock(2);
2549 		}
2550 		pulse_clock(2);
2551 		break;
2552 	case 2:
2553 		// after READ
2554 		pulse_clock(2);
2555 		pulse_clock(2);
2556 		break;
2557 	case 3:
2558 		count = m_current_value & 0x000f; // from the instruction or from R0
2559 		if (count==0) count = 16;
2560 
2561 		value = m_value_copy;
2562 
2563 		// we are re-implementing the shift operations because we have to pulse
2564 		// the clock at each single shift anyway.
2565 		// Also, it is easier to implement the status bit setting.
2566 		// Note that count is never 0
2567 		if (m_command == SRA) sign = value & 0x8000;
2568 
2569 		for (int i=0; i < count; i++)
2570 		{
2571 			switch (m_command)
2572 			{
2573 			case SRL:
2574 			case SRA:
2575 				carry = ((value & 1)!=0);
2576 				value = (value >> 1) | sign;
2577 				break;
2578 			case SLA:
2579 				carry = ((value & 0x8000)!=0);
2580 				value <<= 1;
2581 				check_ov = true;
2582 				if (carry != ((value&0x8000)!=0)) overflow = true;
2583 				break;
2584 			case SRC:
2585 				carry = ((value & 1)!=0);
2586 				value = (value>>1) | (carry? 0x8000 : 0x0000);
2587 				break;
2588 			}
2589 			pulse_clock(2);
2590 		}
2591 
2592 		m_current_value = value & 0xffff;
2593 		set_status_bit(ST_C, carry);
2594 		if (check_ov) set_status_bit(ST_OV, overflow); // only SLA
2595 		compare_and_set_lae(m_current_value, 0);
2596 		m_address = m_address_saved;        // Register address
2597 		LOGMASKED(LOG_STATUS, "ST = %04x (val=%04x)\n", ST, m_current_value);
2598 		break;
2599 	}
2600 	m_state++;
2601 }
2602 
alu_ai_ori()2603 void tms99xx_device::alu_ai_ori()
2604 {
2605 	uint32_t dest_new = 0;
2606 	switch (m_command)
2607 	{
2608 	case AI:
2609 		dest_new = m_current_value + m_value_copy;
2610 		// See status bit handling for Add
2611 		set_status_bit(ST_C, (dest_new & 0x10000) != 0);
2612 		set_status_bit(ST_OV, ((dest_new ^ m_current_value) & (dest_new ^ m_value_copy) & 0x8000)!=0);
2613 		break;
2614 	case ANDI:
2615 		dest_new = m_current_value & m_value_copy;
2616 		break;
2617 	case ORI:
2618 		dest_new = m_current_value | m_value_copy;
2619 		break;
2620 	}
2621 	m_current_value = dest_new & 0xffff;
2622 	m_address = m_address_copy;
2623 	compare_and_set_lae(m_current_value, 0);
2624 	pulse_clock(2);
2625 }
2626 
alu_ci()2627 void tms99xx_device::alu_ci()
2628 {
2629 	compare_and_set_lae(m_value_copy, m_current_value);
2630 	pulse_clock(2);
2631 }
2632 
alu_li()2633 void tms99xx_device::alu_li()
2634 {
2635 	compare_and_set_lae(m_current_value, 0);
2636 	pulse_clock(2);
2637 }
2638 
alu_lwpi()2639 void tms99xx_device::alu_lwpi()
2640 {
2641 	WP = m_current_value & m_prgaddr_mask;
2642 	pulse_clock(2);
2643 }
2644 
alu_limi()2645 void tms99xx_device::alu_limi()
2646 {
2647 	ST = (ST & 0xfff0) | (m_current_value & 0x000f);
2648 	LOGMASKED(LOG_STATUS, "ST = %04x\n", ST);
2649 	pulse_clock(2);
2650 }
2651 
alu_stwp_stst()2652 void tms99xx_device::alu_stwp_stst()
2653 {
2654 	if (m_command==STST) m_current_value = ST;
2655 	else m_current_value = WP;
2656 	pulse_clock(2);
2657 }
2658 
alu_external()2659 void tms99xx_device::alu_external()
2660 {
2661 	// Call some possibly attached external device
2662 	// We pass the bit pattern of the address bus to the external function
2663 
2664 	// IDLE = 0000 0011 0100 0000
2665 	// RSET = 0000 0011 0110 0000
2666 	// CKON = 0000 0011 1010 0000
2667 	// CKOF = 0000 0011 1100 0000
2668 	// LREX = 0000 0011 1110 0000
2669 	//                  ---
2670 	if (m_command == IDLE)
2671 		m_idle_state = true;
2672 
2673 	if (!m_external_operation.isnull()) m_external_operation((IR >> 5) & 0x07, 1, 0xff);
2674 	pulse_clock(2);
2675 }
2676 
alu_rtwp()2677 void tms99xx_device::alu_rtwp()
2678 {
2679 	switch (m_state)
2680 	{
2681 	case 0:
2682 		m_address = WP + 30;        // R15
2683 		pulse_clock(2);
2684 		break;
2685 	case 1:
2686 		ST = m_current_value;
2687 		m_address -= 2;             // R14
2688 		break;
2689 	case 2:
2690 		PC = m_current_value & m_prgaddr_mask;
2691 		m_address -= 2;             // R13
2692 		break;
2693 	case 3:
2694 		WP = m_current_value & m_prgaddr_mask;
2695 		pulse_clock(2);
2696 		// Just for debugging purposes
2697 		m_log_interrupt = false;
2698 		LOGMASKED(LOG_CONTEXT, "Context switch (rtwp): WP=%04x, PC=%04x, ST=%04x\n", WP, PC, ST);
2699 		break;
2700 	}
2701 	m_state++;
2702 }
2703 
2704 
alu_int()2705 void tms99xx_device::alu_int()
2706 {
2707 	switch (m_state)
2708 	{
2709 	case 0:
2710 		if (m_irq_level == RESET_INT)
2711 		{
2712 			m_address = 0;
2713 			pulse_clock(2);
2714 		}
2715 		else
2716 		{
2717 			if (m_irq_level == LOAD_INT) m_address = 0xfffc; // will be truncated for TMS9980
2718 			else
2719 			{
2720 				LOGMASKED(LOG_INTD, "interrupt service (0): Prepare to read vector\n");
2721 				m_address = (m_irq_level << 2);
2722 			}
2723 		}
2724 		break;
2725 	case 1:
2726 		m_address_copy = m_address;
2727 		m_value_copy = WP;                          // old WP
2728 		WP = m_current_value & m_prgaddr_mask;      // new WP
2729 		m_current_value = ST;
2730 		m_address = (WP + 30) & m_prgaddr_mask;
2731 		LOGMASKED(LOG_INTD, "interrupt service (1): Read new WP = %04x, save ST to %04x\n", WP, m_address);
2732 		break;
2733 	case 2:
2734 		m_current_value = PC;
2735 		m_address = (WP + 28) & m_prgaddr_mask;
2736 		LOGMASKED(LOG_INTD, "interrupt service (2): Save PC to %04x\n", m_address);
2737 		break;
2738 	case 3:
2739 		m_current_value = m_value_copy; // old WP
2740 		m_address = (WP + 26) & m_prgaddr_mask;
2741 		LOGMASKED(LOG_INTD, "interrupt service (3): Save WP to %04x\n", m_address);
2742 		break;
2743 	case 4:
2744 		m_address = (m_address_copy + 2) & m_prgaddr_mask;
2745 		LOGMASKED(LOG_INTD, "interrupt service (4): Read PC from %04x\n", m_address);
2746 		break;
2747 	case 5:
2748 		PC = m_current_value & m_prgaddr_mask;
2749 		if (m_irq_level > 0 )
2750 		{
2751 			ST = (ST & 0xfff0) | (m_irq_level - 1);
2752 		}
2753 		if (m_irq_level == LOAD_INT)
2754 			LOGMASKED(LOG_LOAD, "Context switch (LOAD): WP=%04x, PC=%04x, ST=%04x\n", WP, PC, ST);
2755 		else
2756 			LOGMASKED(LOG_CONTEXT, "Context switch (int): WP=%04x, PC=%04x, ST=%04x\n", WP, PC, ST);
2757 		break;
2758 	}
2759 	m_state++;
2760 	pulse_clock(2);
2761 }
2762 
2763 /**************************************************************************/
2764 
2765 /*
2766     The minimum number of cycles applies to a command like STWP R0.
2767 */
execute_min_cycles() const2768 uint32_t tms99xx_device::execute_min_cycles() const noexcept
2769 {
2770 	return 8;
2771 }
2772 
2773 /*
2774     The maximum number of cycles applies to a DIV command, depending on the
2775     data to be divided, and the mode of adressing.
2776 */
execute_max_cycles() const2777 uint32_t tms99xx_device::execute_max_cycles() const noexcept
2778 {
2779 	return 124;
2780 }
2781 
execute_input_lines() const2782 uint32_t tms99xx_device::execute_input_lines() const noexcept
2783 {
2784 	return 2;
2785 }
2786 
2787 // clocks to cycles, cycles to clocks = id
2788 // execute_default_irq_vector = 0
2789 // execute_burn = nop
2790 
2791 // device_disasm_interface overrides
2792 
create_disassembler()2793 std::unique_ptr<util::disasm_interface> tms99xx_device::create_disassembler()
2794 {
2795 	return std::make_unique<tms9900_disassembler>(TMS9900_ID);
2796 }
2797 
2798 
2799 DEFINE_DEVICE_TYPE(TMS9900, tms9900_device, "tms9900", "Texas Instruments TMS9900")
2800