diff options
Diffstat (limited to 'src/devices/cpu/mcs51/mcs51.cpp')
-rw-r--r-- | src/devices/cpu/mcs51/mcs51.cpp | 84 |
1 files changed, 61 insertions, 23 deletions
diff --git a/src/devices/cpu/mcs51/mcs51.cpp b/src/devices/cpu/mcs51/mcs51.cpp index 46087800aab..1c682e06e0e 100644 --- a/src/devices/cpu/mcs51/mcs51.cpp +++ b/src/devices/cpu/mcs51/mcs51.cpp @@ -250,16 +250,17 @@ static ADDRESS_MAP_START(program_13bit, AS_PROGRAM, 8, mcs51_cpu_device) ADDRESS_MAP_END static ADDRESS_MAP_START(data_7bit, AS_DATA, 8, mcs51_cpu_device) - AM_RANGE(0x0000, 0x007f) AM_RAM - AM_RANGE(0x0100, 0x01ff) AM_RAM /* SFR */ + AM_RANGE(0x0000, 0x007f) AM_RAM AM_SHARE("scratchpad") + AM_RANGE(0x0100, 0x01ff) AM_RAM AM_SHARE("sfr_ram") /* SFR */ ADDRESS_MAP_END static ADDRESS_MAP_START(data_8bit, AS_DATA, 8, mcs51_cpu_device) - AM_RANGE(0x0000, 0x00ff) AM_RAM - AM_RANGE(0x0100, 0x01ff) AM_RAM /* SFR */ + AM_RANGE(0x0000, 0x00ff) AM_RAM AM_SHARE("scratchpad") + AM_RANGE(0x0100, 0x01ff) AM_RAM AM_SHARE("sfr_ram") /* SFR */ ADDRESS_MAP_END + 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) : cpu_device(mconfig, type, tag, owner, clock) , m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0, @@ -271,6 +272,8 @@ mcs51_cpu_device::mcs51_cpu_device(const machine_config &mconfig, device_type ty , m_features(features) , m_ram_mask( (data_width == 8) ? 0xFF : 0x7F ) , m_num_interrupts(5) + , m_sfr_ram(*this, "sfr_ram") + , m_scratchpad(*this, "scratchpad") , m_serial_tx_cb(*this) , m_serial_rx_cb(*this) , m_rtemp(0) @@ -369,8 +372,11 @@ at89c4051_device::at89c4051_device(const machine_config &mconfig, const char *ta { } +/* program width field is set to 0 because technically the SRAM isn't internal */ ds5002fp_device::ds5002fp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : mcs51_cpu_device(mconfig, DS5002FP, tag, owner, clock, 12, 7, FEATURE_DS5002FP | FEATURE_CMOS) + : mcs51_cpu_device(mconfig, DS5002FP, tag, owner, clock, 0, 7, FEATURE_DS5002FP | FEATURE_CMOS) + , device_nvram_interface(mconfig, *this) + , m_region(*this, "internal") { } @@ -463,7 +469,7 @@ void mcs51_cpu_device::iram_iwrite(offs_t a, uint8_t d) { if (a <= m_ram_mask) m #define B SFR_A(ADDR_B) #define SBUF SFR_A(ADDR_SBUF) -#define R_REG(r) m_internal_ram[(r) | (PSW & 0x18)] +#define R_REG(r) m_scratchpad[(r) | (PSW & 0x18)] #define DPTR ((DPH<<8) | DPL) /* 8052 Only registers */ @@ -522,7 +528,7 @@ void mcs51_cpu_device::iram_iwrite(offs_t a, uint8_t d) { if (a <= m_ram_mask) m #define SET_SBUF(v) SET_SFR_A(ADDR_SBUF, v) /* No actions triggered on write */ -#define SET_REG(r, v) do { m_internal_ram[(r) | (PSW & 0x18)] = (v); } while (0) +#define SET_REG(r, v) do { m_scratchpad[(r) | (PSW & 0x18)] = (v); } while (0) #define SET_DPTR(n) do { DPH = ((n) >> 8) & 0xff; DPL = (n) & 0xff; } while (0) @@ -740,12 +746,6 @@ uint8_t mcs51_cpu_device::r_acc() { return SFR_A(ADDR_ACC); } uint8_t mcs51_cpu_device::r_psw() { return SFR_A(ADDR_PSW); } -void mcs51_cpu_device::update_ptrs() -{ - m_internal_ram = (uint8_t *)m_data->get_write_ptr(0x00); - m_sfr_ram = (uint8_t *)m_data->get_write_ptr(0x100); -} - /* Generate an external ram address for read/writing using indirect addressing mode */ @@ -1958,8 +1958,6 @@ void mcs51_cpu_device::execute_run() { uint8_t op; - update_ptrs(); - /* external interrupts may have been set since we last checked */ m_inst_cycles = 0; check_irqs(); @@ -2107,9 +2105,6 @@ void mcs51_cpu_device::device_start() m_data = &space(AS_DATA); m_io = &space(AS_IO); - /* ensure these pointers are set before get_info is called */ - update_ptrs(); - m_serial_rx_cb.resolve_safe(0); m_serial_tx_cb.resolve_safe(); @@ -2232,8 +2227,6 @@ void mcs51_cpu_device::state_string_export(const device_state_entry &entry, std: /* Reset registers to the initial values */ void mcs51_cpu_device::device_reset() { - update_ptrs(); - m_last_line_state = 0; m_t0_cnt = 0; m_t1_cnt = 0; @@ -2292,11 +2285,11 @@ void mcs51_cpu_device::device_reset() { // set initial values (some of them are set using the bootstrap loader) PCON = 0; - MCON = m_ds5002fp.mcon & 0xfb; - RPCTL = m_ds5002fp.rpctl & 0x01; + MCON = m_sfr_ram[ADDR_MCON-0x80]; + RPCTL = m_sfr_ram[ADDR_RPCTL-0x80]; RPS = 0; RNR = 0; - CRCR = m_ds5002fp.crc & 0xf0; + CRCR = m_sfr_ram[ADDR_CRCR-0x80]; CRCL = 0; CRCH = 0; TA = 0; @@ -2469,6 +2462,51 @@ uint8_t ds5002fp_device::sfr_read(size_t offset) return m_data->read_byte((size_t) offset | 0x100); } +/* +Documentation states that having the battery connected "maintains the internal scratchpad RAM" and "certain SFRs" +(although it isn't clear exactly which SFRs except for those explicitly mentioned) +*/ + +void ds5002fp_device::nvram_default() +{ + memset( m_scratchpad, 0, 0x80 ); + memset( m_sfr_ram, 0, 0x80 ); + + int expected_bytes = 0x80 + 0x80; + + if (!m_region.found()) + { + logerror( "ds5002fp_device region not found\n" ); + } + else if( m_region->bytes() != expected_bytes ) + { + logerror( "ds5002fp_device region length 0x%x expected 0x%x\n", m_region->bytes(), expected_bytes ); + } + else + { + uint8_t *region = m_region->base(); + + memcpy( m_scratchpad, region, 0x80 ); region += 0x80; + memcpy( m_sfr_ram, region, 0x80 ); region += 0x80; + /* does anything else need storing? any registers that aren't in sfr ram? + It isn't clear if the various initial MCON registers etc. are just stored in sfr ram + or if the DS5002FP stores them elsewhere and the bootstrap copies them */ + } +} + +void ds5002fp_device::nvram_read( emu_file &file ) +{ + file.read( m_scratchpad, 0x80 ); + file.read( m_sfr_ram, 0x80 ); +} + +void ds5002fp_device::nvram_write( emu_file &file ) +{ + file.write( m_scratchpad, 0x80 ); + file.write( m_sfr_ram, 0x80 ); +} + + offs_t mcs51_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { |