summaryrefslogtreecommitdiffstats
path: root/src/devices/cpu/hmcs40/hmcs40.h
blob: ffa5ea26d5ed4a268ebbfb3aa8ba1536e05c8ddb (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
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
// license:BSD-3-Clause
// copyright-holders:hap
/*

  Hitachi HMCS40 MCU family cores

*/

#ifndef MAME_CPU_HMCS40_HMCS40_H
#define MAME_CPU_HMCS40_HMCS40_H

#pragma once


// I/O ports setup

// max 8 4-bit R ports
#define MCFG_HMCS40_READ_R_CB(R, _devcb) \
	downcast<hmcs40_cpu_device &>(*device).set_read_r##R##_callback(DEVCB_##_devcb);
#define MCFG_HMCS40_WRITE_R_CB(R, _devcb) \
	downcast<hmcs40_cpu_device &>(*device).set_write_r##R##_callback(DEVCB_##_devcb);

// 16-bit discrete
#define MCFG_HMCS40_READ_D_CB(_devcb) \
	downcast<hmcs40_cpu_device &>(*device).set_read_d_callback(DEVCB_##_devcb);
#define MCFG_HMCS40_WRITE_D_CB(_devcb) \
	downcast<hmcs40_cpu_device &>(*device).set_write_d_callback(DEVCB_##_devcb);

enum
{
	HMCS40_INPUT_LINE_INT0 = 0,
	HMCS40_INPUT_LINE_INT1,
	HMCS40_INPUT_LINE_HLT
};


// pinout reference

/*
            _________________
    D3   1 |*                | 42 D2
    D4   2 |                 | 41 D1
    D5   3 |                 | 40 D0
    D6   4 |                 | 39 R33
    D7   5 |                 | 38 R32
    D8   6 |                 | 37 R31
    D9   7 |                 | 36 R30
    D10  8 |                 | 35 R23          .......................................
    D11  9 |                 | 34 R22         :
    D12 10 |     HD38750     | 33 R21         :
    D13 11 |     HD38800     | 32 R20         :
    D14 12 |                 | 31 INT1        :
    D15 13 |                 | 30 INT0        :                     _________________
  Vdisp 14 |                 | 29 R13         :             D4   1 |*                | 64 D3
  RESET 15 |                 | 28 R12         :             D5   2 |                 | 63 D2
    Vbb 16 |                 | 27 R11         :             D6   3 |                 | 62 D1
    Vdd 17 |                 | 26 R10         :             D7   4 |                 | 61 D0
    OSC 18 |                 | 25 R03         :             D8   5 |                 | 60 R63
   <NC> 19 |                 | 24 R02         :             D9   6 |                 | 59 R62
  /TEST 20 |                 | 23 R01         :             <NC> 7 |                 | 58 <NC>
    Vss 21 |_________________| 22 R00         :             <NC> 8 |                 | 57 <NC>
                                                            <NC> 9 |                 | 56 <NC>
                                                            D10 10 |                 | 55 R61
            D8 D7 D6 D5 D4    <NC>D3 D2 D1 D0               D11 11 |                 | 54 R60
             5  4  3  2  1     54 53 52 51 50               D12 12 |                 | 53 R33
            __________________________________              D13 13 |                 | 52 R32
           /                                  |             D14 14 |                 | 51 R31
    D9   6 |                                  | 49 R63      D15 15 |                 | 50 R30
    D10  7 |                                  | 48 R62      R40 16 |                 | 49 R23
    D11  8 |                                  | 47 R61      R41 17 |                 | 48 R22
    D12  9 |                                  | 46 R60      R42 18 |                 | 47 R21
    D13 10 |                                  | 45 R33      R43 19 |                 | 46 R20
    D14 11 |                                  | 44 R32      R50 20 |                 | 45 INT1
    D15 12 |                                  | 43 R31      R51 21 |                 | 44 INT0
    R40 13 |             HD38820              | 42 R30      R52 22 |    HD38820      | 43 R13
    R41 14 |             (FP-54 pkg)          | 41 R23      R53 23 |    (DP-64S pkg) | 42 R12
    R42 15 |                                  | 40 R22    Vdisp 24 |                 | 41 <NC>
    R43 16 |                                  | 39 R21     <NC> 25 |                 | 40 <NC>
    R50 17 |                                  | 38 R20    RESET 26 |                 | 39 <NC>
    R51 18 |                                  | 37 INT1     Vbb 27 |                 | 38 R11
    R52 19 |                                  | 36 INT0     Vdd 28 |                 | 37 R10
    R53 20 |                                  | 35 R13      OSC 29 |                 | 36 R03
  Vdisp 21 |                                  | 34 R12     <NC> 30 |                 | 35 R02
  RESET 22 |                                  | 33 R11    /TEST 31 |                 | 34 R01
           |__________________________________|             Vss 32 |_________________| 33 R00

            23 24 25 26 27     28 29 30 31 32
            Vbb | OSC | Vss    R00 | R02 | R10
               Vdd   /TEST        R01   R03
*/


class hmcs40_cpu_device : public cpu_device
{
public:
	enum
	{
		PORT_R0X = 0,
		PORT_R1X,
		PORT_R2X,
		PORT_R3X,
		PORT_R4X,
		PORT_R5X,
		PORT_R6X,
		PORT_R7X
	};

	// configuration helpers
	template <class Object> devcb_base &set_read_r0_callback(Object &&cb) { return m_read_r0.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_read_r1_callback(Object &&cb) { return m_read_r1.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_read_r2_callback(Object &&cb) { return m_read_r2.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_read_r3_callback(Object &&cb) { return m_read_r3.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_read_r4_callback(Object &&cb) { return m_read_r4.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_read_r5_callback(Object &&cb) { return m_read_r5.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_read_r6_callback(Object &&cb) { return m_read_r6.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_read_r7_callback(Object &&cb) { return m_read_r7.set_callback(std::forward<Object>(cb)); }

	template <class Object> devcb_base &set_write_r0_callback(Object &&cb) { return m_write_r0.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_write_r1_callback(Object &&cb) { return m_write_r1.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_write_r2_callback(Object &&cb) { return m_write_r2.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_write_r3_callback(Object &&cb) { return m_write_r3.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_write_r4_callback(Object &&cb) { return m_write_r4.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_write_r5_callback(Object &&cb) { return m_write_r5.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_write_r6_callback(Object &&cb) { return m_write_r6.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_write_r7_callback(Object &&cb) { return m_write_r7.set_callback(std::forward<Object>(cb)); }

	template <class Object> devcb_base &set_read_d_callback(Object &&cb) { return m_read_d.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_write_d_callback(Object &&cb) { return m_write_d.set_callback(std::forward<Object>(cb)); }

protected:
	enum
	{
		HMCS40_FAMILY_HMCS42 = 0,
		HMCS40_FAMILY_HMCS43,
		HMCS40_FAMILY_HMCS44,
		HMCS40_FAMILY_HMCS45,
		HMCS40_FAMILY_HMCS46,
		HMCS40_FAMILY_HMCS47
	};

	// construction/destruction
	hmcs40_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int family, u16 polarity, int stack_levels, int pcwidth, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data);

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

	// device_execute_interface overrides
	virtual u64 execute_clocks_to_cycles(u64 clocks) const override { return (clocks + 4 - 1) / 4; } // 4 cycles per machine cycle
	virtual u64 execute_cycles_to_clocks(u64 cycles) const override { return (cycles * 4); } // "
	virtual u32 execute_min_cycles() const override { return 1; }
	virtual u32 execute_max_cycles() const override { return 2; }
	virtual u32 execute_input_lines() const override { return 2+1; } // 3rd one is internal
	virtual void execute_set_input(int line, int state) override;
	virtual void execute_run() override;

	// device_memory_interface overrides
	virtual space_config_vector memory_space_config() const override;

	// device_disasm_interface overrides
	virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
	virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;

	// memorymaps
	void program_1k(address_map &map);
	void program_2k(address_map &map);
	void data_160x4(address_map &map);
	void data_80x4(address_map &map);

	address_space_config m_program_config;
	address_space_config m_data_config;
	address_space *m_program;
	address_space *m_data;

	int m_pcwidth;      // Program Counter bit-width
	int m_prgwidth;
	int m_datawidth;
	int m_pcmask;
	int m_prgmask;
	int m_datamask;
	int m_family;       // MCU family (42-47)
	u16 m_polarity;     // i/o polarity (pmos vs cmos)
	int m_stack_levels; // number of callstack levels
	u16 m_stack[4];     // max 4
	u16 m_op;           // current opcode
	u16 m_prev_op;
	u8 m_i;             // 4-bit immediate opcode param
	int m_eint_line;    // which input_line caused an interrupt
	emu_timer *m_timer;
	int m_halt;         // internal HLT state
	attotime m_timer_halted_remain;
	int m_icount;

	u16 m_pc;           // Program Counter
	u16 m_prev_pc;
	u8 m_page;          // LPU prepared page
	u8 m_a;             // 4-bit Accumulator
	u8 m_b;             // 4-bit B register
	u8 m_x;             // 1/3/4-bit X register
	u8 m_spx;           // 1/3/4-bit SPX register
	u8 m_y;             // 4-bit Y register
	u8 m_spy;           // 4-bit SPY register
	u8 m_s;             // Status F/F (F/F = flip-flop)
	u8 m_c;             // Carry F/F
	u8 m_tc;            // Timer/Counter
	u8 m_cf;            // CF F/F (timer mode or counter mode)
	u8 m_ie;            // I/E(Interrupt Enable) F/F
	u8 m_iri;           // external interrupt pending I/RI F/F
	u8 m_irt;           // timer interrupt pending I/RT F/F
	u8 m_if[2];         // external interrupt mask IF0,1 F/F
	u8 m_tf;            // timer interrupt mask TF F/F
	u8 m_int[2];        // INT0/1 pins state
	u8 m_r[8];          // R outputs state
	u16 m_d;            // D pins state

	// i/o handlers
	devcb_read8 m_read_r0, m_read_r1, m_read_r2, m_read_r3, m_read_r4, m_read_r5, m_read_r6, m_read_r7;
	devcb_write8 m_write_r0, m_write_r1, m_write_r2, m_write_r3, m_write_r4, m_write_r5, m_write_r6, m_write_r7;
	devcb_read16 m_read_d;
	devcb_write16 m_write_d;

	// misc internal helpers
	void increment_pc();

	u8 ram_r();
	void ram_w(u8 data);
	void pop_stack();
	void push_stack();

	virtual u8 read_r(int index);
	virtual void write_r(int index, u8 data);
	virtual int read_d(int index);
	virtual void write_d(int index, int state);

	void reset_prescaler();
	TIMER_CALLBACK_MEMBER( simple_timer_cb );
	void increment_tc();
	void do_interrupt();

	// opcode handlers
	void op_illegal();

	void op_lab();
	void op_lba();
	void op_lay();
	void op_laspx();
	void op_laspy();
	void op_xamr();

	void op_lxa();
	void op_lya();
	void op_lxi();
	void op_lyi();
	void op_iy();
	void op_dy();
	void op_ayy();
	void op_syy();
	void op_xsp();

	void op_lam();
	void op_lbm();
	void op_xma();
	void op_xmb();
	void op_lmaiy();
	void op_lmady();

	void op_lmiiy();
	void op_lai();
	void op_lbi();

	void op_ai();
	void op_ib();
	void op_db();
	void op_amc();
	void op_smc();
	void op_am();
	void op_daa();
	void op_das();
	void op_nega();
	void op_comb();
	void op_sec();
	void op_rec();
	void op_tc();
	void op_rotl();
	void op_rotr();
	void op_or();

	void op_mnei();
	void op_ynei();
	void op_anem();
	void op_bnem();
	void op_alei();
	void op_alem();
	void op_blem();

	void op_sem();
	void op_rem();
	void op_tm();

	void op_br();
	void op_cal();
	void op_lpu();
	void op_tbr();
	void op_rtn();

	void op_seie();
	void op_seif0();
	void op_seif1();
	void op_setf();
	void op_secf();
	void op_reie();
	void op_reif0();
	void op_reif1();
	void op_retf();
	void op_recf();
	void op_ti0();
	void op_ti1();
	void op_tif0();
	void op_tif1();
	void op_ttf();
	void op_lti();
	void op_lta();
	void op_lat();
	void op_rtni();

	void op_sed();
	void op_red();
	void op_td();
	void op_sedd();
	void op_redd();
	void op_lar();
	void op_lbr();
	void op_lra();
	void op_lrb();
	void op_p();
};


class hmcs43_cpu_device : public hmcs40_cpu_device
{
protected:
	hmcs43_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u16 polarity);

	// overrides
	virtual u8 read_r(int index) override;
	virtual void write_r(int index, u8 data) override;
	virtual int read_d(int index) override;
};

class hd38750_device : public hmcs43_cpu_device
{
public:
	hd38750_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};

class hd38755_device : public hmcs43_cpu_device
{
public:
	hd38755_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};

class hd44750_device : public hmcs43_cpu_device
{
public:
	hd44750_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};

class hd44758_device : public hmcs43_cpu_device
{
public:
	hd44758_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};


class hmcs44_cpu_device : public hmcs40_cpu_device
{
protected:
	hmcs44_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u16 polarity);

	// overrides
	virtual u8 read_r(int index) override;
	virtual void write_r(int index, u8 data) override;
};

class hd38800_device : public hmcs44_cpu_device
{
public:
	hd38800_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};

class hd38805_device : public hmcs44_cpu_device
{
public:
	hd38805_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};

class hd44801_device : public hmcs44_cpu_device
{
public:
	hd44801_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};

class hd44808_device : public hmcs44_cpu_device
{
public:
	hd44808_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};


class hmcs45_cpu_device : public hmcs40_cpu_device
{
protected:
	hmcs45_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u16 polarity);

	// overrides
	virtual u8 read_r(int index) override;
	virtual void write_r(int index, u8 data) override;
};

class hd38820_device : public hmcs45_cpu_device
{
public:
	hd38820_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};

class hd38825_device : public hmcs45_cpu_device
{
public:
	hd38825_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};

class hd44820_device : public hmcs45_cpu_device
{
public:
	hd44820_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};

class hd44828_device : public hmcs45_cpu_device
{
public:
	hd44828_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};



DECLARE_DEVICE_TYPE(HD38750, hd38750_device)
DECLARE_DEVICE_TYPE(HD38755, hd38755_device)
DECLARE_DEVICE_TYPE(HD44750, hd44750_device)
DECLARE_DEVICE_TYPE(HD44758, hd44758_device)

DECLARE_DEVICE_TYPE(HD38800, hd38800_device)
DECLARE_DEVICE_TYPE(HD38805, hd38805_device)
DECLARE_DEVICE_TYPE(HD44801, hd44801_device)
DECLARE_DEVICE_TYPE(HD44808, hd44808_device)

DECLARE_DEVICE_TYPE(HD38820, hd38820_device)
DECLARE_DEVICE_TYPE(HD38825, hd38825_device)
DECLARE_DEVICE_TYPE(HD44820, hd44820_device)
DECLARE_DEVICE_TYPE(HD44828, hd44828_device)

#endif // MAME_CPU_HMCS40_HMCS40_H