⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serialport.cpp

📁 DOSBox emulates a full x86 pc with sound and dos. Its main use is to run old dosgames on platforms w
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		case LSR_TX_HOLDING_EMPTY_MASK|LSR_TX_EMPTY_MASK:			// bad case there must have been one		case LSR_TX_HOLDING_EMPTY_MASK:		case LSR_TX_EMPTY_MASK: // holding full but workreg empty impossible			LOG_MSG("Internal error in serial port(1)(0x%x).",LSR);			break;		case 0: // THR is empty now.			LSR |= LSR_TX_HOLDING_EMPTY_MASK;						// trigger interrupt			rise (TX_PRIORITY);			break;	}}/*****************************************************************************//* ByteTransmitted: When a byte was sent, notify here.                      **//*****************************************************************************/void CSerial::ByteTransmitted () {	switch(LSR&(LSR_TX_HOLDING_EMPTY_MASK|LSR_TX_EMPTY_MASK))	{		case LSR_TX_HOLDING_EMPTY_MASK|LSR_TX_EMPTY_MASK:			// bad case there must have been one		case LSR_TX_EMPTY_MASK: // holding full but workreg empty impossible			LOG_MSG("Internal error in serial port(2).");			break;				case LSR_TX_HOLDING_EMPTY_MASK: // now both are empty			LSR |= LSR_TX_EMPTY_MASK;			break;		case 0: // now one is empty, send the other one			LSR |= LSR_TX_HOLDING_EMPTY_MASK;			if (loopback) {				loopback_data=THR;				setEvent(SERIAL_TX_LOOPBACK_EVENT, bytetime);			}			else {		#if SERIAL_DEBUG				if(dbg_serialtraffic)					fprintf(debugfp,THR<0x10? "%12.3f tx 0x%02x (%u) (from THR)\r\n":														"%12.3f tx 0x%02x (%c) (from THR)\r\n",						PIC_FullIndex(),THR,						THR);		#endif				transmitByte(THR,false);			}			// It's ok here.			rise (TX_PRIORITY);			break;	}}/*****************************************************************************//* Transmit Holding Register, also LSB of Divisor Latch (r/w)               **//*****************************************************************************/void CSerial::Write_THR (Bit8u data) {	// 0-7 transmit data		if ((LCR & LCR_DIVISOR_Enable_MASK)) {		// write to DLL		baud_divider&=0xFF00;		baud_divider |= data;		changeLineProperties();	} else {		// write to THR		clear (TX_PRIORITY);		switch(LSR&(LSR_TX_HOLDING_EMPTY_MASK|LSR_TX_EMPTY_MASK))		{			case 0: // both full - overflow#if SERIAL_DEBUG				if(dbg_serialtraffic) fprintf(debugfp, "%12.3f tx overflow\r\n",					PIC_FullIndex());#endif				// overwrite THR				THR = data;				break;					case LSR_TX_EMPTY_MASK: // holding full but workreg empty impossible				LOG_MSG("Internal error in serial port(3).");				break;					case LSR_TX_HOLDING_EMPTY_MASK: // now both are full				LSR &= (~LSR_TX_HOLDING_EMPTY_MASK);				THR = data;				break;			case LSR_TX_HOLDING_EMPTY_MASK|LSR_TX_EMPTY_MASK:				// both are full until the first delay has passed				THR=data;				LSR &= (~LSR_TX_EMPTY_MASK);				LSR &= (~LSR_TX_HOLDING_EMPTY_MASK);				if(loopback) setEvent(SERIAL_THR_LOOPBACK_EVENT, bytetime/10);				else {			#if SERIAL_DEBUG					if(dbg_serialtraffic)						fprintf(debugfp,data<0x10? "%12.3f tx 0x%02x (%u)\r\n":												   "%12.3f tx 0x%02x (%c)\r\n",							PIC_FullIndex(),data,							data);#endif													transmitByte (data,true);				}								// triggered				// when holding gets empty				// rise (TX_PRIORITY);				break;		}	}}/*****************************************************************************//* Receive Holding Register, also LSB of Divisor Latch (r/w)                **//*****************************************************************************/Bitu CSerial::Read_RHR () {	// 0-7 received data	if ((LCR & LCR_DIVISOR_Enable_MASK)) return baud_divider&0xff;	else {		clear (RX_PRIORITY);		LSR &= (~LSR_RX_DATA_READY_MASK);		return RHR;	}}/*****************************************************************************//* Interrupt Enable Register, also MSB of Divisor Latch (r/w)               **//*****************************************************************************/// Modified by:// - writing to it.Bitu CSerial::Read_IER () {	// 0	receive holding register (byte received)	// 1	transmit holding register (byte sent)	// 2	receive line status (overrun, parity error, frame error, break)	// 3	modem status 	// 4-7	0	if (LCR & LCR_DIVISOR_Enable_MASK) return baud_divider>>8;	else return IER;}void CSerial::Write_IER (Bit8u data) {	if ((LCR & LCR_DIVISOR_Enable_MASK)) {	// write to DLM		baud_divider&=0xff;		baud_divider |= ((Bit16u)data)<<8;		changeLineProperties();	} else {		IER = data&0xF;		if ((LSR & LSR_TX_HOLDING_EMPTY_MASK) && (IER&TX_PRIORITY))			waiting_interrupts |= TX_PRIORITY;				ComputeInterrupts();	}}/*****************************************************************************//* Interrupt Status Register (r)                                            **//*****************************************************************************/// modified by:// - incoming interrupts// - loopback modeBitu CSerial::Read_ISR () {	// 0	0:interrupt pending 1: no interrupt	// 1-3	identification	//      011 LSR	//		010 RXRDY	//		001 TXRDY	//		000 MSR	// 4-7	0	if(IER&Modem_Status_INT_Enable_MASK) updateMSR();	Bit8u retval = ISR;	// clear changes ISR!! mean..	if(ISR==ISR_TX_VAL) clear (TX_PRIORITY);	return retval;}void CSerial::Write_FCR (Bit8u data) {	if((!fifo_warn) && (data&0x1)) {		fifo_warn=true;		LOG_MSG("Serial%d: Warning: Tried to activate FIFO.",COMNUMBER);	}}/*****************************************************************************//* Line Control Register (r/w)                                              **//*****************************************************************************/// signal decoder configuration:// - parity, stopbits, word length// - send break// - switch between RHR/THR and baud rate registers// Modified by:// - writing to it.Bitu CSerial::Read_LCR () {	// 0-1	word length	// 2	stop bits	// 3	parity enable	// 4-5	parity type	// 6	set break	// 7	divisor latch enable	return LCR;}void CSerial::Write_LCR (Bit8u data) {	Bit8u lcr_old = LCR;	LCR = data;	if (((data ^ lcr_old) & LCR_PORTCONFIG_MASK) != 0) {		changeLineProperties();	}	if (((data ^ lcr_old) & LCR_BREAK_MASK) != 0) {		if(!loopback) setBreak ((LCR & LCR_BREAK_MASK)!=0);		else {			// TODO: set loopback break event to reveiveError after		}#if SERIAL_DEBUG		if(dbg_serialtraffic)			fprintf(debugfp,((LCR & LCR_BREAK_MASK)!=0)?						"%12.3f break on.\r\n":						"%12.3f break off.\r\n", PIC_FullIndex());#endif	}}/*****************************************************************************//* Modem Control Register (r/w)                                             **//*****************************************************************************/// Set levels of RTS and DTR, as well as loopback-mode.// Modified by: // - writing to it.Bitu CSerial::Read_MCR () {	// 0	-DTR	// 1	-RTS	// 2	-OP1	// 3	-OP2	// 4	loopback enable	// 5-7	0	Bit8u retval=0;	if(dtr) retval|=MCR_DTR_MASK;	if(rts) retval|=MCR_RTS_MASK;	if(op1) retval|=MCR_OP1_MASK;	if(op2) retval|=MCR_OP2_MASK;	if(loopback) retval|=MCR_LOOPBACK_Enable_MASK;	return retval;}void CSerial::Write_MCR (Bit8u data) {	// WARNING: At the time setRTSDTR is called rts and dsr members are still wrong.	bool temp_dtr = data & MCR_DTR_MASK? true:false;	bool temp_rts = data & MCR_RTS_MASK? true:false;	bool temp_op1 = data & MCR_OP1_MASK? true:false;	bool temp_op2 = data & MCR_OP2_MASK? true:false;	bool temp_loopback = data & MCR_LOOPBACK_Enable_MASK? true:false;	if(loopback!=temp_loopback) {		if(temp_loopback) setRTSDTR(false,false);		else setRTSDTR(temp_rts,temp_dtr);	}	if (temp_loopback) {	// is on:		// DTR->DSR		// RTS->CTS		// OP1->RI		// OP2->CD		if(temp_dtr!=dtr && !d_dsr) {			d_dsr=true;			rise (MSR_PRIORITY);		}		if(temp_rts!=rts && !d_cts) {			d_cts=true;			rise (MSR_PRIORITY);		}		if(temp_op1!=op1 && !d_ri) {			// interrupt only at trailing edge			if(!temp_op1) {				d_ri=true;				rise (MSR_PRIORITY);			}		}		if(temp_op2!=op2 && !d_cd) {			d_cd=true;			rise (MSR_PRIORITY);		}	} else {		// loopback is off		if(temp_rts!=rts) {			// RTS difference			if(temp_dtr!=dtr) {				// both difference#if SERIAL_DEBUG			if(dbg_modemcontrol)			{				fprintf(debugfp,temp_rts?"%12.3f RTS on.\r\n":									"%12.3f RTS off.\r\n", PIC_FullIndex());				fprintf(debugfp,temp_dtr?"%12.3f DTR on.\r\n":									"%12.3f DTR off.\r\n", PIC_FullIndex());			}#endif				setRTSDTR(temp_rts, temp_dtr);			} else {				// only RTS#if SERIAL_DEBUG			if(dbg_modemcontrol)				fprintf(debugfp,temp_rts?"%12.3f RTS on.\r\n":"%12.3f RTS off.\r\n", PIC_FullIndex());#endif				setRTS(temp_rts);			}		} else if(temp_dtr!=dtr) {			// only DTR#if SERIAL_DEBUG			if(dbg_modemcontrol)				fprintf(debugfp,temp_dtr?"%12.3f DTR on.\r\n":"%12.3f DTR off.\r\n", PIC_FullIndex());#endif			setDTR(temp_dtr);		}	}	dtr=temp_dtr;	rts=temp_rts;	op1=temp_op1;	op2=temp_op2;	loopback=temp_loopback;}/*****************************************************************************//* Line Status Register (r)                                                 **//*****************************************************************************/// errors, tx registers status, rx register status// modified by:// - event from real serial port// - loopbackBitu CSerial::Read_LSR () {	Bitu retval = LSR;	LSR &= (~LSR_ERROR_MASK);			// clear error bits on read	clear (ERROR_PRIORITY);	return retval;}void CSerial::Write_MSR (Bit8u val) {	d_cts = (val&MSR_dCTS_MASK)?true:false;	d_dsr = (val&MSR_dDSR_MASK)?true:false;	d_cd = (val&MSR_dCD_MASK)?true:false;	d_ri = (val&MSR_dRI_MASK)?true:false;}/*****************************************************************************//* Modem Status Register (r)                                                **//*****************************************************************************/// Contains status of the control input lines (CD, RI, DSR, CTS) and// their "deltas": if level changed since last read delta = 1.// modified by:// - real values// - write operation to MCR in loopback modeBitu CSerial::Read_MSR () {	Bit8u retval=0;		if (loopback) {				if (rts) retval |= MSR_CTS_MASK;		if (dtr) retval |= MSR_DSR_MASK;		if (op1) retval |= MSR_RI_MASK;		if (op2) retval |= MSR_CD_MASK;		} else {		updateMSR();		if (cd) retval |= MSR_CD_MASK;		if (ri) retval |= MSR_RI_MASK;		if (dsr) retval |= MSR_DSR_MASK;		if (cts) retval |= MSR_CTS_MASK;		}	// new delta flags	if(d_cd) retval|=MSR_dCD_MASK;	if(d_ri) retval|=MSR_dRI_MASK;	if(d_cts) retval|=MSR_dCTS_MASK;	if(d_dsr) retval|=MSR_dDSR_MASK;		d_cd = false;	d_ri = false;	d_cts = false;	d_dsr = false;		clear (MSR_PRIORITY);	return retval;}/*****************************************************************************//* Scratchpad Register (r/w)                                                **//*****************************************************************************/// Just a memory register. Not much to do here.Bitu CSerial::Read_SPR () {	return SPR;}void CSerial::Write_SPR (Bit8u data) {	SPR = data;}/*****************************************************************************//* Write_reserved                                                           **//*****************************************************************************/void CSerial::Write_reserved (Bit8u data, Bit8u address) {	/*LOG_UART("Serial%d: Write to reserved register, value 0x%x, register %x",		COMNUMBER, data, address);*/}/*****************************************************************************//* MCR Access: returns cirquit state as boolean.                            **/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -