📄 dptarget.c
字号:
register volatile uChar dummy, expval, val; register DpChannel *cp = &channels[0]; uChar *srcp; int tmp; void (*sendvalp)(); if(emoffonwrite_set == 1) { do_emoffonwrite(); emoffonwrite_set = 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 set memory character */ dummy = READ_POD(cp, READADDR_CTLCHAR(cp, RA_SET_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; } } /* send the offset */ ra_putch((uChar) ((addr >> 24) & 0xFF)); ra_putch((uChar) ((addr >> 16) & 0xFF)); ra_putch((uChar) ((addr >> 8) & 0xFF)); ra_putch((uChar) (addr & 0xFF)); /* copy our sendval routine to ram */ tmp = (uInt32) buf & 0x03; /* force 32-bit alignment */ if(tmp != 0) buf += (4 - tmp); srcp = (uChar *) ra_setmem_sendval; sendvalp = (void (*)()) buf; for(tmp = 0; tmp < RA_SETMEM_RTN_SIZE; tmp++) { *buf = *srcp; buf++; srcp++; } /* call the sendval routine */ (*sendvalp)(ch);}/* sends a request to NetROM to reset the target returns 0 if NetROM not ready*/intra_reset(){ register volatile uChar dummy, expval, val; register DpChannel *cp = &channels[0]; /* check for the NetROM to be ready for interrupts */ val = READ_POD(cp, RA_RI); if(val == !1 || val != READ_POD(cp, RA_RI)) { /* NetROM is not receiving */ return(0); } cp->rxackval = READ_POD(cp, RA_ACK); /* AMP */ /* send the 1st sequence character */ dummy = READ_POD(cp, READADDR_CTLCHAR(cp, RA_RESET)); /* 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; } } /* send the 2nd sequence char */ ra_putch((uChar) (0x01)); /* send the 3rd sequence character */ dummy = READ_POD(cp, READADDR_CTLCHAR(cp, RA_RESET)); /* 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; } } /* send the 4th sequence char */ dummy = READ_POD(cp, READADDR_CTLCHAR(cp, RA_RESET)); ra_putch((uChar) (0x02)); /* send the last sequence character */ dummy = READ_POD(cp, READADDR_CTLCHAR(cp, RA_RESET)); /* don't wait for it to be acked */ return(1);}/* sends a request to NetROM to re-initalize (resync) the dualport parameters returns 0 if NetROM not ready, returns 1 when done */intra_resync(){ register volatile uChar dummy, expval, val; register DpChannel *cp = &channels[0]; /* check for the NetROM to be ready for interrupts */ val = READ_POD(cp, RA_RI); if(val == !1 || val != READ_POD(cp, RA_RI)) { /* NetROM is not receiving */ return(0); } cp->rxackval = READ_POD(cp, RA_ACK); /* AMP */ /* send the 1st sequence character */ dummy = READ_POD(cp, READADDR_CTLCHAR(cp, RA_RESYNC)); /* wait for it to be acked */ expval = ++cp->rxackval; while(1) { val = READ_POD(cp, RA_ACK); dummy = READ_POD(cp, RA_ACK+8); if(val == expval && val == READ_POD(cp, RA_ACK)) { /* got an ack for our last character */ break; } } /* send the 2nd sequence char */ ra_putch((uChar) (0x01)); /* send the 3rd sequence character */ dummy = READ_POD(cp, READADDR_CTLCHAR(cp, RA_RESYNC)); /* wait for it to be acked */ expval = ++cp->rxackval; while(1) { val = READ_POD(cp, RA_ACK); dummy = READ_POD(cp, RA_ACK+8); if(val == expval && val == READ_POD(cp, RA_ACK)) { /* got an ack for our last character */ break; } } /* send the 4th sequence char */ ra_putch((uChar) (0x02)); /* send the last sequence character */ dummy = READ_POD(cp, READADDR_CTLCHAR(cp, RA_RESYNC)); /* wait for it to be acked */ expval = ++cp->rxackval; while(1) { val = READ_POD(cp, RA_ACK); dummy = READ_POD(cp, RA_ACK+8); if(val == expval && val == READ_POD(cp, RA_ACK)) { /* got an ack for our last character */ break; } } /* Wait for NetROM to turn RA_RI back on before completing, so that we won't try anything else before NetROM has resynced. Requires NetROM firmware version 1.3.1 or later. */ while(1) { val = READ_POD(cp, RA_RI); if(val == 1 && val == READ_POD(cp, RA_RI)) { break; } } return(1);}/* acknowledges a receive interrupt returns 0 if NetROM not ready, returns 1 when done */intra_rx_intr_ack(){ register volatile uChar dummy, expval, val; register DpChannel *cp = &channels[0]; /* check for the NetROM to be ready for interrupts */ val = READ_POD(cp, RA_RI); if(val == !1 || val != READ_POD(cp, RA_RI)) { /* NetROM is not receiving */ return(0); } cp->rxackval = READ_POD(cp, RA_ACK); /* AMP */ /* send the 1st sequence character */ dummy = READ_POD(cp, READADDR_CTLCHAR(cp, RA_MISC)); /* 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; } } /* send the 2nd sequence char */ ra_putch((uChar) (RX_INTR_ACK)); return(1);}/* tells netrom to turn off emulation before writing to memory returns 0 if NetROM not ready, returns 1 when done */voidra_emoffonwrite(){ emoffonwrite_set=1; /* set global so ra_setmem can first call do_emoffonwrite just in case debug connection was not connected at the time of this call */}intdo_emoffonwrite(){ register volatile uChar dummy, expval, val; register DpChannel *cp = &channels[0]; /* check for the NetROM to be ready for interrupts */ val = READ_POD(cp, RA_RI); if(val == !1 || val != READ_POD(cp, RA_RI)) { /* NetROM is not receiving */ return(0); } cp->rxackval = READ_POD(cp, RA_ACK); /* AMP */ /* send the 1st sequence character */ dummy = READ_POD(cp, READADDR_CTLCHAR(cp, RA_MISC)); /* 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; } } /* send the 2nd sequence char */ ra_putch((uChar) (EMOFFONWRITE)); return(1);}#endif /* READONLY_TARGET */#ifdef READWRITE_TARGET#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. */intchan_getmsg(chan, buf, len, bytesread)int chan;uChar *buf;int len, *bytesread;{ register DpChannel *cp = &channels[0]; int done = 0; int nbytes = 0; register uInt16 flags, size; int msg_len = 0; /* look for the whole message */ while(done == 0) { /* wait for the buffer to become valid */ while(cp->rx == (-1)) { /* poll for new buffers */ c_dpcons_hdlr(chan, RW_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(); } } /* read the status and size of the new message block */ flags = dp_readint(cp->rx + DPM_FLAGS); size = dp_readint(cp->rx + DPM_SIZE);#ifdef VETHER /* get whole msg len from first pkt of msg */ if (nbytes == 0) { /* if ((flags & DPMSG_START) == 0) printf("no START: %04x ", flags & 0xffff); */ msg_len = (size >> 6) | (flags & DPMSG_1K_BIT); size = size & 0x3f; }#endif /* copy data into the buffer */ if(size > len) { *bytesread = nbytes; return(GM_MSGOVERFLOW); } dp_bread(cp->rx + DPM_DATA, buf, (int) size); /* return the buffer */ dp_writeint(cp->rx + DPM_FLAGS, flags & ~DPMSG_READY); /* update our buffer pointers */ buf += size; nbytes += size; len -= size; /* 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; } *bytesread = nbytes;#ifdef VETHER if (nbytes != msg_len) { /* printf("chan_getmsg: 1st pkt len=%d, got %d\n", msg_len, nbytes); */ return(GM_NOTDONE); } else #endif return(GM_MSGCOMPLETE);}intchan_getch(chan)int chan;/* This routine attempts to read a character from the receive msg buffers * of the readwrite channel. */{ DpChannel *cp = &channels[chan]; BufIo *bp = &cp->rxbuf; int ch; /* 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(chan, RW_MSGBASE); /* did we get a message? */ if(cp->rx == (-1)) { if(cp->chanflags & CF_NOWAITIO) return(-1); YIELD_CPU(); } } /* 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 */ dp_writeint(cp->rx + DPM_FLAGS, (uInt16)bp->flags & ~DPMSG_READY);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -