diff options
Diffstat (limited to 'src/emu/cpu/e0c6200/e0c6s46.c')
-rw-r--r-- | src/emu/cpu/e0c6200/e0c6s46.c | 102 |
1 files changed, 51 insertions, 51 deletions
diff --git a/src/emu/cpu/e0c6200/e0c6s46.c b/src/emu/cpu/e0c6200/e0c6s46.c index 55a0127db7b..be131a1e5dc 100644 --- a/src/emu/cpu/e0c6200/e0c6s46.c +++ b/src/emu/cpu/e0c6200/e0c6s46.c @@ -4,7 +4,7 @@ Seiko Epson E0C6S46 MCU QFP5-128pin, see manual for pinout - + TODO: - OSC3 - K input interrupts @@ -64,7 +64,7 @@ e0c6s46_device::e0c6s46_device(const machine_config &mconfig, const char *tag, d void e0c6s46_device::device_start() { e0c6200_cpu_device::device_start(); - + // find ports m_write_r0.resolve_safe(); m_write_r1.resolve_safe(); @@ -88,7 +88,7 @@ void e0c6s46_device::device_start() m_prgtimer_handle->adjust(attotime::never); m_buzzer_handle = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(e0c6s46_device::buzzer_cb), this)); m_buzzer_handle->adjust(attotime::never); - + // zerofill memset(m_port_r, 0x0, sizeof(m_port_r)); m_r_dir = 0; @@ -97,7 +97,7 @@ void e0c6s46_device::device_start() m_p_pullup = 0; memset(m_port_k, 0xf, sizeof(m_port_k)); m_dfk0 = 0xf; - + memset(m_irqflag, 0, sizeof(m_irqflag)); memset(m_irqmask, 0, sizeof(m_irqmask)); m_osc = 0; @@ -114,7 +114,7 @@ void e0c6s46_device::device_start() m_swl_slice = 0; m_swl_count = 0; m_swh_count = 0; - + m_prgtimer_select = 0; m_prgtimer_on = 0; m_prgtimer_src_pulse = 0; @@ -130,7 +130,7 @@ void e0c6s46_device::device_start() m_bz_1shot_running = false; m_bz_1shot_count = 0; m_bz_pulse = 0; - + // register for savestates save_item(NAME(m_port_r)); save_item(NAME(m_r_dir)); @@ -139,7 +139,7 @@ void e0c6s46_device::device_start() save_item(NAME(m_p_pullup)); save_item(NAME(m_port_k)); save_item(NAME(m_dfk0)); - + save_item(NAME(m_irqflag)); save_item(NAME(m_irqmask)); save_item(NAME(m_osc)); @@ -187,7 +187,7 @@ void e0c6s46_device::device_reset() // reset interrupts memset(m_irqflag, 0, sizeof(m_irqflag)); memset(m_irqmask, 0, sizeof(m_irqmask)); - + // reset other i/o m_data->write_byte(0xf41, 0xf); m_data->write_byte(0xf54, 0xf); @@ -205,7 +205,7 @@ void e0c6s46_device::device_reset() m_data->write_byte(0xf7b, 0x0); m_data->write_byte(0xf7d, 0x0); m_data->write_byte(0xf7e, 0x0); - + // reset ports for (int i = 0; i < 5; i++) write_r(i, m_port_r[i]); @@ -224,7 +224,7 @@ void e0c6s46_device::execute_one() // E0C6S46 has no support for SLP opcode if (m_op == 0xff9) return; - + e0c6200_cpu_device::execute_one(); } @@ -255,7 +255,7 @@ bool e0c6s46_device::check_interrupt() m_irq_vector = 2*pri + 2; int reg = priorder[pri]; m_irq_id = reg; - + switch (reg) { // other: mask vs flag @@ -265,7 +265,7 @@ bool e0c6s46_device::check_interrupt() break; } } - + return false; } @@ -278,7 +278,7 @@ void e0c6s46_device::execute_set_input(int line, int state) state = (state) ? 1 : 0; int port = line >> 2 & 1; UINT8 bit = 1 << (line & 3); - + m_port_k[port] = (m_port_k[port] & ~bit) | (state ? bit : 0); } @@ -299,14 +299,14 @@ void e0c6s46_device::write_r(UINT8 port, UINT8 data) UINT8 out = data; if (port < 4 && !(m_r_dir >> port & 1)) out = 0xf; - + switch (port) { case 0: m_write_r0(port, out, 0xff); break; case 1: m_write_r1(port, out, 0xff); break; case 2: m_write_r2(port, out, 0xff); break; case 3: m_write_r3(port, out, 0xff); break; // TODO: R33 PTCLK/_SRDY - + // R4x: special output case 4: // d3: buzzer on: direct output or 1-shot output @@ -336,7 +336,7 @@ void e0c6s46_device::write_p(UINT8 port, UINT8 data) { data &= 0xf; m_port_p[port] = data; - + // don't output if port direction is set to input if (!(m_p_dir >> port & 1)) return; @@ -355,7 +355,7 @@ UINT8 e0c6s46_device::read_p(UINT8 port) // return written value if port direction is set to output if (m_p_dir >> port & 1) return m_port_p[port]; - + switch (port) { case 0: return m_read_p0(port, 0xff); @@ -363,7 +363,7 @@ UINT8 e0c6s46_device::read_p(UINT8 port) case 2: return m_read_p2(port, 0xff); case 3: return m_read_p3(port, 0xff); } - + return 0; } @@ -412,7 +412,7 @@ void e0c6s46_device::clock_watchdog() void e0c6s46_device::clock_clktimer() { m_clktimer_count++; - + // irq on falling edge of 32, 8, 2, 1hz UINT8 flag = 0; if ((m_clktimer_count & 0x07) == 0) @@ -427,7 +427,7 @@ void e0c6s46_device::clock_clktimer() m_irqflag[IRQREG_CLKTIMER] |= flag; if (m_irqflag[IRQREG_CLKTIMER] & m_irqmask[IRQREG_CLKTIMER]) m_possible_irq = true; - + // 1hz falling edge also clocks the watchdog timer if (m_clktimer_count == 0) clock_watchdog(); @@ -439,14 +439,14 @@ void e0c6s46_device::clock_clktimer() void e0c6s46_device::clock_stopwatch() { m_swl_slice++; - + // 1 slice is 3 ticks(256hz) on even and 2 ticks on uneven counts, // but from count 1 to 2 it's 3 ticks, 6 out of 100 times, to make // exactly 26/256hz * 6 + 25/256hz * 4 = 1 second int swl_next = 3 - (m_swl_count & 1); if (m_swl_count == 1 && !(m_swh_count >> 1 & 1)) swl_next = 3; - + if (m_swl_slice == swl_next) { m_swl_slice = 0; @@ -477,7 +477,7 @@ void e0c6s46_device::clock_prgtimer() m_irqflag[IRQREG_PRGTIMER] |= 1; if (m_irqflag[IRQREG_PRGTIMER] & m_irqmask[IRQREG_PRGTIMER]) m_possible_irq = true; - + // note: a reload of 0 indicates a 256-counter m_prgtimer_count = m_prgtimer_reload; } @@ -489,7 +489,7 @@ bool e0c6s46_device::prgtimer_reset_prescaler() UINT8 sel = m_prgtimer_select & 7; if (sel >= 2) m_prgtimer_handle->adjust(attotime::from_ticks(2 << (sel ^ 7), unscaled_clock())); - + return (sel >= 2); } @@ -501,7 +501,7 @@ TIMER_CALLBACK_MEMBER(e0c6s46_device::prgtimer_cb) m_prgtimer_src_pulse ^= 1; m_prgtimer_cur_pulse = m_prgtimer_src_pulse | (m_prgtimer_on ^ 1); - + // clock prgtimer on falling edge of pulse+on if (m_prgtimer_cur_pulse == 0) clock_prgtimer(); @@ -515,17 +515,17 @@ void e0c6s46_device::schedule_buzzer() // only schedule next buzzer timeout if it's on if (m_bz_43_on != 0 && !m_bz_1shot_running) return; - + // pulse width differs per frequency selection int mul = (m_bz_freq & 4) ? 1 : 2; int high = (m_bz_freq & 2) ? 12 : 8; int low = 16 + (m_bz_freq << 2 & 0xc); - + // pulse width envelope if it's on if (m_bz_envelope & 1) high -= m_bz_duty_ratio; low -= high; - + m_buzzer_handle->adjust(attotime::from_ticks(m_bz_pulse ? high : low, mul * unscaled_clock())); } @@ -548,14 +548,14 @@ void e0c6s46_device::reset_buzzer() void e0c6s46_device::clock_bz_1shot() { m_bz_1shot_running = true; - + // reload counter the 1st time if (m_bz_1shot_count == 0) { reset_buzzer(); m_bz_1shot_count = (m_bz_freq & 8) ? 16 : 8; } - + // stop ringing when counter reaches 0 else if (--m_bz_1shot_count == 0) { @@ -586,7 +586,7 @@ UINT32 e0c6s46_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap pixel = 1; else lcd_on = true; - + // draw pixels for (int offset = 0; offset < 0x50; offset++) { @@ -594,11 +594,11 @@ UINT32 e0c6s46_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap { if (lcd_on) pixel = vram[offset] >> c & 1; - + // 16 COM(common) pins, 40 SEG(segment) pins int seg = offset / 2; int com = bank * 8 + (offset & 1) * 4 + c; - + if (m_pixel_update_handler != NULL) m_pixel_update_handler(*this, bitmap, cliprect, m_lcd_contrast, seg, com, pixel); else if (cliprect.contains(seg, com)) @@ -631,7 +631,7 @@ READ8_MEMBER(e0c6s46_device::io_r) } case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: return m_irqmask[offset-0x10]; - + // K input ports case 0x40: case 0x42: return m_port_k[offset >> 1 & 1]; @@ -643,7 +643,7 @@ READ8_MEMBER(e0c6s46_device::io_r) return m_port_r[offset & 7]; case 0x7b: return m_r_dir; - + // P I/O ports case 0x60: case 0x61: case 0x62: case 0x63: return read_p(offset & 3); @@ -651,11 +651,11 @@ READ8_MEMBER(e0c6s46_device::io_r) return m_p_dir; case 0x7e: return m_p_pullup; - + // clock-timer (lo, hi) case 0x20: case 0x21: return m_clktimer_count >> (4 * (offset & 1)) & 0xf; - + // stopwatch timer case 0x22: return m_swl_count; @@ -663,7 +663,7 @@ READ8_MEMBER(e0c6s46_device::io_r) return m_swh_count; case 0x77: return m_stopwatch_on; - + // programmable timer case 0x24: case 0x25: return m_prgtimer_count >> (4 * (offset & 1)) & 0xf; @@ -673,34 +673,34 @@ READ8_MEMBER(e0c6s46_device::io_r) return m_prgtimer_on; case 0x79: return m_prgtimer_select; - + // buzzer case 0x74: return m_bz_freq; case 0x75: // d3: 1-shot buzzer is on return m_bz_1shot_on | m_bz_envelope; - + // OSC circuit case 0x70: return m_osc; - + // LCD driver case 0x71: return m_lcd_control; case 0x72: return m_lcd_contrast; - + // SVD circuit (supply voltage detection) case 0x73: // d3: criteria voltage* is 0: <=, 1: > source voltage (Vdd-Vss) // *0,1,2,3: -2.2V, -2.5V, -3.1V, -4.2V, 1 when off return m_svd | ((m_svd & 4 && m_svd != 7) ? 0 : 8); - + // write-only registers case 0x76: break; - + default: if (!space.debugger_access()) logerror("%s unknown io_r from $0F%02X at $%04X\n", tag(), offset, m_prev_pc); @@ -722,13 +722,13 @@ WRITE8_MEMBER(e0c6s46_device::io_w) m_possible_irq = true; break; } - + // K input ports case 0x41: // d0-d3: K0x irq on 0: rising edge, 1: falling edge m_dfk0 = data; break; - + // R output ports case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: write_r(offset & 7, data); @@ -744,7 +744,7 @@ WRITE8_MEMBER(e0c6s46_device::io_w) write_r(i, m_port_r[i]); } break; - + // P I/O ports case 0x60: case 0x61: case 0x62: case 0x63: write_p(offset & 3, data); @@ -764,7 +764,7 @@ WRITE8_MEMBER(e0c6s46_device::io_w) // d0-d3: Px* pull up resistor on/off m_p_pullup = data; break; - + // OSC circuit case 0x70: // d0,d1: CPU operating voltage @@ -793,7 +793,7 @@ WRITE8_MEMBER(e0c6s46_device::io_w) // d2: on m_svd = data & 7; break; - + // clock-timer case 0x76: // d0: reset watchdog @@ -804,7 +804,7 @@ WRITE8_MEMBER(e0c6s46_device::io_w) if (data & 2) m_clktimer_count = 0; break; - + // stopwatch timer case 0x77: // d0: run/stop counter @@ -878,7 +878,7 @@ WRITE8_MEMBER(e0c6s46_device::io_w) m_bz_envelope = data & 3; m_bz_1shot_on |= data & 8; break; - + // read-only registers case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: |