From 1eaba9c1684bbe0e5a7bd688c929b9425f1e8749 Mon Sep 17 00:00:00 2001 From: jbu Date: Tue, 9 Dec 2014 13:06:54 +0100 Subject: Skeleton Rockwell 10788 chip emulation and use in gts1 - WIP (nw) --- src/emu/machine/machine.mak | 9 ++ src/emu/machine/r10788.c | 195 ++++++++++++++++++++++++++++++++++++++++++++ src/emu/machine/r10788.h | 72 ++++++++++++++++ src/mame/drivers/gts1.c | 44 +++++++++- src/mame/mame.mak | 1 + 5 files changed, 317 insertions(+), 4 deletions(-) create mode 100644 src/emu/machine/r10788.c create mode 100644 src/emu/machine/r10788.h diff --git a/src/emu/machine/machine.mak b/src/emu/machine/machine.mak index ddd1de3e803..50f21afac6c 100644 --- a/src/emu/machine/machine.mak +++ b/src/emu/machine/machine.mak @@ -1302,6 +1302,15 @@ ifneq ($(filter PLA,$(MACHINES)),) MACHINEOBJS += $(MACHINEOBJ)/pla.o endif +#------------------------------------------------- +# +#@src/emu/machine/r10788.h,MACHINES += R10788 +#------------------------------------------------- + +ifneq ($(filter R10788,$(MACHINES)),) +MACHINEOBJS+= $(MACHINEOBJ)/r10788.o +endif + #------------------------------------------------- # #@src/emu/machine/rf5c296.h,MACHINES += RF5C296 diff --git a/src/emu/machine/r10788.c b/src/emu/machine/r10788.c new file mode 100644 index 00000000000..7c3984c2823 --- /dev/null +++ b/src/emu/machine/r10788.c @@ -0,0 +1,195 @@ +/********************************************************************** + + Rockwell 10788 General Purpose Keyboard and Display circuit + + Copyright Nicola Salmoria and the MAME Team. + Visit http://mamedev.org for licensing and usage restrictions. + + + REGISTER DESCRIPTION + + + [ Opcodes IOL, I2 ] + NAME W/IO CS I/O CMD I/O Names + -------------------------------------------------------------- + KTR 1 1 x x x 1 1 0 0 Transfer Keyboard Return + KTS 1 1 x x x 1 0 1 0 Transfer Keyboard Strobe + KLA 1 1 x x x 1 1 1 0 Load Display Register A + KLB 1 1 x x x 1 1 0 1 Load Display Register A + KDN 1 1 x x x 0 0 1 1 Turn On Display + KAF 1 1 x x x 1 0 1 1 Turn Off A + KBF 1 1 x x x 0 1 1 1 Turn Off B + KER 1 1 x x x 0 1 1 0 Reset Keyboard Error + + Notes: + 1.) W/IO is generated by the first word of the PPS IOL instruction. + 2.) Polarities of I/O7, I/O6 and I/O5 must be the same as the + polarities of the chip select straps SC7, SC6 and SC5. + 3.) KLA resets DA1-DA4 and DB1 and DB2 to VSS level. KLB resets + DB3 and DB4 to VSS level. + 4.) KAF and KBF is used to blank the display without changing the + contents of display data registers. + 5.) KAF resets output lines DA1, DA2, DA3, DA4, DB1 and DB2 to + VSS level. KBF resets output lines DB3 and DB4 to VSS level. + 6.) KAF stops the circulation of the display register A, and KBF + stops the circulation of the display register B. + 7.) KER takes a maximum of 10-bit times to complete (= 80 clocks) + Therefore, there must be at least 10 bit times between KER + and the next KTS instruction. +**********************************************************************/ + +#include "emu.h" +#include "machine/r10788.h" + + +/************************************* + * + * Device interface + * + *************************************/ + +const device_type R10788 = &device_creator; + +r10788_device::r10788_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, R10788, "Rockwell 10788", tag, owner, clock, "r10788", __FILE__), + m_reg(), + m_ktr(0), m_kts(0), m_kla(0), m_klb(0), m_enable(3), m_ker(0), + m_scan_counter(0), + m_display(*this) +{ +} + +/** + * @brief r10788_device::device_start device-specific startup + */ +void r10788_device::device_start() +{ + m_display.resolve(); + + save_item(NAME(m_reg)); + save_item(NAME(m_ktr)); + save_item(NAME(m_kts)); + save_item(NAME(m_kla)); + save_item(NAME(m_klb)); + save_item(NAME(m_enable)); + save_item(NAME(m_ker)); + save_item(NAME(m_scan_counter)); + + m_timer = timer_alloc(TIMER_DISPLAY); + /* Default clock is from CPU1 */ + if (clock() == 0) + { + set_unscaled_clock(machine().firstcpu->clock()); + } + m_timer->adjust(clocks_to_attotime(36)); +} + +/** + * @brief r10788_device::device_reset device-specific reset + */ +void r10788_device::device_reset() +{ + for (int i = 0; i < 16; i++) + m_reg[0][i] = m_reg[1][i] = 0; + m_ktr = 0; + m_kts = 0; + m_kla = 0; + m_klb = 0; + m_enable = 3; + m_ker = 0; + m_scan_counter = 0; +} + + +/** + * @brief r10788_device::device_timer timer event callback + * @param timer emu_timer which fired + * @param id timer identifier + * @param param parameter + * @param ptr pointer parameter + */ +void r10788_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + m_scan_counter = (m_scan_counter + 1) % 16; + switch (id) + { + case TIMER_DISPLAY: + m_display(m_scan_counter, m_reg[0][m_scan_counter] << 4 | m_reg[1][m_scan_counter], 0xff); + break; + } +} + +/************************************* + * + * Constants + * + *************************************/ + +/************************************* + * + * Command access handlers + * + *************************************/ + +WRITE8_MEMBER( r10788_device::io_w ) +{ + assert(offset < 16); + switch (offset) + { + case KTR: // Transfer Keyboard Return + m_ktr = data; + break; + case KTS: // Transfer Keyboard Strobe + m_kts = data; + break; + case KLA: // Load Display Register A + m_kla = data; + break; + case KLB: // Load Display Register B + m_klb = data; + break; + case KDN: // Turn On Display + m_enable = 1 | 2; + break; + case KAF: // Turn Off A + m_enable &= ~1; + break; + case KBF: // Turn Off B + m_enable &= ~1; + break; + case KER: // Reset Keyboard Error + m_ker = 10; + break; + } +} + + +READ8_MEMBER( r10788_device::io_r ) +{ + assert(offset < 16); + UINT8 data = 0xf; + switch (offset) + { + case KTR: // Transfer Keyboard Return + data = m_ktr; + break; + case KTS: // Transfer Keyboard Strobe + data = m_kts; + break; + case KLA: // Load Display Register A + data = m_kla; + break; + case KLB: // Load Display Register B + data = m_klb; + break; + case KDN: // Turn On Display + break; + case KAF: // Turn Off A + break; + case KBF: // Turn Off B + break; + case KER: // Reset Keyboard Error + break; + } + return data; +} diff --git a/src/emu/machine/r10788.h b/src/emu/machine/r10788.h new file mode 100644 index 00000000000..d758876f16c --- /dev/null +++ b/src/emu/machine/r10788.h @@ -0,0 +1,72 @@ +/********************************************************************** + + Rockwell 10788 General Purpose Keyboard and Display circuit + + Juergen Buchmueller + + The device decodes reads/write to a 16 byte I/O range defined + by three wired inputs SC5, SC6 and SC7. The range is one of + 80-8f, 90-9f, ..., f0-ff depending on the wiring. + +**********************************************************************/ + +#ifndef __R10788_H__ +#define __R10788_H__ + +#include "device.h" + +/************************************* + * + * Device configuration macros + * + *************************************/ + +/* Set the writer used to update a display digit */ +#define MCFG_R10788_UPDATE(_devcb) \ + r10788_device::set_update(*device, DEVCB_##_devcb); + +class r10788_device : public device_t +{ +public: + r10788_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + ~r10788_device() {} + + enum { + KTR = 0xc, //!< Transfer Keyboard Return + KTS = 0xa, //!< Transfer Keyboard Strobe + KLA = 0xe, //!< Load Display Register A + KLB = 0xd, //!< Load Display Register B + KDN = 0x3, //!< Turn On Display + KAF = 0xb, //!< Turn Off A + KBF = 0x7, //!< Turn Off B + KER = 0x6 //!< Reset Keyboard Error + }; + + DECLARE_READ8_MEMBER ( io_r ); + DECLARE_WRITE8_MEMBER( io_w ); + + template static devcb_base &set_update(device_t &device, _Object object) { return downcast(device).m_display.set_callback(object); } +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + +private: + static const device_timer_id TIMER_DISPLAY = 0; + + UINT8 m_reg[2][16]; //!< display registers + UINT8 m_ktr; //!< transfer keyboard return value + UINT8 m_kts; //!< transfer keyboard strobe value + UINT8 m_kla; //!< display register A value + UINT8 m_klb; //!< display register B value + UINT8 m_enable; //!< display enable flags for A (1) and B (2) + UINT8 m_ker; //!< keyboard error value + int m_scan_counter; //!< current display scan + devcb_write8 m_display; //!< display updater + emu_timer* m_timer; //!< timer running at clock / 18 / 36 +}; + +extern const device_type R10788; + +#endif /* __R10788_H__ */ diff --git a/src/mame/drivers/gts1.c b/src/mame/drivers/gts1.c index 4c1613b9ede..da96e9b3023 100644 --- a/src/mame/drivers/gts1.c +++ b/src/mame/drivers/gts1.c @@ -67,6 +67,7 @@ ToDo: #include "machine/genpin.h" +#include "machine/r10788.h" #include "cpu/pps4/pps4.h" #include "gts1.lh" @@ -87,12 +88,19 @@ public: { } DECLARE_DRIVER_INIT(gts1); + + DECLARE_WRITE8_MEMBER(gts1_display_w); + DECLARE_READ8_MEMBER (gts1_io_r); + DECLARE_WRITE8_MEMBER(gts1_io_w); DECLARE_READ8_MEMBER (gts1_pa_r); DECLARE_WRITE8_MEMBER(gts1_pa_w); DECLARE_WRITE8_MEMBER(gts1_pb_w); private: virtual void machine_reset(); required_device m_maincpu; + // required_device m_gpkd; // FIXME: doesn't compile + UINT8 m_io[256]; + UINT8 m_counter; UINT8 m_6351_addr; }; @@ -101,12 +109,14 @@ static ADDRESS_MAP_START( gts1_map, AS_PROGRAM, 8, gts1_state ) ADDRESS_MAP_END static ADDRESS_MAP_START( gts1_data, AS_DATA, 8, gts1_state ) - AM_RANGE(0x0000, 0x0fff) AM_RAM // not correct + AM_RANGE(0x0000, 0x00ff) AM_RAM // not correct ADDRESS_MAP_END static ADDRESS_MAP_START( gts1_io, AS_IO, 8, gts1_state ) - AM_RANGE(0x0000, 0x00ff) AM_RAM // connects to all the other chips - AM_RANGE(0x0100, 0x0100) AM_READ (gts1_pa_r) AM_WRITE(gts1_pa_w) + AM_RANGE(0x00d0, 0x00df) AM_DEVREADWRITE ( "r10788", r10788_device, io_r, io_w ) + AM_RANGE(0x0000, 0x00ff) AM_READ ( gts1_io_r ) AM_WRITE( gts1_io_w ) // connects to all the other chips + + AM_RANGE(0x0100, 0x0100) AM_READ ( gts1_pa_r ) AM_WRITE( gts1_pa_w ) AM_RANGE(0x0101, 0x0101) AM_WRITE(gts1_pb_w) ADDRESS_MAP_END @@ -199,6 +209,29 @@ DRIVER_INIT_MEMBER(gts1_state,gts1) { } +/** + * @brief write a 8seg display value + * @param offset digit number 0 .. 19 + * @param data 4-bit value to display + */ +WRITE8_MEMBER(gts1_state::gts1_display_w) +{ + output_set_digit_value(offset, data); +} + +READ8_MEMBER (gts1_state::gts1_io_r) +{ + UINT8 data = m_io[offset] & 0x0f; + LOG(("%s: io[%02x] -> %x\n", __FUNCTION__, offset, data)); + return data; +} + +WRITE8_MEMBER(gts1_state::gts1_io_w) +{ + LOG(("%s: io[%02x] <- %x\n", __FUNCTION__, offset, data)); + m_io[offset] = data; +} + READ8_MEMBER (gts1_state::gts1_pa_r) { // return ROM nibble @@ -232,8 +265,11 @@ static MACHINE_CONFIG_START( gts1, gts1_state ) //MCFG_NVRAM_ADD_0FILL("nvram") + /* General Purpose Display and Keyboard */ + MCFG_R10788_UPDATE( WRITE8(gts1_state,gts1_display_w) ) + /* Video */ - MCFG_DEFAULT_LAYOUT(layout_gts1) + MCFG_DEFAULT_LAYOUT( layout_gts1 ) /* Sound */ MCFG_FRAGMENT_ADD( genpin_audio ) diff --git a/src/mame/mame.mak b/src/mame/mame.mak index 300a071e9c8..ddb9180e57a 100644 --- a/src/mame/mame.mak +++ b/src/mame/mame.mak @@ -499,6 +499,7 @@ MACHINES += PCKEYBRD MACHINES += PIC8259 MACHINES += PIT8253 MACHINES += PLA +MACHINES += R10788 #MACHINES += PROFILE #MACHINES += R64H156 MACHINES += RF5C296 -- cgit v1.2.3