diff options
Diffstat (limited to 'src/devices/machine/roc10937.cpp')
-rw-r--r-- | src/devices/machine/roc10937.cpp | 388 |
1 files changed, 388 insertions, 0 deletions
diff --git a/src/devices/machine/roc10937.cpp b/src/devices/machine/roc10937.cpp new file mode 100644 index 00000000000..fbfda7ce0e8 --- /dev/null +++ b/src/devices/machine/roc10937.cpp @@ -0,0 +1,388 @@ +// license:BSD-3-Clause +// copyright-holders:James Wallace +/********************************************************************** + + Rockwell 10937/10957 interface and emulation by J.Wallace + OKI MSC1937 is a clone of this chip + +**********************************************************************/ + +#include "emu.h" +#include "roc10937.h" + +/* + Rockwell 10937 16 segment charset lookup table + 0 1 + ---- ---- + |\ | /| + 7 | \F |8 /9| 2 + | \ | / | + -E-- --A- + | / | \ | + 6 | /D |C \B| 3 + |/ | \| + ---- ---- .11 + 5 4 ,10 + +In 14 segment mode, 0 represents the whole top line, +and 5 the bottom line, allowing both modes to share +a charset. + +Note that, although we call this a '16 segment' display, +we actually have 18 segments, including the semicolon portions. +16-bit tables are used to hold the main characters, the rest are OR'd in +*/ + +static const UINT16 roc10937charset[]= +{ // FEDC BA98 7654 3210 + 0x507F, // 0101 0000 0111 1111 @. + 0x44CF, // 0100 0100 1100 1111 A. + 0x153F, // 0001 0101 0011 1111 B. + 0x00F3, // 0000 0000 1111 0011 C. + 0x113F, // 0001 0001 0011 1111 D. + 0x40F3, // 0100 0000 1111 0011 E. + 0x40C3, // 0100 0000 1100 0011 F. + 0x04FB, // 0000 0100 1111 1011 G. + 0x44CC, // 0100 0100 1100 1100 H. + 0x1133, // 0001 0001 0011 0011 I. + 0x007C, // 0000 0000 0111 1100 J. + 0x4AC0, // 0100 1010 1100 0000 K. + 0x00F0, // 0000 0000 1111 0000 L. + 0x82CC, // 1000 0010 1100 1100 M. + 0x88CC, // 1000 1000 1100 1100 N. + 0x00FF, // 0000 0000 1111 1111 O. + 0x44C7, // 0100 0100 1100 0111 P. + 0x08FF, // 0000 1000 1111 1111 Q. + 0x4CC7, // 0100 1100 1100 0111 R. + 0x44BB, // 0100 0100 1011 1011 S. + 0x1103, // 0001 0001 0000 0011 T. + 0x00FC, // 0000 0000 1111 1100 U. + 0x22C0, // 0010 0010 1100 0000 V. + 0x28CC, // 0010 1000 1100 1100 W. + 0xAA00, // 1010 1010 0000 0000 X. + 0x9200, // 1001 0010 0000 0000 Y. + 0x2233, // 0010 0010 0011 0011 Z. + 0x00E1, // 0000 0000 1110 0001 [. + 0x8800, // 1000 1000 0000 0000 \. + 0x001E, // 0000 0000 0001 1110 ]. + 0x2800, // 0010 1000 0000 0000 ^. + 0x0030, // 0000 0000 0011 0000 _. + 0x0000, // 0000 0000 0000 0000 dummy. + 0x8121, // 1000 0001 0010 0001 !. + 0x0180, // 0000 0001 1000 0000 ". + 0x553C, // 0101 0101 0011 1100 #. + 0x55BB, // 0101 0101 1011 1011 $. + 0x7799, // 0111 0111 1001 1001 %. + 0xC979, // 1100 1001 0111 1001 &. + 0x0200, // 0000 0010 0000 0000 '. + 0x0A00, // 0000 1010 0000 0000 (. + 0xA050, // 1010 0000 0000 0000 ). + 0xFF00, // 1111 1111 0000 0000 *. + 0x5500, // 0101 0101 0000 0000 +. + 0x0000, // 0000 0000 0000 0000 ;. (Set separately) + 0x4400, // 0100 0100 0000 0000 --. + 0x0000, // 0000 0000 0000 0000 . .(Set separately) + 0x2200, // 0010 0010 0000 0000 /. + 0x22FF, // 0010 0010 1111 1111 0. + 0x1100, // 0001 0001 0000 0000 1. + 0x4477, // 0100 0100 0111 0111 2. + 0x443F, // 0100 0100 0011 1111 3. + 0x448C, // 0100 0100 1000 1100 4. + 0x44BB, // 0100 0100 1011 1011 5. + 0x44FB, // 0100 0100 1111 1011 6. + 0x000F, // 0000 0000 0000 1111 7. + 0x44FF, // 0100 0100 1111 1111 8. + 0x44BF, // 0100 0100 1011 1111 9. + 0x0021, // 0000 0000 0010 0001 - + // -. + 0x2001, // 0010 0000 0000 0001 - + // /. + 0x2230, // 0010 0010 0011 0000 <. + 0x4430, // 0100 0100 0011 0000 =. + 0x8830, // 1000 1000 0011 0000 >. + 0x1407, // 0001 0100 0000 0111 ?. +}; + + +/////////////////////////////////////////////////////////////////////////// +static const int roc10937poslut[]= +{ + 1,//0 + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 0//15 +}; + +const device_type ROC10937 = &device_creator<roc10937_t>; + +rocvfd_t::rocvfd_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) : + device_t(mconfig, type, name, tag, owner, clock, shortname, source) +{ + m_port_val=0; +} + + +void rocvfd_t::static_set_value(device_t &device, int val) +{ + rocvfd_t &roc = downcast<rocvfd_t &>(device); + roc.m_port_val = val; +} + +void rocvfd_t::device_start() +{ + save_item(NAME(m_port_val)); + save_item(NAME(m_cursor_pos)); + save_item(NAME(m_window_size)); + save_item(NAME(m_shift_count)); + save_item(NAME(m_shift_data)); + save_item(NAME(m_pcursor_pos)); + save_item(NAME(m_chars)); + save_item(NAME(m_outputs)); + save_item(NAME(m_brightness)); + save_item(NAME(m_count)); + save_item(NAME(m_sclk)); + save_item(NAME(m_data)); + save_item(NAME(m_duty)); + save_item(NAME(m_disp)); + + + device_reset(); +} + +void rocvfd_t::device_reset() +{ + m_cursor_pos = 0; + m_window_size = 16; + m_shift_count = 0; + m_shift_data = 0; + m_pcursor_pos = 0; + m_brightness =31; + m_count=0; + m_duty=31; + m_disp = 0; + m_sclk = 0; + m_data = 0; + + memset(m_chars, 0, sizeof(m_chars)); + memset(m_outputs, 0, sizeof(m_outputs)); +} + +/////////////////////////////////////////////////////////////////////////// +UINT32 rocvfd_t::set_display(UINT32 segin) +{ + return BITSWAP32(segin, 31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,11,9,15,13,12,8,10,14,7,6,5,4,3,2,1,0); + +} + +/////////////////////////////////////////////////////////////////////////// +void rocvfd_t::device_post_load() +{ + update_display(); +} + +void rocvfd_t::update_display() +{ + for (int i =0; i<16; i++) + { + m_outputs[i] = set_display(m_chars[i]); + output_set_indexed_value("vfd", (m_port_val*16) + i, m_outputs[i]); + } +} + +WRITE_LINE_MEMBER( rocvfd_t::sclk ) +{ + shift_clock(state); +} + +WRITE_LINE_MEMBER( rocvfd_t::data ) +{ + m_data = state; +} + +WRITE_LINE_MEMBER( rocvfd_t::por ) +{ + //If line goes low, reset mode is engaged, until such a time as it goes high again. + if (!state) + { + reset(); + } +} + + +void rocvfd_t::shift_clock(int state) +{ + if (m_sclk != state) + { + //Clock data on FALLING edge + if (!m_sclk) + { + m_shift_data <<= 1; + + if ( m_data ) m_shift_data |= 1; + + if ( ++m_shift_count >= 8 ) + { + write_char(m_shift_data); + m_shift_count = 0; + m_shift_data = 0; + } + update_display(); + + } + } + m_sclk = state; +} + +/////////////////////////////////////////////////////////////////////////// +roc10937_t::roc10937_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : rocvfd_t(mconfig, ROC10937, "Rockwell 10937 VFD controller and compatible", tag, owner, clock, "roc10937", __FILE__) +{ + m_port_val=0; +} + +const device_type MSC1937 = &device_creator<msc1937_t>; + +msc1937_t::msc1937_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : rocvfd_t(mconfig, MSC1937, "OKI MSC1937 VFD controller", tag, owner, clock, "msc1937", __FILE__) +{ + m_port_val=0; +} + +void rocvfd_t::write_char(int data) +{ + if ( data & 0x80 ) + { // Control data received + if ( (data & 0xF0) == 0xA0 ) // 1010 xxxx + { // 1 010 xxxx Buffer Pointer control + m_cursor_pos = roc10937poslut[data & 0x0F]; + } + else if ( (data & 0xF0) == 0xC0 ) // 1100 xxxx + { // 1100 xxxx Set number of digits + data &= 0x0F; + + if ( data == 0 ) m_window_size = 16; + else m_window_size = data; + } + else if ( (data & 0xE0) == 0xE0 ) // 111x xxxx + { // 111x xxxx Set duty cycle ( brightness ) + m_brightness = (data & 0x1F); + } + else if ( (data & 0xE0) == 0x80 ) // 100x --- + { // 100x xxxx Test mode + m_duty =4; + } + } + else + { // Display data +// data &= 0x3F; + + switch ( data ) + { + case 0x2C: // ; + m_chars[m_pcursor_pos] |= (1<<16);//. + m_chars[m_pcursor_pos] |= (1<<17);//, + break; + case 0x2E: // + m_chars[m_pcursor_pos] |= (1<<16);//. + break; + default : + m_pcursor_pos = m_cursor_pos; + m_chars[m_cursor_pos] = roc10937charset[data & 0x3F]; + + m_cursor_pos++; + if ( m_cursor_pos > (m_window_size -1) ) + { + m_cursor_pos = 0; + } + break; + } + } +} + +const device_type ROC10957 = &device_creator<roc10957_t>; + +roc10957_t::roc10957_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : rocvfd_t(mconfig, ROC10957, "Rockwell 10957 VFD controller and compatible", tag, owner, clock, "roc10957", __FILE__) +{ + m_port_val=0; +} + +void roc10957_t::write_char(int data) +{ + if ( data & 0x80 ) + { // Control data received + if ( (data & 0xF0) == 0xA0 ) // 1010 xxxx + { // 1 010 xxxx Buffer Pointer control + m_cursor_pos = roc10937poslut[data & 0x0F]; + } + else if ( (data & 0xF0) == 0xC0 ) // 1100 xxxx + { // 1100 xxxx Set number of digits + data &= 0x0F; + + if ( data == 0 ) m_window_size = 16; + else m_window_size = data; + } + else if ( (data & 0xE0) == 0xE0 ) // 111x xxxx + { // 111x xxxx Set duty cycle ( brightness ) + m_brightness = (data & 0x1F); + } + else if ( (data & 0xE0) == 0x80 ) // 100x --- + { // 100x xxxx Test mode + popmessage("TEST MODE ENABLED!"); + m_duty = 4; + } + } + else + { // Display data + data &= 0x3F; + + switch ( data ) + { + case 0x2C: // ; + m_chars[m_pcursor_pos] |= (1<<16);//. + m_chars[m_pcursor_pos] |= (1<<17);//, + break; + case 0x2E: // + m_chars[m_pcursor_pos] |= (1<<16);//. + break; + case 0x6C: // ; + m_chars[m_pcursor_pos] |= (1<<16);//. + break; + case 0x6E: // + { + m_chars[m_pcursor_pos] = 0; + } + break; + default : + m_pcursor_pos = m_cursor_pos; + m_chars[m_cursor_pos] = roc10937charset[data & 0x3F]; + + m_cursor_pos++; + if ( m_cursor_pos > (m_window_size -1) ) + { + m_cursor_pos = 0; + } + break; + } + } +} + +const device_type S16LF01 = &device_creator<s16lf01_t>; + +s16lf01_t::s16lf01_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : rocvfd_t(mconfig, S16LF01, "Samsung 16LF01 Series VFD controller and compatible", tag, owner, clock, "s16lf01", __FILE__) +{ + m_port_val=0; +} |