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
|
/**********************************************************************
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
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__ */
|