summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/tms32025/tms32025.h
blob: e112dafde5164e8a31d79748f651fe1747c343f1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
// license:BSD-3-Clause
// copyright-holders:Tony La Porta, hap
	/**************************************************************************\
	*                Texas Instruments TMS320x25 DSP Emulator                  *
	*                                                                          *
	*                 Copyright Tony La Porta                                  *
	*                      Written for the MAME project.                       *
	*                                                                          *
	*      Note :  This is a word based microcontroller, with addressing       *
	*              architecture based on the Harvard addressing scheme.        *
	*                                                                          *
	*  Three versions of the chip are available, and they are:                 *
	*  TMS320C25   Internal ROM one time programmed at TI                      *
	*  TMS320E25   Internal ROM programmable as a normal EPROM                 *
	*  TMS320P25   Internal ROM programmable once as a normal EPROM only       *
	*  These devices can also be used as a MicroController with external ROM   *
	*                                                                          *
	\***************************************************************************/

#pragma once

#ifndef __TMS32025_H__
#define __TMS32025_H__


#define MCFG_TMS32025_BIO_IN_CB(_devcb) \
	devcb = &tms32025_device::set_bio_in_cb(*device, DEVCB_##_devcb); /* BIO input  */

#define MCFG_TMS32025_HOLD_IN_CB(_devcb) \
	devcb = &tms32025_device::set_hold_in_cb(*device, DEVCB_##_devcb); /* HOLD input */

#define MCFG_TMS32025_HOLD_ACK_OUT_CB(_devcb) \
	devcb = &tms32025_device::set_hold_ack_out_cb(*device, DEVCB_##_devcb); /* HOLD Acknowledge output */

#define MCFG_TMS32025_XF_OUT_CB(_devcb) \
	devcb = &tms32025_device::set_xf_out_cb(*device, DEVCB_##_devcb); /* XF output  */

#define MCFG_TMS32025_DR_IN_CB(_devcb) \
	devcb = &tms32025_device::set_dr_in_cb(*device, DEVCB_##_devcb); /* Serial Data  Receive  input  */

#define MCFG_TMS32025_DX_OUT_CB(_devcb) \
	devcb = &tms32025_device::set_dx_out_cb(*device, DEVCB_##_devcb); /* Serial Data  Transmit output */


/****************************************************************************
 *  Interrupt constants
 */

#define TMS32025_INT0             0         /* External INT0 */
#define TMS32025_INT1             1         /* External INT1 */
#define TMS32025_INT2             2         /* External INT2 */
#define TMS32025_TINT             3         /* Internal Timer interrupt */
#define TMS32025_RINT             4         /* Serial Port receive  interrupt */
#define TMS32025_XINT             5         /* Serial Port transmit interrupt */
#define TMS32025_TRAP             6         /* Trap instruction */
#define TMS32025_INT_NONE         -1

/* Non-irq line */
#define TMS32025_FSX              7         /* Frame synchronisation */

enum
{
	TMS32025_PC=1,
	TMS32025_PFC,  TMS32025_STR0, TMS32025_STR1, TMS32025_IFR,
	TMS32025_RPTC, TMS32025_ACC,  TMS32025_PREG, TMS32025_TREG,
	TMS32025_AR0,  TMS32025_AR1,  TMS32025_AR2,  TMS32025_AR3,
	TMS32025_AR4,  TMS32025_AR5,  TMS32025_AR6,  TMS32025_AR7,
	TMS32025_STK0, TMS32025_STK1, TMS32025_STK2, TMS32025_STK3,
	TMS32025_STK4, TMS32025_STK5, TMS32025_STK6, TMS32025_STK7,
	TMS32025_DRR,  TMS32025_DXR,  TMS32025_TIM,  TMS32025_PRD,
	TMS32025_IMR,  TMS32025_GREG
};


/****************************************************************************
 *  Public Functions
 */


class tms32025_device : public cpu_device
{
public:
	// construction/destruction
	tms32025_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
	tms32025_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);

	// static configuration helpers
	template<class _Object> static devcb_base & set_bio_in_cb(device_t &device, _Object object) { return downcast<tms32025_device &>(device).m_bio_in.set_callback(object); }
	template<class _Object> static devcb_base & set_hold_in_cb(device_t &device, _Object object) { return downcast<tms32025_device &>(device).m_hold_in.set_callback(object); }
	template<class _Object> static devcb_base & set_hold_ack_out_cb(device_t &device, _Object object) { return downcast<tms32025_device &>(device).m_hold_ack_out.set_callback(object); }
	template<class _Object> static devcb_base & set_xf_out_cb(device_t &device, _Object object) { return downcast<tms32025_device &>(device).m_xf_out.set_callback(object); }
	template<class _Object> static devcb_base & set_dr_in_cb(device_t &device, _Object object) { return downcast<tms32025_device &>(device).m_dr_in.set_callback(object); }
	template<class _Object> static devcb_base & set_dx_out_cb(device_t &device, _Object object) { return downcast<tms32025_device &>(device).m_dx_out.set_callback(object); }

protected:
	// device-level overrides
	virtual void device_start() override;
	virtual void device_reset() override;

	// device_execute_interface overrides
	virtual UINT32 execute_min_cycles() const override { return 4; }
	virtual UINT32 execute_max_cycles() const override { return 20; }
	virtual UINT32 execute_input_lines() const override { return 6; }
	virtual void execute_run() override;
	virtual void execute_set_input(int inputnum, int state) override;

	// device_memory_interface overrides
	virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const override { return (spacenum == AS_PROGRAM) ? &m_program_config : ( (spacenum == AS_IO) ? &m_io_config : ( (spacenum == AS_DATA) ? &m_data_config : nullptr ) ); }
	virtual bool memory_read(address_spacenum spacenum, offs_t offset, int size, UINT64 &value) override;
	virtual bool memory_write(address_spacenum spacenum, offs_t offset, int size, UINT64 value) override;
	virtual bool memory_readop(offs_t offset, int size, UINT64 &value) override;

	// device_state_interface overrides
	virtual void state_import(const device_state_entry &entry) override;
	virtual void state_export(const device_state_entry &entry) override;
	virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;

	// device_disasm_interface overrides
	virtual UINT32 disasm_min_opcode_bytes() const override { return 2; }
	virtual UINT32 disasm_max_opcode_bytes() const override { return 4; }
	virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;

private:
	address_space_config m_program_config;
	address_space_config m_data_config;
	address_space_config m_io_config;

	typedef void ( tms32025_device::*opcode_func ) ();
	struct tms32025_opcode
	{
		UINT8       cycles;
		opcode_func function;
	};
	static const tms32025_opcode s_opcode_main[256];
	static const tms32025_opcode s_opcode_CE_subset[256];
	static const tms32025_opcode s_opcode_Dx_subset[8];

	devcb_read16 m_bio_in;
	devcb_read16 m_hold_in;
	devcb_write16 m_hold_ack_out;
	devcb_write16 m_xf_out;
	devcb_read16 m_dr_in;
	devcb_write16 m_dx_out;


	/******************** CPU Internal Registers *******************/
	UINT16  m_PREVPC;     /* previous program counter */
	UINT16  m_PC;
	UINT16  m_PFC;
	UINT16  m_STR0, m_STR1;
	UINT8   m_IFR;
	UINT8   m_RPTC;
	PAIR    m_ACC;
	PAIR    m_Preg;
	UINT16  m_Treg;
	UINT16  m_AR[8];
	UINT16  m_STACK[8];
	PAIR    m_ALU;
protected:
	UINT16  m_intRAM[0x800];
private:
	UINT8   m_timerover;

	/********************** Status data ****************************/
	PAIR    m_opcode;
	int     m_idle;
	int     m_hold;
	int     m_external_mem_access;    /** required for hold mode. Implement it ! */
	int     m_init_load_addr;         /* 0=No, 1=Yes, 2=Once for repeat mode */
	int     m_tms32025_irq_cycles;
	int     m_tms32025_dec_cycles;

	PAIR    m_oldacc;
	UINT32  m_memaccess;
	int     m_icount;
	int     m_mHackIgnoreARP;          /* special handling for lst, lst1 instructions */
	int     m_waiting_for_serial_frame;

	address_space *m_program;
	direct_read_data *m_direct;
	address_space *m_data;
	address_space *m_io;

	UINT16 *m_pgmmap[0x200];
protected:
	UINT16 *m_datamap[0x200];

private:
	UINT32 m_debugger_temp;

	inline void CLR0(UINT16 flag);
	inline void SET0(UINT16 flag);
	inline void CLR1(UINT16 flag);
	inline void SET1(UINT16 flag);
	inline void MODIFY_DP(int data);
	inline void MODIFY_PM(int data);
	inline void MODIFY_ARP(int data);
	inline UINT16 M_RDROM(offs_t addr);
	inline void M_WRTROM(offs_t addr, UINT16 data);
	inline UINT16 M_RDRAM(offs_t addr);
	inline void M_WRTRAM(offs_t addr, UINT16 data);
	UINT16 reverse_carry_add(UINT16 arg0, UINT16 arg1 );
	inline void MODIFY_AR_ARP();
	inline void CALCULATE_ADD_CARRY();
	inline void CALCULATE_SUB_CARRY();
	inline void CALCULATE_ADD_OVERFLOW(INT32 addval);
	inline void CALCULATE_SUB_OVERFLOW(INT32 subval);
	inline UINT16 POP_STACK();
	inline void PUSH_STACK(UINT16 data);
	inline void SHIFT_Preg_TO_ALU();
	inline void GETDATA(int shift,int signext);
	inline void PUTDATA(UINT16 data);
	inline void PUTDATA_SST(UINT16 data);
	void opcodes_CE();
	void opcodes_Dx();
	void illegal();
	void abst();
	void add();
	void addc();
	void addh();
	void addk();
	void adds();
	void addt();
	void adlk();
	void adrk();
	void and_();
	void andk();
	void apac();
	void br();
	void bacc();
	void banz();
	void bbnz();
	void bbz();
	void bc();
	void bgez();
	void bgz();
	void bioz();
	void bit();
	void bitt();
	void blez();
	void blkd();
	void blkp();
	void blz();
	void bnc();
	void bnv();
	void bnz();
	void bv();
	void bz();
	void cala();
	void call();
	void cmpl();
	void cmpr();
	void cnfd();
	void cnfp();
	void conf();
	void dint();
	void dmov();
	void eint();
	void fort();
	void idle();
	void in();
	void lac();
	void lack();
	void lact();
	void lalk();
	void lar_ar0();
	void lar_ar1();
	void lar_ar2();
	void lar_ar3();
	void lar_ar4();
	void lar_ar5();
	void lar_ar6();
	void lar_ar7();
	void lark_ar0();
	void lark_ar1();
	void lark_ar2();
	void lark_ar3();
	void lark_ar4();
	void lark_ar5();
	void lark_ar6();
	void lark_ar7();
	void ldp();
	void ldpk();
	void lph();
	void lrlk();
	void lst();
	void lst1();
	void lt();
	void lta();
	void ltd();
	void ltp();
	void lts();
	void mac();
	void macd();
	void mar();
	void mpy();
	void mpya();
	void mpyk();
	void mpys();
	void mpyu();
	void neg();
	void norm();
	void or_();
	void ork();
	void out();
	void pac();
	void pop();
	void popd();
	void pshd();
	void push();
	void rc();
	void ret();
	void rfsm();
	void rhm();
	void rol();
	void ror();
	void rovm();
	void rpt();
	void rptk();
	void rsxm();
	void rtc();
	void rtxm();
	void rxf();
	void sach();
	void sacl();
	void sar_ar0();
	void sar_ar1();
	void sar_ar2();
	void sar_ar3();
	void sar_ar4();
	void sar_ar5();
	void sar_ar6();
	void sar_ar7();
	void sblk();
	void sbrk_ar();
	void sc();
	void sfl();
	void sfr();
	void sfsm();
	void shm();
	void sovm();
	void spac();
	void sph();
	void spl();
	void spm();
	void sqra();
	void sqrs();
	void sst();
	void sst1();
	void ssxm();
	void stc();
	void stxm();
	void sub();
	void subb();
	void subc();
	void subh();
	void subk();
	void subs();
	void subt();
	void sxf();
	void tblr();
	void tblw();
	void trap();
	void xor_();
	void xork();
	void zalh();
	void zalr();
	void zals();
	inline int process_IRQs();
	inline void process_timer(int clocks);

};


class tms32026_device : public tms32025_device
{
public:
	// construction/destruction
	tms32026_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);

protected:
	virtual void device_reset() override;
};


extern const device_type TMS32025;
extern const device_type TMS32026;


#endif  /* __TMS32025_H__ */