📄 serialport.cpp
字号:
/*****************************************************************************/bool CSerial::getDTR () { if(loopback) return false; else return dtr;}bool CSerial::getRTS () { if(loopback) return false; else return rts;}/*****************************************************************************//* MSR Access **//*****************************************************************************/bool CSerial::getRI () { return ri;}bool CSerial::getCD () { return cd;}bool CSerial::getDSR () { return dsr;}bool CSerial::getCTS () { return cts;}void CSerial::setRI (bool value) { if (value != ri) {#if SERIAL_DEBUG if(dbg_modemcontrol) fprintf(debugfp,value?"%12.3f RI on.\r\n":"%12.3f RI off.\r\n", PIC_FullIndex());#endif // don't change delta when in loopback mode ri=value; if(!loopback) { if(value==false) d_ri=true; rise (MSR_PRIORITY); } } //else no change}void CSerial::setDSR (bool value) { if (value != dsr) {#if SERIAL_DEBUG if(dbg_modemcontrol) fprintf(debugfp,value?"%12.3f DSR on.\r\n":"%12.3f DSR off.\r\n", PIC_FullIndex());#endif // don't change delta when in loopback mode dsr=value; if(!loopback) { d_dsr=true; rise (MSR_PRIORITY); } } //else no change}void CSerial::setCD (bool value) { if (value != cd) {#if SERIAL_DEBUG if(dbg_modemcontrol) fprintf(debugfp,value?"%12.3f CD on.\r\n":"%12.3f CD off.\r\n", PIC_FullIndex());#endif // don't change delta when in loopback mode cd=value; if(!loopback) { d_cd=true; rise (MSR_PRIORITY); } } //else no change}void CSerial::setCTS (bool value) { if (value != cts) {#if SERIAL_DEBUG if(dbg_modemcontrol) fprintf(debugfp,value?"%12.3f CTS on.\r\n":"%12.3f CTS off.\r\n", PIC_FullIndex());#endif // don't change delta when in loopback mode cts=value; if(!loopback) { d_cts=true; rise (MSR_PRIORITY); } } //else no change}/*****************************************************************************//* Initialisation **//*****************************************************************************/void CSerial::Init_Registers () { // The "power on" settings irq_active=false; waiting_interrupts = 0x0; Bit32u initbps = 9600; Bit8u bytesize = 8; char parity = 'N'; Bit8u stopbits = 1; Bit8u lcrresult = 0; Bit16u baudresult = 0; RHR = 0; THR = 0; IER = 0; ISR = 0x1; LCR = 0; //MCR = 0xff; loopback = true; dtr=true; rts=true; op1=true; op2=true; LSR = 0x60; d_cts = true; d_dsr = true; d_ri = true; d_cd = true; cts = true; dsr = true; ri = true; cd = true; SPR = 0xFF; baud_divider=0x0; // make lcr: byte size, parity, stopbits, baudrate if (bytesize == 5) lcrresult |= LCR_DATABITS_5; else if (bytesize == 6) lcrresult |= LCR_DATABITS_6; else if (bytesize == 7) lcrresult |= LCR_DATABITS_7; else lcrresult |= LCR_DATABITS_8; switch(parity) { case 'N': case 'n': lcrresult |= LCR_PARITY_NONE; break; case 'O': case 'o': lcrresult |= LCR_PARITY_ODD; break; case 'E': case 'e': lcrresult |= LCR_PARITY_EVEN; break; case 'M': case 'm': lcrresult |= LCR_PARITY_MARK; break; case 'S': case 's': lcrresult |= LCR_PARITY_SPACE; break; } // baudrate if (initbps > 0) baudresult = (Bit16u) (115200 / initbps); else baudresult = 12; // = 9600 baud Write_MCR (0); Write_LCR (LCR_DIVISOR_Enable_MASK); Write_THR ((Bit8u) baudresult & 0xff); Write_IER ((Bit8u) (baudresult >> 8)); Write_LCR (lcrresult); updateMSR(); Read_MSR();}CSerial::CSerial(Bitu id, CommandLine* cmd) {#if SERIAL_DEBUG dbg_serialtraffic = cmd->FindExist("dbgtr", false); dbg_modemcontrol = cmd->FindExist("dbgmd", false); dbg_register = cmd->FindExist("dbgreg", false); dbg_interrupt = cmd->FindExist("dbgirq", false); dbg_aux = cmd->FindExist("dbgaux", false); if(dbg_serialtraffic|dbg_modemcontrol|dbg_register|dbg_interrupt|dbg_aux) debugfp=OpenCaptureFile("serlog",".serlog.txt"); else debugfp=0;#endif idnumber=id; mydosdevice=new device_COM(this); DOS_AddDevice(mydosdevice); Bit16u base = serial_baseaddr[id]; fifo_warn=false; errormsg_pending=false; framingErrors=0; parityErrors=0; overrunErrors=0; overrunIF0=0; breakErrors=0; // find the IRQ irq = serial_defaultirq[id]; getBituSubstring("irq:",&irq, cmd); if (irq < 2 || irq > 15) irq = serial_defaultirq[id]; for (Bitu i = 0; i <= 7; i++) { WriteHandler[i].Install (i + base, SERIAL_Write, IO_MB); ReadHandler[i].Install (i + base, SERIAL_Read, IO_MB); }#if SERIAL_DEBUG if(debugfp) fprintf(debugfp,"COM%d: BASE %3x, IRQ %d\r\n\r\n", COMNUMBER,base,irq);#endif};bool CSerial::getBituSubstring(const char* name,Bitu* data, CommandLine* cmd) { std::string tmpstring; if(!(cmd->FindStringBegin(name,tmpstring,false))) return false; const char* tmpchar=tmpstring.c_str(); if(sscanf(tmpchar,"%u",data)!=1) return false; return true;}CSerial::~CSerial(void) { DOS_DelDevice(mydosdevice); for(Bitu i = 0; i <= SERIAL_BASE_EVENT_COUNT; i++) removeEvent(i);};bool CSerial::Getchar(Bit8u* data, bool wait_dsr, Bitu timeout) { double starttime=PIC_FullIndex(); // wait for it to become empty // wait for DSR on if(wait_dsr) { while((!(Read_MSR()&0x20))&&(starttime>PIC_FullIndex()-timeout)) CALLBACK_Idle(); if(!(starttime>PIC_FullIndex()-timeout)) { #if SERIAL_DEBUGif(dbg_aux) fprintf(debugfp,"%12.3f API read timeout: MSR 0x%x\r\n", PIC_FullIndex(),Read_MSR());#endif return false; } } // wait for a byte to arrive while((!(Read_LSR()&0x1))&&(starttime>PIC_FullIndex()-timeout)) CALLBACK_Idle(); if(!(starttime>PIC_FullIndex()-timeout)) { #if SERIAL_DEBUGif(dbg_aux) fprintf(debugfp,"%12.3f API read timeout: MSR 0x%x\r\n", PIC_FullIndex(),Read_MSR());#endif return false; } *data=Read_RHR();#if SERIAL_DEBUG if(dbg_aux) fprintf(debugfp,"%12.3f API read success: 0x%x\r\n", PIC_FullIndex(),*data);#endif return true;}bool CSerial::Putchar(Bit8u data, bool wait_dsr, bool wait_cts, Bitu timeout) { double starttime=PIC_FullIndex(); //Bit16u starttime= // wait for it to become empty while(!(LSR&0x20)) { CALLBACK_Idle(); } // wait for DSR+CTS on if(wait_dsr||wait_cts) { if(wait_dsr||wait_cts) { while(((Read_MSR()&0x30)!=0x30)&&(starttime>PIC_FullIndex()-timeout)) CALLBACK_Idle(); } else if(wait_dsr) { while(!(Read_MSR()&0x20)&&(starttime>PIC_FullIndex()-timeout)) CALLBACK_Idle(); } else if(wait_cts) { while(!(Read_MSR()&0x10)&&(starttime>PIC_FullIndex()-timeout)) CALLBACK_Idle(); } if(!(starttime>PIC_FullIndex()-timeout)) {#if SERIAL_DEBUG if(dbg_aux) fprintf(debugfp,"%12.3f API write timeout: MSR 0x%x\r\n", PIC_FullIndex(),Read_MSR());#endif return false; } } Write_THR(data);#if SERIAL_DEBUG if(dbg_aux) fprintf(debugfp,"%12.3f API write success: 0x%x\r\n", PIC_FullIndex(),data);#endif return true;}class SERIALPORTS:public Module_base {public: SERIALPORTS (Section * configuration):Module_base (configuration) { Bit16u biosParameter[4] = { 0, 0, 0, 0 }; Section_prop *section = static_cast <Section_prop*>(configuration); const char *configstrings[4] = { section->Get_string ("serial1"), section->Get_string ("serial2"), section->Get_string ("serial3"), section->Get_string ("serial4") }; // iterate through all 4 com ports for (Bitu i = 0; i < 4; i++) { biosParameter[i] = serial_baseaddr[i]; CommandLine* cmd; std::string str; cmd=new CommandLine(0,configstrings[i]); cmd->FindCommand(1,str); if(!str.compare("dummy")) { serialports[i] = new CSerialDummy (i, cmd); }#ifdef DIRECTSERIAL_AVAILIBLE else if(!str.compare("directserial")) { serialports[i] = new CDirectSerial (i, cmd); if (!serialports[i]->InstallationSuccessful) { // serial port name was wrong or already in use delete serialports[i]; serialports[i] = NULL; biosParameter[i] = 0; } }#endif#if C_MODEM else if(!str.compare("modem")) { serialports[i] = new CSerialModem (i, cmd); if (!serialports[i]->InstallationSuccessful) { delete serialports[i]; serialports[i] = NULL; biosParameter[i] = 0; } } else if(!str.compare("nullmodem")) { serialports[i] = new CNullModem (i, cmd); if (!serialports[i]->InstallationSuccessful) { delete serialports[i]; serialports[i] = NULL; biosParameter[i] = 0; } }#endif else if(!str.compare("disabled")) { serialports[i] = NULL; biosParameter[i] = 0; } else { LOG_MSG ("Invalid type for COM%d.", i + 1); serialports[i] = NULL; biosParameter[i] = 0; } delete cmd; } // for BIOS_SetComPorts (biosParameter); } ~SERIALPORTS () { for (Bitu i = 0; i < 4; i++) if (serialports[i]) { delete serialports[i]; serialports[i] = 0; } }};static SERIALPORTS *testSerialPortsBaseclass;void SERIAL_Destroy (Section * sec) { delete testSerialPortsBaseclass; testSerialPortsBaseclass = NULL;}void SERIAL_Init (Section * sec) { // should never happen if (testSerialPortsBaseclass) delete testSerialPortsBaseclass; testSerialPortsBaseclass = new SERIALPORTS (sec); sec->AddDestroyFunction (&SERIAL_Destroy, true);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -