summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/drivers/minicom.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mess/drivers/minicom.c')
-rw-r--r--src/mess/drivers/minicom.c219
1 files changed, 219 insertions, 0 deletions
diff --git a/src/mess/drivers/minicom.c b/src/mess/drivers/minicom.c
new file mode 100644
index 00000000000..56e1541976b
--- /dev/null
+++ b/src/mess/drivers/minicom.c
@@ -0,0 +1,219 @@
+// license:MAME|GPL-2.0+
+// copyright-holders: Felipe Sanches
+/***************************************************************************
+
+ Ultratec Minicom IV
+ http://www.ultratec.com/ttys/non-printing/minicom.php
+
+ Driver by Felipe Sanches
+
+There messages are displayed in a 20 digit 14 segment VFD.
+
+ ***********
+ * * * * *
+ * * * * *
+ * * * * *
+ ***** *****
+ * * * * *
+ * * * * *
+ * * * * *
+ *********** *
+
+Digits seem to be selected by a mux fed by a counter that is incremented by pulses in P1.2
+There may be a bit connected to the counter reset signal...
+
+Segment data is sent to each 14seg digit by first writing half of the data to port P0 and
+ toggling T0 and then the other half of data is written to P0 again but toggling T1 afterwards.
+
+ Changelog:
+
+ 2014 JUL 19 [Felipe Sanches]:
+ * Got the display working except for a few glitches
+
+ 2014 JUL 16 [Felipe Sanches]:
+ * Initial driver skeleton
+*/
+
+#define LOG_IO_PORTS 0
+#define PRINTER_ATTACHED 1
+
+#include "emu.h"
+#include "cpu/mcs51/mcs51.h"
+#include "minicom.lh"
+
+UINT16 display_data;
+
+class minicom_state : public driver_device
+{
+public:
+ minicom_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag)
+ , m_maincpu(*this, "maincpu")
+ { }
+
+ DECLARE_WRITE8_MEMBER(minicom_io_w);
+ DECLARE_READ8_MEMBER(minicom_io_r);
+ DECLARE_DRIVER_INIT(minicom);
+private:
+ int digit_index;
+ virtual void machine_start();
+ virtual void machine_reset();
+ required_device<cpu_device> m_maincpu;
+};
+
+static ADDRESS_MAP_START(i87c52_io, AS_IO, 8, minicom_state)
+ AM_RANGE(MCS51_PORT_P0, MCS51_PORT_P3) AM_READWRITE(minicom_io_r, minicom_io_w)
+ADDRESS_MAP_END
+
+void minicom_state::machine_start()
+{
+}
+
+void minicom_state::machine_reset()
+{
+ int i;
+ digit_index = 19;
+ display_data = 0;
+
+ for (i=0; i<20; i++)
+ output_set_digit_value(i, 0);
+}
+
+READ8_MEMBER(minicom_state::minicom_io_r)
+{
+ switch (offset)
+ {
+ case 1:
+ //P1.3 seems to be an indicator of whether or not we have a printer device attached.
+ // at address 0xABF the code checks this flag in order to decide which string to display:
+ // "MINIPRINT IS RESET" or "MINICOM IS RESET"
+ return PRINTER_ATTACHED << 3;
+ case 2:
+// return 0; //para a palestra no Garoa... :-)
+ return 1; //to skip the "NO POWER" warning. I'm not sure why.
+ default:
+#if LOG_IO_PORTS
+ printf("Unhandled I/O Read at offset 0x%02X (return 0)\n", offset);
+#endif
+ return 0;
+ }
+}
+
+#if LOG_IO_PORTS
+static void printbits(unsigned char v) {
+ int i;
+ for(i = 7; i >= 0; i--) putchar('0' + ((v >> i) & 1));
+}
+#endif
+
+#define FALLING_EDGE(old_data, new_data, bit) (BIT(old_data ^ new_data, bit) && !BIT(new_data, bit))
+#define RISING_EDGE(old_data, new_data, bit) (BIT(old_data ^ new_data, bit) && BIT(new_data, bit))
+
+#define P1_UNKNOWN_BITS (0xFF & ~(1 << 2))
+#define P2_UNKNOWN_BITS 0xFF
+#define P3_UNKNOWN_BITS (0xFF & ~((1 << 4)|(1 << 5)))
+WRITE8_MEMBER(minicom_state::minicom_io_w)
+{
+ static UINT8 p0=0, p1=0, p2=0, p3=0;
+ switch (offset)
+ {
+ case 0x00:
+ {
+ p0=data;
+ break;
+ }
+ case 0x01:
+ {
+ if (data != p1)
+ {
+#if LOG_IO_PORTS
+ char changed = p1 ^ data;
+ if (changed ^ P1_UNKNOWN_BITS){
+ printf("Write to P1: %02X changed: ( ) (", data);
+ printbits(changed);
+ printf(") ( ) ( )\n");
+ }
+#endif
+ if (FALLING_EDGE(p1, data, 2)){
+ digit_index--;
+ if (digit_index<0) digit_index = 19;
+ }
+ p1=data;
+ }
+ break;
+ }
+ case 0x02:
+ {
+ if (data != p2)
+ {
+#if LOG_IO_PORTS
+ char changed = p2 ^ data;
+ if (changed ^ P2_UNKNOWN_BITS){
+ printf("Write to P2: %02X changed: ( ) ( ) (", data);
+ printbits(changed);
+ printf(") ( )\n");
+ }
+#endif
+ p2=data;
+ }
+ break;
+ }
+ case 0x03:
+ {
+ if (data != p3)
+ {
+ char changed = p3 ^ data;
+#if LOG_IO_PORTS
+ if (changed ^ P3_UNKNOWN_BITS){
+ printf("Write to P3: %02X changed: ( ) ( ) ( ) (", data);
+ printbits(changed);
+ printf(")\n");
+ }
+#endif
+
+ if (FALLING_EDGE(p3, data, 4)){ //P3.4 = T0
+ display_data &= 0xFF00;
+ display_data |= p0;
+ }
+
+ if (FALLING_EDGE(p3, data, 5)){ //P3.5 = T1
+ display_data &= 0xFF;
+ display_data |= (p0 << 8);
+ }
+
+ if (BIT(changed,4) || BIT(changed,5)){
+ 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);
+ }
+ p3=data;
+ }
+ break;
+ }
+ }
+}
+
+DRIVER_INIT_MEMBER( minicom_state, minicom )
+{
+}
+
+static MACHINE_CONFIG_START( minicom, minicom_state )
+ /* basic machine hardware */
+ MCFG_CPU_ADD("maincpu", I87C52, XTAL_10MHz) /*FIX-ME: verify the correct clock frequency */
+ MCFG_CPU_IO_MAP(i87c52_io)
+
+ /* video hardware */
+ /* fluorescent 14-segment display forming a row of 20 characters */
+ MCFG_DEFAULT_LAYOUT(layout_minicom)
+
+/* TODO: Map the keyboard rows/cols inputs (43-key, 4-row keyboard) */
+
+/* TODO: Treat the modem as a sound device. That may be an interesting challenge... :-) */
+MACHINE_CONFIG_END
+
+ROM_START( minicom )
+ ROM_REGION( 0x2000, "maincpu", 0 )
+ ROM_LOAD( "ultratec_minicom_iv.rom", 0x0000, 0x2000, CRC(22881366) SHA1(fc3faea5ecc1476e5bcb7999638f3150d06c9a81) )
+ROM_END
+
+/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
+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 */
+//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) */