trunk/src/mess/layout/minicom.lay
| r0 | r31364 | |
| 1 | <?xml version="1.0"?> |
| 2 | <mamelayout version="2"> |
| 3 | <element name="digit" defstate="0"> |
| 4 | <led14seg> |
| 5 | <color red="0.0" green="0.75" blue="0.75" /> |
| 6 | </led14seg> |
| 7 | </element> |
| 8 | |
| 9 | <element name="led" defstate="0"> |
| 10 | <disk state="1"> |
| 11 | <color red="0.75" green="0.0" blue="0.0" /> |
| 12 | </disk> |
| 13 | <disk state="0"> |
| 14 | <color red="0.09375" green="0.0" blue="0.0" /> |
| 15 | </disk> |
| 16 | </element> |
| 17 | |
| 18 | <element name="background"> |
| 19 | <rect> |
| 20 | <bounds left="0" top="0" right="1" bottom="1" /> |
| 21 | <color red="0.0" green="0.0" blue="0.0" /> |
| 22 | </rect> |
| 23 | </element> |
| 24 | |
| 25 | <view name="Default Layout"> |
| 26 | <!-- Black background --> |
| 27 | <bezel element="background"> |
| 28 | <bounds left="00" top="00" right="1380" bottom="130" /> |
| 29 | </bezel> |
| 30 | |
| 31 | <!-- 20 digits --> |
| 32 | <bezel name="digit0" element="digit"> |
| 33 | <bounds x="0" y="15" width="50" height="80" /> |
| 34 | </bezel> |
| 35 | |
| 36 | <bezel name="digit1" element="digit"> |
| 37 | <bounds x="70" y="15" width="50" height="80" /> |
| 38 | </bezel> |
| 39 | |
| 40 | <bezel name="digit2" element="digit"> |
| 41 | <bounds x="140" y="15" width="50" height="80" /> |
| 42 | </bezel> |
| 43 | |
| 44 | <bezel name="digit3" element="digit"> |
| 45 | <bounds x="210" y="15" width="50" height="80" /> |
| 46 | </bezel> |
| 47 | |
| 48 | <bezel name="digit4" element="digit"> |
| 49 | <bounds x="280" y="15" width="50" height="80" /> |
| 50 | </bezel> |
| 51 | |
| 52 | <bezel name="digit5" element="digit"> |
| 53 | <bounds x="350" y="15" width="50" height="80" /> |
| 54 | </bezel> |
| 55 | |
| 56 | <bezel name="digit6" element="digit"> |
| 57 | <bounds x="420" y="15" width="50" height="80" /> |
| 58 | </bezel> |
| 59 | |
| 60 | <bezel name="digit7" element="digit"> |
| 61 | <bounds x="490" y="15" width="50" height="80" /> |
| 62 | </bezel> |
| 63 | |
| 64 | <bezel name="digit8" element="digit"> |
| 65 | <bounds x="560" y="15" width="50" height="80" /> |
| 66 | </bezel> |
| 67 | |
| 68 | <bezel name="digit9" element="digit"> |
| 69 | <bounds x="630" y="15" width="50" height="80" /> |
| 70 | </bezel> |
| 71 | |
| 72 | <bezel name="digit10" element="digit"> |
| 73 | <bounds x="700" y="15" width="50" height="80" /> |
| 74 | </bezel> |
| 75 | |
| 76 | <bezel name="digit11" element="digit"> |
| 77 | <bounds x="770" y="15" width="50" height="80" /> |
| 78 | </bezel> |
| 79 | |
| 80 | <bezel name="digit12" element="digit"> |
| 81 | <bounds x="840" y="15" width="50" height="80" /> |
| 82 | </bezel> |
| 83 | |
| 84 | <bezel name="digit13" element="digit"> |
| 85 | <bounds x="910" y="15" width="50" height="80" /> |
| 86 | </bezel> |
| 87 | |
| 88 | <bezel name="digit14" element="digit"> |
| 89 | <bounds x="980" y="15" width="50" height="80" /> |
| 90 | </bezel> |
| 91 | |
| 92 | <bezel name="digit15" element="digit"> |
| 93 | <bounds x="1050" y="15" width="50" height="80" /> |
| 94 | </bezel> |
| 95 | |
| 96 | <bezel name="digit16" element="digit"> |
| 97 | <bounds x="1120" y="15" width="50" height="80" /> |
| 98 | </bezel> |
| 99 | |
| 100 | <bezel name="digit17" element="digit"> |
| 101 | <bounds x="1190" y="15" width="50" height="80" /> |
| 102 | </bezel> |
| 103 | |
| 104 | <bezel name="digit18" element="digit"> |
| 105 | <bounds x="1260" y="15" width="50" height="80" /> |
| 106 | </bezel> |
| 107 | |
| 108 | <bezel name="digit19" element="digit"> |
| 109 | <bounds x="1330" y="15" width="50" height="80" /> |
| 110 | </bezel> |
| 111 | |
| 112 | </view> |
| 113 | </mamelayout> |
trunk/src/mess/drivers/minicom.c
| r0 | r31364 | |
| 1 | // license:MAME|GPL-2.0+ |
| 2 | // copyright-holders: Felipe Sanches |
| 3 | /*************************************************************************** |
| 4 | |
| 5 | Ultratec Minicom IV |
| 6 | http://www.ultratec.com/ttys/non-printing/minicom.php |
| 7 | |
| 8 | Driver by Felipe Sanches |
| 9 | |
| 10 | There messages are displayed in a 20 digit 14 segment VFD. |
| 11 | |
| 12 | *********** |
| 13 | * * * * * |
| 14 | * * * * * |
| 15 | * * * * * |
| 16 | ***** ***** |
| 17 | * * * * * |
| 18 | * * * * * |
| 19 | * * * * * |
| 20 | *********** * |
| 21 | |
| 22 | Digits seem to be selected by a mux fed by a counter that is incremented by pulses in P1.2 |
| 23 | There may be a bit connected to the counter reset signal... |
| 24 | |
| 25 | Segment data is sent to each 14seg digit by first writing half of the data to port P0 and |
| 26 | toggling T0 and then the other half of data is written to P0 again but toggling T1 afterwards. |
| 27 | |
| 28 | Changelog: |
| 29 | |
| 30 | 2014 JUL 19 [Felipe Sanches]: |
| 31 | * Got the display working except for a few glitches |
| 32 | |
| 33 | 2014 JUL 16 [Felipe Sanches]: |
| 34 | * Initial driver skeleton |
| 35 | */ |
| 36 | |
| 37 | #define LOG_IO_PORTS 0 |
| 38 | #define PRINTER_ATTACHED 1 |
| 39 | |
| 40 | #include "emu.h" |
| 41 | #include "cpu/mcs51/mcs51.h" |
| 42 | #include "minicom.lh" |
| 43 | |
| 44 | UINT16 display_data; |
| 45 | |
| 46 | class minicom_state : public driver_device |
| 47 | { |
| 48 | public: |
| 49 | minicom_state(const machine_config &mconfig, device_type type, const char *tag) |
| 50 | : driver_device(mconfig, type, tag) |
| 51 | , m_maincpu(*this, "maincpu") |
| 52 | { } |
| 53 | |
| 54 | DECLARE_WRITE8_MEMBER(minicom_io_w); |
| 55 | DECLARE_READ8_MEMBER(minicom_io_r); |
| 56 | DECLARE_DRIVER_INIT(minicom); |
| 57 | private: |
| 58 | int digit_index; |
| 59 | virtual void machine_start(); |
| 60 | virtual void machine_reset(); |
| 61 | required_device<cpu_device> m_maincpu; |
| 62 | }; |
| 63 | |
| 64 | static ADDRESS_MAP_START(i87c52_io, AS_IO, 8, minicom_state) |
| 65 | AM_RANGE(MCS51_PORT_P0, MCS51_PORT_P3) AM_READWRITE(minicom_io_r, minicom_io_w) |
| 66 | ADDRESS_MAP_END |
| 67 | |
| 68 | void minicom_state::machine_start() |
| 69 | { |
| 70 | } |
| 71 | |
| 72 | void minicom_state::machine_reset() |
| 73 | { |
| 74 | int i; |
| 75 | digit_index = 19; |
| 76 | display_data = 0; |
| 77 | |
| 78 | for (i=0; i<20; i++) |
| 79 | output_set_digit_value(i, 0); |
| 80 | } |
| 81 | |
| 82 | READ8_MEMBER(minicom_state::minicom_io_r) |
| 83 | { |
| 84 | switch (offset) |
| 85 | { |
| 86 | case 1: |
| 87 | //P1.3 seems to be an indicator of whether or not we have a printer device attached. |
| 88 | // at address 0xABF the code checks this flag in order to decide which string to display: |
| 89 | // "MINIPRINT IS RESET" or "MINICOM IS RESET" |
| 90 | return PRINTER_ATTACHED << 3; |
| 91 | case 2: |
| 92 | // return 0; //para a palestra no Garoa... :-) |
| 93 | return 1; //to skip the "NO POWER" warning. I'm not sure why. |
| 94 | default: |
| 95 | #if LOG_IO_PORTS |
| 96 | printf("Unhandled I/O Read at offset 0x%02X (return 0)\n", offset); |
| 97 | #endif |
| 98 | return 0; |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | #if LOG_IO_PORTS |
| 103 | static void printbits(unsigned char v) { |
| 104 | int i; |
| 105 | for(i = 7; i >= 0; i--) putchar('0' + ((v >> i) & 1)); |
| 106 | } |
| 107 | #endif |
| 108 | |
| 109 | #define FALLING_EDGE(old_data, new_data, bit) (BIT(old_data ^ new_data, bit) && !BIT(new_data, bit)) |
| 110 | #define RISING_EDGE(old_data, new_data, bit) (BIT(old_data ^ new_data, bit) && BIT(new_data, bit)) |
| 111 | |
| 112 | #define P1_UNKNOWN_BITS (0xFF & ~(1 << 2)) |
| 113 | #define P2_UNKNOWN_BITS 0xFF |
| 114 | #define P3_UNKNOWN_BITS (0xFF & ~((1 << 4)|(1 << 5))) |
| 115 | WRITE8_MEMBER(minicom_state::minicom_io_w) |
| 116 | { |
| 117 | static UINT8 p0=0, p1=0, p2=0, p3=0; |
| 118 | switch (offset) |
| 119 | { |
| 120 | case 0x00: |
| 121 | { |
| 122 | p0=data; |
| 123 | break; |
| 124 | } |
| 125 | case 0x01: |
| 126 | { |
| 127 | if (data != p1) |
| 128 | { |
| 129 | #if LOG_IO_PORTS |
| 130 | char changed = p1 ^ data; |
| 131 | if (changed ^ P1_UNKNOWN_BITS){ |
| 132 | printf("Write to P1: %02X changed: ( ) (", data); |
| 133 | printbits(changed); |
| 134 | printf(") ( ) ( )\n"); |
| 135 | } |
| 136 | #endif |
| 137 | if (FALLING_EDGE(p1, data, 2)){ |
| 138 | digit_index--; |
| 139 | if (digit_index<0) digit_index = 19; |
| 140 | } |
| 141 | p1=data; |
| 142 | } |
| 143 | break; |
| 144 | } |
| 145 | case 0x02: |
| 146 | { |
| 147 | if (data != p2) |
| 148 | { |
| 149 | #if LOG_IO_PORTS |
| 150 | char changed = p2 ^ data; |
| 151 | if (changed ^ P2_UNKNOWN_BITS){ |
| 152 | printf("Write to P2: %02X changed: ( ) ( ) (", data); |
| 153 | printbits(changed); |
| 154 | printf(") ( )\n"); |
| 155 | } |
| 156 | #endif |
| 157 | p2=data; |
| 158 | } |
| 159 | break; |
| 160 | } |
| 161 | case 0x03: |
| 162 | { |
| 163 | if (data != p3) |
| 164 | { |
| 165 | char changed = p3 ^ data; |
| 166 | #if LOG_IO_PORTS |
| 167 | if (changed ^ P3_UNKNOWN_BITS){ |
| 168 | printf("Write to P3: %02X changed: ( ) ( ) ( ) (", data); |
| 169 | printbits(changed); |
| 170 | printf(")\n"); |
| 171 | } |
| 172 | #endif |
| 173 | |
| 174 | if (FALLING_EDGE(p3, data, 4)){ //P3.4 = T0 |
| 175 | display_data &= 0xFF00; |
| 176 | display_data |= p0; |
| 177 | } |
| 178 | |
| 179 | if (FALLING_EDGE(p3, data, 5)){ //P3.5 = T1 |
| 180 | display_data &= 0xFF; |
| 181 | display_data |= (p0 << 8); |
| 182 | } |
| 183 | |
| 184 | if (BIT(changed,4) || BIT(changed,5)){ |
| 185 | output_set_digit_value(digit_index, BITSWAP16(display_data, 9, 1, 3, 11, 12, 4, 2, 10, 14, 6, 7, 5, 0, 15, 13, 8) & 0x3FFF); |
| 186 | } |
| 187 | p3=data; |
| 188 | } |
| 189 | break; |
| 190 | } |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | DRIVER_INIT_MEMBER( minicom_state, minicom ) |
| 195 | { |
| 196 | } |
| 197 | |
| 198 | static MACHINE_CONFIG_START( minicom, minicom_state ) |
| 199 | /* basic machine hardware */ |
| 200 | MCFG_CPU_ADD("maincpu", I87C52, XTAL_10MHz) /*FIX-ME: verify the correct clock frequency */ |
| 201 | MCFG_CPU_IO_MAP(i87c52_io) |
| 202 | |
| 203 | /* video hardware */ |
| 204 | /* fluorescent 14-segment display forming a row of 20 characters */ |
| 205 | MCFG_DEFAULT_LAYOUT(layout_minicom) |
| 206 | |
| 207 | /* TODO: Map the keyboard rows/cols inputs (43-key, 4-row keyboard) */ |
| 208 | |
| 209 | /* TODO: Treat the modem as a sound device. That may be an interesting challenge... :-) */ |
| 210 | MACHINE_CONFIG_END |
| 211 | |
| 212 | ROM_START( minicom ) |
| 213 | ROM_REGION( 0x2000, "maincpu", 0 ) |
| 214 | ROM_LOAD( "ultratec_minicom_iv.rom", 0x0000, 0x2000, CRC(22881366) SHA1(fc3faea5ecc1476e5bcb7999638f3150d06c9a81) ) |
| 215 | ROM_END |
| 216 | |
| 217 | /* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ |
| 218 | COMP( 1997, minicom, 0, 0, minicom, 0, minicom_state, minicom, "Ultratec", "Minicom IV", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_NO_SOUND) /* fw release data: 11th Aug 1997 */ |
| 219 | //COMP( 2002, minicom, 0, 0, minicom, 0, minicom_state, minicom, "Ultratec", "Minicom IV", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_NO_SOUND) /* fw release data: 19th Apr 2002 - Seen at a subway station in São Paulo, Brazil (Metrô Trianon MASP) */ |