📄 dptarget.c
字号:
/* read the msb first, in case it contains flags */ val = (uChar)nr_ReadByte(cp, addr); val <<= 8; val += (uChar)nr_ReadByte(cp, addr + 1); /* return, in host byte order */ return(val);}/*** Function: nr_WriteBuf** Description: Copies bytes to dual-port RAM** Warning: Assumes 'chan' is valid**** Parameters:** chan channel to write to** src data to write** addr start address for write** len length of buf**** Returns:*/STATIC voidnr_WriteBuf( uInt16 chan, uChar *src, uInt32 addr, uInt16 len ){ register Int16 i; register DpChannel *cp = &channels[chan];#if (nr_HasCache != True && READONLY_TARGET == False) register Int16 inc; register volatile uChar *dst;#endif#if (nr_HasCache == True && READONLY_TARGET == False) /* RW tgt with cache */ for(i = 0; i < len; i++) { nr_WriteByte(cp, addr++, *src); src++; }#elif (READONLY_TARGET == True) /* Read only tgt, either way */ RR_ENABLE(cp, addr); /* Enable RR & latch start addr */ for(i = 0; i < len; i++) { RR_WRITE_BYTE(cp, *src); /* Write & autoincrement dest addr */ src++; } RR_DISABLE(cp);#else /* RW tgt without cache */ inc = cp->width; dst = (volatile uChar *)(cp->dpbase + (cp->width * addr) + cp->index); for(i = 0; i < len; i++) { *dst = *src; dst += inc; src++; }#endif}/*** Function: nr_ReadBuf** Description: Copies bytes from dualport RAM**** Parameters:** chan channel to read from** addr start address for read** buf buffer to read into** len length of buf**** Returns:*/STATIC voidnr_ReadBuf( uInt16 chan, uInt32 addr, volatile uChar *buf, Int16 len ){ register Int16 i; volatile uChar ch; register DpChannel *cp = &channels[chan]; for(i = 0; i < len; i++, buf++, addr++) { *buf = (ch = nr_ReadByte(cp, addr)); }}/*** Function: nr_PutOOBMsg** Description: sends out-of-band message to NetROM**** Parameters:** chan channel to write to** cmd command number, see dptarget.h for commands** buf data, if any, required by this command** size size of buf; must be less than 58 bytes**** Returns:** Err_NoError if the OOB msg was sent successfully** Err_NotReady if NetROM is not ready to process messages** Err_BadChan if the chan is invalid (0,1,2,3 are valid on NR5xx)** Err_BadLength if the "size" of the buffer is too big** Err_BadCommand if the command is invalid*/STATIC Int16nr_PutOOBMsg( uInt16 chan, uInt16 cmd, register char *buf, uInt16 size ){ register DpChannel *cp; uInt16 flags; if( !nr_ChanReady(chan) ) /* NetROM not ready */ return Err_NotReady; if( chan >= DP_MAXCHANNELS ) /* Invalid channel! */ return Err_BadChan; if( size > DP_DATA_SIZE-2 ) /* Includes cmd and buf */ return Err_BadLength; if( cmd > DP_OOB_MAXCMD ) /* Invalid command! */ return Err_BadCommand; /* get a pointer to the channel */ cp = &channels[chan]; /* Wait for the buffer */ while(1) { flags = nr_ReadInt(chan, cp->tx + DPM_FLAGS); if(flags != nr_ReadInt(chan, cp->tx + DPM_FLAGS)) { /* read failed on the verify, NetROM must be writing */ continue; } if((flags & DPMSG_READY) == 0) break; nr_YieldCPU(); } /* Write size field to DP buf */ nr_WriteInt(chan, cp->tx + DPM_SIZE, size+sizeof(cmd)); /* Write out-of-band command number to DP buf */ nr_WriteInt(chan, cp->tx + DPM_OOB_CMD, cmd); if( size > 0 ) nr_WriteBuf(chan, (uChar*)buf, cp->tx + DPM_OOBDATA, size); /* Write flags for OOB msg */ /* If doing SetMEM, do _not_ set Ready flag! */ flags = (flags & DPMSG_WRAP) | DPMSG_OOB | DPMSG_START | DPMSG_END; if( DP_OOB_SETMEM != cmd ) flags |= DPMSG_READY; nr_WriteInt(chan, cp->tx + DPM_FLAGS, flags); /* Notify NetROM that the buffer is ready, unless it's nr_SetMem */ /* nr_SetMem will read DP_MRI from a routine in RAM */ if( DP_OOB_SETMEM != cmd ) dummy = nr_ReadByte(cp, DP_MRI); else (*(cp->wait_nr_done_ptr))(cp); /* Wait in RAM until NR is finished */ /* 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; } return Err_NoError;}/*** Function: nr_Wait** Note: 1. This ftn must run from RAM** 2. nr_WaitEnd() must be defined immediately after nr_Wait** 3. (2) assumes that the compiler keeps ftns in order** Description: Finishes writing OOB_SetMem msg, waits for NR to** write memory, then exits**** Parameters:** cp Pointer to channel to use**** Returns:*/STATIC voidnr_Wait( DpChannel *cp ){ uChar flagsMSB; /* Warning: cp is assumed to be valid */ do{ nr_WriteByte( cp, DP_NR_DONE, False ); /* Force flag to False */ } while( nr_ReadByte(cp, DP_NR_DONE) != False ); /* Finish writing flags: write READY bit */ /* Assumes Ready-bit is in MSB */ flagsMSB = nr_ReadByte(cp, cp->tx + DPM_FLAGS); flagsMSB |= (DPMSG_READY >> 8); nr_WriteByte(cp, cp->tx + DPM_FLAGS, flagsMSB ); dummy = nr_ReadByte(cp, DP_MRI); /* Ask NR to process messages */ /* Wait for NetROM to finish the PodMem write ** Note: when emulation is OFF, target will see 0xFF in ** this location. This is not a problem, because the target ** will hang in wait loop, below, until the flag == True. ** Flag will equal True after NetROM sets it True and turns ** emulation back on. ** ** If your code is hanging here, NetROM is not completing ** its write to Pod memory */ while( nr_ReadByte( cp, DP_NR_DONE ) != True ) {}}/*** Function: nr_WaitEnd** Description: This empty ftn marks the end of nr_Wait()** Note: wait_fnt_end() must be defined immediately after nr_Wait**** Parameters:**** Returns:*/STATIC void nr_WaitEnd( void ){}/*** Function: nr_ProcessMsgs** Description: Processes any messages received from NetROM**** Parameters:** chan Channel to process**** Returns:** Err_BadChan if the chan is invalid** Err_NoError otherwise*/STATIC Int16 nr_ProcessMsgs( uInt16 chan ){ register DpChannel *cp; register uInt16 flags; if( chan >= DP_MAXCHANNELS ) /* Invalid channel! */ return Err_BadChan; /* get a pointer to the channel */ cp = &channels[chan]; /* a received message indicator */ while(cp->rx != cp->rxlim) { flags = nr_ReadInt(chan, cp->rxlim + DPM_FLAGS); if(flags != nr_ReadInt(chan, 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; } } else { /* no more messages */ break; } } return Err_NoError;}#if (DEBUG_ON == True)/*** Function: nr_TestComm** Description: Determines if NR Comm is working** Notes:** 1. Tests 1 through 6 test low-level reads & writes to dualport RAM** Before executing the tests, execute a 'fill 0 dpmem' and a ** 'tgtreset' on NetROM.** After executing the tests, verify their success by typing** 'di dpmem 0x50 0x80' at the NetROM prompt. Your NetROM display ** should look like:** ** 0050 6e72 5f57 7269 7465 - 4279 7465 0000 0000 nr_WriteByte....** 0060 6e72 5f52 6561 6442 - 7974 6500 0000 0000 nr_ReadByte.....** 0070 6e72 5f57 7269 7465 - 496e 7420 0000 0000 nr_WriteInt ....** 0080 0000 0000 0000 0000 - 0000 0000 0000 0000 ................** 0090 6e72 5f52 6561 6449 - 6e74 2020 0000 0000 nr_ReadInt ....** 00a0 6e72 5f57 7269 7465 - 4275 6600 0000 0000 nr_WriteBuf.....** 00b0 6e72 5f52 6561 6442 - 7566 2000 0000 0000 nr_ReadBuf .....**** 2. Tests 7 and higher test higher-level char and msg passing thru DP RAM** for these tests, you'll need to telnet to ** the NetROM debugport (1235 is the default)** Example: telnet netrom 1235** The name of the function tested should appear in the telnet window.**** Parameters:** chan Channel to test, 0-3** lastTest See tests, below to select** endian 0 for Intel (little-endian), 1 for Motorola (big-endian)**** Returns:** Err_BadChan if chan is invalid ** Err_NoError otherwise*/Int16 nr_TestComm( uInt16 chan, uInt16 lastTest, uInt16 endian ){ Int32 i,j; uChar ch; uChar testNum = 1; static char *wb_buf = "nr_WriteByte"; static char *rb_buf = "nr_ReadByte"; static char *wi_buf[2] = {"rnW_iretnI t", "nr_WriteInt "}; /* intel, mot */ static char *ri_buf[2] = {"rnR_aeIdtn ", "nr_ReadInt "}; /* intel, mot */ static char *wbuf = "nr_WriteBuf"; static char *rbuf = "nr_ReadBuf "; static char *putch_buf = "\r\n\n\nnr_Putch\r\n"; static char putmsg_buf[1024] = "\r\nnr_PutMsg\r\n"; char* getch_buf = "\r\nnr_Getch test\r\n"; char* getmsg_buf = "\r\nnr_GetMsg test\r\n"; char* query_buf = "Type a message, then press <ret> \r\n"; char buf[81]; uInt16 bytesread; DpChannel *cp; BufIo *bp; if( chan >= DP_MAXCHANNELS ) /* Invalid channel! */ return Err_BadChan; /* get a pointer to the channel */ cp = &channels[chan]; bp = &cp->txbuf; /* Test 1 ** Test nr_ConfigDP params & nr_WriteByte ** Write 'nr_WriteByte ' to DPRAM, starting at DP_BASE + 0x50 ** Assuming your hardware is correctly installed, and ** this test fails, either you are calling nr_ConfigP with the ** wrong parameters, or your NetROM is not set up correctly */ for(i=0; i<strlen(wb_buf); i++) { nr_WriteByte(cp, 0x50+i, wb_buf[i]); } if(testNum++ >= lastTest) return Err_NoError; /* Test 2 ** Test nr_ReadByte macro ** Read nr_WriteByte, convert, write nr_ReadByte */ for(i=0; i<strlen(rb_buf); i++ ) { ch = nr_ReadByte(cp, 0x50+i) + rb_buf[i] - wb_buf[i]; nr_WriteByte(cp, 0x60+i, ch); } if(testNum++ >= lastTest) return Err_NoError; /* Test 3 ** Test nr_WriteInt ftn ** Write 'nr_WriteInt' */ for(i=0; i<strlen(wi_buf[endian]); i+=2) { nr_WriteInt(chan, 0x70+i, *(uInt16*)(&wi_buf[endian][i] )); } if(testNum++ >= lastTest) return Err_NoError; /* Test 4 ** Test nr_ReadInt ftn ** Read nr_WriteInt, convert, write as nr_ReadInt */ for(i=0; i<strlen(wi_buf[endian]); i+=2) { j = nr_ReadInt(chan, 0x70+i) + *(uInt16*)(&ri_buf[endian][i]) - *(uInt16*)(&wi_buf[endian][i]); nr_WriteInt(chan, 0x90+i, j ); } if(testNum++ >= lastTest) return Err_NoError; /* Test 5 ** Test nr_WriteBuf ftn ** Write 'nr_WriteBuf' */ nr_WriteBuf( chan, (uChar*)wbuf, 0xA0, strlen(wbuf) ); if(testNum++ >= lastTest) return Err_NoError; /* Test 6 ** Test nr_ReadBuf ftn ** Read 'nr_WriteBuf', convert, then write 'nr_ReadBuf' */ nr_ReadBuf( 0, 0xA0, (uChar*)buf, sizeof(buf) ); for(i=0; i<strlen(rbuf); i++ ) rbuf[i] = buf[i] + rbuf[i] - wbuf[i]; nr_WriteBuf( 0, (uChar*)rbuf, 0xB0, strlen(rbuf) ); if(testNum++ >= lastTest) return Err_NoError; /* Test 7 ** Test nr_Putch ftn and nr_FlushTX ftn ** Send the chars 'n' 'r' '_' 'P' 'u' 't' 'c' 'h' to the NR debug port ** Do you see 'nr_Putch' on the debug window? */ for( i=0; i<strlen(putch_buf); i++) nr_Putch(chan, putch_buf[i]); nr_FlushTX(0); if(testNum++ >= lastTest) return Err_NoError; /* Test 8 ** Test nr_PutMsg ftn ** Send the message "nr_PutMsg\r\n" */ nr_PutMsg( chan, putmsg_buf, strlen(putmsg_buf) ); if(testNum++ >= lastTest) return Err_NoError; /* Test 9 ** Test nr_OOBMsg ftn via nr_Cputs ** You will see "nr_Cputs working" in the NetROM console window on NR5xx ** On NR4xx, OOB msgs pass thru like normal in-band msgs */ nr_Cputs( chan, "nr_Cputs\r\n", 10 ); if(testNum++ >= lastTest) return Err_NoError; /* Test A ** Test nr_GetMsg ftn ** Get user input, then echo. */ nr_SetBlockIO(chan, True); nr_PutMsg(chan, getmsg_buf, strlen(getmsg_buf) ); nr_PutMsg(chan, query_buf, strlen(query_buf) ); nr_GetMsg(chan, buf, 80, &bytesread ); nr_PutMsg(chan, buf, bytesread ); if(testNum++ >= lastTest) return Err_NoError; /* Test B ** Test nr_Getch ftn ** Get user input, then echo. */ nr_PutMsg(chan, getch_buf, strlen(getch_buf) ); nr_PutMsg(chan, query_buf, strlen(query_buf) ); do{ ch = nr_Getch(chan); if(ch > 0)nr_Putch(chan, ch); }while( ch != '\n' ); nr_FlushTX(chan); if(testNum++ >= lastTest) return Err_NoError; /* Test C ** Test nr_SetMem ftn ** Write "SetMem" ** Note: Move address so that SetMem writes to regular podmem, ** NOT dualport RAM! Don't stomp code or data! */ nr_SetMem( 0, ROMSTART + 0x2000, "SetMem", 6 ); if(testNum++ >= lastTest) return Err_NoError; /* Test D ** Stress test nr_PutMsg ftn ** Send 1k buffer 100 times */ nr_PutMsg(0, "\r\n*** nr_PutMsg Stress Test ***\r\n\r\n", 36); for(j=0; j<=1023; j++) { if( (j%2) ) putmsg_buf[j] = ' '; else putmsg_buf[j] = 0x08; /* BS */ } putmsg_buf[0] = ' '; putmsg_buf[1] = '['; putmsg_buf[6] = ']'; putmsg_buf[7] = ' '; for(i=1; i <= 9000; i++) { int a,b,c,d; a = i/1000; b = (i - a*1000)/100; c = (i - a*1000 - b*100)/10; d = (i - a*1000 - b*100 - c*10); putmsg_buf[2] = '0' + a; putmsg_buf[3] = '0' + b; putmsg_buf[4] = '0' + c; putmsg_buf[5] = '0' + d; nr_PutMsg( chan, putmsg_buf, 1024); } return Err_NoError;}#else /* DEBUG_ON */Int16 nr_TestComm( uInt16 chan, uInt16 lastTest, uInt16 endian ){ return -1;}#endif /* DEBUG_ON */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -