ROC10937 converted to a modern device - still needs proper character clock timing for the brightness effects.

Displays now have to be added to the CONFIG_START, and take the form 'MCFG_ROC10937_ADD(tag,port,RIGHT_TO_LEFT/LEFT_TO_RIGHT)'
The last option represents the direction for moving from start to end on the display.

Converted all drivers that used the old form, adding improved serial communications where documentation is known.

Made BFM_BD1 save states properly this time.
This commit is contained in:
James Wallace 2012-07-15 18:44:16 +00:00
parent cc531f091b
commit 41d03848d2
16 changed files with 575 additions and 459 deletions

View File

@ -8,40 +8,6 @@
#include "emu.h"
#include "roc10937.h"
static struct
{
UINT8 type, // type of alpha display
reversed, // Allows for the data being written from right to left, not left to right.
changed, // flag <>0, if contents are changed
window_start, // display window start pos 0-15
window_end, // display window end pos 0-15
window_size; // window size
INT8 pcursor_pos, // previous cursor pos
cursor_pos; // current cursor pos
UINT16 brightness; // display brightness level 0-31 (31=MAX)
UINT8 string[18]; // text buffer
UINT32 segments[16], // segments
outputs[16]; // standardised outputs
UINT8 count, // bit counter
data; // receive register
} roc10937[MAX_ROCK_ALPHAS];
//
// Rockwell 10937 charset to ASCII conversion table
//
static const char roc10937ASCII[]=
//0123456789ABCDEF0123456789ABC DEF01 23456789ABCDEF0123456789ABCDEF
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_ ?\"#$%%'()*+;-./0123456789&%<=>?"
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_ ?\"#$%%'()*+;-./0123456789&%<=>?"
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_ ?\"#$%%'()*+;-./0123456789&%<=>?";
/*
Rockwell 10937 16 segment charset lookup table
0 1
@ -60,81 +26,82 @@ 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,
Note that, although we call this a '16 segment' display,
we actually have 18 segments, including the semicolon portions.
This means our segment maths needs to be more than 16-bit to work!
16-bit tables are used to hold the main characters, the rest are OR'd in
*/
static const UINT32 roc10937charset[]=
{ // 11 10 FEDC BA98 7654 3210
0x0507F, // 0 0 0101 0000 0111 1111 @.
0x044CF, // 0 0 0100 0100 1100 1111 A.
0x0153F, // 0 0 0001 0101 0011 1111 B.
0x000F3, // 0 0 0000 0000 1111 0011 C.
0x0113F, // 0 0 0001 0001 0011 1111 D.
0x040F3, // 0 0 0100 0000 1111 0011 E.
0x040C3, // 0 0 0100 0000 1100 0011 F.
0x004FB, // 0 0 0000 0100 1111 1011 G.
0x044CC, // 0 0 0100 0100 1100 1100 H.
0x01133, // 0 0 0001 0001 0011 0011 I.
0x0007C, // 0 0 0000 0000 0111 1100 J.
0x04AC0, // 0 0 0100 1010 1100 0000 K.
0x000F0, // 0 0 0000 0000 1111 0000 L.
0x082CC, // 0 0 1000 0010 1100 1100 M.
0x088CC, // 0 0 1000 1000 1100 1100 N.
0x000FF, // 0 0 0000 0000 1111 1111 O.
0x044C7, // 0 0 0100 0100 1100 0111 P.
0x008FF, // 0 0 0000 1000 1111 1111 Q.
0x04CC7, // 0 0 0100 1100 1100 0111 R.
0x044BB, // 0 0 0100 0100 1011 1011 S.
0x01103, // 0 0 0001 0001 0000 0011 T.
0x000FC, // 0 0 0000 0000 1111 1100 U.
0x022C0, // 0 0 0010 0010 1100 0000 V.
0x028CC, // 0 0 0010 1000 1100 1100 W.
0x0AA00, // 0 0 1010 1010 0000 0000 X.
0x09200, // 0 0 1001 0010 0000 0000 Y.
0x02233, // 0 0 0010 0010 0011 0011 Z.
0x000E1, // 0 0 0000 0000 1110 0001 [.
0x08800, // 0 0 1000 1000 0000 0000 \.
0x0001E, // 0 0 0000 0000 0001 1110 ].
0x02800, // 0 0 0010 1000 0000 0000 ^.
0x00030, // 0 0 0000 0000 0011 0000 _.
0x00000, // 0 0 0000 0000 0000 0000 dummy.
0x08121, // 0 0 1000 0001 0010 0001 Unknown symbol.
0x00180, // 0 0 0000 0001 1000 0000 ".
0x0553C, // 0 0 0101 0101 0011 1100 #.
0x055BB, // 0 0 0101 0101 1011 1011 $.
0x07799, // 0 0 0111 0111 1001 1001 %.
0x0C979, // 0 0 1100 1001 0111 1001 &.
0x00200, // 0 0 0000 0010 0000 0000 '.
0x00A00, // 0 0 0000 1010 0000 0000 (.
0x0A050, // 0 0 1010 0000 0000 0000 ).
0x0FF00, // 0 0 1111 1111 0000 0000 *.
0x05500, // 0 0 0101 0101 0000 0000 +.
0x30000, // 1 1 0000 0000 0000 0000 ;.
0x04400, // 0 0 0100 0100 0000 0000 --.
0x20000, // 1 0 0000 0000 0000 0000 . .
0x02200, // 0 0 0010 0010 0000 0000 /.
0x022FF, // 0 0 0010 0010 1111 1111 0.
0x01100, // 0 0 0001 0001 0000 0000 1.
0x04477, // 0 0 0100 0100 0111 0111 2.
0x0443F, // 0 0 0100 0100 0011 1111 3.
0x0448C, // 0 0 0100 0100 1000 1100 4.
0x044BB, // 0 0 0100 0100 1011 1011 5.
0x044FB, // 0 0 0100 0100 1111 1011 6.
0x0000E, // 0 0 0000 0000 0000 1110 7.
0x044FF, // 0 0 0100 0100 1111 1111 8.
0x044BF, // 0 0 0100 0100 1011 1111 9.
0x00021, // 0 0 0000 0000 0010 0001 -
// -.
0x02001, // 0 0 0010 0000 0000 0001 -
// /.
0x02430, // 0 0 0010 0100 0011 0000 <.
0x04430, // 0 0 0100 0100 0011 0000 =.
0x08830, // 0 0 1000 1000 0011 0000 >.
0x01407, // 0 0 0001 0100 0000 0111 ?.
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.
0x000E, // 0000 0000 0000 1110 7.
0x44FF, // 0100 0100 1111 1111 8.
0x44BF, // 0100 0100 1011 1111 9.
0x0021, // 0000 0000 0010 0001 -
// -.
0x2001, // 0010 0000 0000 0001 -
// /.
0x2430, // 0010 0100 0011 0000 <.
0x4430, // 0100 0100 0011 0000 =.
0x8830, // 1000 1000 0011 0000 >.
0x1407, // 0001 0100 0000 0111 ?.
};
///////////////////////////////////////////////////////////////////////////
static const int roc10937poslut[]=
{
1,//0
@ -155,244 +122,282 @@ static const int roc10937poslut[]=
0//15
};
///////////////////////////////////////////////////////////////////////////
const device_type ROC10937 = &device_creator<roc10937_t>;
void ROC10937_init(int id, int type,int reversed)
rocvfd_t::rocvfd_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, type, name, tag, owner, clock)
{
assert_always((id >= 0) && (id < MAX_ROCK_ALPHAS), "roc10937_init called on an invalid display ID!");
m_port_val=0;
m_reversed=0;
}
memset( &roc10937[id], 0, sizeof(roc10937[0]));
roc10937[id].type = type;
roc10937[id].reversed = reversed;
ROC10937_reset(id);
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::static_set_zero(device_t &device, bool reversed)
{
rocvfd_t &roc = downcast<rocvfd_t &>(device);
roc.m_reversed = reversed;
}
void rocvfd_t::device_start()
{
save_item(NAME(m_port_val));
save_item(NAME(m_reversed));
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_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;
memset(m_chars, 0, sizeof(m_chars));
memset(m_outputs, 0, sizeof(m_outputs));
}
///////////////////////////////////////////////////////////////////////////
void ROC10937_reset(int id)
UINT32 rocvfd_t::set_display(UINT32 segin)
{
roc10937[id].window_end = 15;
roc10937[id].window_size = (roc10937[id].window_end - roc10937[id].window_start)+1;
memset(roc10937[id].string, ' ', 16);
UINT32 segout=0;
if ( segin & 0x0001 ) segout |= 0x0001;
else segout &= ~0x0001;
if ( segin & 0x0002 ) segout |= 0x0002;
else segout &= ~0x0002;
if ( segin & 0x0004 ) segout |= 0x0004;
else segout &= ~0x0004;
if ( segin & 0x0008 ) segout |= 0x0008;
else segout &= ~0x0008;
if ( segin & 0x0010 ) segout |= 0x0010;
else segout &= ~0x0010;
if ( segin & 0x0020 ) segout |= 0x0020;
else segout &= ~0x0020;
if ( segin & 0x0040 ) segout |= 0x0040;
else segout &= ~0x0040;
if ( segin & 0x0080 ) segout |= 0x0080;
else segout &= ~0x0080;
if ( segin & 0x4000 ) segout |= 0x0100;
else segout &= ~0x0100;
if ( segin & 0x0400 ) segout |= 0x0200;
else segout &= ~0x0200;
if ( segin & 0x0100 ) segout |= 0x0400;
else segout &= ~0x0400;
if ( segin & 0x1000 ) segout |= 0x0800;
else segout &= ~0x0800;
if ( segin & 0x2000 ) segout |= 0x1000;
else segout &= ~0x1000;
if ( segin & 0x8000 ) segout |= 0x2000;
else segout &= ~0x2000;
if ( segin & 0x0200 ) segout |= 0x4000;
else segout &= ~0x4000;
if ( segin & 0x0800 ) segout |= 0x8000;
else segout &= ~0x8000;
if ( segin & 0x10000 ) segout |= 0x10000;
else segout &= ~0x10000;
if ( segin & 0x20000 ) segout |= 0x20000;
else segout &= ~0x20000;
roc10937[id].brightness = 31;
roc10937[id].count = 0;
roc10937[id].changed |= 1;
return segout;
}
///////////////////////////////////////////////////////////////////////////
UINT32 *ROC10937_get_segments(int id)
void rocvfd_t::device_post_load()
{
return roc10937[id].segments;
}
///////////////////////////////////////////////////////////////////////////
UINT32 *ROC10937_get_outputs(int id)
{
return roc10937[id].outputs;
}
///////////////////////////////////////////////////////////////////////////
UINT32 *ROC10937_set_outputs(int id)
{
int cursor,val;
for (cursor = 0; cursor < 16; cursor++)
for (int i =0; i<16; i++)
{
if (!roc10937[id].reversed)//Output to the screen is naturally backwards, so we need to invert it
output_set_indexed_value("vfd", (m_port_val*16) + i, m_outputs[i]);
}
}
void rocvfd_t::update_display()
{
for (int i =0; i<16; i++)
{
if (m_reversed)
{
val = 15-cursor;
m_outputs[i] = set_display(m_chars[15-i]);
}
else
{
//If the controller is reversed, things look normal.
val = cursor;
m_outputs[i] = set_display(m_chars[i]);
}
if ( ROC10937_get_segments(id)[val] & 0x0001 ) roc10937[id].outputs[cursor] |= 0x0001;
else roc10937[id].outputs[cursor] &= ~0x0001;
if ( ROC10937_get_segments(id)[val] & 0x0002 ) roc10937[id].outputs[cursor] |= 0x0002;
else roc10937[id].outputs[cursor] &= ~0x0002;
if ( ROC10937_get_segments(id)[val] & 0x0004 ) roc10937[id].outputs[cursor] |= 0x0004;
else roc10937[id].outputs[cursor] &= ~0x0004;
if ( ROC10937_get_segments(id)[val] & 0x0008 ) roc10937[id].outputs[cursor] |= 0x0008;
else roc10937[id].outputs[cursor] &= ~0x0008;
if ( ROC10937_get_segments(id)[val] & 0x0010 ) roc10937[id].outputs[cursor] |= 0x0010;
else roc10937[id].outputs[cursor] &= ~0x0010;
if ( ROC10937_get_segments(id)[val] & 0x0020 ) roc10937[id].outputs[cursor] |= 0x0020;
else roc10937[id].outputs[cursor] &= ~0x0020;
if ( ROC10937_get_segments(id)[val] & 0x0040 ) roc10937[id].outputs[cursor] |= 0x0040;
else roc10937[id].outputs[cursor] &= ~0x0040;
if ( ROC10937_get_segments(id)[val] & 0x0080 ) roc10937[id].outputs[cursor] |= 0x0080;
else roc10937[id].outputs[cursor] &= ~0x0080;
if ( ROC10937_get_segments(id)[val] & 0x4000 ) roc10937[id].outputs[cursor] |= 0x0100;
else roc10937[id].outputs[cursor] &= ~0x0100;
if ( ROC10937_get_segments(id)[val] & 0x0400 ) roc10937[id].outputs[cursor] |= 0x0200;
else roc10937[id].outputs[cursor] &= ~0x0200;
if ( ROC10937_get_segments(id)[val] & 0x0100 ) roc10937[id].outputs[cursor] |= 0x0400;
else roc10937[id].outputs[cursor] &= ~0x0400;
if ( ROC10937_get_segments(id)[val] & 0x1000 ) roc10937[id].outputs[cursor] |= 0x0800;
else roc10937[id].outputs[cursor] &= ~0x0800;
if ( ROC10937_get_segments(id)[val] & 0x2000 ) roc10937[id].outputs[cursor] |= 0x1000;
else roc10937[id].outputs[cursor] &= ~0x1000;
if ( ROC10937_get_segments(id)[val] & 0x8000 ) roc10937[id].outputs[cursor] |= 0x2000;
else roc10937[id].outputs[cursor] &= ~0x2000;
if ( ROC10937_get_segments(id)[val] & 0x0200 ) roc10937[id].outputs[cursor] |= 0x4000;
else roc10937[id].outputs[cursor] &= ~0x4000;
if ( ROC10937_get_segments(id)[val] & 0x0800 ) roc10937[id].outputs[cursor] |= 0x8000;
else roc10937[id].outputs[cursor] &= ~0x8000;
if ( ROC10937_get_segments(id)[val] & 0x10000 ) roc10937[id].outputs[cursor] |= 0x10000;
else roc10937[id].outputs[cursor] &= ~0x10000;
if ( ROC10937_get_segments(id)[val] & 0x20000 ) roc10937[id].outputs[cursor] |= 0x20000;
else roc10937[id].outputs[cursor] &= ~0x20000;
output_set_indexed_value("vfd", (m_port_val*16) + i, m_outputs[i]);
}
return 0;
}
///////////////////////////////////////////////////////////////////////////
char *ROC10937_get_string( int id)
void rocvfd_t::shift_data(int data)
{
return (char *)roc10937[id].string;
}
m_shift_data <<= 1;
///////////////////////////////////////////////////////////////////////////
if ( !data ) m_shift_data |= 1;
void ROC10937_shift_data(int id, int data)
{
roc10937[id].data <<= 1;
if ( !data ) roc10937[id].data |= 1;
if ( ++roc10937[id].count >= 8 )
if ( ++m_shift_count >= 8 )
{
if ( ROC10937_newdata(id, roc10937[id].data) )
{
roc10937[id].changed |= 1;
}
roc10937[id].count = 0;
roc10937[id].data = 0;
write_char(m_shift_data);
m_shift_count = 0;
m_shift_data = 0;
}
update_display();
}
///////////////////////////////////////////////////////////////////////////
int ROC10937_newdata(int id, int data)
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)
{
int change = 0;
m_port_val=0;
m_reversed=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)
{
m_port_val=0;
m_reversed=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
roc10937[id].cursor_pos = roc10937poslut[data & 0x0F];
m_cursor_pos = roc10937poslut[data & 0x0F];
}
else if ( (data & 0xF0) == 0xC0 ) // 1100 xxxx
{ // 1100 xxxx Set number of digits
data &= 0x0F;
if ( data == 0 ) roc10937[id].window_size = 16;
else roc10937[id].window_size = data;
roc10937[id].window_start = 0;
roc10937[id].window_end = roc10937[id].window_size-1;
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 )
roc10937[id].brightness = (data & 0x1F);
change = 1;
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)
{
m_port_val=0;
m_reversed=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;
change = 1;
switch ( data )
{
case 0x2C: // ;
roc10937[id].segments[roc10937[id].pcursor_pos] |= (1<<16);//.
roc10937[id].segments[roc10937[id].pcursor_pos] |= (1<<17);//,
m_chars[m_pcursor_pos] |= (1<<16);//.
m_chars[m_pcursor_pos] |= (1<<17);//,
break;
case 0x2E: //
roc10937[id].segments[roc10937[id].pcursor_pos] |= (1<<16);//.
m_chars[m_pcursor_pos] |= (1<<16);//.
break;
case 0x6C: // ;
roc10937[id].segments[roc10937[id].pcursor_pos] |= (1<<16);//.
if ( roc10937[id].type == ROCKWELL10937)
{
roc10937[id].segments[roc10937[id].pcursor_pos] |= (1<<17);//,
}
m_chars[m_pcursor_pos] |= (1<<16);//.
break;
case 0x6E: //
if ( roc10937[id].type == ROCKWELL10937)
{
roc10937[id].segments[roc10937[id].pcursor_pos] |= (1<<16);//.
}
else
{
roc10937[id].segments[roc10937[id].pcursor_pos] |= (1<<17);//,
m_chars[m_pcursor_pos] = 0;
}
break;
default :
roc10937[id].pcursor_pos = roc10937[id].cursor_pos;
roc10937[id].string[ roc10937[id].cursor_pos ] = roc10937ASCII[data];
roc10937[id].segments[roc10937[id].cursor_pos] = roc10937charset[data & 0x3F];
m_pcursor_pos = m_cursor_pos;
m_chars[m_cursor_pos] = roc10937charset[data & 0x3F];
roc10937[id].cursor_pos++;
if ( roc10937[id].cursor_pos > roc10937[id].window_end )
m_cursor_pos++;
if ( m_cursor_pos > (m_window_size -1) )
{
roc10937[id].cursor_pos = 0;
m_cursor_pos = 0;
}
break;
}
}
return change;
}
///////////////////////////////////////////////////////////////////////////
static void ROC10937_plot(int id, int power)
{
int cursor;
ROC10937_set_outputs(id);
for (cursor = 0; cursor < 16; cursor++)
{
output_set_indexed_value("vfd", (id*16)+cursor, power?ROC10937_get_outputs(id)[cursor]:0x00000);
}
}
static void ROC10937_draw(int id, int segs)
{
int cycle;
for (cycle = 0; cycle < 32; cycle++)
{
if ((roc10937[id].brightness < cycle)||(roc10937[id].brightness == cycle))
{
ROC10937_plot(id,1);
}
else
{
ROC10937_plot(id,0);
}
}
}
//Helper functions
void ROC10937_draw_16seg(int id)
{
ROC10937_draw(id,16);
}
void ROC10937_draw_14seg(int id)
{
ROC10937_draw(id,14);
}

View File

@ -4,31 +4,124 @@
OKI MSC1937 is a clone of this chip
**********************************************************************/
#pragma once
#ifndef ROC10937
#define ROC10937
#ifndef ROC10937_H
#define ROC10937_H
#define MAX_ROCK_ALPHAS 3 // max number of displays emulated
#define LEFT_TO_RIGHT 1
#define RIGHT_TO_LEFT 0
#define ROCKWELL10937 0 // Rockwell 10937
#define MSC1937 0 // OKI MSC1937 clone of Rockwell 10937
#define ROCKWELL10957 1 // Rockwell 10957
#define MCFG_ROC10937_ADD(_tag,_val,_reversed) \
MCFG_DEVICE_ADD(_tag, ROC10937,60)\
MCFG_ROC10937_PORT(_val) \
MCFG_ROC10937_REVERSE(_reversed) \
void ROC10937_init( int id, int type,int reversed ); // setup a display
#define MCFG_ROC10937_PORT(_val) \
roc10937_t::static_set_value(*device, _val); \
void ROC10937_reset( int id); // reset the alpha
#define MCFG_ROC10937_REVERSE(_reversed) \
roc10937_t::static_set_zero(*device, _reversed); \
#define MCFG_ROC10937_REMOVE(_tag) \
MCFG_DEVICE_REMOVE(_tag)
void ROC10937_shift_data(int id, int data); // clock in a bit of data
#define MCFG_ROC10957_ADD(_tag,_val,_reversed) \
MCFG_DEVICE_ADD(_tag, ROC10957,60)\
MCFG_ROC10957_PORT(_val) \
MCFG_ROC10957_REVERSE(_reversed) \
int ROC10937_newdata( int id, int data); // clock in 8 bits of data
#define MCFG_ROC10957_PORT(_val) \
roc10957_t::static_set_value(*device, _val); \
UINT32 *ROC10937_get_segments(int id); // get current segments displayed
UINT32 *ROC10937_set_outputs(int id); // convert segments to standard for display
UINT32 *ROC10937_get_outputs(int id); // get converted segments
#define MCFG_ROC10957_REVERSE(_reversed) \
roc10957_t::static_set_zero(*device, _reversed); \
char *ROC10937_get_string( int id); // get current string displayed (not as accurate)
#define MCFG_ROC10957_REMOVE(_tag) \
MCFG_DEVICE_REMOVE(_tag)
#define MCFG_MSC1937_ADD(_tag,_val,_reversed) \
MCFG_DEVICE_ADD(_tag, ROC10937,60)\
MCFG_MSC1937_PORT(_val) \
MCFG_MSC1937_REVERSE(_reversed) \
#define MCFG_MSC1937_PORT(_val) \
MCFG_ROC10937_PORT(_val)
#define MCFG_MSC1937_REVERSE(_reversed) \
roc10937_t::static_set_zero(*device, _reversed); \
#define MCFG_MSC1937_REMOVE(_tag) \
MCFG_DEVICE_REMOVE(_tag)
class rocvfd_t : public device_t {
public:
typedef delegate<void (bool state)> line_cb;
rocvfd_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
// inline configuration helpers
static void static_set_value(device_t &device, int val);
static void static_set_zero(device_t &device, bool reversed);
virtual void update_display();
UINT8 m_port_val;
bool m_reversed;
void blank(int data);
void shift_data(int data);
void write_char(int data);
void setdata(int segdata, int data);
UINT32 set_display(UINT32 segin);
protected:
int m_cursor_pos;
int m_window_size; // window size
int m_shift_count;
int m_shift_data;
int m_pcursor_pos;
int m_brightness;
int m_count;
int m_duty;
int m_disp;
UINT8 m_cursor;
UINT32 m_chars[16];
UINT32 m_outputs[16];
virtual void device_start();
virtual void device_reset();
virtual void device_post_load();
};
class roc10937_t : public rocvfd_t {
public:
roc10937_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
protected:
};
class msc1937_t : public rocvfd_t {
public:
msc1937_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
protected:
};
class roc10957_t : public rocvfd_t {
public:
roc10957_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
void write_char(int data);
protected:
};
extern const device_type ROC10937;
extern const device_type MSC1937;
extern const device_type ROC10957;
void ROC10937_draw_16seg(int id);
void ROC10937_draw_14seg(int id);
#endif

View File

@ -1179,7 +1179,7 @@ WRITE8_MEMBER(bfm_sc2_state::vfd1_data_w)
}
else
{
m_vfd0->write_char(data);
m_vfd0->write_char(data);
}
}

View File

@ -72,11 +72,14 @@ class bfmsys85_state : public driver_device
{
public:
bfmsys85_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag) { }
: driver_device(mconfig, type, tag),
m_vfd(*this, "vfd")
{ }
optional_device<roc10937_t> m_vfd;
int m_mmtr_latch;
int m_triac_latch;
int m_vfd_latch;
int m_alpha_clock;
int m_irq_status;
int m_optic_pattern;
int m_locked;
@ -146,7 +149,7 @@ static ACIA6850_INTERFACE( m6809_acia_if )
static MACHINE_RESET( bfm_sys85 )
{
bfmsys85_state *state = machine.driver_data<bfmsys85_state>();
state->m_vfd_latch = 0;
state->m_alpha_clock = 0;
state->m_mmtr_latch = 0;
state->m_triac_latch = 0;
state->m_irq_status = 0;
@ -156,7 +159,7 @@ static MACHINE_RESET( bfm_sys85 )
state->m_mux_input_strobe = 0;
state->m_mux_input = 0;
ROC10937_reset(0); // reset display1
state->m_vfd->reset(); // reset display1
// reset stepper motors ///////////////////////////////////////////////////
{
@ -257,31 +260,23 @@ READ8_MEMBER(bfmsys85_state::mmtr_r)
WRITE8_MEMBER(bfmsys85_state::vfd_w)
{
int changed = m_vfd_latch ^ data;
m_vfd_latch = data;
if ( changed )
if (data & VFD_RESET)//inverted?
{
if ( changed & VFD_RESET )
{ // vfd reset line changed
if ( !(data & VFD_RESET) )
{ // reset the vfd
ROC10937_reset(0);
ROC10937_reset(1);
ROC10937_reset(2);
if (m_alpha_clock != (data & VFD_CLOCK1))
{
if (m_alpha_clock)//rising edge
{
m_vfd->shift_data(data & VFD_DATA?1:0);
}
}
if ( changed & VFD_CLOCK1 )
{ // clock line changed
if ( !(data & VFD_CLOCK1) && (data & VFD_RESET) )
{ // new data clocked into vfd //////////////////////////////////////
ROC10937_shift_data(0, data & VFD_DATA );
}
}
ROC10937_draw_16seg(0);
m_alpha_clock = (data & VFD_CLOCK1);
}
else
{
m_vfd->reset();
}
}
//////////////////////////////////////////////////////////////////////////////////
@ -380,8 +375,6 @@ static MACHINE_START( bfm_sys85 )
stepper_config(machine, i, &starpoint_interface_48step);
}
ROC10937_init(0,MSC1937,1);//?
}
// memory map for bellfruit system85 board ////////////////////////////////
@ -426,6 +419,7 @@ static MACHINE_CONFIG_START( bfmsys85, bfmsys85_state )
MCFG_CPU_ADD("maincpu", M6809, MASTER_CLOCK/4) // 6809 CPU at 1 Mhz
MCFG_CPU_PROGRAM_MAP(memmap) // setup read and write memorymap
MCFG_CPU_PERIODIC_INT(timer_irq, 1000 ) // generate 1000 IRQ's per second
MCFG_MSC1937_ADD("vfd",0,RIGHT_TO_LEFT)
MCFG_ACIA6850_ADD("acia6850_0", m6809_acia_if)

View File

@ -7,6 +7,7 @@
Motherboard contains very few major components
Missing sound roms? (or is sound data in the program roms?)
NOTE: VFD is guessed as 16 segment, need to know more
*******************************************************************************/
@ -22,62 +23,62 @@ class globalfr_state : public driver_device
public:
globalfr_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu")
{ }
m_maincpu(*this, "maincpu"),
m_vfd(*this, "vfd")
{ }
required_device<cpu_device> m_maincpu;
optional_device<roc10937_t> m_vfd;
// serial vfd
bool vfd_old_clock;
int m_alpha_clock;
DECLARE_WRITE16_MEMBER(vfd_w);
};
/******************************************************************************/
static WRITE16_HANDLER(vfd_w)
WRITE16_MEMBER(globalfr_state::vfd_w)
{
globalfr_state *state = space->machine().driver_data<globalfr_state>();
bool clock = (data & 0x40) != 0;
int datline = (data & 0x80);
//Unlike MPU4, this uses positive transitions on both lines, so this may be a similar, but not identical component
// if the clock line changes
if ( clock != state->vfd_old_clock )
// if(!(data & 0x20)) need to find reset
{
if ( clock )//clock on rising edge
bool clock = (data & 0x40) != 0;
int datline = (data & 0x80);
if (m_alpha_clock != clock)
{
ROC10937_shift_data(0, datline?1:0);
if (!m_alpha_clock)
{
m_vfd->shift_data(datline?1:0);
}
}
m_alpha_clock = clock;
}
ROC10937_draw_16seg(0);
state->vfd_old_clock = clock;
// else
// {
// m_vfd->reset();
// }
}
static ADDRESS_MAP_START( globalfr_map, AS_PROGRAM, 16, globalfr_state )
AM_RANGE(0x002000, 0x002fff) AM_RAM
AM_RANGE(0x008000, 0x07ffff) AM_ROM AM_REGION("maincpu", 0x8000)
AM_RANGE(0x0a0000, 0x0a01ff) AM_RAM
AM_RANGE(0x7e0040, 0x7e0041) AM_WRITE_LEGACY(vfd_w)
AM_RANGE(0x7e0040, 0x7e0041) AM_WRITE(vfd_w)
ADDRESS_MAP_END
static INPUT_PORTS_START( globalfr )
INPUT_PORTS_END
static MACHINE_START( globalfr )
{
//We assume this is a 16 seg display, but could be 14.
ROC10937_init(0, MSC1937,1);
}
/******************************************************************************/
static MACHINE_CONFIG_START( globalfr, globalfr_state )
/* basic machine hardware */
MCFG_MACHINE_START(globalfr )
MCFG_CPU_ADD("maincpu", M37710, 4000000)
MCFG_CPU_PROGRAM_MAP(globalfr_map)
MCFG_ROC10937_ADD("vfd",0,RIGHT_TO_LEFT)
MCFG_DEFAULT_LAYOUT(layout_globalfr)
MACHINE_CONFIG_END

View File

@ -944,25 +944,23 @@ WRITE8_MEMBER(jpmimpct_state::payen_a_w)
WRITE8_MEMBER(jpmimpct_state::display_c_w)
{
//Reset 0x04, data 0x02, clock 0x01
if(data & 0x04)
{
m_alpha_data_line = ((data >> 1) & 1);
if (m_alpha_clock != (data & 1))
int alpha_data = (data & 0x02)?0:1;
if (m_alpha_clock != (data & 0x01))
{
if (!m_alpha_clock)//falling edge
{
ROC10937_shift_data(0, m_alpha_data_line?0:1);
m_vfd->shift_data(alpha_data);
}
}
m_alpha_clock = (data & 1);
m_alpha_clock = (data & 0x01);
}
else
{
ROC10937_reset(0);
m_vfd->reset();
}
ROC10937_draw_16seg(0);
//?
}
static I8255_INTERFACE (ppi8255_intf)
@ -1003,9 +1001,7 @@ static MACHINE_RESET( impctawp )
/* Reset states */
state->m_duart_1_irq = 0;
ROC10937_init(0, MSC1937,1);//Reversed
ROC10937_reset(0); /* reset display1 */
state->m_vfd->reset();
}
/*************************************
*
@ -1379,6 +1375,7 @@ static MACHINE_CONFIG_START( impctawp, jpmimpct_state )
MCFG_CPU_PROGRAM_MAP(awp68k_program_map)
MCFG_QUANTUM_TIME(attotime::from_hz(30000))
MCFG_ROC10937_ADD("vfd",0,RIGHT_TO_LEFT)
MCFG_MACHINE_START(impctawp)
MCFG_MACHINE_RESET(impctawp)

View File

@ -47,7 +47,9 @@ class jpmsys5_state : public driver_device
{
public:
jpmsys5_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag) { }
: driver_device(mconfig, type, tag),
m_vfd(*this, "vfd")
{ }
UINT8 m_palette[16][3];
int m_pal_addr;
@ -60,6 +62,8 @@ public:
int m_lamp_strobe;
int m_mpxclk;
int m_muxram[255];
int m_alpha_clock;
optional_device<roc10937_t> m_vfd;
UINT8 m_a0_acia_dcd;
UINT8 m_a0_data_out;
UINT8 m_a0_data_in;
@ -303,20 +307,47 @@ READ16_MEMBER(jpmsys5_state::mux_r)
WRITE16_MEMBER(jpmsys5_state::jpm_upd7759_w)
{
device_t *device = machine().device("upd7759");
if (offset == 0)
switch (offset)
{
upd7759_port_w(device, 0, data & 0xff);
upd7759_start_w(device, 0);
upd7759_start_w(device, 1);
}
else if (offset == 2)
{
upd7759_reset_w(device, ~data & 0x4);
upd7759_set_bank_base(device, (data & 2) ? 0x20000 : 0);
}
else
{
logerror("%s: upd7759: Unknown write to %x with %x\n", machine().describe_context(), offset, data);
case 0:
{
upd7759_port_w(device, 0, data & 0xff);
upd7759_start_w(device, 0);
upd7759_start_w(device, 1);
break;
}
case 1:
{
//Reset 0x04, data 0x02, clock 0x01
if(data & 0x04)
{
int alpha_data = (data & 0x02)?0:1;
if (m_alpha_clock != (data & 0x01))
{
if (!m_alpha_clock)//falling edge
{
m_vfd->shift_data(alpha_data);
}
}
m_alpha_clock = (data & 0x01);
}
else
{
m_vfd->reset();
}
break;
}
case 2:
{
upd7759_reset_w(device, ~data & 0x04);
upd7759_set_bank_base(device, (data & 2) ? 0x20000 : 0);
break;
}
default:
{
logerror("%s: upd7759: Unknown write to %x with %x\n", machine().describe_context(), offset, data);
break;
}
}
}
@ -661,6 +692,8 @@ static MACHINE_RESET( jpmsys5v )
state->m_touch_state = IDLE;
state->m_a2_data_in = 1;
state->m_a2_acia_dcd = 0;
state->m_vfd->reset();
}
@ -680,6 +713,8 @@ static MACHINE_CONFIG_START( jpmsys5v, jpmsys5_state )
MCFG_NVRAM_ADD_0FILL("nvram")
MCFG_ROC10937_ADD("vfd",0,RIGHT_TO_LEFT)//for debug ports
MCFG_MACHINE_START(jpmsys5v)
MCFG_MACHINE_RESET(jpmsys5v)
@ -809,6 +844,7 @@ static MACHINE_RESET( jpmsys5 )
jpmsys5_state *state = machine.driver_data<jpmsys5_state>();
state->m_a2_data_in = 1;
state->m_a2_acia_dcd = 0;
state->m_vfd->reset();
}
/*************************************
@ -826,6 +862,7 @@ static MACHINE_CONFIG_START( jpmsys5, jpmsys5_state )
MCFG_ACIA6850_ADD("acia6850_2", acia2_if)
MCFG_NVRAM_ADD_0FILL("nvram")
MCFG_ROC10937_ADD("vfd",0,RIGHT_TO_LEFT)
MCFG_MACHINE_START(jpmsys5)
MCFG_MACHINE_RESET(jpmsys5)

View File

@ -112,7 +112,9 @@ class maygay1b_state : public driver_device
{
public:
maygay1b_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag) { }
: driver_device(mconfig, type, tag),
m_vfd(*this, "vfd")
{ }
UINT8 m_lamppos;
int m_alpha_clock;
@ -123,6 +125,7 @@ public:
int m_SRSEL;
UINT8 m_Lamps[256];
int m_optic_pattern;
optional_device<roc10937_t> m_vfd;
device_t *m_duart68681;
i8279_state m_i8279[2];
DECLARE_READ8_MEMBER(m1_8279_r);
@ -537,7 +540,7 @@ static void m1_stepper_reset(running_machine &machine)
static MACHINE_RESET( m1 )
{
maygay1b_state *state = machine.driver_data<maygay1b_state>();
ROC10937_reset(0); // reset display1
state->m_vfd->reset(); // reset display1
state->m_duart68681 = machine.device( "duart68681" );
m1_stepper_reset(machine);
}
@ -570,16 +573,21 @@ static void cpu0_nmi(running_machine &machine, int state)
WRITE8_MEMBER(maygay1b_state::m1_pia_porta_w)
{
if ( data & 0x40 ) ROC10937_reset(0);
if ( !m_alpha_clock && (data & 0x20) )
if(!(data & 0x40))
{
ROC10937_shift_data(0, ( data & 0x10 )?0:1);
if (m_alpha_clock != (data & 0x20))
{
if (!m_alpha_clock)//falling edge
{
m_vfd->shift_data((data & 0x10)?1:0);
}
}
m_alpha_clock = (data & 0x20);
}
else
{
m_vfd->reset();
}
m_alpha_clock = data & 0x20;
ROC10937_draw_16seg(0);
}
WRITE8_MEMBER(maygay1b_state::m1_pia_portb_w)
@ -735,8 +743,6 @@ static MACHINE_START( m1 )
stepper_config(machine, i, &starpoint_interface_48step);
}
// setup the standard oki MSC1937 display ///////////////////////////////
ROC10937_init(0, MSC1937,0);
}
WRITE8_MEMBER(maygay1b_state::reel12_w)
{
@ -911,7 +917,7 @@ static MACHINE_CONFIG_START( m1, maygay1b_state )
MCFG_DUART68681_ADD("duart68681", M1_DUART_CLOCK, maygaym1_duart68681_config)
MCFG_PIA6821_ADD("pia", m1_pia_intf)
MCFG_MSC1937_ADD("vfd",0,LEFT_TO_RIGHT)
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("aysnd",AY8913, M1_MASTER_CLOCK)
MCFG_SOUND_CONFIG(ay8910_config)

View File

@ -117,7 +117,10 @@ class mpu3_state : public driver_device
{
public:
mpu3_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag) { }
: driver_device(mconfig, type, tag),
m_vfd(*this, "vfd")
{ }
optional_device<roc10937_t> m_vfd;
int m_alpha_data_line;
@ -213,7 +216,7 @@ static void mpu3_stepper_reset(running_machine &machine)
static MACHINE_RESET( mpu3 )
{
mpu3_state *state = machine.driver_data<mpu3_state>();
ROC10937_reset(0); /* reset display1 */
state->m_vfd->reset();
mpu3_stepper_reset(machine);
@ -622,16 +625,18 @@ READ8_MEMBER(mpu3_state::pia_ic6_portb_r)
WRITE8_MEMBER(mpu3_state::pia_ic6_porta_w)
{
LOG(("%s: IC6 PIA Port A Set to %2x (Alpha)\n", machine().describe_context(),data));
if ( data & 0x08 ) ROC10937_reset(0);
if ( data & 0x08 ) m_vfd->reset();
m_alpha_data_line = ((data & 0x20) >> 5);
if ( !m_alpha_clock && (data & 0x10) )
if (m_alpha_clock != ((data & 0x10) >>4))
{
ROC10937_shift_data(0, m_alpha_data_line&0x01?0:1);
if (!m_alpha_clock)//falling edge
{
m_vfd->shift_data(m_alpha_data_line?1:0);
}
}
m_alpha_clock = (data & 0x10);
ROC10937_draw_16seg(0);
m_alpha_clock = (data & 0x10) >>4;
}
WRITE8_MEMBER(mpu3_state::pia_ic6_portb_w)
@ -792,8 +797,6 @@ static MACHINE_START( mpu3 )
stepper_config(machine, 2, &mpu3_reel_interface);
stepper_config(machine, 3, &mpu3_reel_interface);
/* setup the standard oki MSC1937 display */
ROC10937_init(0, MSC1937,0);
}
/*
Characteriser (CHR)
@ -898,6 +901,8 @@ static MACHINE_CONFIG_START( mpu3base, mpu3_state )
MCFG_CPU_ADD("maincpu", M6808, MPU3_MASTER_CLOCK)///4)
MCFG_CPU_PROGRAM_MAP(mpu3_basemap)
MCFG_MSC1937_ADD("vfd",0,LEFT_TO_RIGHT)
MCFG_TIMER_ADD_PERIODIC("50hz",gen_50hz, attotime::from_hz(100))
MCFG_TIMER_ADD_PERIODIC("555_ic10",ic10_callback, PERIOD_OF_555_ASTABLE(10000,1000,0.0000001))

View File

@ -440,7 +440,7 @@ void mpu4_stepper_reset(mpu4_state *state)
static MACHINE_RESET( mpu4 )
{
mpu4_state *state = machine.driver_data<mpu4_state>();
ROC10937_reset(0); /* reset display1 */
state->m_vfd->reset();
mpu4_stepper_reset(state);
@ -612,6 +612,7 @@ WRITE8_MEMBER(mpu4_state::pia_ic3_portb_w)
{
/* Some games (like Connect 4) use 'programmable' LED displays, built from light display lines in section 2. */
/* These are mostly low-tech machines, where such wiring proved cheaper than an extender card */
/* TODO: replace this with 'segment' lamp masks, to make it more generic */
UINT8 pled_segs[2] = {0,0};
static const int lamps1[8] = { 106, 107, 108, 109, 104, 105, 110, 133 };
@ -643,7 +644,7 @@ WRITE_LINE_MEMBER(mpu4_state::pia_ic3_cb2_w)
// DM Data pin A
if ( !state )
{
ROC10937_reset(0);
m_vfd->reset();
}
}
@ -790,16 +791,16 @@ READ8_MEMBER(mpu4_state::pia_ic4_portb_r)
if (!m_reel_mux)
{
if ( m_optic_pattern & 0x01 ) m_ic4_input_b |= 0x40; /* reel A tab */
else m_ic4_input_b &= ~0x40;
else m_ic4_input_b &= ~0x40;
if ( m_optic_pattern & 0x02 ) m_ic4_input_b |= 0x20; /* reel B tab */
else m_ic4_input_b &= ~0x20;
else m_ic4_input_b &= ~0x20;
if ( m_optic_pattern & 0x04 ) m_ic4_input_b |= 0x10; /* reel C tab */
else m_ic4_input_b &= ~0x10;
else m_ic4_input_b &= ~0x10;
if ( m_optic_pattern & 0x08 ) m_ic4_input_b |= 0x08; /* reel D tab */
else m_ic4_input_b &= ~0x08;
else m_ic4_input_b &= ~0x08;
}
else
@ -814,7 +815,7 @@ READ8_MEMBER(mpu4_state::pia_ic4_portb_r)
}
}
if ( m_signal_50hz ) m_ic4_input_b |= 0x04; /* 50 Hz */
else m_ic4_input_b &= ~0x04;
else m_ic4_input_b &= ~0x04;
if (m_ic4_input_b & 0x02)
{
@ -961,7 +962,7 @@ WRITE8_MEMBER(mpu4_state::pia_ic5_porta_w)
if (mame_stricmp(machine().system().name, "m4gambal") == 0)
{
/* The 'Gamball' device is a unique piece of mechanical equipment, designed to
provide a truly fair hi-lo gamble for an AWP machine(). Functionally, it consists of
provide a truly fair hi-lo gamble for an AWP. Functionally, it consists of
a ping-pong ball or similar enclosed in the machine's backbox, on a platform with 12
holes. When the low 4 bytes of AUX1 are triggered, this fires the ball out from the
hole it's currently in, to land in another. Landing in the same hole causes the machine to
@ -971,7 +972,7 @@ WRITE8_MEMBER(mpu4_state::pia_ic5_porta_w)
of making the game fair, short of simulating the physics of a bouncing ball ;)*/
if (data & 0x0f)
{
switch (machine().rand() & 0x2)
switch ((machine().rand()>>5) & 0x2)
{
case 0x00: //Top row
{
@ -1340,12 +1341,6 @@ all eight meters are driven from this port, giving the 8 line driver chip
}
}
WRITE_LINE_MEMBER(mpu4_state::pia_ic7_ca2_w)
{
mpu4_state *drvstate = machine().driver_data<mpu4_state>();
@ -1430,11 +1425,10 @@ WRITE_LINE_MEMBER(mpu4_state::pia_ic8_cb2_w)
{
if (!m_alpha_clock)//falling edge
{
ROC10937_shift_data(0, m_alpha_data_line?0:1);
m_vfd->shift_data(m_alpha_data_line?0:1);
}
}
m_alpha_clock = state;
ROC10937_draw_16seg(0);
}
@ -1507,7 +1501,7 @@ READ8_MEMBER(mpu4_state::pia_gb_portb_r)
//
if ( okim6376_nar_r(msm6376) ) data |= 0x80;
else data &= ~0x80;
else data &= ~0x80;
if ( okim6376_busy_r(msm6376) ) data |= 0x40;
else data &= ~0x40;
@ -2588,9 +2582,6 @@ void mpu4_config_common(running_machine &machine)
/* setup 8 mechanical meters */
MechMtr_config(machine,8);
/* setup the standard oki MSC1937 display */
ROC10937_init(0, MSC1937,0);
}
static void mpu4_config_common_reels(running_machine &machine,int reels)
@ -2839,7 +2830,7 @@ READ8_MEMBER(mpu4_state::crystal_sound_r)
{
return machine().rand();
}
//this may be a YMZ280B
WRITE8_MEMBER(mpu4_state::crystal_sound_w)
{
printf("crystal_sound_w %02x\n",data);
@ -2895,6 +2886,7 @@ const ay8910_interface ay8910_config =
MACHINE_CONFIG_FRAGMENT( mpu4_common )
MCFG_TIMER_ADD_PERIODIC("50hz",gen_50hz, attotime::from_hz(100))
MCFG_MSC1937_ADD("vfd",0,LEFT_TO_RIGHT)
/* 6840 PTM */
MCFG_PTM6840_ADD("ptm_ic2", ptm_ic2_intf)

View File

@ -1944,9 +1944,6 @@ static MACHINE_START( mpu4_vid )
/* setup 8 mechanical meters */
MechMtr_config(machine,8);
/* setup the standard oki MSC1937 display */
ROC10937_init(0, MSC1937, 0);
/* Hook the reset line */
m68k_set_reset_callback(machine.device("video"), video_reset);
}
@ -1954,7 +1951,7 @@ static MACHINE_START( mpu4_vid )
static MACHINE_RESET( mpu4_vid )
{
mpu4_state *state = machine.driver_data<mpu4_state>();
ROC10937_reset(0);
state->m_vfd->reset(); //for debug ports only
mpu4_stepper_reset(state);
@ -2931,12 +2928,6 @@ ROM_START( v4dealem )
ROM_LOAD( "zenndlem.u10", 0x000, 0x104, CRC(e3103c05) SHA1(91b7be75c5fb37025039ab54b484e46a033969b5) )
ROM_END
/*
Barcrest released two different games called "The Crystal Maze".
One is a non-video AWP, and uses only the MPU4 card, and the other SWP is the one we're interested in running
Some of the dumps available seem to confuse the two, due to an early database not distinguishing
between MPU4 and MPU4Video, as the latter had not been emulated at all at that stage. */
#define VID_BIOS \
ROM_LOAD("vid.p1", 0x00000, 0x10000, CRC(e996bc18) SHA1(49798165640627eb31024319353da04380787b10))
@ -4748,7 +4739,7 @@ ROM_END
/* Complete sets */
/* Standard sets are the most common setups, while Datapak releases use a BACTA datalogger (not emulated) to record more information about the game operation, for security etc.
AMLD versions do not pay out, and instead just feature highscore tables. These were mainly intended for locations unwilling to pay for gaming licenses.
The AMLD versions appear to be a mixture of the original game modules and Team Challenge's scoring system. This would suggest they were all made ~1994. */
The AMLD Crystal Maze versions appear to be a mixture of the original game modules and Team Challenge's scoring system. This would suggest they were all made ~1994. */
GAME( 199?,v4bios, 0, mod2, mpu4, 0, ROT0, "Barcrest","MPU4 Video Firmware",GAME_IS_BIOS_ROOT )

View File

@ -21,6 +21,7 @@ class proconn_state : public driver_device
public:
proconn_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_vfd(*this, "vfd"),
m_maincpu(*this, "maincpu"),
m_z80pio_1(*this, "z80pio_1"),
m_z80pio_2(*this, "z80pio_2"),
@ -32,6 +33,7 @@ public:
m_ay(*this, "aysnd")
{ }
optional_device<roc10937_t> m_vfd;
DECLARE_WRITE8_MEMBER( ay_w0 ) { ay8910_address_data_w(m_ay, 0, data); }
DECLARE_WRITE8_MEMBER( ay_w1 ) { ay8910_address_data_w(m_ay, 1, data); }
@ -258,10 +260,15 @@ static Z80CTC_INTERFACE( ctc_intf )
static WRITE8_DEVICE_HANDLER( serial_transmit )
{
// if (offset == 0)
proconn_state *state = device->machine().driver_data<proconn_state>();
//Don't like the look of this, should be a clock somewhere
// if (offset == 0)
// state->m_vfd->write_char( data );
for (int i=0; i<8;i++)
{
ROC10937_newdata(0, data);
ROC10937_draw_16seg(0);
state->m_vfd->shift_data( (data & (1<<i))?0:1 );
}
}
@ -300,13 +307,8 @@ static const z80_daisy_config z80_daisy_chain[] =
static MACHINE_RESET( proconn )
{
ROC10937_reset(0);
ROC10937_draw_16seg(0);
}
static MACHINE_START( proconn )
{
ROC10937_init(0, ROCKWELL10937,1);
proconn_state *state = machine.driver_data<proconn_state>();
state->m_vfd->reset(); // reset display1
}
static MACHINE_CONFIG_START( proconn, proconn_state )
@ -314,7 +316,8 @@ static MACHINE_CONFIG_START( proconn, proconn_state )
MCFG_CPU_CONFIG(z80_daisy_chain)
MCFG_CPU_PROGRAM_MAP(proconn_map)
MCFG_CPU_IO_MAP(proconn_portmap)
MCFG_ROC10937_ADD("vfd",0,LEFT_TO_RIGHT)
MCFG_Z80PIO_ADD( "z80pio_1", 4000000, pio_interface_1 ) /* ?? Mhz */
MCFG_Z80PIO_ADD( "z80pio_2", 4000000, pio_interface_2 ) /* ?? Mhz */
MCFG_Z80PIO_ADD( "z80pio_3", 4000000, pio_interface_3 ) /* ?? Mhz */
@ -325,7 +328,6 @@ static MACHINE_CONFIG_START( proconn, proconn_state )
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
MCFG_MACHINE_START( proconn )
MCFG_MACHINE_RESET( proconn )
MCFG_DEFAULT_LAYOUT(layout_awpvid16)

View File

@ -3,6 +3,7 @@
JPM IMPACT with Video hardware
****************************************************************************/
#include "machine/roc10937.h"
struct duart_t
{
@ -54,6 +55,7 @@ class jpmimpct_state : public driver_device
public:
jpmimpct_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_vfd(*this, "vfd"),
m_vram(*this, "vram") { }
UINT8 m_tms_irq;
@ -65,12 +67,12 @@ public:
UINT8 m_Lamps[256];
int m_optic_pattern;
int m_payen;
int m_alpha_data_line;
int m_alpha_clock;
int m_hopinhibit;
int m_slidesout;
int m_hopper[3];
int m_motor[3];
optional_device<roc10937_t> m_vfd;
optional_shared_ptr<UINT16> m_vram;
struct bt477_t m_bt477;
DECLARE_WRITE16_MEMBER(m68k_tms_w);

View File

@ -97,6 +97,7 @@ class mpu4_state : public driver_device
public:
mpu4_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_vfd(*this, "vfd"),
m_6840ptm(*this, "ptm_ic2"),
m_pia3(*this, "pia_ic3"),
m_pia4(*this, "pia_ic4"),
@ -113,7 +114,7 @@ public:
{
return 0;
}
optional_device<roc10937_t> m_vfd;
optional_device<ptm6840_device> m_6840ptm;
optional_device<pia6821_device> m_pia3;
optional_device<pia6821_device> m_pia4;

View File

@ -113,9 +113,7 @@ void bfm_bd1_t::static_set_value(device_t &device, int val)
void bfm_bd1_t::device_start()
{
m_timer=timer_alloc(0);
save_item(NAME(m_cursor));
save_item(NAME(m_cursor));
save_item(NAME(m_cursor_pos));
save_item(NAME(m_window_start)); // display window start pos 0-15
save_item(NAME(m_window_end)); // display window end pos 0-15
@ -131,6 +129,7 @@ void bfm_bd1_t::device_start()
save_item(NAME(m_flash_control));
save_item(NAME(m_chars));
save_item(NAME(m_attrs));
save_item(NAME(m_outputs));
save_item(NAME(m_user_data)); // user defined character data (16 bit)
save_item(NAME(m_user_def)); // user defined character state
@ -157,19 +156,13 @@ void bfm_bd1_t::device_reset()
m_user_def = 0;
memset(m_chars, 0, sizeof(m_chars));
memset(m_outputs, 0, sizeof(m_outputs));
memset(m_attrs, 0, sizeof(m_attrs));
m_timer->adjust(attotime::from_hz(clock()), 0);
}
void bfm_bd1_t::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
UINT16 bfm_bd1_t::set_display(UINT16 segin)
{
update_display();
m_timer->adjust(attotime::from_hz(clock()), 0);
}
UINT32 bfm_bd1_t::set_display(UINT16 segin)
{
UINT32 segout=0;
UINT16 segout=0;
if ( segin & 0x0004 ) segout |= 0x0001;
else segout &= ~0x0001;
if ( segin & 0x0002 ) segout |= 0x0002;
@ -214,13 +207,10 @@ void bfm_bd1_t::device_post_load()
void bfm_bd1_t::update_display()
{
m_outputs[m_cursor] = set_display(m_chars[m_cursor]);;
output_set_indexed_value("vfd", (m_port_val*16) + m_cursor, m_outputs[m_cursor]);
m_cursor++;
if (m_cursor >15)
for (int i =0; i<16; i++)
{
m_cursor=0;
m_outputs[i] = set_display(m_chars[i]);
output_set_indexed_value("vfd", (m_port_val*16) + i, m_outputs[i]);
}
}
///////////////////////////////////////////////////////////////////////////
@ -272,8 +262,10 @@ void bfm_bd1_t::blank(int data)
break;
}
}
int bfm_bd1_t::write_char(int data)
{
update_display();
int change = 0;
if ( m_user_def )
{
@ -289,6 +281,7 @@ int bfm_bd1_t::write_char(int data)
setdata( m_user_data, data);
change ++;
}
else
{

View File

@ -2,9 +2,8 @@
#ifndef BFM_BD1_H
#define BFM_BD1_H
//Based on the datasheet, the makimum oscillation rate for one character is 31.25 KHz, so we set our character clock to that.
#define MCFG_BFMBD1_ADD(_tag,_val) \
MCFG_DEVICE_ADD(_tag, BFM_BD1,312500)\
MCFG_DEVICE_ADD(_tag, BFM_BD1,60)\
MCFG_BD1_PORT(_val) \
#define MCFG_BD1_PORT(_val) \
@ -27,17 +26,16 @@ public:
virtual void update_display();
UINT8 m_port_val;
void blank(int data);
void shift_data(int data);
void setdata(int segdata, int data);
UINT32 set_display(UINT16 segin);
UINT16 set_display(UINT16 segin);
protected:
static const UINT8 AT_NORMAL = 0x00;
static const UINT8 AT_FLASH = 0x01;
static const UINT8 AT_FLASHED = 0x80; // set when character should be blinked off
emu_timer *m_timer;
int m_cursor_pos;
int m_window_start; // display window start pos 0-15
int m_window_end; // display window end pos 0-15
@ -61,7 +59,6 @@ protected:
virtual void device_start();
virtual void device_reset();
virtual void device_post_load();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
};