OSDN Git Service

[INITIAL] Import 20141226 version of http://homepage3.nifty.com/takeda-toshiya/common...
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmr30 / serial.cpp
diff --git a/source/src/vm/fmr30/serial.cpp b/source/src/vm/fmr30/serial.cpp
new file mode 100644 (file)
index 0000000..0c2e3fe
--- /dev/null
@@ -0,0 +1,147 @@
+/*\r
+       FUJITSU FMR-30 Emulator 'eFMR-30'\r
+\r
+       Author : Takeda.Toshiya\r
+       Date   : 2008.12.31 -\r
+\r
+       [ serial ]\r
+*/\r
+\r
+#include "serial.h"\r
+#include "../i8251.h"\r
+#include "../i8259.h"\r
+\r
+void SERIAL::initialize()\r
+{\r
+       for(int i = 0; i < 4; i++) {\r
+               sioctrl[i].baud = 0;\r
+               sioctrl[i].ctrl = 0;\r
+               sioctrl[i].rxrdy = false;\r
+               sioctrl[i].txrdy = false;\r
+               sioctrl[i].intstat = 0;\r
+               sioctrl[i].intmask = 0;\r
+       }\r
+}\r
+\r
+void SERIAL::write_io8(uint32 addr, uint32 data)\r
+{\r
+       switch(addr & 0xffff) {\r
+       case 0x0a:\r
+               sioctrl[0].baud = data;\r
+               break;\r
+       case 0x0b:\r
+               sioctrl[0].ctrl = data;\r
+               d_kb->write_signal(SIG_I8251_LOOPBACK, data, 8);\r
+               update_intr(0);\r
+               break;\r
+       case 0x12:\r
+               sioctrl[1].baud = data;\r
+               break;\r
+       case 0x13:\r
+               sioctrl[1].ctrl = data;\r
+               d_sub->write_signal(SIG_I8251_LOOPBACK, data, 8);\r
+               update_intr(1);\r
+               break;\r
+       case 0x62:\r
+               sioctrl[2].baud = data;\r
+               break;\r
+       case 0x63:\r
+               sioctrl[2].ctrl = data;\r
+               d_ch1->write_signal(SIG_I8251_LOOPBACK, data, 8);\r
+               update_intr(2);\r
+               break;\r
+       case 0x64:\r
+               sioctrl[2].intmask = data;\r
+               break;\r
+       case 0x65:\r
+               sioctrl[2].intstat &= ~data;\r
+               break;\r
+       case 0x72:\r
+               sioctrl[3].baud = data;\r
+               break;\r
+       case 0x73:\r
+               sioctrl[3].ctrl = data;\r
+               d_ch2->write_signal(SIG_I8251_LOOPBACK, data, 8);\r
+               update_intr(3);\r
+               break;\r
+       case 0x74:\r
+               sioctrl[3].intmask = data;\r
+               break;\r
+       case 0x75:\r
+               sioctrl[3].intstat &= ~data;\r
+               break;\r
+       }\r
+}\r
+\r
+uint32 SERIAL::read_io8(uint32 addr)\r
+{\r
+       switch(addr & 0xffff) {\r
+       case 0x0a:\r
+               return sioctrl[0].baud;\r
+       case 0x0b:\r
+               return sioctrl[0].ctrl;\r
+       case 0x12:\r
+               return sioctrl[1].baud;\r
+       case 0x13:\r
+               return sioctrl[1].ctrl;\r
+       case 0x62:\r
+               return sioctrl[2].baud;\r
+       case 0x63:\r
+               return sioctrl[2].ctrl;\r
+       case 0x64:\r
+               return sioctrl[2].intmask;\r
+       case 0x65:\r
+               return sioctrl[2].intstat;\r
+       case 0x66:\r
+               return 0xf0;    // append register\r
+       case 0x72:\r
+               return sioctrl[3].baud;\r
+       case 0x73:\r
+               return sioctrl[3].ctrl;\r
+       case 0x74:\r
+               return sioctrl[3].intmask;\r
+       case 0x75:\r
+               return sioctrl[3].intstat;\r
+       case 0x76:\r
+               return 0xf0;    // append register\r
+       }\r
+       return 0xff;\r
+}\r
+\r
+void SERIAL::write_signal(int id, uint32 data, uint32 mask)\r
+{\r
+       switch(id) {\r
+       case SIG_SERIAL_RXRDY_KB:\r
+       case SIG_SERIAL_RXRDY_SUB:\r
+       case SIG_SERIAL_RXRDY_CH1:\r
+       case SIG_SERIAL_RXRDY_CH2:\r
+               sioctrl[id & 3].rxrdy = ((data & mask) != 0);\r
+               update_intr(id & 3);\r
+               break;\r
+       case SIG_SERIAL_TXRDY_KB:\r
+       case SIG_SERIAL_TXRDY_SUB:\r
+       case SIG_SERIAL_TXRDY_CH1:\r
+       case SIG_SERIAL_TXRDY_CH2:\r
+               sioctrl[id & 3].txrdy = ((data & mask) != 0);\r
+               update_intr(id & 3);\r
+               break;\r
+       }\r
+}\r
+\r
+void SERIAL::update_intr(int ch)\r
+{\r
+       static const int pic_ids[4] = {\r
+               SIG_I8259_CHIP0 | SIG_I8259_IR2,        // keyboard\r
+               SIG_I8259_CHIP0 | SIG_I8259_IR3,        // sub\r
+               SIG_I8259_CHIP0 | SIG_I8259_IR4,        // rs-232c ch.1\r
+               SIG_I8259_CHIP1 | SIG_I8259_IR4         // rs-232c ch.2\r
+       };\r
+       \r
+       if((sioctrl[ch].rxrdy && (sioctrl[ch].ctrl & 0x40)) || (sioctrl[ch].txrdy && (sioctrl[ch].ctrl & 0x20))) {\r
+               d_pic->write_signal(pic_ids[ch], 1, 1);\r
+               sioctrl[ch].intstat |=  4;\r
+       } else {\r
+               d_pic->write_signal(pic_ids[ch], 0, 1);\r
+               sioctrl[ch].intstat &=  ~4;\r
+       }\r
+}\r