summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/cosmac/cosmac.h
blob: e2e8888be3ed1a710671888613a7235cf68f238a (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
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
/**********************************************************************

    RCA "COSMAC" CPU emulation

    Copyright MESS Team.
    Visit http://mamedev.org for licensing and usage restrictions.

**********************************************************************
                            _____   _____
                 CLOCK   1 |*    \_/     | 40  Vdd
                 _WAIT   2 |             | 39  _XTAL
                _CLEAR   3 |             | 38  _DMA IN
                     Q   4 |             | 37  _DMA OUT
                   SC1   5 |             | 36  _INTERRUPT
                   SC0   6 |             | 35  _MWR
                  _MRD   7 |             | 34  TPA
                 BUS 7   8 |             | 33  TPB
                 BUS 6   9 |   CDP1802   | 32  MA7
                 BUS 5  10 |   CDP1803   | 31  MA6
                 BUS 4  11 |   CDP1804   | 30  MA5
                 BUS 3  12 |   CDP1805   | 29  MA4
                 BUS 2  13 |   CDP1806   | 28  MA3
                 BUS 1  14 |             | 27  MA2
                 BUS 0  15 |             | 26  MA1
                     *  16 |             | 25  MA0
                    N2  17 |             | 24  _EF1
                    N1  18 |             | 23  _EF2
                    N0  19 |             | 22  _EF3
                   Vss  20 |_____________| 21  _EF4


	Type            Internal ROM    Internal RAM    Timer	Pin 16 (*)
    ------------------------------------------------------------------
    CDP1802         none            none            no			Vcc
    CDP1803         ?               ?               ?			?
    CDP1804         2 KB            64 bytes        yes			?
    CDP1805         none            64 bytes        yes			_ME
    CDP1806         none            none            yes			Vdd
	
**********************************************************************/

#pragma once

#ifndef __COSMAC_H__
#define __COSMAC_H__


//**************************************************************************
//  ENUMERATIONS
//**************************************************************************

// registers
enum
{
	COSMAC_P,
	COSMAC_X,
	COSMAC_D,
	COSMAC_B,
	COSMAC_T,
	COSMAC_R0,
	COSMAC_R1,
	COSMAC_R2,
	COSMAC_R3,
	COSMAC_R4,
	COSMAC_R5,
	COSMAC_R6,
	COSMAC_R7,
	COSMAC_R8,
	COSMAC_R9,
	COSMAC_Ra,
	COSMAC_Rb,
	COSMAC_Rc,
	COSMAC_Rd,
	COSMAC_Re,
	COSMAC_Rf,
	COSMAC_DF,
	COSMAC_IE,
	COSMAC_Q,
	COSMAC_N,
	COSMAC_I,
	COSMAC_SC
};


// input lines
enum
{
	COSMAC_INPUT_LINE_INT = 0,
	COSMAC_INPUT_LINE_DMAIN,
	COSMAC_INPUT_LINE_DMAOUT,
	COSMAC_INPUT_LINE_EF1,
	COSMAC_INPUT_LINE_EF2,
	COSMAC_INPUT_LINE_EF3,
	COSMAC_INPUT_LINE_EF4,
};


// state codes
enum cosmac_state_code
{
	COSMAC_STATE_CODE_S0_FETCH = 0,
	COSMAC_STATE_CODE_S1_EXECUTE,
	COSMAC_STATE_CODE_S2_DMA,
	COSMAC_STATE_CODE_S3_INTERRUPT
};


// device type definition
extern const device_type COSMAC;



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

typedef void (*cosmac_out_sc_func)(running_device *device, cosmac_state_code sc);
#define COSMAC_SC_WRITE(name) void name(running_device *device, cosmac_state_code sc)


// ======================> cosmac_interface

struct cosmac_interface
{
	devcb_read_line		m_in_wait_func;
	devcb_read_line		m_in_clear_func;
	devcb_read_line		m_in_ef1_func;
	devcb_read_line		m_in_ef2_func;
	devcb_read_line		m_in_ef3_func;
	devcb_read_line		m_in_ef4_func;
	devcb_write_line	m_out_q_func;
	devcb_read8			m_in_dma_func;
	devcb_write8		m_out_dma_func;
	cosmac_out_sc_func	m_out_sc_func;
	devcb_write_line	m_out_tpa_func;
	devcb_write_line	m_out_tpb_func;
};

#define COSMAC_INTERFACE(name) \
	const cosmac_interface (name) =


// ======================> cosmac_device_config

class cosmac_device_config :	public cpu_device_config,
                                public cosmac_interface
{
	friend class cosmac_device;

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

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

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

	// device_config_execute_interface overrides
	virtual UINT32 execute_min_cycles() const;
	virtual UINT32 execute_max_cycles() const;
	virtual UINT32 execute_input_lines() const;

	// device_config_memory_interface overrides
	virtual const address_space_config *memory_space_config(int spacenum = 0) const;

	// device_config_disasm_interface overrides
	virtual UINT32 disasm_min_opcode_bytes() const;
	virtual UINT32 disasm_max_opcode_bytes() const;

	// inline data
	const address_space_config		m_program_config;
	const address_space_config		m_io_config;
};



// ======================> cosmac_device

class cosmac_device : public cpu_device
{
	friend class cosmac_device_config;

	// construction/destruction
	cosmac_device(running_machine &_machine, const cosmac_device_config &config);

public:
	// public interfaces
	offs_t get_memory_address();

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

	// device_execute_interface overrides
	virtual void execute_run();
	virtual void execute_set_input(int inputnum, int state);

	// device_state_interface overrides
	virtual void state_import(const device_state_entry &entry);
	virtual void state_export(const device_state_entry &entry);
	virtual void state_string_export(const device_state_entry &entry, astring &string);

	// device_disasm_interface overrides
	virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);

	// helpers
	inline UINT8 read_opcode(offs_t pc);
	inline UINT8 read_byte(offs_t address);
	inline UINT8 read_io_byte(offs_t address);
	inline void write_byte(offs_t address, UINT8 data);
	inline void write_io_byte(offs_t address, UINT8 data);

	// execution logic
	inline void run();
	inline void debug();
	inline void reset();
	inline void initialize();
	inline void fetch_instruction();
	inline void fetch_instruction_debug();
	inline void execute_instruction();
	inline void dma_input();
	inline void dma_output();
	inline void interrupt();
	inline void sample_wait_clear();
	inline void sample_ef_lines();
	inline void output_state_code();
	inline void set_q_flag(int state);

	// arithmetic handlers
	void add(int left, int right);
	void add_with_carry(int left, int right);
	void subtract(int left, int right);
	void subtract_with_borrow(int left, int right);

	// condition handlers
	void short_branch(int taken);
	void long_branch(int taken);
	void long_skip(int taken);

	// control handlers
	void return_from_interrupt(int ie);

	// memory reference opcode handlers
	void ldn();
	void lda();
	void ldx();
	void ldxa();
	void ldi();
	void str();
	void stxd();

	// register operations opcode handlers
	void inc();
	void dec();
	void irx();
	void glo();
	void plo();
	void ghi();
	void phi();

	// logic operations opcode handlers
	void _or();
	void ori();
	void _xor();
	void xri();
	void _and();
	void ani();
	void shr();
	void shrc();
	void shl();
	void shlc();

	// arithmetic operations opcode handlers
	void add();
	void adi();
	void adc();
	void adci();
	void sd();
	void sdi();
	void sdb();
	void sdbi();
	void sm();
	void smi();
	void smb();
	void smbi();

	// short branch instructions opcode handlers
	void br();
	void nbr();
	void bz();
	void bnz();
	void bdf();
	void bnf();
	void bq();
	void bnq();
	void b();
	void bn();

	// long branch instructions opcode handlers
	void lbr();
	void nlbr();
	void lbz();
	void lbnz();
	void lbdf();
	void lbnf();
	void lbq();
	void lbnq();

	// skip instructions opcode handlers
	void lsz();
	void lsnz();
	void lsdf();
	void lsnf();
	void lsq();
	void lsnq();
	void lsie();
	
	// control instructions opcode handlers
	void idl();
	void nop();
	void sep();
	void sex();
	void seq();
	void req();
	void sav();
	void mark();
	void ret();
	void dis();

	// input/output byte transfer opcode handlers
	void out();
	void inp();

	// device callbacks
	devcb_resolved_read_line	m_in_wait_func;
	devcb_resolved_read_line	m_in_clear_func;
	devcb_resolved_read_line	m_in_ef_func[4];
	devcb_resolved_write_line	m_out_q_func;
	devcb_resolved_read8		m_in_dma_func;
	devcb_resolved_write8		m_out_dma_func;
	cosmac_out_sc_func			m_out_sc_func;
	devcb_resolved_write_line	m_out_tpa_func;
	devcb_resolved_write_line	m_out_tpb_func;
		
	// control modes
	enum _cosmac_mode
	{
		COSMAC_MODE_LOAD = 0,
		COSMAC_MODE_RESET,
		COSMAC_MODE_PAUSE,
		COSMAC_MODE_RUN
	};
	typedef enum _cosmac_mode cosmac_mode;

	// execution states
	enum _cosmac_state
	{
		COSMAC_STATE_0_FETCH = 0,
		COSMAC_STATE_1_RESET,
		COSMAC_STATE_1_INIT,
		COSMAC_STATE_1_EXECUTE,
		COSMAC_STATE_2_DMA_IN,
		COSMAC_STATE_2_DMA_OUT,
		COSMAC_STATE_3_INT
	};
	typedef enum _cosmac_state cosmac_state;

	// internal state
	UINT8				m_op;				// current opcode
	UINT8				m_flagsio;			// flags storage for state saving
	cosmac_state		m_state;			// state
	cosmac_mode			m_mode;				// control mode
	cosmac_mode			m_pmode;			// previous control mode
	int					m_irq;				// interrupt request
	int					m_dmain;			// DMA input request
	int					m_dmaout;			// DMA output request
	int					m_ef[4];			// external flags

	// registers
	UINT8				m_d;				// data register (accumulator)
	UINT8				m_b;				// auxiliary holding register
	UINT16				m_r[16];			// scratchpad registers
	UINT8				m_p;				// designates which register is Program Counter
	UINT8				m_x;				// designates which register is Data Pointer
	UINT8				m_n;				// low-order instruction digit
	UINT8				m_i;				// high-order instruction digit
	UINT8				m_t;				// temporary register

	// flags
	int					m_df;				// data flag (ALU carry)
	int					m_ie;				// interrupt enable
	int					m_q;				// output flip-flop

	// internal stuff
	int					m_icount;
	address_space *		m_program;
	address_space *		m_io;
	direct_read_data *	m_direct;

	// opcode/condition tables
	typedef void (cosmac_device::*ophandler)();

	static const ophandler s_opcodetable[256];

	const cosmac_device_config &m_config;
};



#endif /* __COSMAC_H__ */