1 // license:BSD-3-Clause
2 // copyright-holders:Steve Ellenoff, Manuel Abadia, Couriersud
3 /*****************************************************************************
4 *
5 * i8051.c
6 * Portable MCS-51 Family Emulator
7 *
8 * Chips in the family:
9 * 8051 Product Line (8031,8051,8751)
10 * 8052 Product Line (8032,8052,8752)
11 * 8054 Product Line (8054)
12 * 8058 Product Line (8058)
13 * 80552 Product Line (80552, 83552, 87552)
14 * 80562 Product Line (80562, 83562, 87562)
15 *
16 * Copyright Steve Ellenoff, all rights reserved.
17 *
18 * This work is based on:
19 * #1) 'Intel(tm) MC51 Microcontroller Family Users Manual' and
20 * #2) 8051 simulator by Travis Marlatte
21 * #3) Portable UPI-41/8041/8741/8042/8742 emulator V0.1 by Juergen Buchmueller (MAME CORE)
22 *
23 *****************************************************************************/
24
25 /*****************************************************************************
26 * DS5002FP emulator by Manuel Abadia
27 *
28 * October 2008, couriersud: Merged back in mcs51
29 *
30 * What has been added?
31 * - Extra SFRs
32 * - Bytewide Bus Support
33 * - Memory Partition and Memory Range
34 * - Bootstrap Configuration
35 * - Power Fail Interrupt
36 * - Timed Access
37 * - Stop Mode
38 * - Idle Mode
39 *
40 * What is not implemented?
41 * - Peripherals and Reprogrammable Peripheral Controller
42 * - CRC-16
43 * - Watchdog timer
44 *
45 * The main features of the DS5002FP are:
46 * - 100% code-compatible with 8051
47 * - Directly addresses 64kB program/64kB data memory
48 * - Nonvolatile memory control circuitry
49 * - 10-year data retention in the absence of power
50 * - In-system reprogramming via serial port
51 * - Dedicated memory bus, preserving four 8-bit ports for general purpose I/O
52 * - Power-fail reset
53 * - Early warning power-fail interrupt
54 * - Watchdog timer
55 * - Accesses up to 128kB on the bytewide bus
56 * - Decodes memory for 32kB x 8 or 128kB x 8 SRAMs
57 * - Four additional decoded peripheral-chip enables
58 * - CRC hardware for checking memory validity
59 * - Optionally emulates an 8042-style slave interface
60 * - Memory encryption using an 80-bit encryption key
61 * - Automatic random generation of encryption keys
62 * - Self-destruct input for tamper protection
63 * - Optional top-coating prevents microprobe
64 *
65 *****************************************************************************/
66
67 /******************************************************************************
68 * Notes:
69 *
70 * The term cycles is used here to really refer to clock oscilations, because 1 machine cycle
71 * actually takes 12 oscilations.
72 *
73 * Read/Write/Modify Instruction -
74 * Data is read from the Port Latch (not the Port Pin!), possibly modified, and
75 * written back to (the pin? and) the latch!
76 *
77 * The following all perform this on a port address..
78 * (anl, orl, xrl, jbc, cpl, inc, dec, djnz, mov px.y,c, clr px.y, setb px.y)
79 *
80 * Serial UART emulation is not really accurate, but faked enough to work as far as i can tell
81 *
82 * August 27,2003: Currently support for only 8031/8051/8751 chips (ie 128 RAM)
83 * October 14,2003: Added initial support for the 8752 (ie 256 RAM)
84 * October 22,2003: Full support for the 8752 (ie 256 RAM)
85 * July 28,2004: Fixed MOVX command and added External Ram Paging Support
86 * July 31,2004: Added Serial Mode 0 Support & Fixed Interrupt Flags for Serial Port
87 *
88 * October, 2008, Couriersud - Major rewrite
89 *
90 *****************************************************************************/
91
92 /* TODO: Various
93 * - EA pin - defined by architecture, must implement:
94 * 1 means external access, bypassing internal ROM
95 * - T0 output clock ?
96 *
97 * - Implement 80C52 extended serial capabilities
98 * - Fix serial communication - This is a big hack (but working) right now.
99 * - Implement 83C751 in sslam.c
100 * - Fix cardline.c
101 * most likely due to different behaviour of I/O pins. The boards
102 * actually use 80CXX, i.e. CMOS versions.
103 * "Normal" 805X will return a 0 if reading from a output port which has
104 * a 0 written to it's latch. At least cardline expects a 1 here.
105 * - ADC support for 80552/80562 (controls analog inputs for Arctic Thunder)
106 *
107 * Done: (Couriersud)
108 * - Merged DS5002FP
109 * - Disassembler now uses type specific memory names
110 * - Merged DS5002FP disasm
111 * - added 83C751 memory names to disassembler
112 * - Pointer-ified
113 * - Implemented cmos features
114 * - Implemented 80C52 interrupt handling
115 * - Fix segas18.c (segaic16.c) memory handling.
116 * - Fix sslam.c
117 * - Fix limenko.c videopkr.c : Issue with core allocation of ram (duplicate savestate)
118 * - Handle internal ram better (debugger visible)
119 * - Fixed port reading
120 * - Rewrote Macros for better readability
121 * - Fixed and rewrote Interrupt handling
122 * - Now returns INTERNAL_DIVIDER, adjusted cycle counts
123 * - Remove unnecessary and duplicated code
124 * - Remove unnecessary functions
125 * - Rewrite to have sfr-registers stored in int_ram.
126 * - Debugger may now watch sfr-registers as well.
127 * - implemented interrupt callbacks (HOLD_LINE now supported)
128 * - Runtime switch for processor type - remove ifdefs
129 * - internal memory maps for internal rom versions (internal ram now displayed in debugger)
130 * - more timer cleanups from manual
131 */
132
133 #include "emu.h"
134 #include "debugger.h"
135 #include "mcs51.h"
136 #include "mcs51dasm.h"
137
138 #define VERBOSE 0
139
140 #define LOG(x) do { if (VERBOSE) logerror x; } while (0)
141
142 /***************************************************************************
143 CONSTANTS
144 ***************************************************************************/
145
146 enum
147 {
148 FEATURE_NONE = 0x00,
149 FEATURE_I8052 = 0x01,
150 FEATURE_CMOS = 0x02,
151 FEATURE_I80C52 = 0x04,
152 FEATURE_DS5002FP = 0x08
153 };
154
155 /* Internal address in SFR of registers */
156 enum
157 {
158 ADDR_PSW = 0xd0,
159 ADDR_ACC = 0xe0,
160 ADDR_B = 0xf0,
161
162 ADDR_P0 = 0x80,
163 ADDR_SP = 0x81,
164 ADDR_DPL = 0x82,
165 ADDR_DPH = 0x83,
166 ADDR_PCON = 0x87,
167 ADDR_TCON = 0x88,
168 ADDR_TMOD = 0x89,
169 ADDR_TL0 = 0x8a,
170 ADDR_TL1 = 0x8b,
171 ADDR_TH0 = 0x8c,
172 ADDR_TH1 = 0x8d,
173 ADDR_P1 = 0x90,
174 ADDR_SCON = 0x98,
175 ADDR_SBUF = 0x99,
176 ADDR_P2 = 0xa0,
177 ADDR_IE = 0xa8,
178 ADDR_P3 = 0xb0,
179 ADDR_IP = 0xb8,
180
181 /* 8052 Only registers */
182 ADDR_T2CON = 0xc8,
183 ADDR_RCAP2L = 0xca,
184 ADDR_RCAP2H = 0xcb,
185 ADDR_TL2 = 0xcc,
186 ADDR_TH2 = 0xcd,
187
188 /* 80C52 Only registers */
189 ADDR_IPH = 0xb7,
190 ADDR_SADDR = 0xa9,
191 ADDR_SADEN = 0xb9,
192
193 /* Philips 80C52 */
194 ADDR_AUXR = 0x8e,
195 ADDR_AUXR1 = 0xa2,
196
197 /* DS5002FP */
198 ADDR_CRCR = 0xc1,
199 ADDR_CRCL = 0xc2,
200 ADDR_CRCH = 0xc3,
201 ADDR_MCON = 0xc6,
202 ADDR_TA = 0xc7,
203 ADDR_RNR = 0xcf,
204 ADDR_RPCTL = 0xd8,
205 ADDR_RPS = 0xda
206
207 };
208
209 /* PC vectors */
210
211 enum
212 {
213 V_RESET = 0x000, /* power on address */
214 V_IE0 = 0x003, /* External Interrupt 0 */
215 V_TF0 = 0x00b, /* Timer 0 Overflow */
216 V_IE1 = 0x013, /* External Interrupt 1 */
217 V_TF1 = 0x01b, /* Timer 1 Overflow */
218 V_RITI = 0x023, /* Serial Receive/Transmit */
219
220 /* 8052 Only Vectors */
221 V_TF2 = 0x02b, /* Timer 2 Overflow */
222
223 /* DS5002FP */
224 V_PFI = 0x02b /* Power Failure Interrupt */
225 };
226
227
228 DEFINE_DEVICE_TYPE(I8031, i8031_device, "i8031", "Intel 8031")
229 DEFINE_DEVICE_TYPE(I8032, i8032_device, "i8032", "Intel 8032")
230 DEFINE_DEVICE_TYPE(I8051, i8051_device, "i8051", "Intel 8051")
231 DEFINE_DEVICE_TYPE(I8751, i8751_device, "i8751", "Intel 8751")
232 DEFINE_DEVICE_TYPE(AM8753, am8753_device, "am8753", "AMD Am8753")
233 DEFINE_DEVICE_TYPE(I8052, i8052_device, "i8052", "Intel 8052")
234 DEFINE_DEVICE_TYPE(I8752, i8752_device, "i8752", "Intel 8752")
235 DEFINE_DEVICE_TYPE(I80C31, i80c31_device, "i80c31", "Intel 80C31")
236 DEFINE_DEVICE_TYPE(I80C51, i80c51_device, "i80c51", "Intel 80C51")
237 DEFINE_DEVICE_TYPE(I87C51, i87c51_device, "i87c51", "Intel 87C51")
238 DEFINE_DEVICE_TYPE(I80C32, i80c32_device, "i80c32", "Intel 80C32")
239 DEFINE_DEVICE_TYPE(I80C52, i80c52_device, "i80c52", "Intel 80C52")
240 DEFINE_DEVICE_TYPE(I87C52, i87c52_device, "i87c52", "Intel 87C52")
241 DEFINE_DEVICE_TYPE(I87C51FA, i87c51fa_device, "i87c51fa", "Intel 87C51FA")
242 DEFINE_DEVICE_TYPE(I80C51GB, i80c51gb_device, "i80c51gb", "Intel 80C51GB")
243 DEFINE_DEVICE_TYPE(AT89C52, at89c52_device, "at89c52", "Atmel AT89C52")
244 DEFINE_DEVICE_TYPE(AT89S52, at89s52_device, "at89s52", "Atmel AT89S52")
245 DEFINE_DEVICE_TYPE(AT89C4051, at89c4051_device, "at89c4051", "Atmel AT89C4051")
246 DEFINE_DEVICE_TYPE(DS80C320, ds80c320_device, "ds80c320", "Dallas DS80C320 HSM")
247 DEFINE_DEVICE_TYPE(SAB80C535, sab80c535_device, "sab80c535", "Siemens SAB80C535")
248 DEFINE_DEVICE_TYPE(I8344, i8344_device, "i8344", "Intel 8344AH RUPI-44")
249 DEFINE_DEVICE_TYPE(DS5002FP, ds5002fp_device, "ds5002fp", "Dallas DS5002FP")
250
251
252 /***************************************************************************
253 ADDRESS MAPS
254 ***************************************************************************/
255
program_internal(address_map & map)256 void mcs51_cpu_device::program_internal(address_map &map)
257 {
258 if (m_rom_size > 0)
259 map(0, m_rom_size - 1).rom().region(DEVICE_SELF, 0);
260 }
261
data_internal(address_map & map)262 void mcs51_cpu_device::data_internal(address_map &map)
263 {
264 map(0x0000, m_ram_mask).ram().share("scratchpad");
265 map(0x0100, 0x01ff).ram().share("sfr_ram"); /* SFR */
266 }
267
268
269
mcs51_cpu_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock,int program_width,int data_width,uint8_t features)270 mcs51_cpu_device::mcs51_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int program_width, int data_width, uint8_t features)
271 : cpu_device(mconfig, type, tag, owner, clock)
272 , m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(FUNC(mcs51_cpu_device::program_internal), this))
273 , m_data_config("data", ENDIANNESS_LITTLE, 8, 9, 0, address_map_constructor(FUNC(mcs51_cpu_device::data_internal), this))
274 , m_io_config("io", ENDIANNESS_LITTLE, 8, (features & FEATURE_DS5002FP) ? 17 : 16, 0)
275 , m_pc(0)
276 , m_features(features)
277 , m_rom_size(program_width > 0 ? 1 << program_width : 0)
278 , m_ram_mask( (data_width == 8) ? 0xFF : 0x7F )
279 , m_num_interrupts(5)
280 , m_sfr_ram(*this, "sfr_ram")
281 , m_scratchpad(*this, "scratchpad")
282 , m_port_in_cb(*this)
283 , m_port_out_cb(*this)
284 , m_serial_tx_cb(*this)
285 , m_serial_rx_cb(*this)
286 , m_rtemp(0)
287 {
288 m_ds5002fp.mcon = 0;
289 m_ds5002fp.rpctl = 0;
290 m_ds5002fp.crc = 0;
291
292 /* default to standard cmos interfacing */
293
294 for (auto & elem : m_forced_inputs)
295 elem = 0;
296 }
297
298
i8031_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)299 i8031_device::i8031_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
300 : mcs51_cpu_device(mconfig, I8031, tag, owner, clock, 0, 7)
301 {
302 }
303
i8051_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)304 i8051_device::i8051_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
305 : mcs51_cpu_device(mconfig, I8051, tag, owner, clock, 12, 7)
306 {
307 }
308
i8751_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)309 i8751_device::i8751_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
310 : mcs51_cpu_device(mconfig, I8751, tag, owner, clock, 12, 7)
311 {
312 }
313
am8753_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)314 am8753_device::am8753_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
315 : mcs51_cpu_device(mconfig, AM8753, tag, owner, clock, 13, 7)
316 {
317 }
318
i8052_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock,int program_width,int data_width,uint8_t features)319 i8052_device::i8052_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int program_width, int data_width, uint8_t features)
320 : mcs51_cpu_device(mconfig, type, tag, owner, clock, program_width, data_width, features | FEATURE_I8052)
321 {
322 m_num_interrupts = 6;
323 }
324
i8052_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)325 i8052_device::i8052_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
326 : i8052_device(mconfig, I8052, tag, owner, clock, 13, 8)
327 {
328 }
329
i8032_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)330 i8032_device::i8032_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
331 : i8052_device(mconfig, I8032, tag, owner, clock, 0, 8)
332 {
333 }
334
i8752_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)335 i8752_device::i8752_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
336 : i8052_device(mconfig, I8752, tag, owner, clock, 13, 8)
337 {
338 }
339
i80c31_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)340 i80c31_device::i80c31_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
341 : i8052_device(mconfig, I80C31, tag, owner, clock, 0, 7)
342 {
343 }
344
i80c51_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock,int program_width,int data_width,uint8_t features)345 i80c51_device::i80c51_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int program_width, int data_width, uint8_t features)
346 : mcs51_cpu_device(mconfig, type, tag, owner, clock, program_width, data_width, features | FEATURE_CMOS)
347 {
348 }
349
i80c51_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)350 i80c51_device::i80c51_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
351 : i80c51_device(mconfig, I80C51, tag, owner, clock, 12, 7)
352 {
353 }
354
i87c51_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)355 i87c51_device::i87c51_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
356 : i80c51_device(mconfig, I87C51, tag, owner, clock, 12, 7)
357 {
358 }
359
360
i80c52_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock,int program_width,int data_width,uint8_t features)361 i80c52_device::i80c52_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int program_width, int data_width, uint8_t features)
362 : i8052_device(mconfig, type, tag, owner, clock, program_width, data_width, features | FEATURE_I80C52 | FEATURE_CMOS)
363 {
364 }
365
i80c52_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)366 i80c52_device::i80c52_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
367 : i80c52_device(mconfig, I80C52, tag, owner, clock, 13, 8)
368 {
369 }
370
i80c32_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)371 i80c32_device::i80c32_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
372 : i80c52_device(mconfig, I80C32, tag, owner, clock, 0, 8)
373 {
374 }
375
376
i87c52_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)377 i87c52_device::i87c52_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
378 : i80c52_device(mconfig, I87C52, tag, owner, clock, 13, 8)
379 {
380 }
381
i87c51fa_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock,int program_width,int data_width,uint8_t features)382 i87c51fa_device::i87c51fa_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int program_width, int data_width, uint8_t features)
383 : i80c52_device(mconfig, type, tag, owner, clock, program_width, data_width, features)
384 {
385 }
386
i87c51fa_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)387 i87c51fa_device::i87c51fa_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
388 : i87c51fa_device(mconfig, I87C51FA, tag, owner, clock, 13, 8)
389 {
390 }
391
i80c51gb_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)392 i80c51gb_device::i80c51gb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
393 : i87c51fa_device(mconfig, I80C51GB, tag, owner, clock, 0, 8)
394 {
395 }
396
at89c52_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)397 at89c52_device::at89c52_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
398 : i80c52_device(mconfig, AT89C52, tag, owner, clock, 13, 8)
399 {
400 }
401
at89s52_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)402 at89s52_device::at89s52_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
403 : i80c52_device(mconfig, AT89S52, tag, owner, clock, 13, 8)
404 {
405 }
406
at89c4051_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)407 at89c4051_device::at89c4051_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
408 : i80c51_device(mconfig, AT89C4051, tag, owner, clock, 12, 7)
409 {
410 }
411
ds80c320_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)412 ds80c320_device::ds80c320_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
413 : i80c52_device(mconfig, DS80C320, tag, owner, clock, 0, 8)
414 {
415 }
416
sab80c535_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)417 sab80c535_device::sab80c535_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
418 : i80c51_device(mconfig, SAB80C535, tag, owner, clock, 0, 8)
419 {
420 }
421
i8344_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)422 i8344_device::i8344_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
423 : mcs51_cpu_device(mconfig, I8344, tag, owner, clock, 0, 8)
424 {
425 }
426
427 /* program width field is set to 0 because technically the SRAM isn't internal */
ds5002fp_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)428 ds5002fp_device::ds5002fp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
429 : mcs51_cpu_device(mconfig, DS5002FP, tag, owner, clock, 0, 7, FEATURE_DS5002FP | FEATURE_CMOS)
430 , device_nvram_interface(mconfig, *this)
431 , m_region(*this, "internal")
432 {
433 }
434
memory_space_config() const435 device_memory_interface::space_config_vector mcs51_cpu_device::memory_space_config() const
436 {
437 return space_config_vector {
438 std::make_pair(AS_PROGRAM, &m_program_config),
439 std::make_pair(AS_DATA, &m_data_config),
440 std::make_pair(AS_IO, &m_io_config)
441 };
442 }
443
444
445 /***************************************************************************
446 MACROS
447 ***************************************************************************/
448
449 /* Read Opcode/Opcode Arguments from Program Code */
450 #define ROP(pc) m_program.read_byte(pc)
451 #define ROP_ARG(pc) m_program.read_byte(pc)
452
453 /* Read a byte from External Code Memory (Usually Program Rom(s) Space) */
454 #define CODEMEM_R(a) (uint8_t)m_program.read_byte(a)
455
456 /* Read/Write a byte from/to External Data Memory (Usually RAM or other I/O) */
457 #define DATAMEM_R(a) (uint8_t)m_io.read_byte(a)
458 #define DATAMEM_W(a,v) m_io.write_byte(a, v)
459
460 /* Read/Write a byte from/to the Internal RAM */
461
462 #define IRAM_R(a) iram_read(a)
463 #define IRAM_W(a, d) iram_write(a, d)
464
465 /* Read/Write a byte from/to the Internal RAM indirectly */
466 /* (called from indirect addressing) */
iram_iread(offs_t a)467 uint8_t mcs51_cpu_device::iram_iread(offs_t a) { return (a <= m_ram_mask) ? m_data.read_byte(a) : 0xff; }
iram_iwrite(offs_t a,uint8_t d)468 void mcs51_cpu_device::iram_iwrite(offs_t a, uint8_t d) { if (a <= m_ram_mask) m_data.write_byte(a, d); }
469
470 #define IRAM_IR(a) iram_iread(a)
471 #define IRAM_IW(a, d) iram_iwrite(a, d)
472
473 /* Form an Address to Read/Write to External RAM indirectly */
474 /* (called from indirect addressing) */
475 #define ERAM_ADDR(a,m) external_ram_iaddr(a,m)
476
477 /* Read/Write a bit from Bit Addressable Memory */
478 #define BIT_R(a) bit_address_r(a)
479 #define BIT_W(a,v) bit_address_w(a, v)
480
481
482 /***************************************************************************
483 SHORTCUTS
484 ***************************************************************************/
485
486 #define PPC m_ppc
487 #define PC m_pc
488 #define RWM m_rwm
489
490 /* SFR Registers - These are accessed directly for speed on read */
491 /* Read accessors */
492
493 #define SFR_A(a) m_sfr_ram[(a)]
494 #define SET_SFR_A(a,v) do { SFR_A(a) = (v); } while (0)
495
496 #define ACC SFR_A(ADDR_ACC)
497 #define PSW SFR_A(ADDR_PSW)
498
499 #define P0 ((const uint8_t) SFR_A(ADDR_P0))
500 #define P1 ((const uint8_t) SFR_A(ADDR_P1))
501 #define P2 ((const uint8_t) SFR_A(ADDR_P2))
502 #define P3 ((const uint8_t) SFR_A(ADDR_P3))
503
504 #define SP SFR_A(ADDR_SP)
505 #define DPL SFR_A(ADDR_DPL)
506 #define DPH SFR_A(ADDR_DPH)
507 #define PCON SFR_A(ADDR_PCON)
508 #define TCON SFR_A(ADDR_TCON)
509 #define TMOD SFR_A(ADDR_TMOD)
510 #define TL0 SFR_A(ADDR_TL0)
511 #define TL1 SFR_A(ADDR_TL1)
512 #define TH0 SFR_A(ADDR_TH0)
513 #define TH1 SFR_A(ADDR_TH1)
514 #define SCON SFR_A(ADDR_SCON)
515 #define IE SFR_A(ADDR_IE)
516 #define IP SFR_A(ADDR_IP)
517 #define B SFR_A(ADDR_B)
518 #define SBUF SFR_A(ADDR_SBUF)
519
520 #define R_REG(r) m_scratchpad[(r) | (PSW & 0x18)]
521 #define DPTR ((DPH<<8) | DPL)
522
523 /* 8052 Only registers */
524 #define T2CON SFR_A(ADDR_T2CON)
525 #define RCAP2L SFR_A(ADDR_RCAP2L)
526 #define RCAP2H SFR_A(ADDR_RCAP2H)
527 #define TL2 SFR_A(ADDR_TL2)
528 #define TH2 SFR_A(ADDR_TH2)
529
530 /* 80C52 Only registers */
531 #define IPH SFR_A(ADDR_IPH)
532 #define SADDR SFR_A(ADDR_SADDR)
533 #define SADEN SFR_A(ADDR_SADEN)
534
535 /* Philips 80C52 */
536 /* ============= */
537 /* Reduced EMI Mode
538 * The AO bit (AUXR.0) in the AUXR register when set disables the
539 * ALE output.
540 */
541 #define AUXR SFR_A(ADDR_AUXR)
542
543 /* The dual DPTR structure (see Figure 12) is a way by which the
544 * 80C52/54/58 will specify the address of an external data memory
545 * location. There are two 16-bit DPTR registers that address the
546 * external memory, and a single bit called DPS = AUXR1/bit0 that
547 * allows the program code to switch between them.
548 */
549 #define AUXR1 SFR_A(ADDR_AUXR1)
550
551 /* DS5002FP only registers */
552 #define CRCR SFR_A(ADDR_CRCR)
553 #define CRCL SFR_A(ADDR_CRCL)
554 #define CRCH SFR_A(ADDR_CRCH)
555 #define MCON SFR_A(ADDR_MCON)
556 #define TA SFR_A(ADDR_TA)
557 #define RNR SFR_A(ADDR_RNR)
558 #define RPCTL SFR_A(ADDR_RPCTL)
559 #define RPS SFR_A(ADDR_RPS)
560
561
562 /* WRITE accessors */
563
564 /* Shortcuts */
565
566 #define SET_PSW(v) do { SFR_A(ADDR_PSW) = (v); SET_PARITY(); } while (0)
567 #define SET_ACC(v) do { SFR_A(ADDR_ACC) = (v); SET_PARITY(); } while (0)
568
569 /* These trigger actions on modification and have to be written through SFR_W */
570 #define SET_P0(v) IRAM_W(ADDR_P0, v)
571 #define SET_P1(v) IRAM_W(ADDR_P1, v)
572 #define SET_P2(v) IRAM_W(ADDR_P2, v)
573 #define SET_P3(v) IRAM_W(ADDR_P3, v)
574
575 /* Within the cpu core, do not trigger a send */
576 #define SET_SBUF(v) SET_SFR_A(ADDR_SBUF, v)
577
578 /* No actions triggered on write */
579 #define SET_REG(r, v) do { m_scratchpad[(r) | (PSW & 0x18)] = (v); } while (0)
580
581 #define SET_DPTR(n) do { DPH = ((n) >> 8) & 0xff; DPL = (n) & 0xff; } while (0)
582
583 /* Macros for Setting Flags */
584 #define SET_X(R, v) do { R = (v);} while (0)
585
586 #define SET_CY(n) SET_PSW((PSW & 0x7f) | (n<<7)) //Carry Flag
587 #define SET_AC(n) SET_PSW((PSW & 0xbf) | (n<<6)) //Aux.Carry Flag
588 #define SET_FO(n) SET_PSW((PSW & 0xdf) | (n<<5)) //User Flag
589 #define SET_RS(n) SET_PSW((PSW & 0xe7) | (n<<3)) //R Bank Select
590 #define SET_OV(n) SET_PSW((PSW & 0xfb) | (n<<2)) //Overflow Flag
591 #define SET_P(n) SET_PSW((PSW & 0xfe) | (n<<0)) //Parity Flag
592
593 #define SET_BIT(R, n, v) do { R = (R & ~(1<<(n))) | ((v) << (n));} while (0)
594 #define GET_BIT(R, n) (((R)>>(n)) & 0x01)
595
596 #define SET_EA(n) SET_BIT(IE, 7, n) //Global Interrupt Enable/Disable
597 #define SET_ES(n) SET_BIT(IE, 4, v) //Serial Interrupt Enable/Disable
598 #define SET_ET1(n) SET_BIT(IE, 3, n) //Timer 1 Interrupt Enable/Disable
599 #define SET_EX1(n) SET_BIT(IE, 2, n) //External Int 1 Interrupt Enable/Disable
600 #define SET_ET0(n) SET_BIT(IE, 1, n) //Timer 0 Interrupt Enable/Disable
601 #define SET_EX0(n) SET_BIT(IE, 0, n) //External Int 0 Interrupt Enable/Disable
602 /* 8052 Only flags */
603 #define SET_ET2(n) SET_BIT(IE, 5, n) //Timer 2 Interrupt Enable/Disable
604
605 /* 8052 Only flags */
606 #define SET_PT2(n) SET_BIT(IP, 5, n); //Set Timer 2 Priority Level
607
608 #define SET_PS0(n) SET_BIT(IP, 4, n) //Set Serial Priority Level
609 #define SET_PT1(n) SET_BIT(IP, 3, n) //Set Timer 1 Priority Level
610 #define SET_PX1(n) SET_BIT(IP, 2, n) //Set External Int 1 Priority Level
611 #define SET_PT0(n) SET_BIT(IP, 1, n) //Set Timer 0 Priority Level
612 #define SET_PX0(n) SET_BIT(IP, 0, n) //Set External Int 0 Priority Level
613
614 #define SET_TF1(n) SET_BIT(TCON, 7, n) //Indicated Timer 1 Overflow Int Triggered
615 #define SET_TR1(n) SET_BIT(TCON, 6, n) //IndicateS Timer 1 is running
616 #define SET_TF0(n) SET_BIT(TCON, 5, n) //Indicated Timer 0 Overflow Int Triggered
617 #define SET_TR0(n) SET_BIT(TCON, 4, n) //IndicateS Timer 0 is running
618 #define SET_IE1(n) SET_BIT(TCON, 3, n) //Indicated External Int 1 Triggered
619 #define SET_IT1(n) SET_BIT(TCON, 2, n) //Indicates how External Int 1 is Triggered
620 #define SET_IE0(n) SET_BIT(TCON, 1, n) //Indicated External Int 0 Triggered
621 #define SET_IT0(n) SET_BIT(TCON, 0, n) //Indicates how External Int 0 is Triggered
622
623 #define SET_SM0(n) SET_BIT(SCON, 7, n) //Sets Serial Port Mode
624 #define SET_SM1(n) SET_BIT(SCON, 6, n) //Sets Serial Port Mode
625 #define SET_SM2(n) SET_BIT(SCON, 5, n) //Sets Serial Port Mode (Multiprocesser mode)
626 #define SET_REN(n) SET_BIT(SCON, 4, n) //Sets Serial Port Receive Enable
627 #define SET_TB8(n) SET_BIT(SCON, 3, n) //Transmit 8th Bit
628 #define SET_RB8(n) SET_BIT(SCON, 2, n) //Receive 8th Bit
629 #define SET_TI(n) SET_BIT(SCON, 1, n) //Indicates Transmit Interrupt Occurred
630 #define SET_RI(n) SET_BIT(SCON, 0, n) //Indicates Receive Interrupt Occurred
631
632 #define SET_GATE1(n) SET_BIT(TMOD, 7, n) //Timer 1 Gate Mode
633 #define SET_CT1(n) SET_BIT(TMOD, 6, n) //Timer 1 Counter Mode
634 #define SET_M1_1(n) SET_BIT(TMOD, 5, n) //Timer 1 Timer Mode Bit 1
635 #define SET_M1_0(n) SET_BIT(TMOD, 4, n) //Timer 1 Timer Mode Bit 0
636 #define SET_GATE0(n) SET_BIT(TMOD, 3, n) //Timer 0 Gate Mode
637 #define SET_CT0(n) SET_BIT(TMOD, 2, n) //Timer 0 Counter Mode
638 #define SET_M0_1(n) SET_BIT(TMOD, 1, n) //Timer 0 Timer Mode Bit 1
639 #define SET_M0_0(n) SET_BIT(TMOD, 0, n) //Timer 0 Timer Mode Bit 0
640
641
642
643 /* 8052 Only flags - T2CON Flags */
644 #define SET_TF2(n) SET_BIT(T2CON, 7, n) //Indicated Timer 2 Overflow Int Triggered
645 #define SET_EXF2(n) SET_BIT(T2CON, 6, n) //Indicates Timer 2 External Flag
646 #define SET_RCLK(n) SET_BIT(T2CON, 5, n) //Receive Clock
647 #define SET_TCLK(n) SET_BIT(T2CON, 4, n) //Transmit Clock
648 #define SET_EXEN2(n) SET_BIT(T2CON, 3, n) //Timer 2 External Interrupt Enable
649 #define SET_TR2(n) SET_BIT(T2CON, 2, n) //Indicates Timer 2 is running
650 #define SET_CT2(n) SET_BIT(T2CON, 1, n) //Sets Timer 2 Counter/Timer Mode
651 #define SET_CP(n) SET_BIT(T2CON, 0, n) //Sets Timer 2 Capture/Reload Mode
652
653 #define SET_GF1(n) SET_BIT(PCON, 3, n)
654 #define SET_GF0(n) SET_BIT(PCON, 2, n)
655 #define SET_PD(n) SET_BIT(PCON, 1, n)
656 #define SET_IDL(n) SET_BIT(PCON, 0, n)
657
658 /* Macros for accessing flags */
659
660 #define GET_CY GET_BIT(PSW, 7)
661 #define GET_AC GET_BIT(PSW, 6)
662 #define GET_FO GET_BIT(PSW, 5)
663 #define GET_RS GET_BIT(PSW, 3)
664 #define GET_OV GET_BIT(PSW, 2)
665 #define GET_P GET_BIT(PSW, 0)
666
667 #define GET_EA GET_BIT(IE, 7)
668 #define GET_ET2 GET_BIT(IE, 5)
669 #define GET_ES GET_BIT(IE, 4)
670 #define GET_ET1 GET_BIT(IE, 3)
671 #define GET_EX1 GET_BIT(IE, 2)
672 #define GET_ET0 GET_BIT(IE, 1)
673 #define GET_EX0 GET_BIT(IE, 0)
674
675 /* 8052 Only flags */
676 #define GET_PT2 GET_BIT(IP, 5)
677
678 #define GET_PS GET_BIT(IP, 4)
679 #define GET_PT1 GET_BIT(IP, 3)
680 #define GET_PX1 GET_BIT(IP, 2)
681 #define GET_PT0 GET_BIT(IP, 1)
682 #define GET_PX0 GET_BIT(IP, 0)
683
684 #define GET_TF1 GET_BIT(TCON, 7)
685 #define GET_TR1 GET_BIT(TCON, 6)
686 #define GET_TF0 GET_BIT(TCON, 5)
687 #define GET_TR0 GET_BIT(TCON, 4)
688 #define GET_IE1 GET_BIT(TCON, 3)
689 #define GET_IT1 GET_BIT(TCON, 2)
690 #define GET_IE0 GET_BIT(TCON, 1)
691 #define GET_IT0 GET_BIT(TCON, 0)
692
693 #define GET_SM0 GET_BIT(SCON, 7)
694 #define GET_SM1 GET_BIT(SCON, 6)
695 #define GET_SM2 GET_BIT(SCON, 5)
696 #define GET_REN GET_BIT(SCON, 4)
697 #define GET_TB8 GET_BIT(SCON, 3)
698 #define GET_RB8 GET_BIT(SCON, 2)
699 #define GET_TI GET_BIT(SCON, 1)
700 #define GET_RI GET_BIT(SCON, 0)
701
702 #define GET_GATE1 GET_BIT(TMOD, 7)
703 #define GET_CT1 GET_BIT(TMOD, 6)
704 #define GET_M1_1 GET_BIT(TMOD, 5)
705 #define GET_M1_0 GET_BIT(TMOD, 4)
706 #define GET_GATE0 GET_BIT(TMOD, 3)
707 #define GET_CT0 GET_BIT(TMOD, 2)
708 #define GET_M0_1 GET_BIT(TMOD, 1)
709 #define GET_M0_0 GET_BIT(TMOD, 0)
710
711 #define GET_SMOD GET_BIT(PCON, 7)
712
713 /* Only in 80C51BH & other cmos */
714
715 #define GET_GF1 GET_BIT(PCON, 3)
716 #define GET_GF0 GET_BIT(PCON, 2)
717 #define GET_PD GET_BIT(PCON, 1)
718 #define GET_IDL (GET_BIT(PCON, 0) & ~(GET_PD)) /* PD takes precedence! */
719
720 /* 8052 Only flags */
721 #define GET_TF2 GET_BIT(T2CON, 7)
722 #define GET_EXF2 GET_BIT(T2CON, 6)
723 #define GET_RCLK GET_BIT(T2CON, 5)
724 #define GET_TCLK GET_BIT(T2CON, 4)
725 #define GET_EXEN2 GET_BIT(T2CON, 3)
726 #define GET_TR2 GET_BIT(T2CON, 2)
727 #define GET_CT2 GET_BIT(T2CON, 1)
728 #define GET_CP GET_BIT(T2CON, 0)
729
730 /* DS5002FP Only flags */
731
732 /* PCON Flags - DS5002FP */
733
734 #define GET_POR GET_BIT(PCON, 6)
735 #define GET_PFW GET_BIT(PCON, 5)
736 #define GET_WTR GET_BIT(PCON, 4)
737 #define GET_EPFW GET_BIT(PCON, 3)
738 #define GET_EWT GET_BIT(PCON, 2)
739
740 #define SET_PFW(n) SET_BIT(PCON, 5, n)
741
742 /* MCON Flags - DS5002FP */
743
744 #define GET_PA ((MCON & 0xf0)>>4)
745 #define GET_RG1 GET_BIT(MCON, 3)
746 #define GET_PES GET_BIT(MCON, 2)
747 #define GET_PM GET_BIT(MCON, 1)
748 #define GET_SL GET_BIT(MCON, 0)
749
750 /* RPCTL Flags - DS5002FP */
751 #define GET_RNR GET_BIT(RPCTL, 7) /* Bit 6 ?? */
752 #define GET_EXBS GET_BIT(RPCTL, 5)
753 #define GET_AE GET_BIT(RPCTL, 4)
754 #define GET_IBI GET_BIT(RPCTL, 3)
755 #define GET_DMA GET_BIT(RPCTL, 2)
756 #define GET_RPCON GET_BIT(RPCTL, 1)
757 #define GET_RG0 GET_BIT(RPCTL, 0)
758
759
760 /*Add and Subtract Flag settings*/
761 #define DO_ADD_FLAGS(a,d,c) do_add_flags(a, d, c)
762 #define DO_SUB_FLAGS(a,d,c) do_sub_flags(a, d, c)
763
764 #define SET_PARITY() do {m_recalc_parity |= 1;} while (0)
765 #define PUSH_PC() push_pc()
766 #define POP_PC() pop_pc()
767
768 /* Clear Current IRQ */
769 #define CLEAR_CURRENT_IRQ() clear_current_irq()
770
771
772 /* Hold callback functions so they can be set by caller (before the cpu reset) */
773
774 /***************************************************************************
775 INLINE FUNCTIONS
776 ***************************************************************************/
777
clear_current_irq()778 void mcs51_cpu_device::clear_current_irq()
779 {
780 if (m_cur_irq_prio >= 0)
781 m_irq_active &= ~(1 << m_cur_irq_prio);
782 if (m_irq_active & 4)
783 m_cur_irq_prio = 2;
784 else if (m_irq_active & 2)
785 m_cur_irq_prio = 1;
786 else if (m_irq_active & 1)
787 m_cur_irq_prio = 0;
788 else
789 m_cur_irq_prio = -1;
790 LOG(("New: %d %02x\n", m_cur_irq_prio, m_irq_active));
791 }
792
r_acc()793 uint8_t mcs51_cpu_device::r_acc() { return SFR_A(ADDR_ACC); }
794
r_psw()795 uint8_t mcs51_cpu_device::r_psw() { return SFR_A(ADDR_PSW); }
796
797
798 /* Generate an external ram address for read/writing using indirect addressing mode */
799
800 /*The lowest 8 bits of the address are passed in (from the R0/R1 register), however
801 the hardware can be configured to set the rest of the address lines to any available output port pins, which
802 means the only way we can implement this is to allow the driver to setup a callback to generate the
803 address as defined by the specific hardware setup. We'll assume the address won't be bigger than 32 bits
804
805 Couriersud, October 2008:
806 There is no way external hardware can distinguish between 8bit access and 16 bit access.
807 During 16bit access the high order byte of the address is output on port 2. We therefore
808 assume that most hardware will use port 2 for 8bit access as well.
809
810 On configurations where 8 bit access in conjunction with other ports is used,
811 it is up to the driver to use mirror() to mask out the high level address and
812 provide it's own mapping.
813 */
814
815 /*
816 The DS5002FP has 2 16 bits data address buses (the byte-wide bus and the expanded bus). The exact memory position accessed depends on the
817 partition mode, the memory range and the expanded bus select. The partition mode and the expanded bus select can be changed at any time.
818
819 In order to simplify memory mapping to the data address bus, the following address map is assumed for partitioned mode:
820
821 0x00000-0x0ffff -> data memory on the expanded bus
822 0x10000-0x1ffff -> data memory on the byte-wide bus
823
824 For non-partitioned mode the following memory map is assumed:
825
826 0x0000-0xffff -> data memory (the bus used to access it does not matter)
827 */
828
external_ram_iaddr(offs_t offset,offs_t mem_mask)829 offs_t mcs51_cpu_device::external_ram_iaddr(offs_t offset, offs_t mem_mask)
830 {
831 /* Memory Range (RG1 and RG0 @ MCON and RPCTL registers) */
832 static const uint16_t ds5002fp_ranges[4] = { 0x1fff, 0x3fff, 0x7fff, 0xffff };
833 /* Memory Partition Table (RG1 & RG0 @ MCON & RPCTL registers) */
834 static const uint32_t ds5002fp_partitions[16] = {
835 0x0000, 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000,
836 0x8000, 0x9000, 0xa000, 0xb000, 0xc000, 0xd000, 0xe000, 0x10000 };
837
838 /* if partition mode is set, adjust offset based on the bus */
839 if (m_features & FEATURE_DS5002FP)
840 {
841 if (!GET_PM) {
842 if (!GET_EXBS) {
843 if ((offset >= ds5002fp_partitions[GET_PA]) && (offset <= ds5002fp_ranges[m_ds5002fp.range])) {
844 offset += 0x10000;
845 }
846 }
847 }
848 }
849 else
850 {
851 if (mem_mask == 0x00ff)
852 return (offset & mem_mask) | (P2 << 8);
853 }
854 return offset;
855 }
856
857 /* Internal ram read/write */
858
iram_read(size_t offset)859 uint8_t mcs51_cpu_device::iram_read(size_t offset)
860 {
861 return (((offset) < 0x80) ? m_data.read_byte(offset) : sfr_read(offset));
862 }
863
iram_write(size_t offset,uint8_t data)864 void mcs51_cpu_device::iram_write(size_t offset, uint8_t data)
865 {
866 if ((offset) < 0x80)
867 m_data.write_byte(offset, data);
868 else
869 sfr_write(offset, data);
870 }
871
872 /*Push the current PC to the stack*/
push_pc()873 void mcs51_cpu_device::push_pc()
874 {
875 uint8_t tmpSP = SP+1; //Grab and Increment Stack Pointer
876 IRAM_IW(tmpSP, (PC & 0xff)); //Store low byte of PC to Internal Ram (Use IRAM_IW to store stack above 128 bytes)
877 tmpSP++; // ""
878 SP = tmpSP; // ""
879 IRAM_IW(tmpSP, ( (PC & 0xff00) >> 8)); //Store hi byte of PC to next address in Internal Ram (Use IRAM_IW to store stack above 128 bytes)
880 }
881
882 /*Pop the current PC off the stack and into the pc*/
pop_pc()883 void mcs51_cpu_device::pop_pc()
884 {
885 uint8_t tmpSP = SP; //Grab Stack Pointer
886 PC = (IRAM_IR(tmpSP--) & 0xff) << 8; //Store hi byte to PC (must use IRAM_IR to access stack pointing above 128 bytes)
887 PC = PC | IRAM_IR(tmpSP--); //Store lo byte to PC (must use IRAM_IR to access stack pointing above 128 bytes)
888 SP = tmpSP; //Decrement Stack Pointer
889 }
890
891 //Set the PSW Parity Flag
set_parity()892 void mcs51_cpu_device::set_parity()
893 {
894 //This flag will be set when the accumulator contains an odd # of bits set..
895 uint8_t p = 0;
896 int i;
897 uint8_t a = ACC;
898
899 for (i=0; i<8; i++) { //Test for each of the 8 bits in the ACC!
900 p ^= (a & 1);
901 a = (a >> 1);
902 }
903
904 SET_P(p & 1);
905 }
906
bit_address_r(uint8_t offset)907 uint8_t mcs51_cpu_device::bit_address_r(uint8_t offset)
908 {
909 uint8_t word;
910 uint8_t mask;
911 int bit_pos;
912 int distance; /* distance between bit addressable words */
913 /* 1 for normal bits, 8 for sfr bit addresses */
914
915 m_last_bit = offset;
916
917 //User defined bit addresses 0x20-0x2f (values are 0x0-0x7f)
918 if (offset < 0x80) {
919 distance = 1;
920 word = ( (offset & 0x78) >> 3) * distance + 0x20;
921 bit_pos = offset & 0x7;
922 mask = (0x1 << bit_pos);
923 return((IRAM_R(word) & mask) >> bit_pos);
924 }
925 //SFR bit addressable registers
926 else {
927 distance = 8;
928 word = ( (offset & 0x78) >> 3) * distance + 0x80;
929 bit_pos = offset & 0x7;
930 mask = (0x1 << bit_pos);
931 return ((IRAM_R(word) & mask) >> bit_pos);
932 }
933 }
934
935
bit_address_w(uint8_t offset,uint8_t bit)936 void mcs51_cpu_device::bit_address_w(uint8_t offset, uint8_t bit)
937 {
938 int word;
939 uint8_t mask;
940 int bit_pos;
941 uint8_t result;
942 int distance;
943
944 /* User defined bit addresses 0x20-0x2f (values are 0x0-0x7f) */
945 if (offset < 0x80) {
946 distance = 1;
947 word = ((offset & 0x78) >> 3) * distance + 0x20;
948 bit_pos = offset & 0x7;
949 bit = (bit & 0x1) << bit_pos;
950 mask = ~(1 << bit_pos) & 0xff;
951 result = IRAM_R(word) & mask;
952 result = result | bit;
953 IRAM_W(word, result);
954 }
955 /* SFR bit addressable registers */
956 else {
957 distance = 8;
958 word = ((offset & 0x78) >> 3) * distance + 0x80;
959 bit_pos = offset & 0x7;
960 bit = (bit & 0x1) << bit_pos;
961 mask = ~(1 << bit_pos) & 0xff;
962 result = IRAM_R(word) & mask;
963 result = result | bit;
964 IRAM_W(word, result);
965 }
966 }
967
do_add_flags(uint8_t a,uint8_t data,uint8_t c)968 void mcs51_cpu_device::do_add_flags(uint8_t a, uint8_t data, uint8_t c)
969 {
970 uint16_t result = a+data+c;
971 int16_t result1 = (int8_t)a+(int8_t)data+c;
972
973 SET_CY((result & 0x100) >> 8);
974 result = (a&0x0f)+(data&0x0f)+c;
975 SET_AC((result & 0x10) >> 4);
976 SET_OV(result1 < -128 || result1 > 127);
977 }
978
do_sub_flags(uint8_t a,uint8_t data,uint8_t c)979 void mcs51_cpu_device::do_sub_flags(uint8_t a, uint8_t data, uint8_t c)
980 {
981 uint16_t result = a-(data+c);
982 int16_t result1 = (int8_t)a-(int8_t)(data+c);
983
984 SET_CY((result & 0x100) >> 8);
985 result = (a&0x0f)-((data&0x0f)+c);
986 SET_AC((result & 0x10) >> 4);
987 SET_OV((result1 < -128 || result1 > 127));
988 }
989
transmit_receive(int source)990 void mcs51_cpu_device::transmit_receive(int source)
991 {
992 int mode = (GET_SM0<<1) | GET_SM1;
993
994 if (source == 1) /* timer1 */
995 m_uart.smod_div = (m_uart.smod_div + 1) & (2-GET_SMOD);
996
997 switch(mode) {
998 //8 bit shifter ( + start,stop bit ) - baud set by clock freq / 12
999 case 0:
1000 m_uart.rx_clk += (source == 0) ? 16 : 0; /* clock / 12 */
1001 m_uart.tx_clk += (source == 0) ? 16 : 0; /* clock / 12 */
1002 break;
1003 //8 bit uart ( + start,stop bit ) - baud set by timer1 or timer2
1004 case 1:
1005 case 3:
1006 if (source == 1)
1007 {
1008 m_uart.tx_clk += (GET_TCLK ? 0 : !m_uart.smod_div);
1009 m_uart.rx_clk += (GET_RCLK ? 0 : !m_uart.smod_div);
1010 }
1011 if (source == 2)
1012 {
1013 m_uart.tx_clk += (GET_TCLK ? 1 : 0);
1014 m_uart.rx_clk += (GET_RCLK ? 1 : 0);
1015 }
1016 break;
1017 //9 bit uart
1018 case 2:
1019 m_uart.rx_clk += (source == 0) ? (GET_SMOD ? 6 : 3) : 0; /* clock / 12 * 3 / 8 (16) = clock / 32 (64)*/
1020 m_uart.tx_clk += (source == 0) ? (GET_SMOD ? 6 : 3) : 0; /* clock / 12 */
1021 break;
1022 }
1023 /* transmit ? */
1024 if (m_uart.tx_clk >= 16)
1025 {
1026 m_uart.tx_clk &= 0x0f;
1027 if(m_uart.bits_to_send)
1028 {
1029 m_uart.bits_to_send--;
1030 if(m_uart.bits_to_send == 0) {
1031 //Call the callback function
1032 m_serial_tx_cb(0, m_uart.data_out, 0xff);
1033 //Set Interrupt Flag
1034 SET_TI(1);
1035 }
1036 }
1037
1038 }
1039 /* receive */
1040 if (m_uart.rx_clk >= 16)
1041 {
1042 m_uart.rx_clk &= 0x0f;
1043 if (m_uart.delay_cycles>0)
1044 {
1045 m_uart.delay_cycles--;
1046 if (m_uart.delay_cycles == 0)
1047 {
1048 int data = 0;
1049 //Call our callball function to retrieve the data
1050 data = m_serial_rx_cb(0, 0xff);
1051 LOG(("RX Deliver %d\n", data));
1052 SET_SBUF(data);
1053 //Flag the IRQ
1054 SET_RI(1);
1055 SET_RB8(1); // HACK force 2nd stop bit
1056 }
1057 }
1058 }
1059 }
1060
1061
update_timer_t0(int cycles)1062 void mcs51_cpu_device::update_timer_t0(int cycles)
1063 {
1064 int mode = (GET_M0_1<<1) | GET_M0_0;
1065 uint32_t count;
1066
1067 if (GET_TR0)
1068 {
1069 uint32_t delta;
1070
1071 /* counter / external input */
1072 delta = GET_CT0 ? m_t0_cnt : cycles;
1073 /* taken, reset */
1074 m_t0_cnt = 0;
1075 /* TODO: Not sure about IE0. The manual specifies INT0=high,
1076 * which in turn means CLEAR_LINE.
1077 * IE0 may be edge triggered depending on IT0 */
1078 if (GET_GATE0 && !GET_IE0)
1079 delta = 0;
1080
1081 switch(mode) {
1082 case 0: /* 13 Bit Timer Mode */
1083 count = ((TH0<<5) | ( TL0 & 0x1f ) );
1084 count += delta;
1085 if ( count & 0xffffe000 ) /* Check for overflow */
1086 SET_TF0(1);
1087 TH0 = (count>>5) & 0xff;
1088 TL0 = count & 0x1f ;
1089 break;
1090 case 1: /* 16 Bit Timer Mode */
1091 count = ((TH0<<8) | TL0);
1092 count += delta;
1093 if ( count & 0xffff0000 ) /* Check for overflow */
1094 SET_TF0(1);
1095 TH0 = (count>>8) & 0xff;
1096 TL0 = count & 0xff;
1097 break;
1098 case 2: /* 8 Bit Autoreload */
1099 count = ((uint32_t) TL0) + delta;
1100 if ( count & 0xffffff00 ) /* Check for overflow */
1101 {
1102 SET_TF0(1);
1103 count += TH0; /* Reload timer */
1104 }
1105 /* Update new values of the counter */
1106 TL0 = count & 0xff;
1107 break;
1108 case 3:
1109 /* Split Timer 1 */
1110 count = ((uint32_t) TL0) + delta;
1111 if ( count & 0xffffff00 ) /* Check for overflow */
1112 SET_TF0(1);
1113 TL0 = count & 0xff; /* Update new values of the counter */
1114 break;
1115 }
1116 }
1117 if (GET_TR1)
1118 {
1119 switch(mode)
1120 {
1121 case 3:
1122 /* Split Timer 2 */
1123 count = ((uint32_t) TH0) + cycles; /* No gate control or counting !*/
1124 if ( count & 0xffffff00 ) /* Check for overflow */
1125 SET_TF1(1);
1126 TH0 = count & 0xff; /* Update new values of the counter */
1127 break;
1128 }
1129 }
1130 }
1131
1132 /* From the DS5002FP User Manual
1133 When Timer 1 is selected for operation in Mode 3, it stops counting and holds its current value. This
1134 action is the same as setting TR1 = 0. When Timer 0 is selected in Mode 3, Timer 1???s control bits are
1135 stolen as described above. As a result, Timer 1???s functions are limited in this MODE. It is forced to
1136 operate as a timer whose clock in-put is 12 tCLK and it cannot generate an interrupt on overflow. In
1137 addition, it also cannot be used with the GATE function. However, it can be started and stopped by
1138 switching it into or out of Mode 3 or it can be assigned as a baud rate generator for the serial port.
1139 */
1140
1141 /* Intel documentation:
1142 * Timer 1 may still be used in modes 0, 1, and 2, while timer 0
1143 * is in mode 3. With one important exception: No interrupts
1144 * will be generated by timer 1 while timer 0 is using the TF1
1145 * overflow flag
1146 */
1147
update_timer_t1(int cycles)1148 void mcs51_cpu_device::update_timer_t1(int cycles)
1149 {
1150 uint8_t mode = (GET_M1_1<<1) | GET_M1_0;
1151 uint8_t mode_0 = (GET_M0_1<<1) | GET_M0_0;
1152 uint32_t count;
1153
1154 if (mode_0 != 3)
1155 {
1156 if (GET_TR1)
1157 {
1158 uint32_t delta;
1159 uint32_t overflow = 0;
1160
1161 /* counter / external input */
1162 delta = GET_CT1 ? m_t1_cnt : cycles;
1163 /* taken, reset */
1164 m_t1_cnt = 0;
1165 /* TODO: Not sure about IE0. The manual specifies INT0=high,
1166 * which in turn means CLEAR_LINE. Change to access last_state?
1167 * IE0 may be edge triggered depending on IT0 */
1168 if (GET_GATE1 && !GET_IE1)
1169 delta = 0;
1170
1171 switch(mode) {
1172 case 0: /* 13 Bit Timer Mode */
1173 count = ((TH1<<5) | ( TL1 & 0x1f ) );
1174 count += delta;
1175 overflow = count & 0xffffe000; /* Check for overflow */
1176 TH1 = (count>>5) & 0xff;
1177 TL1 = count & 0x1f ;
1178 break;
1179 case 1: /* 16 Bit Timer Mode */
1180 count = ((TH1<<8) | TL1);
1181 count += delta;
1182 overflow = count & 0xffff0000; /* Check for overflow */
1183 TH1 = (count>>8) & 0xff;
1184 TL1 = count & 0xff;
1185 break;
1186 case 2: /* 8 Bit Autoreload */
1187 count = ((uint32_t) TL1) + delta;
1188 overflow = count & 0xffffff00; /* Check for overflow */
1189 if ( overflow )
1190 {
1191 count += TH1; /* Reload timer */
1192 }
1193 /* Update new values of the counter */
1194 TL1 = count & 0xff;
1195 break;
1196 case 3:
1197 /* do nothing */
1198 break;
1199 }
1200 if (overflow)
1201 {
1202 SET_TF1(1);
1203 transmit_receive(1);
1204 }
1205 }
1206 }
1207 else
1208 {
1209 uint32_t delta;
1210 uint32_t overflow = 0;
1211
1212 delta = cycles;
1213 /* taken, reset */
1214 m_t1_cnt = 0;
1215 switch(mode) {
1216 case 0: /* 13 Bit Timer Mode */
1217 count = ((TH1<<5) | ( TL1 & 0x1f ) );
1218 count += delta;
1219 overflow = count & 0xffffe000; /* Check for overflow */
1220 TH1 = (count>>5) & 0xff;
1221 TL1 = count & 0x1f ;
1222 break;
1223 case 1: /* 16 Bit Timer Mode */
1224 count = ((TH1<<8) | TL1);
1225 count += delta;
1226 overflow = count & 0xffff0000; /* Check for overflow */
1227 TH1 = (count>>8) & 0xff;
1228 TL1 = count & 0xff;
1229 break;
1230 case 2: /* 8 Bit Autoreload */
1231 count = ((uint32_t) TL1) + delta;
1232 overflow = count & 0xffffff00; /* Check for overflow */
1233 if ( overflow )
1234 {
1235 count += TH1; /* Reload timer */
1236 }
1237 /* Update new values of the counter */
1238 TL1 = count & 0xff;
1239 break;
1240 case 3:
1241 /* do nothing */
1242 break;
1243 }
1244 if (overflow)
1245 {
1246 transmit_receive(1);
1247 }
1248 }
1249 }
1250
update_timer_t2(int cycles)1251 void mcs51_cpu_device::update_timer_t2(int cycles)
1252 {
1253 /* Update Timer 2 */
1254 if(GET_TR2) {
1255 int mode = ((GET_TCLK | GET_RCLK) << 1) | GET_CP;
1256 int delta = GET_CT2 ? m_t2_cnt : (mode & 2) ? cycles * (12/2) : cycles;
1257
1258 uint32_t count = ((TH2<<8) | TL2) + delta;
1259 m_t2_cnt = 0;
1260
1261 switch (mode)
1262 {
1263 case 0: /* 16 Bit Auto Reload */
1264 if ( count & 0xffff0000 )
1265 {
1266 SET_TF2(1);
1267 count += ((RCAP2H<<8) | RCAP2L);
1268 }
1269 else if (GET_EXEN2 && m_t2ex_cnt>0)
1270 {
1271 count += ((RCAP2H<<8) | RCAP2L);
1272 m_t2ex_cnt = 0;
1273 }
1274 TH2 = (count>>8) & 0xff;
1275 TL2 = count & 0xff;
1276 break;
1277 case 1: /* 16 Bit Capture */
1278 if ( count & 0xffff0000 )
1279 SET_TF2(1);
1280 TH2 = (count>>8) & 0xff;
1281 TL2 = count & 0xff;
1282
1283 if (GET_EXEN2 && m_t2ex_cnt>0)
1284 {
1285 RCAP2H = TH2;
1286 RCAP2L = TL2;
1287 m_t2ex_cnt = 0;
1288 }
1289 break;
1290 case 2:
1291 case 3: /* Baud rate */
1292 if ( count & 0xffff0000 )
1293 {
1294 count += ((RCAP2H<<8) | RCAP2L);
1295 transmit_receive(2);
1296 }
1297 TH2 = (count>>8) & 0xff;
1298 TL2 = count & 0xff;
1299 break;
1300 }
1301 }
1302 }
1303
update_timers(int cycles)1304 void mcs51_cpu_device::update_timers(int cycles)
1305 {
1306 while (cycles--)
1307 {
1308 update_timer_t0(1);
1309 update_timer_t1(1);
1310
1311 if (m_features & FEATURE_I8052)
1312 {
1313 update_timer_t2(1);
1314 }
1315 }
1316 }
1317
1318 //Set up to transmit data out of serial port
1319 //NOTE: Enable Serial Port Interrupt bit is NOT required to send/receive data!
1320
serial_transmit(uint8_t data)1321 void mcs51_cpu_device::serial_transmit(uint8_t data)
1322 {
1323 int mode = (GET_SM0<<1) | GET_SM1;
1324
1325 //Flag that we're sending data
1326 m_uart.data_out = data;
1327 LOG(("serial_transmit: %x %x\n", mode, data));
1328 switch(mode) {
1329 //8 bit shifter ( + start,stop bit ) - baud set by clock freq / 12
1330 case 0:
1331 m_uart.bits_to_send = 8+2;
1332 break;
1333 //8 bit uart ( + start,stop bit ) - baud set by timer1 or timer2
1334 case 1:
1335 m_uart.bits_to_send = 8+2;
1336 break;
1337 //9 bit uart
1338 case 2:
1339 case 3:
1340 m_uart.bits_to_send = 8+3;
1341 break;
1342 }
1343 }
1344
serial_receive()1345 void mcs51_cpu_device::serial_receive()
1346 {
1347 int mode = (GET_SM0<<1) | GET_SM1;
1348
1349 if (GET_REN) {
1350 switch(mode) {
1351 //8 bit shifter ( + start,stop bit ) - baud set by clock freq / 12
1352 case 0:
1353 m_uart.delay_cycles = 8+2;
1354 break;
1355 //8 bit uart ( + start,stop bit ) - baud set by timer1 or timer2
1356 case 1:
1357 m_uart.delay_cycles = 8+2;
1358 break;
1359 //9 bit uart
1360 case 2:
1361 case 3:
1362 m_uart.delay_cycles = 8+3;
1363 break;
1364 }
1365 }
1366 }
1367
1368 /* Check and update status of serial port */
update_serial(int cycles)1369 void mcs51_cpu_device::update_serial(int cycles)
1370 {
1371 while (--cycles>=0)
1372 transmit_receive(0);
1373 }
1374
1375 /* Check and update status of serial port */
update_irq_prio(uint8_t ipl,uint8_t iph)1376 void mcs51_cpu_device::update_irq_prio(uint8_t ipl, uint8_t iph)
1377 {
1378 int i;
1379 for (i=0; i<8; i++)
1380 m_irq_prio[i] = ((ipl >> i) & 1) | (((iph >>i ) & 1) << 1);
1381 }
1382
1383
1384 /***************************************************************************
1385 OPCODES
1386 ***************************************************************************/
1387
1388 #define OPHANDLER( _name ) void mcs51_cpu_device::_name (uint8_t r)
1389
1390 #include "mcs51ops.hxx"
1391
1392
execute_op(uint8_t op)1393 void mcs51_cpu_device::execute_op(uint8_t op)
1394 {
1395 if (m_recalc_parity)
1396 {
1397 set_parity();
1398 m_recalc_parity = 0;
1399 }
1400
1401 m_last_op = op;
1402
1403 switch( op )
1404 {
1405 case 0x00: nop(op); break; //NOP
1406 case 0x01: ajmp(op); break; //AJMP code addr
1407 case 0x02: ljmp(op); break; //LJMP code addr
1408 case 0x03: rr_a(op); break; //RR A
1409 case 0x04: inc_a(op); break; //INC A
1410 case 0x05: RWM=1; inc_mem(op); RWM=0; break; //INC data addr
1411
1412 case 0x06:
1413 case 0x07: inc_ir(op&1); break; //INC @R0/@R1
1414
1415 case 0x08:
1416 case 0x09:
1417 case 0x0a:
1418 case 0x0b:
1419 case 0x0c:
1420 case 0x0d:
1421 case 0x0e:
1422 case 0x0f: inc_r(op&7); break; //INC R0 to R7
1423
1424 case 0x10: RWM=1; jbc(op); RWM=0; break; //JBC bit addr, code addr
1425 case 0x11: acall(op); break; //ACALL code addr
1426 case 0x12: lcall(op); break; //LCALL code addr
1427 case 0x13: rrc_a(op); break; //RRC A
1428 case 0x14: dec_a(op); break; //DEC A
1429 case 0x15: RWM=1; dec_mem(op); RWM=0; break; //DEC data addr
1430
1431 case 0x16:
1432 case 0x17: dec_ir(op&1); break; //DEC @R0/@R1
1433
1434 case 0x18:
1435 case 0x19:
1436 case 0x1a:
1437 case 0x1b:
1438 case 0x1c:
1439 case 0x1d:
1440 case 0x1e:
1441 case 0x1f: dec_r(op&7); break; //DEC R0 to R7
1442
1443 case 0x20: jb(op); break; //JB bit addr, code addr
1444 case 0x21: ajmp(op); break; //AJMP code addr
1445 case 0x22: ret(op); break; //RET
1446 case 0x23: rl_a(op); break; //RL A
1447 case 0x24: add_a_byte(op); break; //ADD A, #data
1448 case 0x25: add_a_mem(op); break; //ADD A, data addr
1449
1450 case 0x26:
1451 case 0x27: add_a_ir(op&1); break; //ADD A, @R0/@R1
1452
1453 case 0x28:
1454 case 0x29:
1455 case 0x2a:
1456 case 0x2b:
1457 case 0x2c:
1458 case 0x2d:
1459 case 0x2e:
1460 case 0x2f: add_a_r(op&7); break; //ADD A, R0 to R7
1461
1462 case 0x30: jnb(op); break; //JNB bit addr, code addr
1463 case 0x31: acall(op); break; //ACALL code addr
1464 case 0x32: reti(op); break; //RETI
1465 case 0x33: rlc_a(op); break; //RLC A
1466 case 0x34: addc_a_byte(op); break; //ADDC A, #data
1467 case 0x35: addc_a_mem(op); break; //ADDC A, data addr
1468
1469 case 0x36:
1470 case 0x37: addc_a_ir(op&1); break; //ADDC A, @R0/@R1
1471
1472 case 0x38:
1473 case 0x39:
1474 case 0x3a:
1475 case 0x3b:
1476 case 0x3c:
1477 case 0x3d:
1478 case 0x3e:
1479 case 0x3f: addc_a_r(op&7); break; //ADDC A, R0 to R7
1480
1481 case 0x40: jc(op); break; //JC code addr
1482 case 0x41: ajmp(op); break; //AJMP code addr
1483 case 0x42: RWM=1; orl_mem_a(op); RWM=0; break; //ORL data addr, A
1484 case 0x43: RWM=1; orl_mem_byte(op); RWM=0; break; //ORL data addr, #data
1485 case 0x44: orl_a_byte(op); break;
1486 case 0x45: orl_a_mem(op); break; //ORL A, data addr
1487
1488 case 0x46:
1489 case 0x47: orl_a_ir(op&1); break; //ORL A, @RO/@R1
1490
1491 case 0x48:
1492 case 0x49:
1493 case 0x4a:
1494 case 0x4b:
1495 case 0x4c:
1496 case 0x4d:
1497 case 0x4e:
1498 case 0x4f: orl_a_r(op&7); break; //ORL A, RO to R7
1499
1500 case 0x50: jnc(op); break; //JNC code addr
1501 case 0x51: acall(op); break; //ACALL code addr
1502 case 0x52: RWM=1; anl_mem_a(op); RWM=0; break; //ANL data addr, A
1503 case 0x53: RWM=1; anl_mem_byte(op); RWM=0; break; //ANL data addr, #data
1504 case 0x54: anl_a_byte(op); break; //ANL A, #data
1505 case 0x55: anl_a_mem(op); break; //ANL A, data addr
1506
1507 case 0x56:
1508 case 0x57: anl_a_ir(op&1); break; //ANL A, @RO/@R1
1509
1510 case 0x58:
1511 case 0x59:
1512 case 0x5a:
1513 case 0x5b:
1514 case 0x5c:
1515 case 0x5d:
1516 case 0x5e:
1517 case 0x5f: anl_a_r(op&7); break; //ANL A, RO to R7
1518
1519 case 0x60: jz(op); break; //JZ code addr
1520 case 0x61: ajmp(op); break; //AJMP code addr
1521 case 0x62: RWM=1; xrl_mem_a(op); RWM=0; break; //XRL data addr, A
1522 case 0x63: RWM=1; xrl_mem_byte(op); RWM=0; break; //XRL data addr, #data
1523 case 0x64: xrl_a_byte(op); break; //XRL A, #data
1524 case 0x65: xrl_a_mem(op); break; //XRL A, data addr
1525
1526 case 0x66:
1527 case 0x67: xrl_a_ir(op&1); break; //XRL A, @R0/@R1
1528
1529 case 0x68:
1530 case 0x69:
1531 case 0x6a:
1532 case 0x6b:
1533 case 0x6c:
1534 case 0x6d:
1535 case 0x6e:
1536 case 0x6f: xrl_a_r(op&7); break; //XRL A, R0 to R7
1537
1538 case 0x70: jnz(op); break; //JNZ code addr
1539 case 0x71: acall(op); break; //ACALL code addr
1540 case 0x72: orl_c_bitaddr(op); break; //ORL C, bit addr
1541 case 0x73: jmp_iadptr(op); break; //JMP @A+DPTR
1542 case 0x74: mov_a_byte(op); break; //MOV A, #data
1543 case 0x75: mov_mem_byte(op); break; //MOV data addr, #data
1544
1545 case 0x76:
1546 case 0x77: mov_ir_byte(op&1); break; //MOV @R0/@R1, #data
1547
1548 case 0x78:
1549 case 0x79:
1550 case 0x7a:
1551 case 0x7b:
1552 case 0x7c:
1553 case 0x7d:
1554 case 0x7e:
1555 case 0x7f: mov_r_byte(op&7); break; //MOV R0 to R7, #data
1556
1557 case 0x80: sjmp(op); break; //SJMP code addr
1558 case 0x81: ajmp(op); break; //AJMP code addr
1559 case 0x82: anl_c_bitaddr(op); break; //ANL C, bit addr
1560 case 0x83: movc_a_iapc(op); break; //MOVC A, @A + PC
1561 case 0x84: div_ab(op); break; //DIV AB
1562 case 0x85: mov_mem_mem(op); break; //MOV data addr, data addr
1563
1564 case 0x86:
1565 case 0x87: mov_mem_ir(op&1); break; //MOV data addr, @R0/@R1
1566
1567 case 0x88:
1568 case 0x89:
1569 case 0x8a:
1570 case 0x8b:
1571 case 0x8c:
1572 case 0x8d:
1573 case 0x8e:
1574 case 0x8f: mov_mem_r(op&7); break; //MOV data addr,R0 to R7
1575
1576 case 0x90: mov_dptr_byte(op); break; //MOV DPTR, #data
1577 case 0x91: acall(op); break; //ACALL code addr
1578 case 0x92: RWM = 1; mov_bitaddr_c(op); RWM = 0; break; //MOV bit addr, C
1579 case 0x93: movc_a_iadptr(op); break; //MOVC A, @A + DPTR
1580 case 0x94: subb_a_byte(op); break; //SUBB A, #data
1581 case 0x95: subb_a_mem(op); break; //SUBB A, data addr
1582
1583 case 0x96:
1584 case 0x97: subb_a_ir(op&1); break; //SUBB A, @R0/@R1
1585
1586 case 0x98:
1587 case 0x99:
1588 case 0x9a:
1589 case 0x9b:
1590 case 0x9c:
1591 case 0x9d:
1592 case 0x9e:
1593 case 0x9f: subb_a_r(op&7); break; //SUBB A, R0 to R7
1594
1595 case 0xa0: orl_c_nbitaddr(op); break; //ORL C, /bit addr
1596 case 0xa1: ajmp(op); break; //AJMP code addr
1597 case 0xa2: mov_c_bitaddr(op); break; //MOV C, bit addr
1598 case 0xa3: inc_dptr(op); break; //INC DPTR
1599 case 0xa4: mul_ab(op); break; //MUL AB
1600 case 0xa5: illegal(op); break; //reserved
1601
1602 case 0xa6:
1603 case 0xa7: mov_ir_mem(op&1); break; //MOV @R0/@R1, data addr
1604
1605 case 0xa8:
1606 case 0xa9:
1607 case 0xaa:
1608 case 0xab:
1609 case 0xac:
1610 case 0xad:
1611 case 0xae:
1612 case 0xaf: mov_r_mem(op&7); break; //MOV R0 to R7, data addr
1613
1614 case 0xb0: anl_c_nbitaddr(op); break; //ANL C,/bit addr
1615 case 0xb1: acall(op); break; //ACALL code addr
1616 case 0xb2: RWM=1; cpl_bitaddr(op); RWM=0; break; //CPL bit addr
1617 case 0xb3: cpl_c(op); break; //CPL C
1618 case 0xb4: cjne_a_byte(op); break; //CJNE A, #data, code addr
1619 case 0xb5: cjne_a_mem(op); break; //CJNE A, data addr, code addr
1620
1621 case 0xb6:
1622 case 0xb7: cjne_ir_byte(op&1); break; //CJNE @R0/@R1, #data, code addr
1623
1624 case 0xb8:
1625 case 0xb9:
1626 case 0xba:
1627 case 0xbb:
1628 case 0xbc:
1629 case 0xbd:
1630 case 0xbe:
1631 case 0xbf: cjne_r_byte(op&7); break; //CJNE R0 to R7, #data, code addr
1632
1633 case 0xc0: push(op); break; //PUSH data addr
1634 case 0xc1: ajmp(op); break; //AJMP code addr
1635 case 0xc2: RWM=1; clr_bitaddr(op); RWM=0; break; //CLR bit addr
1636 case 0xc3: clr_c(op); break; //CLR C
1637 case 0xc4: swap_a(op); break; //SWAP A
1638 case 0xc5: xch_a_mem(op); break; //XCH A, data addr
1639
1640 case 0xc6:
1641 case 0xc7: xch_a_ir(op&1); break; //XCH A, @RO/@R1
1642
1643 case 0xc8:
1644 case 0xc9:
1645 case 0xca:
1646 case 0xcb:
1647 case 0xcc:
1648 case 0xcd:
1649 case 0xce:
1650 case 0xcf: xch_a_r(op&7); break; //XCH A, RO to R7
1651
1652 case 0xd0: pop(op); break; //POP data addr
1653 case 0xd1: acall(op); break; //ACALL code addr
1654 case 0xd2: RWM=1; setb_bitaddr(op); RWM=0; break; //SETB bit addr
1655 case 0xd3: setb_c(op); break; //SETB C
1656 case 0xd4: da_a(op); break; //DA A
1657 case 0xd5: RWM=1; djnz_mem(op); RWM=0; break; //DJNZ data addr, code addr
1658
1659 case 0xd6:
1660 case 0xd7: xchd_a_ir(op&1); break; //XCHD A, @R0/@R1
1661
1662 case 0xd8:
1663 case 0xd9:
1664 case 0xda:
1665 case 0xdb:
1666 case 0xdc:
1667 case 0xdd:
1668 case 0xde:
1669 case 0xdf: djnz_r(op&7); break; //DJNZ R0 to R7,code addr
1670
1671 case 0xe0: movx_a_idptr(op); break; //MOVX A,@DPTR
1672 case 0xe1: ajmp(op); break; //AJMP code addr
1673
1674 case 0xe2:
1675 case 0xe3: movx_a_ir(op&1); break; //MOVX A, @R0/@R1
1676
1677 case 0xe4: clr_a(op); break; //CLR A
1678 case 0xe5: mov_a_mem(op); break; //MOV A, data addr
1679 case 0xe6:
1680 case 0xe7: mov_a_ir(op&1); break; //MOV A,@RO/@R1
1681
1682 case 0xe8:
1683 case 0xe9:
1684 case 0xea:
1685 case 0xeb:
1686 case 0xec:
1687 case 0xed:
1688 case 0xee:
1689 case 0xef: mov_a_r(op&7); break; //MOV A,R0 to R7
1690
1691 case 0xf0: movx_idptr_a(op); break; //MOVX @DPTR,A
1692 case 0xf1: acall(op); break; //ACALL code addr
1693
1694 case 0xf2:
1695 case 0xf3: movx_ir_a(op&1); break; //MOVX @R0/@R1,A
1696
1697 case 0xf4: cpl_a(op); break; //CPL A
1698 case 0xf5: mov_mem_a(op); break; //MOV data addr, A
1699
1700 case 0xf6:
1701 case 0xf7: mov_ir_a(op&1); break; //MOV @R0/@R1, A
1702
1703 case 0xf8:
1704 case 0xf9:
1705 case 0xfa:
1706 case 0xfb:
1707 case 0xfc:
1708 case 0xfd:
1709 case 0xfe:
1710 case 0xff: mov_r_a(op&7); break; //MOV R0 to R7, A
1711 default:
1712 illegal(op);
1713 }
1714 }
1715
1716 /***************************************************************************
1717 OPCODE CYCLES
1718 ***************************************************************************/
1719
1720 /* # of oscilations each opcode requires*/
1721 const uint8_t mcs51_cpu_device::mcs51_cycles[256] = {
1722 1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,
1723 2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,
1724 2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,
1725 2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,
1726 2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,
1727 2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,
1728 2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,
1729 2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,1,
1730 2,2,2,2,4,2,2,2,2,2,2,2,2,2,2,2,
1731 2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,
1732 2,2,1,2,4,1,2,2,2,2,2,2,2,2,2,2,
1733 2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,
1734 2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1735 2,2,1,1,1,2,1,1,2,2,2,2,2,2,2,2,
1736 2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,
1737 2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1
1738 };
1739
1740 /***********************************************************************************
1741 Check for pending Interrupts and process - returns # of cycles used for the int
1742
1743 Note about priority & interrupting interrupts..
1744 1) A high priority interrupt cannot be interrupted by anything!
1745 2) A low priority interrupt can ONLY be interrupted by a high priority interrupt
1746 3) If more than 1 Interrupt Flag is set (ie, 2 simultaneous requests occur),
1747 the following logic works as follows:
1748 1) If two requests come in of different priority levels, the higher one is selected..
1749 2) If the requests are of the same level, an internal order is used:
1750 a) IEO
1751 b) TFO
1752 c) IE1
1753 d) TF1
1754 e) RI+TI
1755 f) TF2+EXF2
1756 **********************************************************************************/
check_irqs()1757 void mcs51_cpu_device::check_irqs()
1758 {
1759 uint8_t ints = (GET_IE0 | (GET_TF0<<1) | (GET_IE1<<2) | (GET_TF1<<3)
1760 | ((GET_RI|GET_TI)<<4));
1761 uint8_t int_vec = 0;
1762 uint8_t int_mask;
1763 int priority_request = -1;
1764 int i;
1765
1766 //If All Inerrupts Disabled or no pending abort..
1767 int_mask = (GET_EA ? IE : 0x00);
1768
1769 if (m_features & FEATURE_I8052)
1770 ints |= ((GET_TF2|GET_EXF2)<<5);
1771
1772 if (m_features & FEATURE_DS5002FP)
1773 {
1774 ints |= ((GET_PFW)<<5);
1775 m_irq_prio[6] = 3; /* force highest priority */
1776 /* mask out interrupts not enabled */
1777 ints &= ((int_mask & 0x1f) | ((GET_EPFW)<<5));
1778 }
1779 else
1780 {
1781 /* mask out interrupts not enabled */
1782 ints &= int_mask;
1783 }
1784
1785 if (!ints) return;
1786
1787 /* CLear IDL - got enabled interrupt */
1788 if (m_features & FEATURE_CMOS)
1789 {
1790 /* any interrupt terminates idle mode */
1791 SET_IDL(0);
1792 /* external interrupt wakes up */
1793 if (ints & (GET_IE0 | GET_IE1))
1794 /* but not the DS5002FP */
1795 if (!(m_features & FEATURE_DS5002FP))
1796 SET_PD(0);
1797 }
1798
1799 for (i=0; i<m_num_interrupts; i++)
1800 {
1801 if (ints & (1<<i))
1802 {
1803 if (m_irq_prio[i] > priority_request)
1804 {
1805 priority_request = m_irq_prio[i];
1806 int_vec = (i<<3) | 3;
1807 }
1808 }
1809 }
1810
1811 /* Skip the interrupt request if currently processing interrupt
1812 * and the new request does not have a higher priority
1813 */
1814
1815 LOG(("Request: %d\n", priority_request));
1816 if (m_irq_active && (priority_request <= m_cur_irq_prio))
1817 {
1818 LOG(("higher or equal priority irq (%u) in progress already, skipping ...\n", m_cur_irq_prio));
1819 return;
1820 }
1821
1822 // Hack to work around polling latency issue with JB INT0/INT1
1823 if (m_last_op == 0x20 && ((int_vec == V_IE0 && m_last_bit == 0xb2) || (int_vec == V_IE1 && m_last_bit == 0xb3)))
1824 PC = PPC + 3;
1825
1826 //Save current pc to stack, set pc to new interrupt vector
1827 push_pc();
1828 PC = int_vec;
1829
1830 /* interrupts take 24 cycles */
1831 m_inst_cycles += 2;
1832
1833 //Set current Irq & Priority being serviced
1834 m_cur_irq_prio = priority_request;
1835 m_irq_active |= (1 << priority_request);
1836
1837 LOG(("Take: %d %02x\n", m_cur_irq_prio, m_irq_active));
1838
1839 //Clear any interrupt flags that should be cleared since we're servicing the irq!
1840 switch(int_vec) {
1841 case V_IE0:
1842 //External Int Flag only cleared when configured as Edge Triggered..
1843 if(GET_IT0) /* for some reason having this, breaks alving dmd games */
1844 SET_IE0(0);
1845
1846 /* indicate we took the external IRQ */
1847 standard_irq_callback(0);
1848
1849 break;
1850 case V_TF0:
1851 //Timer 0 - Always clear Flag
1852 SET_TF0(0);
1853 break;
1854 case V_IE1:
1855 //External Int Flag only cleared when configured as Edge Triggered..
1856 if(GET_IT1) /* for some reason having this, breaks alving dmd games */
1857 SET_IE1(0);
1858 /* indicate we took the external IRQ */
1859 standard_irq_callback(1);
1860
1861 break;
1862 case V_TF1:
1863 //Timer 1 - Always clear Flag
1864 SET_TF1(0);
1865 break;
1866 case V_RITI:
1867 /* no flags are cleared, TI and RI remain set until reset by software */
1868 break;
1869 /* I8052 specific */
1870 case V_TF2:
1871 /* no flags are cleared according to manual */
1872 break;
1873 /* DS5002FP specific */
1874 /* case V_PFI:
1875 * no flags are cleared, PFW is reset by software
1876 * This has the same vector as V_TF2.
1877 */
1878
1879 }
1880 }
1881
burn_cycles(int cycles)1882 void mcs51_cpu_device::burn_cycles(int cycles)
1883 {
1884 /* Update Timer (if any timers are running) */
1885 update_timers(cycles);
1886
1887 /* Update Serial (only for mode 0) */
1888 update_serial(cycles);
1889
1890 /* check_irqs */
1891 check_irqs();
1892 }
1893
execute_set_input(int irqline,int state)1894 void mcs51_cpu_device::execute_set_input(int irqline, int state)
1895 {
1896 /* From the manual:
1897 *
1898 * <cite>In operation all the interrupt flags are latched into the
1899 * interrupt control system during State 5 of every machine cycle.
1900 * The samples are polled during the following machine cycle.</cite>
1901 *
1902 * ==> Since we do not emulate sub-states, this assumes that the signal is present
1903 * for at least one cycle (12 states)
1904 *
1905 */
1906 uint32_t new_state = (m_last_line_state & ~(1 << irqline)) | ((state != CLEAR_LINE) << irqline);
1907 /* detect 0->1 transitions */
1908 uint32_t tr_state = (~m_last_line_state) & new_state;
1909
1910 switch( irqline )
1911 {
1912 //External Interrupt 0
1913 case MCS51_INT0_LINE:
1914 //Line Asserted?
1915 if (state != CLEAR_LINE) {
1916 //Need cleared->active line transition? (Logical 1-0 Pulse on the line) - CLEAR->ASSERT Transition since INT0 active lo!
1917 if (GET_IT0) {
1918 if (GET_BIT(tr_state, MCS51_INT0_LINE))
1919 SET_IE0(1);
1920 }
1921 else
1922 {
1923 SET_IE0(1); //Nope, just set it..
1924 }
1925 }
1926 else
1927 {
1928 if (!GET_IT0) /* clear if level triggered */
1929 SET_IE0(0);
1930 }
1931
1932 break;
1933
1934 //External Interrupt 1
1935 case MCS51_INT1_LINE:
1936 //Line Asserted?
1937 if (state != CLEAR_LINE) {
1938 //Need cleared->active line transition? (Logical 1-0 Pulse on the line) - CLEAR->ASSERT Transition since INT1 active lo!
1939 if(GET_IT1){
1940 if (GET_BIT(tr_state, MCS51_INT1_LINE))
1941 SET_IE1(1);
1942 }
1943 else
1944 SET_IE1(1); //Nope, just set it..
1945 }
1946 else
1947 {
1948 if (!GET_IT1) /* clear if level triggered */
1949 SET_IE1(0);
1950 }
1951 break;
1952
1953 case MCS51_T0_LINE:
1954 if (GET_BIT(tr_state, MCS51_T0_LINE) && GET_TR0)
1955 m_t0_cnt++;
1956 break;
1957
1958 case MCS51_T1_LINE:
1959 if (GET_BIT(tr_state, MCS51_T1_LINE) && GET_TR1)
1960 m_t1_cnt++;
1961 break;
1962
1963 case MCS51_T2_LINE:
1964 if (m_features & FEATURE_I8052)
1965 {
1966 if (GET_BIT(tr_state, MCS51_T2_LINE) && GET_TR1)
1967 m_t2_cnt++;
1968 }
1969 else
1970 fatalerror("mcs51: Trying to set T2_LINE on a non I8052 type cpu.\n");
1971 break;
1972
1973 case MCS51_T2EX_LINE:
1974 if (m_features & FEATURE_I8052)
1975 {
1976 if (GET_BIT(tr_state, MCS51_T2EX_LINE))
1977 {
1978 SET_EXF2(1);
1979 m_t2ex_cnt++;
1980 }
1981 }
1982 else
1983 fatalerror("mcs51: Trying to set T2EX_LINE on a non I8052 type cpu.\n");
1984 break;
1985
1986 case MCS51_RX_LINE: /* Serial Port Receive */
1987 /* Is the enable flags for this interrupt set? */
1988 if (state != CLEAR_LINE)
1989 {
1990 serial_receive();
1991 }
1992 break;
1993
1994 /* Power Fail Interrupt */
1995 case DS5002FP_PFI_LINE:
1996 if (m_features & FEATURE_DS5002FP)
1997 {
1998 /* Need cleared->active line transition? (Logical 1-0 Pulse on the line) - CLEAR->ASSERT Transition since INT1 active lo! */
1999 if (GET_BIT(tr_state, MCS51_INT1_LINE))
2000 SET_PFW(1);
2001 }
2002 else
2003 fatalerror("mcs51: Trying to set DS5002FP_PFI_LINE on a non DS5002FP type cpu.\n");
2004 break;
2005 }
2006 m_last_line_state = new_state;
2007 }
2008
2009 /* Execute cycles - returns number of cycles actually run */
execute_run()2010 void mcs51_cpu_device::execute_run()
2011 {
2012 uint8_t op;
2013
2014 /* external interrupts may have been set since we last checked */
2015 m_inst_cycles = 0;
2016 check_irqs();
2017
2018 /* if in powerdown, just return */
2019 if ((m_features & FEATURE_CMOS) && GET_PD)
2020 {
2021 m_icount = 0;
2022 return;
2023 }
2024
2025 m_icount -= m_inst_cycles;
2026 burn_cycles(m_inst_cycles);
2027
2028 if ((m_features & FEATURE_CMOS) && GET_IDL)
2029 {
2030 do
2031 {
2032 /* burn the cycles */
2033 m_icount--;
2034 burn_cycles(1);
2035 } while( m_icount > 0 );
2036 return;
2037 }
2038
2039 do
2040 {
2041 /* Read next opcode */
2042 PPC = PC;
2043 debugger_instruction_hook(PC);
2044 op = m_program.read_byte(PC++);
2045
2046 /* process opcode and count cycles */
2047 m_inst_cycles = mcs51_cycles[op];
2048 execute_op(op);
2049
2050 /* burn the cycles */
2051 m_icount -= m_inst_cycles;
2052
2053 /* if in powerdown, just return */
2054 if ((m_features & FEATURE_CMOS) && GET_PD)
2055 return;
2056
2057 burn_cycles(m_inst_cycles);
2058
2059 /* decrement the timed access window */
2060 if (m_features & FEATURE_DS5002FP)
2061 m_ds5002fp.ta_window = (m_ds5002fp.ta_window ? (m_ds5002fp.ta_window - 1) : 0x00);
2062
2063 /* If the chip entered in idle mode, end the loop */
2064 if ((m_features & FEATURE_CMOS) && GET_IDL)
2065 return;
2066
2067 } while( m_icount > 0 );
2068 }
2069
2070
2071 /****************************************************************************
2072 * MCS51/8051 Section
2073 ****************************************************************************/
2074
sfr_write(size_t offset,uint8_t data)2075 void mcs51_cpu_device::sfr_write(size_t offset, uint8_t data)
2076 {
2077 /* update register */
2078 assert(offset >= 0x80 && offset <= 0xff);
2079
2080 switch (offset)
2081 {
2082 case ADDR_P0: m_port_out_cb[0](data); break;
2083 case ADDR_P1: m_port_out_cb[1](data); break;
2084 case ADDR_P2: m_port_out_cb[2](data); break;
2085 case ADDR_P3: m_port_out_cb[3](data); break;
2086 case ADDR_SBUF: serial_transmit(data); break;
2087 case ADDR_PSW: SET_PARITY(); break;
2088 case ADDR_ACC: SET_PARITY(); break;
2089 case ADDR_IP: update_irq_prio(data, 0); break;
2090 /* R_SBUF = data; //This register is used only for "Receiving data coming in!" */
2091
2092 case ADDR_B:
2093 case ADDR_SP:
2094 case ADDR_DPL:
2095 case ADDR_DPH:
2096 case ADDR_PCON:
2097 case ADDR_TCON:
2098 case ADDR_TMOD:
2099 case ADDR_IE:
2100 case ADDR_TL0:
2101 case ADDR_TL1:
2102 case ADDR_TH0:
2103 case ADDR_TH1:
2104 case ADDR_SCON:
2105 break;
2106 default:
2107 LOG(("mcs51 '%s': attemping to write to an invalid/non-implemented SFR address: %x at 0x%04x, data=%x\n", tag(), (uint32_t)offset,PC,data));
2108 /* no write in this case according to manual */
2109 return;
2110 }
2111 m_data.write_byte((size_t)offset | 0x100, data);
2112 }
2113
sfr_read(size_t offset)2114 uint8_t mcs51_cpu_device::sfr_read(size_t offset)
2115 {
2116 assert(offset >= 0x80 && offset <= 0xff);
2117
2118 switch (offset)
2119 {
2120 /* Read/Write/Modify operations read the port latch ! */
2121 /* Move to memory map */
2122 case ADDR_P0: return RWM ? P0 : (P0 | m_forced_inputs[0]) & m_port_in_cb[0]();
2123 case ADDR_P1: return RWM ? P1 : (P1 | m_forced_inputs[1]) & m_port_in_cb[1]();
2124 case ADDR_P2: return RWM ? P2 : (P2 | m_forced_inputs[2]) & m_port_in_cb[2]();
2125 case ADDR_P3: return RWM ? P3 : (P3 | m_forced_inputs[3]) & m_port_in_cb[3]()
2126 & ~(GET_BIT(m_last_line_state, MCS51_INT0_LINE) ? 4 : 0)
2127 & ~(GET_BIT(m_last_line_state, MCS51_INT1_LINE) ? 8 : 0);
2128
2129 case ADDR_PSW:
2130 case ADDR_ACC:
2131 case ADDR_B:
2132 case ADDR_SP:
2133 case ADDR_DPL:
2134 case ADDR_DPH:
2135 case ADDR_PCON:
2136 case ADDR_TCON:
2137 case ADDR_TMOD:
2138 case ADDR_TL0:
2139 case ADDR_TL1:
2140 case ADDR_TH0:
2141 case ADDR_TH1:
2142 case ADDR_SCON:
2143 case ADDR_SBUF:
2144 case ADDR_IE:
2145 case ADDR_IP:
2146 return m_data.read_byte((size_t) offset | 0x100);
2147 /* Illegal or non-implemented sfr */
2148 default:
2149 LOG(("mcs51 '%s': attemping to read an invalid/non-implemented SFR address: %x at 0x%04x\n", tag(), (uint32_t)offset,PC));
2150 /* according to the manual, the read may return random bits */
2151 return 0xff;
2152 }
2153 }
2154
2155
device_start()2156 void mcs51_cpu_device::device_start()
2157 {
2158 space(AS_PROGRAM).cache(m_program);
2159 space(AS_DATA).specific(m_data);
2160 space(AS_IO).specific(m_io);
2161
2162 m_port_in_cb.resolve_all_safe(0xff);
2163 m_port_out_cb.resolve_all_safe();
2164 m_serial_rx_cb.resolve_safe(0);
2165 m_serial_tx_cb.resolve_safe();
2166
2167 /* Save states */
2168
2169 save_item(NAME(m_ppc));
2170 save_item(NAME(m_pc));
2171 save_item(NAME(m_last_op));
2172 save_item(NAME(m_last_bit));
2173 save_item(NAME(m_rwm) );
2174 save_item(NAME(m_cur_irq_prio) );
2175 save_item(NAME(m_last_line_state) );
2176 save_item(NAME(m_t0_cnt) );
2177 save_item(NAME(m_t1_cnt) );
2178 save_item(NAME(m_t2_cnt) );
2179 save_item(NAME(m_t2ex_cnt) );
2180 save_item(NAME(m_recalc_parity) );
2181 save_item(NAME(m_irq_prio) );
2182 save_item(NAME(m_irq_active) );
2183 save_item(NAME(m_ds5002fp.previous_ta) );
2184 save_item(NAME(m_ds5002fp.ta_window) );
2185 save_item(NAME(m_ds5002fp.range) );
2186 save_item(NAME(m_uart.data_out));
2187 save_item(NAME(m_uart.bits_to_send));
2188 save_item(NAME(m_uart.smod_div));
2189 save_item(NAME(m_uart.rx_clk));
2190 save_item(NAME(m_uart.tx_clk));
2191 save_item(NAME(m_uart.delay_cycles));
2192
2193 state_add( MCS51_PC, "PC", m_pc).formatstr("%04X");
2194 state_add( MCS51_SP, "SP", SP).formatstr("%02X");
2195 state_add( MCS51_PSW, "PSW", PSW).formatstr("%02X");
2196 state_add( MCS51_ACC, "A", ACC).formatstr("%02X");
2197 state_add( MCS51_B, "B", B).formatstr("%02X");
2198 state_add<uint16_t>( MCS51_DPTR, "DPTR", [this](){ return DPTR; }, [this](uint16_t dp){ SET_DPTR(dp); }).formatstr("%04X");
2199 state_add( MCS51_DPH, "DPH", DPH).noshow();
2200 state_add( MCS51_DPL, "DPL", DPL).noshow();
2201 state_add( MCS51_IE, "IE", IE).formatstr("%02X");
2202 state_add( MCS51_IP, "IP", IP).formatstr("%02X");
2203 if (m_rom_size > 0)
2204 state_add<uint8_t>( MCS51_P0, "P0", [this](){ return P0; }, [this](uint8_t p){ SET_P0(p); }).formatstr("%02X");
2205 state_add<uint8_t>( MCS51_P1, "P1", [this](){ return P1; }, [this](uint8_t p){ SET_P1(p); }).formatstr("%02X");
2206 state_add<uint8_t>( MCS51_P2, "P2", [this](){ return P2; }, [this](uint8_t p){ SET_P2(p); }).formatstr("%02X");
2207 state_add<uint8_t>( MCS51_P3, "P3", [this](){ return P3; }, [this](uint8_t p){ SET_P3(p); }).formatstr("%02X");
2208 state_add<uint8_t>( MCS51_R0, "R0", [this](){ return R_REG(0); }, [this](uint8_t r){ SET_REG(0, r); }).formatstr("%02X");
2209 state_add<uint8_t>( MCS51_R1, "R1", [this](){ return R_REG(1); }, [this](uint8_t r){ SET_REG(1, r); }).formatstr("%02X");
2210 state_add<uint8_t>( MCS51_R2, "R2", [this](){ return R_REG(2); }, [this](uint8_t r){ SET_REG(2, r); }).formatstr("%02X");
2211 state_add<uint8_t>( MCS51_R3, "R3", [this](){ return R_REG(3); }, [this](uint8_t r){ SET_REG(3, r); }).formatstr("%02X");
2212 state_add<uint8_t>( MCS51_R4, "R4", [this](){ return R_REG(4); }, [this](uint8_t r){ SET_REG(4, r); }).formatstr("%02X");
2213 state_add<uint8_t>( MCS51_R5, "R5", [this](){ return R_REG(5); }, [this](uint8_t r){ SET_REG(5, r); }).formatstr("%02X");
2214 state_add<uint8_t>( MCS51_R6, "R6", [this](){ return R_REG(6); }, [this](uint8_t r){ SET_REG(6, r); }).formatstr("%02X");
2215 state_add<uint8_t>( MCS51_R7, "R7", [this](){ return R_REG(7); }, [this](uint8_t r){ SET_REG(7, r); }).formatstr("%02X");
2216 state_add<uint8_t>( MCS51_RB, "RB", [this](){ return (PSW & 0x18)>>3; }, [this](uint8_t rb){ SET_RS(rb); }).mask(0x03).formatstr("%02X");
2217 state_add( MCS51_TCON, "TCON", TCON).formatstr("%02X");
2218 state_add( MCS51_TMOD, "TMOD", TMOD).formatstr("%02X");
2219 state_add( MCS51_TL0, "TL0", TL0).formatstr("%02X");
2220 state_add( MCS51_TH0, "TH0", TH0).formatstr("%02X");
2221 state_add( MCS51_TL1, "TL1", TL1).formatstr("%02X");
2222 state_add( MCS51_TH1, "TH1", TH1).formatstr("%02X");
2223
2224 state_add( STATE_GENPC, "GENPC", m_pc ).noshow();
2225 state_add( STATE_GENPCBASE, "CURPC", m_pc ).noshow();
2226 state_add( STATE_GENFLAGS, "GENFLAGS", m_rtemp).formatstr("%8s").noshow();
2227
2228 set_icountptr(m_icount);
2229 }
2230
state_string_export(const device_state_entry & entry,std::string & str) const2231 void mcs51_cpu_device::state_string_export(const device_state_entry &entry, std::string &str) const
2232 {
2233 switch (entry.index())
2234 {
2235 case STATE_GENFLAGS:
2236 str = string_format("%c%c%c%c%c%c%c%c",
2237 PSW & 0x80 ? 'C':'.',
2238 PSW & 0x40 ? 'A':'.',
2239 PSW & 0x20 ? 'F':'.',
2240 PSW & 0x10 ? '0':'.',
2241 PSW & 0x08 ? '1':'.',
2242 PSW & 0x04 ? 'V':'.',
2243 PSW & 0x02 ? '?':'.',
2244 PSW & 0x01 ? 'P':'.');
2245 break;
2246 }
2247 }
2248
2249 /* Reset registers to the initial values */
device_reset()2250 void mcs51_cpu_device::device_reset()
2251 {
2252 m_last_line_state = 0;
2253 m_t0_cnt = 0;
2254 m_t1_cnt = 0;
2255 m_t2_cnt = 0;
2256 m_t2ex_cnt = 0;
2257 /* Flag as NO IRQ in Progress */
2258 m_irq_active = 0;
2259 m_cur_irq_prio = -1;
2260 m_last_op = 0;
2261 m_last_bit = 0;
2262
2263 /* these are all defined reset states */
2264 PC = 0;
2265 SP = 0x7;
2266 SET_PSW(0);
2267 SET_ACC(0);
2268 DPH = 0;
2269 DPL = 0;
2270 B = 0;
2271 IP = 0;
2272 update_irq_prio(IP, 0);
2273 IE = 0;
2274 SCON = 0;
2275 TCON = 0;
2276 TMOD = 0;
2277 PCON = 0;
2278 TH1 = 0;
2279 TH0 = 0;
2280 TL1 = 0;
2281 TL0 = 0;
2282 /* set the port configurations to all 1's */
2283 SET_P3(0xff);
2284 SET_P2(0xff);
2285 SET_P1(0xff);
2286 SET_P0(0xff);
2287
2288 /* 8052 Only registers */
2289 if (m_features & FEATURE_I8052)
2290 {
2291 T2CON = 0;
2292 RCAP2L = 0;
2293 RCAP2H = 0;
2294 TL2 = 0;
2295 TH2 = 0;
2296 }
2297
2298 /* 80C52 Only registers */
2299 if (m_features & FEATURE_I80C52)
2300 {
2301 IPH = 0;
2302 update_irq_prio(IP, IPH);
2303 SADDR = 0;
2304 SADEN = 0;
2305 }
2306
2307 /* DS5002FP Only registers */
2308 if (m_features & FEATURE_DS5002FP)
2309 {
2310 // set initial values (some of them are set using the bootstrap loader)
2311 PCON = 0;
2312 MCON = m_sfr_ram[ADDR_MCON-0x80];
2313 RPCTL = m_sfr_ram[ADDR_RPCTL-0x80];
2314 RPS = 0;
2315 RNR = 0;
2316 CRCR = m_sfr_ram[ADDR_CRCR-0x80];
2317 CRCL = 0;
2318 CRCH = 0;
2319 TA = 0;
2320
2321 // set internal CPU state
2322 m_ds5002fp.previous_ta = 0;
2323 m_ds5002fp.ta_window = 0;
2324 m_ds5002fp.range = (GET_RG1 << 1) | GET_RG0;
2325 }
2326
2327 m_uart.data_out = 0;
2328 m_uart.rx_clk = 0;
2329 m_uart.tx_clk = 0;
2330 m_uart.bits_to_send = 0;
2331 m_uart.delay_cycles = 0;
2332 m_uart.smod_div = 0;
2333
2334 m_recalc_parity = 0;
2335 }
2336
2337
2338 /****************************************************************************
2339 * 8052 Section
2340 ****************************************************************************/
2341
sfr_write(size_t offset,uint8_t data)2342 void i8052_device::sfr_write(size_t offset, uint8_t data)
2343 {
2344 switch (offset)
2345 {
2346 /* 8052 family specific */
2347 case ADDR_T2CON:
2348 case ADDR_RCAP2L:
2349 case ADDR_RCAP2H:
2350 case ADDR_TL2:
2351 case ADDR_TH2:
2352 m_data.write_byte((size_t) offset | 0x100, data);
2353 break;
2354
2355 default:
2356 mcs51_cpu_device::sfr_write(offset, data);
2357 }
2358 }
2359
sfr_read(size_t offset)2360 uint8_t i8052_device::sfr_read(size_t offset)
2361 {
2362 switch (offset)
2363 {
2364 /* 8052 family specific */
2365 case ADDR_T2CON:
2366 case ADDR_RCAP2L:
2367 case ADDR_RCAP2H:
2368 case ADDR_TL2:
2369 case ADDR_TH2:
2370 return m_data.read_byte((size_t) offset | 0x100);
2371 default:
2372 return mcs51_cpu_device::sfr_read(offset);
2373 }
2374 }
2375
2376
2377 /****************************************************************************
2378 * 80C52 Section
2379 ****************************************************************************/
2380
sfr_write(size_t offset,uint8_t data)2381 void i80c52_device::sfr_write(size_t offset, uint8_t data)
2382 {
2383 switch (offset)
2384 {
2385 /* 80c52 family specific */
2386 case ADDR_IP:
2387 update_irq_prio(data, IPH);
2388 break;
2389 case ADDR_IPH:
2390 update_irq_prio(IP, data);
2391 break;
2392 case ADDR_SADDR:
2393 case ADDR_SADEN:
2394 break;
2395
2396 default:
2397 i8052_device::sfr_write(offset, data);
2398 return;
2399 }
2400 m_data.write_byte((size_t) offset | 0x100, data);
2401 }
2402
sfr_read(size_t offset)2403 uint8_t i80c52_device::sfr_read(size_t offset)
2404 {
2405 switch (offset)
2406 {
2407 /* 80c52 family specific */
2408 case ADDR_IPH:
2409 case ADDR_SADDR:
2410 case ADDR_SADEN:
2411 return m_data.read_byte((size_t) offset | 0x100);
2412 default:
2413 return i8052_device::sfr_read(offset);
2414 }
2415 }
2416
2417
2418 /****************************************************************************
2419 * DS5002FP Section
2420 ****************************************************************************/
2421
2422
2423 #define DS5_LOGW(a, d) LOG(("ds5002fp '%s': write to " # a " register at 0x%04x, data=%x\n", tag(), PC, d))
2424 #define DS5_LOGR(a, d) LOG(("ds5002fp '%s': read from " # a " register at 0x%04x\n", tag(), PC))
2425
ds5002fp_protected(size_t offset,uint8_t data,uint8_t ta_mask,uint8_t mask)2426 uint8_t mcs51_cpu_device::ds5002fp_protected(size_t offset, uint8_t data, uint8_t ta_mask, uint8_t mask)
2427 {
2428 uint8_t is_timed_access;
2429
2430 is_timed_access = (m_ds5002fp.ta_window > 0) && (TA == 0x55);
2431 if (is_timed_access)
2432 {
2433 ta_mask = 0xff;
2434 }
2435 data = (m_sfr_ram[offset] & (~ta_mask)) | (data & ta_mask);
2436 return (m_sfr_ram[offset] & (~mask)) | (data & mask);
2437 }
2438
sfr_write(size_t offset,uint8_t data)2439 void ds5002fp_device::sfr_write(size_t offset, uint8_t data)
2440 {
2441 switch (offset)
2442 {
2443 case ADDR_TA:
2444 m_ds5002fp.previous_ta = TA;
2445 /* init the time window after having wrote 0xaa */
2446 if ((data == 0xaa) && (m_ds5002fp.ta_window == 0))
2447 {
2448 m_ds5002fp.ta_window = 6; /* 4*12 + 2*12 */
2449 LOG(("ds5002fp '%s': TA window initiated at 0x%04x\n", tag(), PC));
2450 }
2451 break;
2452 case ADDR_MCON: data = ds5002fp_protected(ADDR_MCON, data, 0x0f, 0xf7); DS5_LOGW(MCON, data); break;
2453 case ADDR_RPCTL: data = ds5002fp_protected(ADDR_RPCTL, data, 0xef, 0xfe); DS5_LOGW(RPCTL, data); break;
2454 case ADDR_CRCR: data = ds5002fp_protected(ADDR_CRCR, data, 0xff, 0x0f); DS5_LOGW(CRCR, data); break;
2455 case ADDR_PCON: data = ds5002fp_protected(ADDR_PCON, data, 0xb9, 0xff); break;
2456 case ADDR_IP: data = ds5002fp_protected(ADDR_IP, data, 0x7f, 0xff); break;
2457 case ADDR_CRCL: DS5_LOGW(CRCL, data); break;
2458 case ADDR_CRCH: DS5_LOGW(CRCH, data); break;
2459 case ADDR_RNR: DS5_LOGW(RNR, data); break;
2460 case ADDR_RPS: DS5_LOGW(RPS, data); break;
2461 default:
2462 mcs51_cpu_device::sfr_write(offset, data);
2463 return;
2464 }
2465 m_data.write_byte((size_t) offset | 0x100, data);
2466 }
2467
sfr_read(size_t offset)2468 uint8_t ds5002fp_device::sfr_read(size_t offset)
2469 {
2470 switch (offset)
2471 {
2472 case ADDR_CRCR: DS5_LOGR(CRCR, data); break;
2473 case ADDR_CRCL: DS5_LOGR(CRCL, data); break;
2474 case ADDR_CRCH: DS5_LOGR(CRCH, data); break;
2475 case ADDR_MCON: DS5_LOGR(MCON, data); break;
2476 case ADDR_TA: DS5_LOGR(TA, data); break;
2477 case ADDR_RNR: DS5_LOGR(RNR, data); break;
2478 case ADDR_RPCTL: DS5_LOGR(RPCTL, data); return 0x80; break; /* touchgo stalls unless bit 7 is set, why? documentation is unclear */
2479 case ADDR_RPS: DS5_LOGR(RPS, data); break;
2480 case ADDR_PCON:
2481 SET_PFW(0); /* reset PFW flag */
2482 return mcs51_cpu_device::sfr_read(offset);
2483 default:
2484 return mcs51_cpu_device::sfr_read(offset);
2485 }
2486 return m_data.read_byte((size_t) offset | 0x100);
2487 }
2488
2489 /*
2490 Documentation states that having the battery connected "maintains the internal scratchpad RAM" and "certain SFRs"
2491 (although it isn't clear exactly which SFRs except for those explicitly mentioned)
2492 */
2493
nvram_default()2494 void ds5002fp_device::nvram_default()
2495 {
2496 memset( m_scratchpad, 0, 0x80 );
2497 memset( m_sfr_ram, 0, 0x80 );
2498
2499 int expected_bytes = 0x80 + 0x80;
2500
2501 if (!m_region.found())
2502 {
2503 logerror( "ds5002fp_device region not found\n" );
2504 }
2505 else if( m_region->bytes() != expected_bytes )
2506 {
2507 logerror( "ds5002fp_device region length 0x%x expected 0x%x\n", m_region->bytes(), expected_bytes );
2508 }
2509 else
2510 {
2511 uint8_t *region = m_region->base();
2512
2513 memcpy( m_scratchpad, region, 0x80 ); region += 0x80;
2514 memcpy( m_sfr_ram, region, 0x80 ); region += 0x80;
2515 /* does anything else need storing? any registers that aren't in sfr ram?
2516 It isn't clear if the various initial MCON registers etc. are just stored in sfr ram
2517 or if the DS5002FP stores them elsewhere and the bootstrap copies them */
2518 }
2519 }
2520
nvram_read(emu_file & file)2521 void ds5002fp_device::nvram_read( emu_file &file )
2522 {
2523 file.read( m_scratchpad, 0x80 );
2524 file.read( m_sfr_ram, 0x80 );
2525 }
2526
nvram_write(emu_file & file)2527 void ds5002fp_device::nvram_write( emu_file &file )
2528 {
2529 file.write( m_scratchpad, 0x80 );
2530 file.write( m_sfr_ram, 0x80 );
2531 }
2532
create_disassembler()2533 std::unique_ptr<util::disasm_interface> mcs51_cpu_device::create_disassembler()
2534 {
2535 return std::make_unique<i8051_disassembler>();
2536 }
2537
create_disassembler()2538 std::unique_ptr<util::disasm_interface> i8052_device::create_disassembler()
2539 {
2540 return std::make_unique<i8052_disassembler>();
2541 }
2542
create_disassembler()2543 std::unique_ptr<util::disasm_interface> i80c31_device::create_disassembler()
2544 {
2545 return std::make_unique<i80c51_disassembler>();
2546 }
2547
create_disassembler()2548 std::unique_ptr<util::disasm_interface> i80c51_device::create_disassembler()
2549 {
2550 return std::make_unique<i80c51_disassembler>();
2551 }
2552
create_disassembler()2553 std::unique_ptr<util::disasm_interface> i80c52_device::create_disassembler()
2554 {
2555 return std::make_unique<i80c52_disassembler>();
2556 }
2557
create_disassembler()2558 std::unique_ptr<util::disasm_interface> i87c51fa_device::create_disassembler()
2559 {
2560 return std::make_unique<i8xc51fx_disassembler>();
2561 }
2562
create_disassembler()2563 std::unique_ptr<util::disasm_interface> i80c51gb_device::create_disassembler()
2564 {
2565 return std::make_unique<i8xc51gb_disassembler>();
2566 }
2567
create_disassembler()2568 std::unique_ptr<util::disasm_interface> ds80c320_device::create_disassembler()
2569 {
2570 return std::make_unique<ds80c320_disassembler>();
2571 }
2572
create_disassembler()2573 std::unique_ptr<util::disasm_interface> sab80c535_device::create_disassembler()
2574 {
2575 return std::make_unique<sab80c515_disassembler>();
2576 }
2577
create_disassembler()2578 std::unique_ptr<util::disasm_interface> i8344_device::create_disassembler()
2579 {
2580 return std::make_unique<rupi44_disassembler>();
2581 }
2582
create_disassembler()2583 std::unique_ptr<util::disasm_interface> ds5002fp_device::create_disassembler()
2584 {
2585 return std::make_unique<ds5002fp_disassembler>();
2586 }
2587