OSDN Git Service

[VM] MEMORY:: class within some VM will change Foo_MEMORY:: to reduce misundestanding...
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmr30 / serial.cpp
index 0c2e3fe..0f1bf64 100644 (file)
-/*\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
+/*
+       FUJITSU FMR-30 Emulator 'eFMR-30'
+
+       Author : Takeda.Toshiya
+       Date   : 2008.12.31 -
+
+       [ serial ]
+*/
+
+#include "serial.h"
+#include "../i8251.h"
+#include "../i8259.h"
+
+void SERIAL::initialize()
+{
+       memset(sioctrl, sizeof(sioctrl), 1);
+}
+
+void SERIAL::write_io8(uint32_t addr, uint32_t data)
+{
+       switch(addr & 0xffff) {
+       case 0x0a:
+               sioctrl[0].baud = data;
+               break;
+       case 0x0b:
+               sioctrl[0].ctrl = data;
+               d_kb->write_signal(SIG_I8251_LOOPBACK, data, 8);
+               update_intr(0);
+               break;
+       case 0x12:
+               sioctrl[1].baud = data;
+               break;
+       case 0x13:
+               sioctrl[1].ctrl = data;
+               d_sub->write_signal(SIG_I8251_LOOPBACK, data, 8);
+               update_intr(1);
+               break;
+       case 0x62:
+               sioctrl[2].baud = data;
+               break;
+       case 0x63:
+               sioctrl[2].ctrl = data;
+               d_ch1->write_signal(SIG_I8251_LOOPBACK, data, 8);
+               update_intr(2);
+               break;
+       case 0x64:
+               sioctrl[2].intmask = data;
+               break;
+       case 0x65:
+               sioctrl[2].intstat &= ~data;
+               break;
+       case 0x72:
+               sioctrl[3].baud = data;
+               break;
+       case 0x73:
+               sioctrl[3].ctrl = data;
+               d_ch2->write_signal(SIG_I8251_LOOPBACK, data, 8);
+               update_intr(3);
+               break;
+       case 0x74:
+               sioctrl[3].intmask = data;
+               break;
+       case 0x75:
+               sioctrl[3].intstat &= ~data;
+               break;
+       }
+}
+
+uint32_t SERIAL::read_io8(uint32_t addr)
+{
+       switch(addr & 0xffff) {
+       case 0x0a:
+               return sioctrl[0].baud;
+       case 0x0b:
+               return sioctrl[0].ctrl;
+       case 0x12:
+               return sioctrl[1].baud;
+       case 0x13:
+               return sioctrl[1].ctrl;
+       case 0x62:
+               return sioctrl[2].baud;
+       case 0x63:
+               return sioctrl[2].ctrl;
+       case 0x64:
+               return sioctrl[2].intmask;
+       case 0x65:
+               return sioctrl[2].intstat;
+       case 0x66:
+               return 0xf0;    // append register
+       case 0x72:
+               return sioctrl[3].baud;
+       case 0x73:
+               return sioctrl[3].ctrl;
+       case 0x74:
+               return sioctrl[3].intmask;
+       case 0x75:
+               return sioctrl[3].intstat;
+       case 0x76:
+               return 0xf0;    // append register
+       }
+       return 0xff;
+}
+
+void SERIAL::write_signal(int id, uint32_t data, uint32_t mask)
+{
+       switch(id) {
+       case SIG_SERIAL_RXRDY_KB:
+       case SIG_SERIAL_RXRDY_SUB:
+       case SIG_SERIAL_RXRDY_CH1:
+       case SIG_SERIAL_RXRDY_CH2:
+               sioctrl[id & 3].rxrdy = ((data & mask) != 0);
+               update_intr(id & 3);
+               break;
+       case SIG_SERIAL_TXRDY_KB:
+       case SIG_SERIAL_TXRDY_SUB:
+       case SIG_SERIAL_TXRDY_CH1:
+       case SIG_SERIAL_TXRDY_CH2:
+               sioctrl[id & 3].txrdy = ((data & mask) != 0);
+               update_intr(id & 3);
+               break;
+       }
+}
+
+void SERIAL::update_intr(int ch)
+{
+       static const int pic_ids[4] = {
+               SIG_I8259_CHIP0 | SIG_I8259_IR2,        // keyboard
+               SIG_I8259_CHIP0 | SIG_I8259_IR3,        // sub
+               SIG_I8259_CHIP0 | SIG_I8259_IR4,        // rs-232c ch.1
+               SIG_I8259_CHIP1 | SIG_I8259_IR4         // rs-232c ch.2
+       };
+       
+       if((sioctrl[ch].rxrdy && (sioctrl[ch].ctrl & 0x40)) || (sioctrl[ch].txrdy && (sioctrl[ch].ctrl & 0x20))) {
+               d_pic->write_signal(pic_ids[ch], 1, 1);
+               sioctrl[ch].intstat |=  4;
+       } else {
+               d_pic->write_signal(pic_ids[ch], 0, 1);
+               sioctrl[ch].intstat &=  ~4;
+       }
+}
+
+#define STATE_VERSION  1
+
+bool SERIAL::process_state(FILEIO* state_fio, bool loading)
+{
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+               return false;
+       }
+       if(!state_fio->StateCheckInt32(this_device_id)) {
+               return false;
+       }
+       //state_fio->StateBuffer(sioctrl, sizeof(sioctrl), 1);
+       for(int i = 0; i < 4; i++) {
+               state_fio->StateUint8(sioctrl[i].baud);
+               state_fio->StateUint8(sioctrl[i].ctrl);
+               state_fio->StateBool(sioctrl[i].rxrdy);
+               state_fio->StateBool(sioctrl[i].txrdy);
+               state_fio->StateUint8(sioctrl[i].intmask);
+               state_fio->StateUint8(sioctrl[i].intstat);
+       }
+       return true;
+}