diff options
Diffstat (limited to 'src/emu/machine/r10788.c')
-rw-r--r-- | src/emu/machine/r10788.c | 195 |
1 files changed, 195 insertions, 0 deletions
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::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; +} |