📄 tsksio.cpp
字号:
}
else
{
if (portnum > ports)
return;
for (i = 0; i < portnum; i++)
portp = portp->next;
}
if (portp->sio != NULL) /* Port already in use ? */
return;
portp->sio = this;
pbase = port_base = portp->base;
port = portp;
/* Check if port accessible by modifying the modem control register */
i = cmodcontrol = save_mcon = tsk_inp (pbase + modemcontrol);
if (i & 0xe0)
{
port->sio = NULL;
return;
}
tsk_nop ();
tsk_outp (pbase + modemcontrol, 0xe0 | i);
tsk_nop ();
if (tsk_inp (pbase + modemcontrol) != (byte) i)
{
port->sio = NULL;
return;
}
/* Port seems OK */
civect = portp->vector;
irqbit = (byte)(1 << (portp->irq & 0x07));
wait_xmit = xmit_pending = 0;
overrun = 0;
flags = 0;
modem_flags = 0;
r_xoff = t_xoff = 0;
rtsoff = 0;
restore = 1;
clcontrol = save_lcon = tsk_inp (pbase + linecontrol);
tsk_nop ();
save_inten = tsk_inp (pbase + intenable);
tsk_nop ();
if (init)
{
clcontrol = dflt_lcon;
cmodcontrol = dflt_modcon;
}
tsk_outp (pbase + linecontrol, clcontrol | 0x80);
tsk_nop ();
save_bd1 = tsk_inp (pbase + baudreg_dll);
tsk_nop ();
save_bd2 = tsk_inp (pbase + baudreg_dlm);
tsk_nop ();
tsk_outp (pbase + linecontrol, clcontrol);
tsk_nop ();
tsk_outp (pbase + intenable, 0);
if (irq_array [portp->irq] == NULL)
{
intptr = (intprocptr far *)MK_FP (0, civect * 4);
tsk_cli ();
savvect = *intptr;
*intptr = irq_procs [portp->irq];
tsk_sti ();
}
if (init)
{
tsk_outp (pbase + linecontrol, dflt_lcon | 0x80);
tsk_nop ();
tsk_outp (pbase + baudreg_dll, dflt_baud);
tsk_nop ();
tsk_outp (pbase + baudreg_dlm, dflt_baud >> 8);
tsk_nop ();
tsk_outp (pbase + linecontrol, dflt_lcon);
tsk_nop ();
tsk_outp (pbase + modemcontrol, dflt_modcon);
tsk_nop ();
}
else
{
i = tsk_inp (pbase + modemcontrol) | OUT2;
tsk_nop ();
tsk_outp (pbase + modemcontrol, i);
tsk_nop ();
}
while (tsk_inp (pbase + linestatus) & rxreadybit)
{
tsk_nop ();
tsk_inp (pbase + receivedata);
tsk_nop ();
}
tsk_nop ();
tsk_inp (pbase + linestatus);
tsk_nop ();
modstat = tsk_inp (pbase + modemstatus);
tsk_nop ();
tsk_inp (pbase + intid);
tsk_nop ();
inta = (portp->irq > 7) ? inta11 : inta01;
if (irq_array [portp->irq] == NULL)
{
if (portp->irq > 7)
{
i = tsk_inp (inta01) & ~CHAIN_IRQBIT;
tsk_nop ();
tsk_outp (inta01, i);
}
save_irq = (byte)((i = tsk_inp (inta)) & irqbit);
tsk_nop ();
tsk_outp (inta, i & ~irqbit);
}
else
save_irq = (irq_array [portp->irq])->save_irq;
tsk_cli ();
next = irq_array [portp->irq];
irq_array [portp->irq] = this;
tsk_sti ();
/* Enable interrupts with correction for possible loss of the
first tranmit interrupt on INS8250 and INS8250-B chips */
for (;;)
{
if (tsk_inp (pbase + linestatus) & txreadybit)
{
break;
}
tsk_nop ();
}
tsk_nop ();
tsk_cli ();
tsk_outp (pbase + intenable, intdata);
tsk_nop ();
tsk_outp (pbase + intenable, intdata);
tsk_sti ();
}
commport::~commport ()
{
intprocptr far *intptr;
int pbase, i, inta;
portptr portp;
commptr curr, last;
pbase = port_base;
portp = port;
last = NULL;
curr = irq_array [portp->irq];
while (curr != this && curr != NULL)
{
last = curr;
curr = curr->next;
}
if (curr == NULL)
return;
tsk_outp (pbase + intenable, 0);
tsk_cli ();
if (last == NULL)
irq_array [portp->irq] = next;
else
last->next = next;
tsk_sti ();
inta = (portp->irq > 7) ? inta11 : inta01;
// ???? this was an input param, now a member that is set in constructor
if (restore)
{
tsk_outp (pbase + modemcontrol, save_mcon);
tsk_nop ();
tsk_outp (pbase + linecontrol, save_lcon | 0x80);
tsk_nop ();
tsk_outp (pbase + baudreg_dll, save_bd1);
tsk_nop ();
tsk_outp (pbase + baudreg_dlm, save_bd2);
tsk_nop ();
tsk_outp (pbase + linecontrol, save_lcon);
tsk_nop ();
if (irq_array [portp->irq] == NULL)
{
tsk_cli ();
tsk_outp (pbase + intenable, save_inten);
i = tsk_inp (inta) & ~irqbit;
tsk_nop ();
tsk_outp (inta, i | save_irq);
}
}
else if (irq_array [portp->irq] == NULL)
{
tsk_cli ();
i = tsk_inp (inta) | irqbit;
tsk_nop ();
tsk_outp (inta, i);
}
if (irq_array [portp->irq] == NULL)
{
tsk_cli ();
intptr = (intprocptr far *)MK_FP (0, civect * 4);
*intptr = (intprocptr)savvect;
}
tsk_sti ();
portp->sio = NULL;
}
/*-------------------------------------------------------------------------*/
/*
void change_rts (int on)
*/
void far commport::change_rts (int on)
{
cmodcontrol = (cmodcontrol & ~RTS) | ((on) ? RTS : 0);
tsk_outp (port_base + modemcontrol, cmodcontrol);
}
/*
void change_dtr (int on)
*/
void far commport::change_dtr (int on)
{
cmodcontrol = (cmodcontrol & ~DTR) | ((on) ? DTR : 0);
tsk_outp (port_base + modemcontrol, cmodcontrol);
}
/*
void far change_baud (int rate)
*/
void far commport::change_baud (long rate)
{
int i;
for (i = 0; baud_table [i]; i += 2)
if (baud_table [i] == rate)
break;
if (!(i = (int)baud_table [i + 1]))
return;
tsk_outp (port_base + linecontrol, clcontrol | (byte)0x80);
tsk_nop ();
tsk_outp (port_base + baudreg_dll, (byte)i);
tsk_nop ();
tsk_outp (port_base + baudreg_dlm, (byte)(i >> 8));
tsk_nop ();
tsk_outp (port_base + linecontrol, clcontrol);
}
void far commport::change_parity (int par)
{
clcontrol = (clcontrol & 0xc7) | par;
tsk_outp (port_base + linecontrol, clcontrol);
}
void far commport::change_wordlength (int len)
{
int i;
switch (len)
{
case 5: i = 0x00; break;
case 6: i = 0x01; break;
case 7: i = 0x02; break;
case 8: i = 0x03; break;
default: return;
}
clcontrol = (clcontrol & 0xfc) | i;
tsk_outp (port_base + linecontrol, clcontrol);
}
void far commport::change_stopbits (int n)
{
int i;
switch (n)
{
case 1: i = 0x00; break;
case 2: i = 0x04; break;
default: return;
}
clcontrol = (clcontrol & 0xfb) | i;
tsk_outp (port_base + linecontrol, clcontrol);
}
void far commport::watch_modem (byte flags)
{
modem_flags = flags & (CTS | DSR | RI | CD);
}
void far commport::protocol (int prot, word offthresh, word onthresh)
{
byte old;
old = flags;
flags = (byte)prot;
if (prot)
{
if (!offthresh)
offthresh = 10;
xoff_threshold = offthresh;
if (onthresh <= offthresh)
onthresh = offthresh + 10;
xon_threshold = onthresh;
}
if ((old & RTSCTS) != ((byte)prot & RTSCTS))
{
chng_rts (1);
modem_flags = (modem_flags & ~CTS) |
((prot & RTSCTS) ? CTS : 0);
}
if (!(prot & XONXOFF))
{
if (r_xoff)
r_xoff = -2;
t_xoff = 0;
}
if (!xmit_pending)
transmit_ready ();
}
/*-------------------------------------------------------------------------*/
int far commport::send (byte ch, dword timeout)
{
int res;
if ((res = xmit_pipe.write_pipe (ch, timeout)) < 0)
return res;
tsk_cli ();
if (!xmit_pending)
transmit_ready ();
tsk_sti ();
return 0;
}
int far commport::receive (dword timeout)
{
int res;
if ((res = (int)rcv_pipe.read_wpipe (timeout)) < 0)
return res;
if (!flags)
return res;
if (rcv_pipe.wpipe_free () > xon_threshold)
{
tsk_cli ();
if (r_xoff)
{
r_xoff = -2;
if (!xmit_pending)
transmit_ready ();
}
tsk_sti ();
if (rtsoff)
chng_rts (1);
}
return res;
}
int far commport::rcv_overrun (void)
{
int res;
res = overrun;
overrun = 0;
return res;
}
int far commport::check (void)
{
return rcv_pipe.check_wpipe ();
}
int far commport::modem_status (void)
{
return modstat;
}
int far commport::complete (void)
{
return (xmit_pipe.check_pipe () == -1);
}
int far commport::wait_complete (dword timeout)
{
return xmit_pipe.wait_pipe_empty (timeout);
}
void far commport::flush_receive (void)
{
rcv_pipe.flush_wpipe ();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -