📄 dptarget.c
字号:
val = READ_POD(&channels[0], addr); val <<= 8; val += READ_POD(&channels[0], addr + 1); /* return, in host byte order */ return(val);}/* copy bytes to dual-port memory (optimized version - move stuff out of the loop )*/voiddp_bwrite(src, addr, size)uChar *src;uInt32 addr;int size;{ register int inc; register volatile uChar *dst; register int i; DpChannel *cp = &channels[0]; inc = cp->width; dst = (volatile uChar *)(cp->dpbase + (cp->width * addr) + cp->index); for(i = 0; i < size; i++) {#if (HASCACHE == True) WRITE_POD(cp, addr++, *src);#else *dst = *src; dst += inc;#endif src++; }}/* copy bytes from dual-port memory (optimized version - move stuff out of the loop) */voiddp_bread(addr, buf, size)uInt32 addr;volatile uChar *buf;int size;{ register int inc; register volatile uChar *src; register int i; DpChannel *cp = &channels[0]; inc = cp->width; src = (volatile uChar *)(cp->dpbase + (cp->width * addr) + cp->index); for(i = 0; i < size; i++) {#if (HASCACHE == True) uChar tmp = READ_POD(cp, addr++); *buf = tmp;#else *buf = *src; src += inc;#endif buf ++; }}#endif /* RAWRITES_ONLY */#ifdef READONLY_TARGET#ifndef RAWRITES_ONLY#ifdef USE_MSGS/* this routine reads message from dualport ram. It returns different * statuses, depending on whether or not message data is present, the message * is complete, the message is not complete but data was present, or * the message overflows the buffer. The number of bytes read into the * message buffer is changed by side effect. * * This routine doesn't use the buffer pointers in the channel structure. * Note that GM_NODATA will only be returned if we are not in a blocking I/O * mode. */intra_getmsg(buf, len, bytesread)uChar *buf;int len, *bytesread;{ int done = 0; int nbytes = 0; register DpChannel *cp = &channels[0]; register uInt16 flags, size; register uInt16 msg_size; volatile uChar dummy; /* look for the whole message */ while(done == 0) { /* check whether a buffer has become valid */ while(cp->rx == (-1)) { /* poll for new buffers */ c_dpcons_hdlr(0, RA_MSGBASE); /* did we get a message? */ if(cp->rx == (-1)) {#ifdef VETHER if((cp->chanflags & CF_NOWAITIO) || (nbytes == 0)) {#else if(cp->chanflags & CF_NOWAITIO) {#endif *bytesread = nbytes; return(nbytes == 0 ? GM_NODATA : GM_NOTDONE); } YIELD_CPU(); } } /* synchronize ACK values */ cp->rxackval = READ_POD(cp, RA_ACK); /* get the status and length of the message */ flags = dp_readint(cp->rx + DPM_FLAGS); size = dp_readint(cp->rx + DPM_SIZE); /* Msg length may be in top 10 bits of size field of 1st msg */#ifdef VETHER if (nbytes == 0) { msg_size = (size >> 6) | (flags & DPMSG_1K_BIT); }#endif size = size & 0x3f; /* copy data into the buffer */ if(size > len) { *bytesread = nbytes; /*printf("ra_getmsg: msglen=%d, buf=%d, read=%d ", size,len,nbytes);*/ return(GM_MSGOVERFLOW); } /* copy the message into the buffer */ dp_bread(cp->rx + DPM_DATA, buf, (int) size); /* update our buffer pointers */ buf += size; nbytes += size; len -= size; /* return the buffer */ dummy = READ_POD(cp, READADDR_CTLCHAR(cp, RA_PACK_INDEX)); /* wait for our packet ack to be acked in its turn; read the ack * from NetROM twice to make sure it's valid */ cp->rxackval++; while(READ_POD(cp, RA_ACK) != cp->rxackval && READ_POD(cp, RA_ACK) != cp->rxackval) {#ifdef DUMMY_READ dummy = READ_POD(cp, RA_ACK+8 );#endif ; /* do nothing */ } /* advance the read pointer */ if(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); } /* was this the end of the message? */ if((flags & DPMSG_END) != 0) done = 1; }#ifdef VETHER /* Error check if msg len was in 1st buffer */ /* If we have a console for printf to use, do this check if (msg_size) { if (msg_size != nbytes) printf("ra_getmsg: 1st buf len=%d, actual=%d\n",msg_size,nbytes); } */#endif *bytesread = nbytes; return(GM_MSGCOMPLETE);}#endif /* USE_MSGS */intra_getch()/* This routine attempts to read a character from the receive msg buffers of * the readaddress channel. */{ DpChannel *cp = &channels[0]; BufIo *bp = &cp->rxbuf; int ch; volatile uChar dummy; /* see if there is a character in this buffer */ if(bp->index < 0) { /* wait for the buffer to become valid */ while(cp->rx == (-1)) { /* poll for new buffers */ c_dpcons_hdlr(0, RA_MSGBASE); /* did we get a message? */ if(cp->rx == (-1)) { if(cp->chanflags & CF_NOWAITIO) return(-1); YIELD_CPU(); } } /* synchronize ACK values */ cp->rxackval = READ_POD(cp, RA_ACK); /* make sure that the message is ready by reading the flags byte * of the next receive msg. */ bp->flags = dp_readint(cp->rx + DPM_FLAGS); /* Re-read the flags because the NetROM may have been * modifying them while we read them. */ if(bp->flags != dp_readint(cp->rx + DPM_FLAGS)) { /* read failed on the verify, NetROM must be writing */ bp->flags = dp_readint(cp->rx + DPM_FLAGS); } if((bp->flags & DPMSG_READY) == 0) { return(-1); } /* set up the i/o buffer for the message */ bp->bufsize = dp_readint(cp->rx + DPM_SIZE); if(bp->bufsize > DP_DATA_SIZE) { bp->bufsize = DP_DATA_SIZE; } dp_bread(cp->rx + DPM_DATA, bp->buf, (int) bp->bufsize); bp->index = 0; /* return the buffer */ dummy = READ_POD(cp, READADDR_CTLCHAR(cp, RA_PACK_INDEX)); /* wait for our packet ack to be acked in its turn; read the ack * from NetROM twice to make sure it's valid */ cp->rxackval++; while(READ_POD(cp, RA_ACK) != cp->rxackval && READ_POD(cp, RA_ACK) != cp->rxackval) { /* read different address to avoid contention on some targets*/#ifdef DUMMY_READ dummy = READ_POD(cp, RA_ACK+8 );#endif } /* 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);}#endif /* ! RAWRITES_ONLY */static voidra_sendchar(ch)uChar ch;{ register DpChannel *cp = &channels[0]; register volatile uChar val, dummy; register uChar expval; /* reading a character sends an interrupt to NetROM */ dummy = READ_POD(cp, READADDR_DATACHAR(cp, ch)); /* wait for it to be acked */ expval = ++cp->rxackval; while(1) { val = READ_POD(cp, RA_ACK);#ifdef DUMMY_READ dummy = READ_POD(cp, RA_ACK+8); #endif if(val == expval && val == READ_POD(cp, RA_ACK)) { /* got an ack for our last character */ break; } }}voidra_putch(ch)uChar ch;/* This routine sends a character to NetROM over the ReadAddress channel.*/{ register volatile uChar val; register DpChannel *cp = &channels[0]; /* wait for the NetROM to be ready */ while(1) { val = READ_POD(cp, RA_RI); if(val == 1 && val == READ_POD(cp, RA_RI)) { /* NetROM is receiving */ cp->rxackval = READ_POD(cp, RA_ACK); /* AMP */ break; } } /* make sure we can send the character */ while(ch >= cp->oobthresh) { /* send the escape character */ ra_sendchar(cp->oobthresh + RA_ESC_INDEX); /* adjust the character we're sending */ ch -= cp->oobthresh; } /* send the real character */ ra_sendchar(ch);}#ifndef RAWRITES_ONLY#ifdef USE_MSGS/* This routine sends a complete message to NetROM over the ReadAddress * channel. */voidra_putmsg(buf, len)uChar *buf;int len;{ register volatile uChar val; register DpChannel *cp = &channels[0]; /* wait for the NetROM to be ready */ while(1) { val = READ_POD(cp, RA_RI); if(val == 1 && val == READ_POD(cp, RA_RI)) { /* NetROM is receiving */ cp->rxackval = READ_POD(cp, RA_ACK); /* AMP */ break; } } /* send the start message delimiter */ ra_sendchar(cp->oobthresh + RA_STARTMSG_INDEX); /* send the message */ while(len != 0) { ra_putch(*buf); buf++; len--; } /* send the end message delimiter */ ra_sendchar(cp->oobthresh + RA_ENDMSG_INDEX);}#endif /* USE_MSGS */#endif /* ! RAWRITES_ONLY *//* this routine runs from ram to avoid conflicts with NetROM as it sets * memory */voidra_setmem_sendval(ch)uChar ch;{ register volatile uChar dummy, expval, val; register DpChannel *cp = &channels[0]; /* make sure we can send the character */ while(ch >= cp->oobthresh) { /* reading a character sends an interrupt to NetROM */ dummy = READ_POD(cp, READADDR_CTLCHAR(cp, RA_ESC_INDEX)); /* wait for it to be acked */ expval = ++cp->rxackval; while(1) { val = READ_POD(cp, RA_ACK); if(val == expval && val == READ_POD(cp, RA_ACK)) { /* got an ack for our last character */ break; } } /* adjust the character we're sending */ ch -= cp->oobthresh; } /* reading a character sends an interrupt to NetROM */ dummy = READ_POD(cp, READADDR_DATACHAR(cp, ch)); /* wait for it to be acked */ expval = ++cp->rxackval; while(1) { val = READ_POD(cp, RA_ACK); if(val == expval && val == READ_POD(cp, RA_ACK)) { /* got an ack for our last character */ break; } }}/* sends a request to NetROM to write a byte of memory */voidra_setmem(ch, addr, buf)uChar ch;uInt32 addr;uChar *buf; /* should be RA_SETMEM_RTN_SIZE bytes, 32 bit aligned */{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -