summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/machine/roc10937.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/machine/roc10937.c')
-rw-r--r--trunk/src/emu/machine/roc10937.c398
1 files changed, 398 insertions, 0 deletions
diff --git a/trunk/src/emu/machine/roc10937.c b/trunk/src/emu/machine/roc10937.c
new file mode 100644
index 00000000000..5e1abcf6583
--- /dev/null
+++ b/trunk/src/emu/machine/roc10937.c
@@ -0,0 +1,398 @@
+/**********************************************************************
+
+ Rockwell 10937/10957 interface and emulation by J.Wallace
+ OKI MSC1937 is a clone of this chip
+
+**********************************************************************/
+
+#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
+ ---- ----
+ |\ | /|
+ 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.
+This means our segment maths needs to be more than 16-bit to work!
+*/
+
+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 int roc10937poslut[]=
+{
+ 1,//0
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 15,
+ 0//15
+};
+
+///////////////////////////////////////////////////////////////////////////
+
+void ROC10937_init(int id, int type,int reversed)
+{
+ assert_always((id >= 0) && (id < MAX_ROCK_ALPHAS), "roc10937_init called on an invalid display ID!");
+
+ memset( &roc10937[id], 0, sizeof(roc10937[0]));
+
+ roc10937[id].type = type;
+ roc10937[id].reversed = reversed;
+ ROC10937_reset(id);
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+void ROC10937_reset(int id)
+{
+ roc10937[id].window_end = 15;
+ roc10937[id].window_size = (roc10937[id].window_end - roc10937[id].window_start)+1;
+ memset(roc10937[id].string, ' ', 16);
+
+ roc10937[id].brightness = 31;
+ roc10937[id].count = 0;
+
+ roc10937[id].changed |= 1;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+UINT32 *ROC10937_get_segments(int id)
+{
+ 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++)
+ {
+ if (!roc10937[id].reversed)//Output to the screen is naturally backwards, so we need to invert it
+ {
+ val = 15-cursor;
+ }
+ else
+ {
+ //If the controller is reversed, things look normal.
+ val = cursor;
+ }
+
+ 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;
+ }
+ return 0;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+char *ROC10937_get_string( int id)
+{
+ return (char *)roc10937[id].string;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+void ROC10937_shift_data(int id, int data)
+{
+ roc10937[id].data <<= 1;
+
+ if ( !data ) roc10937[id].data |= 1;
+
+ if ( ++roc10937[id].count >= 8 )
+ {
+ if ( ROC10937_newdata(id, roc10937[id].data) )
+ {
+ roc10937[id].changed |= 1;
+ }
+
+ roc10937[id].count = 0;
+ roc10937[id].data = 0;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+int ROC10937_newdata(int id, int data)
+{
+ int change = 0;
+
+ 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];
+ }
+ 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;
+ }
+ else if ( (data & 0xE0) == 0xE0 ) // 111x xxxx
+ { // 111x xxxx Set duty cycle ( brightness )
+ roc10937[id].brightness = (data & 0x1F);
+ change = 1;
+ }
+ else if ( (data & 0xE0) == 0x80 ) // 100x ---
+ { // 100x xxxx Test mode
+ }
+ }
+ 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);//,
+ break;
+ case 0x2E: //
+ roc10937[id].segments[roc10937[id].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);//,
+ }
+ 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);//,
+ }
+ 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];
+
+ roc10937[id].cursor_pos++;
+ if ( roc10937[id].cursor_pos > roc10937[id].window_end )
+ {
+ roc10937[id].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);
+}