diff options
Diffstat (limited to 'trunk/src/emu/machine/roc10937.c')
-rw-r--r-- | trunk/src/emu/machine/roc10937.c | 398 |
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); +} |