📄 dptarget.c
字号:
/* advance the read pointer */ if(bp->flags & DPMSG_WRAP) { cp->rx = cp->rxbase; } else { cp->rx += DPM_MSGSIZE; } /* see if there are more messages waiting */ if(cp->rx == cp->rxlim) { cp->rx = (-1); } } /* extract the character */ ch = (unsigned int) bp->buf[bp->index++]; /* check whether we finished the buffer */ if(bp->index == bp->bufsize) { /* invalidate the buffer */ bp->index = (-1); } return(ch);}/* send a message to netrom */voidchan_putmsg(chan, buf, len)int chan;uChar *buf;register int len;{ register DpChannel *cp = &channels[chan]; register int num_sent = 0; int size, num_left = len, ovf_size; volatile uChar dummy; register uInt16 flags; while(num_sent < len) { /* wait for the buffer */ while(1) { flags = dp_readint(cp->tx + DPM_FLAGS); if(flags != dp_readint(cp->tx + DPM_FLAGS)) { /* read failed on the verify, NetROM must be writing */ continue; } if((flags & DPMSG_READY) == 0) break;#ifdef DUMMY_READ dummy = READ_POD(cp, RA_ACK+8 );#endif YIELD_CPU(); } /* get the number of bytes to send in DP struct and overflow */ if(num_left >= DP_DATA_SIZE) { size = DP_DATA_SIZE; if (num_left >= MAX_MSG_SIZE) ovf_size = MAX_OVF_MSG_SIZE; else ovf_size = num_left - DP_DATA_SIZE; } else { size = num_left; ovf_size = 0; } /* fill the currently available DP buffer */ /* Put full msg size in upper bits of first size field */ if (num_sent == 0) { dp_writeint(cp->tx + DPM_SIZE, (len << 6) | size); } else dp_writeint(cp->tx + DPM_SIZE, size); dp_bwrite(buf, cp->tx + DPM_DATA, size); /* get the flags to write */ flags = (flags & DPMSG_WRAP) | DPMSG_READY; if(num_sent == 0) { flags |= DPMSG_START; /* or in 1K bit of msg len */ flags = flags | (len & DPMSG_1K_BIT); } num_sent += size; num_left -= size; if(num_sent >= len) flags |= DPMSG_END; dp_writeint(cp->tx + DPM_FLAGS, flags); dp_writeint(cp->tx + DPM_FLAGS, flags); /* try writing it twice */ /* notify NetROM that the buffer is ready */ dummy = READ_POD(cp, READADDR_CTLCHAR(cp , RW_MRI)); /* adjust pointers */ buf += size; /* advance the msg pointer */ if(flags & DPMSG_WRAP) { cp->tx = cp->txbase; cp->txovf = cp->txovfbase; } else { cp->tx += DPM_MSGSIZE; cp->txovf += MAX_OVF_MSG_SIZE; } }}/* flush the current character-oriented tx channel */voidchan_flushtx(chan)int chan;{ DpChannel *cp = &channels[chan]; BufIo *bp = &cp->txbuf; volatile uChar dummy; /* if we don't own the message or there's nothing in it, just return */ bp->flags = dp_readint(cp->tx + DPM_FLAGS); if((bp->flags & DPMSG_READY) != 0 || bp->index == 0) { return; } /* send the buffer */ dp_writeint(cp->tx + DPM_SIZE, (uInt16)bp->bufsize); dp_bwrite(bp->buf, cp->tx + DPM_DATA, (int) bp->bufsize); bp->flags &= DPMSG_WRAP; dp_writeint(cp->tx + DPM_FLAGS, (uInt16)bp->flags | (DPMSG_READY|DPMSG_START|DPMSG_END)); /* notify NetROM that the buffer is ready */ dummy = READ_POD(cp, READADDR_CTLCHAR(cp, RW_MRI)); /* advance the msg pointer */ if(bp->flags & DPMSG_WRAP) { cp->tx = cp->txbase; } else { cp->tx += DPM_MSGSIZE; } /* clear the buffer structure */ bp->index = 0; bp->bufsize = 0;}intchan_putch(chan, ch)int chan;uChar ch;/* Write a character into the transmit area of the readwrite channel.*/{ DpChannel *cp = &channels[chan]; BufIo *bp = &cp->txbuf; /* if the current tx channel is owned by the target, wait for it */ bp->flags = dp_readint(cp->tx + DPM_FLAGS); if(bp->flags & DPMSG_READY) { /* wait for the buffer */ while(1) { bp->flags = dp_readint(cp->tx + DPM_FLAGS); if(bp->flags != dp_readint(cp->tx + DPM_FLAGS)) { /* read failed on the verify, NetROM must be writing */ continue; } if((bp->flags & DPMSG_READY) == 0) break; if(cp->chanflags & CF_NOWAITIO) return(-1); YIELD_CPU(); } /* initialize the buffer structure */ bp->index = 0; bp->bufsize = 0; } /* write the character into the buffer */ bp->buf[bp->index++] = ch; bp->bufsize++; /* if the buffer is full, send it */ if(bp->index == DP_DATA_SIZE) { chan_flushtx(chan); } return(1);}#endif /* USE_MSGS */#endif /* READWRITE_TARGET */#ifndef RAWRITES_ONLY/* check if a character is waiting at the channel */intchan_kbhit(chan)int chan;{ DpChannel *cp = &channels[chan]; BufIo *bp = &cp->rxbuf; int retval; /* see if there is a character in this buffer */ if(bp->index < 0) { /* poll for new buffers */ if(cp->chanflags & CF_TXVALID) c_dpcons_hdlr(chan,RW_MSGBASE); else c_dpcons_hdlr(chan,RA_MSGBASE); /* no, check for a new buffer arriving */ if(cp->rx != (-1)) { retval = 1; } else { retval = 0; } } else { retval = 1; } return(retval);}#endif /* ! RAWRITES_ONLY *//* returns 1 if the "active" byte for a particular channel's transmit * and/or receive paths are set, returns 0 otherwise */intdp_chanready(chan)int chan;{ DpChannel *cp = &channels[chan]; uChar val; if(cp->chanflags & CF_TXVALID) { /* check that the rx channel is active */ val = READ_POD(cp, RW_RX); if(val != READ_POD(cp, RW_RX)) { return(0); } else if(val != 1) { return(0); } /* check that the tx channel is active */ val = READ_POD(cp, RW_TX); if(val != READ_POD(cp, RW_TX)){ return(0); } else if(val != 1) { return(0); } } else { /* check that the NetROM is ready for interrupts */ val = READ_POD(cp, RA_RI); if(val != 1 || val != READ_POD(cp, RA_RI)) { /* NetROM is not receiving */ return(0); } } /* NetROM is ready */ return(1);}#ifndef RAWRITES_ONLY/* if the CF_NOWAITIO bit is set in a channel's flags, the channel's get * and put character methods, will return immediately if there are no * available message structures in dualport ram. This routine sets or * clears that bit. */voidset_dp_blockio(chan, val)int chan, val;{ DpChannel *cp = &channels[chan]; if(val == 0) { cp->chanflags |= CF_NOWAITIO; } else { cp->chanflags &= ~CF_NOWAITIO; }}/* This routine handles any messages received from NetROM. */STATIC void c_dpcons_hdlr(chan,base)int chan;uInt32 base;{ register DpChannel *cp; register uInt16 flags; /* volatile uChar dummy; */ /* get a pointer to the channel */ cp = &channels[0]; /* a received message indicator */ while(cp->rx != cp->rxlim) { flags = dp_readint(cp->rxlim + DPM_FLAGS); if(flags != dp_readint(cp->rxlim + DPM_FLAGS)) { /* NetROM must be writing, try again */ continue; } if(flags & DPMSG_READY) { /* a new message is ready */ if(cp->rx == (-1)) { /* record that the message is ready to be read */ cp->rx = cp->rxlim; } /* advance the read limit pointer */ if(flags & DPMSG_WRAP) { cp->rxlim = cp->rxbase; } else { cp->rxlim += DPM_MSGSIZE; } /* process one message at a time if using readaddr protocol */ if((cp->chanflags & CF_TXVALID) == 0) { break; } } else { /* no more messages */ break; } }}#endif /* ! RAWRITES_ONLY *//* configure the dual-port ram to be used in a read-only or a read-write * fashion. */intconfig_dpram(base, width, index, flags, numaccesses)uInt32 base;int width, index, flags, numaccesses;{ DpChannel *cp = &channels[0]; /* set the address of dualport ram in pod 0 */ cp->dpbase = base; cp->width = width; cp->index = index; /* initialize the buffer system */ cp->txbuf.bufsize = 0; cp->txbuf.index = 0; cp->rxbuf.bufsize = 0; cp->rxbuf.index = (-1); cp->numaccess = numaccesses; /* initialize the ack counter */ cp->rxackval = 0; /* use the flags to set up */ switch(flags) {#ifdef READONLY_TARGET case DPF_READONLY_TGT: /* we can only read dualport */ cp->chanflags = CF_RXVALID | CF_NOWAITIO; /* start the receive area after the read-address area, and the * status/control area */ cp->rxbase = cp->rxlim = RA_MSGBASE; cp->rx = (-1); /* to avoid runtime divides, make this a case stmt */ switch(cp->numaccess) { case 4: cp->oobthresh = (READADDR_SIZE / 4) - RA_MAX_INDEX; break; case 2: cp->oobthresh = (READADDR_SIZE / 2) - RA_MAX_INDEX; break; case 1: default: cp->oobthresh = (READADDR_SIZE / 1) - RA_MAX_INDEX; break; } /* Original code with the divide cp->oobthresh = (READADDR_SIZE / cp->numaccess) - RA_MAX_INDEX; */ /* all done */ break;#endif /* READONLY_TARGET */#ifdef READWRITE_TARGET case DPF_ONECHANNEL: /* we can both read and write dualport */ cp->chanflags = CF_TXVALID | CF_RXVALID | CF_NOWAITIO; /* start the receive area after the status/control area */ cp->rxbase = cp->rxlim = RW_MSGBASE; cp->rx = (-1); /* start the transmit area after the receive area */ cp->txbase = cp->tx = (RW_REC_MSGS + 1) * DPM_MSGSIZE; cp->oobthresh = 0; /* all done */ break;#endif /* READWRITE_TARGET */ default: return(-1); break; } return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -