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
|
// license:BSD-3-Clause
// copyright-holders:Sandro Ronco
/**********************************************************************
Sanyo LC8670
**********************************************************************/
#pragma once
#ifndef __LC8670_H__
#define __LC8670_H__
//**************************************************************************
// DEFINITION
//**************************************************************************
enum
{
LC8670_PC = 1,
LC8670_SFR
};
// input ports
enum
{
LC8670_PORT1, // 8-bit I/O port
LC8670_PORT3, // 8-bit I/O port
LC8670_PORT7 // 4-bit I port
};
// external input lines
enum
{
LC8670_EXT_INT0 = 0, // P70
LC8670_EXT_INT1, // P71
LC8670_EXT_INT2, // P72
LC8670_EXT_INT3 // P73
};
// clock sources
enum
{
LC8670_SUB_CLOCK = 0,
LC8670_RC_CLOCK,
LC8670_CF_CLOCK
};
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
typedef UINT32 (*lc8670_lcd_update)(device_t &device, bitmap_ind16 &bitmap, const rectangle &cliprect, UINT8* vram, bool lcd_enabled, UINT8 stad);
#define LC8670_LCD_UPDATE(name) UINT32 name(device_t &device, bitmap_ind16 &bitmap, const rectangle &cliprect, UINT8* vram, bool lcd_enabled, UINT8 stad)
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
#define MCFG_LC8670_SET_CLOCK_SOURCES(_sub_clock, _rc_clock, _cf_clock) \
lc8670_cpu_device::static_set_cpu_clock(*device, LC8670_SUB_CLOCK, _sub_clock); \
lc8670_cpu_device::static_set_cpu_clock(*device, LC8670_RC_CLOCK, _rc_clock); \
lc8670_cpu_device::static_set_cpu_clock(*device, LC8670_CF_CLOCK, _cf_clock);
#define MCFG_LC8670_BANKSWITCH_CB(_devcb) \
devcb = &lc8670_cpu_device::static_set_bankswitch_cb(*device, DEVCB_##_devcb);
#define MCFG_LC8670_LCD_UPDATE_CB(_cb) \
lc8670_cpu_device::static_set_lcd_update_cb(*device, _cb);
// ======================> lc8670_cpu_device
class lc8670_cpu_device : public cpu_device
{
public:
// construction/destruction
lc8670_cpu_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock);
// public interfaces
UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
// internal map handlers
DECLARE_READ8_MEMBER(regs_r);
DECLARE_WRITE8_MEMBER(regs_w);
DECLARE_READ8_MEMBER(mram_r);
DECLARE_WRITE8_MEMBER(mram_w);
DECLARE_READ8_MEMBER(xram_r);
DECLARE_WRITE8_MEMBER(xram_w);
// static configuration helpers
static void static_set_cpu_clock(device_t &device, int _source, UINT32 _clock) { downcast<lc8670_cpu_device &>(device).m_clocks[_source] = _clock; }
static void static_set_lcd_update_cb(device_t &device, lc8670_lcd_update _cb) { downcast<lc8670_cpu_device &>(device).m_lcd_update_func = _cb; }
template<class _Object> static devcb_base & static_set_bankswitch_cb(device_t &device, _Object object) { return downcast<lc8670_cpu_device &>(device).m_bankswitch_func.set_callback(object); }
protected:
// device-level overrides
virtual void device_start();
virtual void device_reset();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
// device_execute_interface overrides
virtual UINT32 execute_min_cycles() const { return 1; }
virtual UINT32 execute_max_cycles() const { return 7; }
virtual UINT32 execute_input_lines() const { return 4; }
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);
void state_string_export(const device_state_entry &entry, std::string &str);
// device_memory_interface overrides
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const;
// device_disasm_interface overrides
virtual UINT32 disasm_min_opcode_bytes() const { return 1; }
virtual UINT32 disasm_max_opcode_bytes() const { return 4; }
virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
private:
// helpers
inline UINT8 fetch();
inline void push(UINT8 data);
inline UINT8 pop();
inline UINT8 read_data(UINT16 offset);
inline void write_data(UINT16 offset, UINT8 data);
inline UINT8 read_data_latch(UINT16 offset);
inline void write_data_latch(UINT16 offset, UINT8 data);
inline void update_port1(UINT8 data);
inline void set_pc(UINT16 new_pc);
inline UINT8 get_data();
inline UINT16 get_addr();
inline void change_clock_source();
inline void check_p_flag();
inline void check_p3int();
inline void set_irq_flag(int source);
int decode_op(UINT8 op);
void check_irqs();
void timer0_prescaler_tick();
void timer0_tick(bool ext_line = false);
void timer1_tick();
void base_timer_tick();
void dasm_arg(UINT8 op, char *buffer, offs_t pc, int arg, const UINT8 *oprom, int &pos);
// opcodes handlers
int op_nop();
int op_br();
int op_ld();
int op_call();
int op_callr();
int op_brf();
int op_st();
int op_callf();
int op_jmpf();
int op_mov();
int op_jmp();
int op_mul();
int op_be();
int op_be_ri();
int op_div();
int op_bne();
int op_bne_ri();
int op_ldf();
int op_stf();
int op_dbnz();
int op_bpc();
int op_push();
int op_inc();
int op_bp();
int op_pop();
int op_dec();
int op_bz();
int op_add();
int op_bn();
int op_bnz();
int op_addc();
int op_ret();
int op_sub();
int op_not1();
int op_reti();
int op_subc();
int op_ror();
int op_ldc();
int op_xch();
int op_clr1();
int op_rorc();
int op_or();
int op_rol();
int op_and();
int op_set1();
int op_rolc();
int op_xor();
private:
address_space_config m_program_config;
address_space_config m_data_config;
address_space_config m_io_config;
address_space * m_program; // program space (ROM or flash)
address_space * m_data; // internal RAM/register
address_space * m_io; // I/O ports
direct_read_data * m_direct;
// timers
static const device_timer_id BASE_TIMER = 1;
static const device_timer_id CLOCK_TIMER = 2;
emu_timer * m_basetimer;
emu_timer * m_clocktimer;
// internal state
int m_icount;
UINT16 m_pc;
UINT16 m_ppc;
UINT8 m_op;
UINT8 m_sfr[0x80]; // special function registers
UINT8 m_mram[0x200]; // main RAM
UINT8 m_xram[0xc6]; // XRAM
UINT8 m_vtrbf[0x200]; // work RAM
UINT16 m_irq_flag;
UINT8 m_irq_lev;
bool m_after_reti;
UINT8 m_p1_data;
UINT8 m_timer0_prescaler;
UINT8 m_timer0[2];
UINT8 m_timer1[2];
UINT8 m_timer1_comparator[2];
UINT8 m_base_timer[2];
bool m_clock_changed;
int m_input_lines[4];
// configuration
UINT32 m_clocks[3]; // clock sources
devcb_write8 m_bankswitch_func; // bankswitch CB
lc8670_lcd_update m_lcd_update_func; // LCD update CB
// interrupts vectors
static const UINT16 s_irq_vectors[16];
// opcodes table
typedef int (lc8670_cpu_device::*op_handler)();
static const op_handler s_opcode_table[80];
// disassembler
enum
{
OP_NULL,
OP_R8,
OP_R8RI,
OP_R16,
OP_RI,
OP_A12,
OP_A16,
OP_I8,
OP_B3,
OP_D9,
OP_D9B3,
OP_RII8
};
// disasm table
struct dasm_entry
{
const char *str;
UINT8 arg1;
UINT8 arg2;
bool inv;
};
static const dasm_entry s_dasm_table[80];
};
extern const device_type LC8670;
#endif /* __LC8670_H__ */
|