Jump to content
IGNORED

Test of incoming telnet


danwinslow

Recommended Posts

Would someone be willing to help me test incoming internet functionality? I have a little telnet type chat thingy running on my 8bit, and I would like to test connectability. If you would be willing to 'meet' me online in about 3 hours, please PM me or email me ( NOSPAMMATION_danwinslow@cox.net ). If you can't meet in 3 hours, just let me know when you could be ready to give it a try sometime today. I am in US CST time zone. You would need an internet connection and a telnet client. YOu will also need to be able to receive and send emails quickly, as we'll need to do a bit of back and forth as we test.

 

Thanks.

Edited by danwinslow
Link to comment
Share on other sites

Would someone be willing to help me test incoming internet functionality? I have a little telnet type chat thingy running on my 8bit, and I would like to test connectability.

1012669[/snapback]

 

Sounds interesting. What sort of TCP stack are you using? Something you found somewhere, or something you wrote yourself?

 

I did a TCP stack on "bare metal" once. Sorta cute. Most interesting feature is that while it uses a couple of ports for real connections, all of the other ports operate as an "echo server". Telnet into port 23, for instance, and any characters you type will be echoed back to you. What makes the echo server most interesting is that it can accommodate a literally-unlimited number of simultaneous connections (traffic would be a problem if too many connections tried to send too much data at once, but if 200,000 machines all opened telnet connections a millisecond apart, the unit would have no problem echoing data to any of them even though it only has 128Kbytes of RAM).

Link to comment
Share on other sites

I am using a stack from WATTCP. The stack itself is running on a very, very small embedded PC SBC that I am using as a NIC. I am driving it via 52k SIO from the atari. The little board fits right in my 130xe :)

1012713[/snapback]

 

Aw, that's cheating. My stack uses a Crystal Semiconductor chip to grab and buffer the incoming ethernet packets, but other than that it's entirely done on "bare metal". I'll confess I cheated on a couple things and am thus not totally RFC-compliant, but my stack does work. The echo server, though it can't possibly be totally RFC-compliant, is still a neat hack (a TCP client is typically required to keep a 32-bit count of how many bytes it has sent or received. Obviously there's no way a stack running on a machine with 128KB of RAM could do this for 100,000 simultaneous connections. What the echo server does, however, is jiggle the packets so that the PC to which it is connected takes care of all the necessary buffering, counting, and retransmissions. Rather cute, actually.

Link to comment
Share on other sites

Well, my object is to put a NIC into my 8bit and be able to do useful things with it, rather than to write my own TCP stack. Its more than just a NIC, it has a 386 processor and a 32MB flash ram drive and 2 serial lines. It's the size of a credit card. It may technically not be just a NIC, but a modern NIC has more processing power than this little card does. I run my version of SIO2PC on it, so it emulates 2 16MB hard drives to teh atari, as well as supporting my custom 'SIO2Ethernet' protocol. It pumps the packets across SIO at 52k.

 

I am writing a couple libraries for developers to use with it...right now the one I am testing is for CC65, but I will be doing versions for Action and several of the basics.

 

The API is a simple one, but after this gets ironed out I will be doing full blown socket.h implementations for CC65.

Edited by danwinslow
Link to comment
Share on other sites

Well, my object is to put a NIC into my 8bit and be able to do useful things with it, rather than to write my own TCP stack. Its more than just a NIC, it has a 386 processor and a 32MB flash ram drive and 2 serial lines. It's the size of a credit card. It may technically not be just a NIC, but a modern NIC has more processing power than this little card does.

1012722[/snapback]

 

When you've got that much more general-purpose processing power in your "NIC" than in your main computer, though, it doesn't really seem like I'd be telnetting into an Atari, but rather into that other computer.

 

The CS 8900 on my telnet project performs address matching and has 4K of memory to hold incoming and outgoing packets, and supports backoff-and-retry for local ethernet collisions, but that's basically it. All of the protocol handling is handled by my code.

Link to comment
Share on other sites

...

 

Well, I certainly admire you for writing your own stack. If you don't think this project is interesting, thats fine by me. Hopefully someone else might. It's not any different than disk support via SIO2PC or APE, and people seem to use those all the time. The only thing being supported by the "NIC" is the basic packet stack, the rest, ie., the telnet protocol is in the 8bit.

Edited by danwinslow
Link to comment
Share on other sites

Well, I certainly admire you for writing your own stack. If you don't think this project is interesting, thats fine by me. Hopefully someone else might. It's not any different than disk support via SIO2PC or APE, and people seem to use those all the time. The only thing being supported by the "NIC" is the basic packet stack, the rest, ie., the telnet protocol is in the 8bit.

1012732[/snapback]

 

I was being a little facetious. I will admit that I do see a bit of a difference, insofar as the purpose of SIO2PC and other things is to make it more convenient for the Atari to do "Atari-ish" stuff rather than take on new tasks. And if in fact you're just using the embedded PC as a raw packet handler and doing all the protocol stuff on the Atari, using the embedded PC only because it was easier than doing your own board with an 8900 on it, I guess that's fair. But sometimes I've seen people do what I call "stone soup" projects--"Hey look at this--I've got this really cool php-enabled webserver running on a PIC 16C54 microprocessor (512 words ROM, 25 bytes RAM)" not mentioning that they're also using an embedded PC that's actually doing all the webserver stuff incorporating a small amount of data supplied by the PIC. I'll help you out with your project if you need, though I have to leave about 3:30pm CST.

Link to comment
Share on other sites

No, I am not trying to show off, or claim I have written some uber teensy stack with my Kung Fu. I am just trying to allow us all to write TCP apps. The little board actually fits into my 130xe, and draws power from it, so it's all self contained. I don't have the hardware chops to do any custom direct connection, so I stuck with what I knew, ie., serial. I wrote my own high speed SIO layer, and then wrote a thin wrapper around it to drive calls across the SIO, that I called 'SSIO' ( Simple Socket IO ). You create a socket, connect, read and write, etc. I really don't think its all that different from using a FILE * to a PC file system via SIO2PC, but I understand what you mean I think.

 

Here's the board :

http://www.jkmicro.com/products/picoflash.html

 

It is completely contained in my 130, all you see externally is the RJ45 jack. So, I have a portable SIO2PC with a real time clock readable from Spartados, 32MB of hard drive space and ethernet support. I also plan on eventually putting CC65 itself on the flash in a PC file system parition, and pass files back and forth for doing 'cross-compiles' behind the scenes directly from my atari. The boards very cheap, and I think its a pretty neat deal. And, its portable with no extra wires.

 

Here's some current test code snips. Feel free to offer advice, I am no genius when it comes to 6502 assembler.

 

#include <stdlib.h>

#include <stdio.h>

#include <unistd.h>

#include <atari.h>

#include <mbuffer.h>

#include <string.h>

#include <time.h>

#include <conio.h>

 

#define AUDF3  0xD204

#define AUDF4  0xD206

#define AUDC4  0xD207

#define AUDCTL  0xD208

#define SERIN  0xD20D

#define SEROUT  0xD20D

#define IRQEN  0xD20E

#define IRQST  0xD20E

#define SKCTL  0xD20F

#define SKSTAT  0xD20F

#define SKREST  0xD20A

#define PBCTL  0xD303

#define CRITIC  0x66

#define WSYNC    *(byte*) 0xD40A

#define VCOUNT  *(byte*) 0xD40B

#define COLPF2  *(byte*) 0xD018

#define RTCLOK2  *(byte*) 0x14

#define CH      *(byte*) 0x2FC

 

 

#define ACK_CHAR  0x41

#define NACK_CHAR 0x4e

#define GO_CHAR  0x47

 

#define SSIO_ERR_NOERR    0

#define SSIO_ERR_NOSOCK    1

#define SSIO_ERR_NOCONNECT 2

#define SSIO_ERR_NORES    3

#define SSIO_ERR_TIMEOUT  4

#define SSIO_ERR_UNKNOWN  5

 

#define SSIO_TCP 1

#define SSIO_UDP 2

 

#define TCP_MODE_BINARY  0      /* default mode */

#define TCP_MODE_ASCII  1

#define UDP_MODE_CHK    0      /* default to having checksums */

#define UDP_MODE_NOCHK  2      /* turn off checksums */

#define TCP_MODE_NAGLE  0      /* Nagle algorithm */

#define TCP_MODE_NONAGLE 4

 

#define tcp_StateLISTEN  0      /* listening for connection */

#define tcp_StateSYNSENT 1      /* syn sent, active open */

#define tcp_StateSYNREC  2      /* syn received, synack+syn sent. */

#define tcp_StateESTAB  3      /* established */

#define tcp_StateESTCL  4      /* established, but will FIN */

#define tcp_StateFINWT1  5      /* sent FIN */

#define tcp_StateFINWT2  6      /* sent FIN, received FINACK */

#define tcp_StateCLOSWT  7      /* received FIN waiting for close */

#define tcp_StateCLOSING 8      /* sent FIN, received FIN (waiting for FINACK) */

#define tcp_StateLASTACK 9      /* fin received, finack+fin sent */

#define tcp_StateTIMEWT  10    /* dally after sending final FINACK */

#define tcp_StateCLOSEMSL 11

#define tcp_StateCLOSED  12    /* finack received */

 

char *tcp_state_names[]=

{"LISTEN  ", 

"SYNSENT ",

"SYNREC  ", 

"ESTAB  ", 

"ESTCL  ", 

"FINWT1  ", 

"FINWT2  ", 

"CLOSWT  ", 

"CLOSING ",

"LASTACK ",

"TIMEWT  ", 

"CLOSEMSL",

"CLOSED  "};

 

typedef unsigned char socket;

 

static unsigned char baud=0x08;

static unsigned char maxtries=3;

 

static unsigned int  uitemp1;

static unsigned int  uitemp2;

static unsigned char chksum;

static unsigned char tries;

static unsigned char ack;

static int      sock_status[8];

static int      sock_data[8];

 

static unsigned char msg[255];

static unsigned char data[255];

 

void _setbaud( unsigned char baud );

void _setretries( unsigned char retry_count );

void _setup( void );

void _takedown( void );

void _pokey( void );

void _set_pokey_read( void );

void _set_pokey_write( void );

void _init_timeout( void );

void _wait_xmit_done( void );

void _sendbyte( void );

void _sendack( void );

void _sendnak( void );

void _set_irqen_xmit( void );

void _set_irqen_recv( void );

void _set_irqen_off( void );

void _getbuff( void );

void _sendbuff( void );

void _getack( void );

void _sendcommand( unsigned char *cmd );

void _senddata( unsigned char *buff, unsigned int length );

void _getdata( unsigned char *buff, unsigned int length );

void _command_on( void ); void _command_off( void );

 

void _setbaud( unsigned char baudrate )

{

  baud=baudrate;

}

 

void _setretries( unsigned char retry_count )

{

  maxtries=retry_count;

}

 

void _setup( void )

{

  tries=0;

  ack=0;

  asm("        SEI");

}

 

void _takedown( void )

{

  asm("        CLI");

}

 

void _pokey( void )

{

  //IO mode is in A

  asm("  STA $D20F");  // SKCTL

  asm("  STA $D20A");  // SKREST

  asm("  LDA _baud");  // baud rate

  asm("  STA $D204");  // AUDF3

  asm("  LDA #0");

  asm("  STA $D206");  // AUDF4

  asm("  LDA #$28");

  asm("  STA $D208");  // AUDCTL

  asm("  LDA #$A8");

  asm("  STA $D207");  // AUDC4

 

void _set_pokey_read( void )

{

  asm("        LDA #$13"); 

  _pokey();

}

 

void _set_pokey_write( void )

{

  asm("        LDA #$23"); 

  _pokey();

}

 

void _init_timeout( void )

{

  asm("        LDX $13");              //init timeout

  asm("        INX");

  asm("        INX");

//  asm("        INX");

}

 

void _wait_xmit_done( void )

{

 

  //wait for transmission done flag 

  asm("@S8:    LDX $13");        //init timeout

  asm("        INX");

  asm("        INX");

  asm("@S9:    CPX $13");        //check time

  asm("        BEQ @TERR");

  asm("        LDA $D20E");      //IRQST

  asm("        BPL @BERR");      //break key?

  asm("        AND #$08");      //byte done?

  asm("        BNE @S9");        //no, wait some more

 

  return;

 

  asm("@TERR: NOP");

  printf("timeout in _wait_xmit_done\n");

  return;

 

  asm("@BERR: NOP");

  printf("break in _wait_xmit_done\n");

  return;

 

  asm("@XIT:  NOP");

}

 

void _sendbyte( void )

{

  //byte to be sent is in a

  asm("        PHA");

  _wait_xmit_done();

  asm("        PLA");

  asm("        STA $D20D");      //SEROUT send byte

  asm("@S1:    LDX $13");        //init timeout

  asm("        INX");

  asm("        INX");

  asm("@S2:    CPX $13");        //check time

  asm("        BEQ @TERR");

  asm("        LDA $D20E");      //IRQST

  asm("        BPL @BERR");      //break key?

  asm("        AND #$10");      //byte needed?

  asm("        BNE @S2");        //no, wait some more

  _wait_xmit_done();

 

  return;

 

  asm("@TERR: NOP");

  printf("timeout in _sendbyte\n");

  _set_irqen_off();

  return;

 

  asm("@BERR: NOP");

  printf("break in _sendbyte\n");

  _set_irqen_off();

  return;

 

  asm("@XIT:  NOP");

}

 

void _sendgo( void )

{

  _set_pokey_write();

  _set_irqen_xmit();

  asm("        LDA #$47"); //go char

  _sendbyte();

  //_set_irqen_off();

}

 

void _sendack( void )

{

  _set_pokey_write();

  _set_irqen_xmit();

  asm("        LDA #$41"); //ack char

  _sendbyte();

  _set_irqen_off();

}

 

void _sendnak( void )

{

  _set_pokey_write();

  _set_irqen_xmit();

  asm("        LDA #$4e"); //nack char

  _sendbyte();

  _set_irqen_off();

}

 

void _set_irqen_xmit( void )

{

  asm("        LDA #$EF");    //1110 1111

  asm("        STA $D20E");  //IRQEN

  asm("        LDA #$D0");    //1101 0000

  asm("        STA $D20E");  //IRQEN

}

 

void _set_irqen_recv( void )

{

  asm("        LDA #$DF");    //1101 1111

  asm("        STA $D20E");  //IRQEN

  asm("        LDA #$E0");    //1110 0000

  asm("        STA $D20E");  //IRQEN

}

 

void _set_irqen_off( void )

{

  asm("        LDA #$FF");    //1111 1111

  asm("        STA $D20E");  //IRQEN

  asm("        LDA #$C0");    //1100 0000

  asm("        STA $D20E");  //IRQEN

}

 

void _getbuff( void )

{

 

  _sendgo();

  _wait_xmit_done();

 

  _set_pokey_read();

  _set_irqen_recv();

 

  asm("        LDY #0");

  asm("        STY _chksum");

 

  asm("@S1:    LDX $13");        //init timeout

  asm("        INX");

  asm("        INX");

  asm("@S2:    CPX $13");        //check time

  asm("        BEQ @TERR");

  asm("        LDA $D20E");      //IRQST

  asm("        BPL @BERR");      //break key?

  asm("        AND #$20");      //byte received?

  asm("        BNE @S2");        //no, wait some more

 

  asm("        LDA $D20D");      //SERIN read byte

  asm("        STA (ptr1),y");  //store char into buffer

  asm("        CLC");            //do checksum

  asm("        ADC _chksum");

  asm("        ADC #0");

  asm("        STA _chksum");

  _set_irqen_recv();

 

  asm("@S25:    INC ptr1");      //inc low byte of addr

  asm("        BNE @S3");

  asm("        INC ptr1+1");    //inc high byte

  asm("@S3:    LDA _uitemp2");  //is low byte equal?

  asm("        CMP ptr1");

  asm("        BNE @S1");        //no go back

  asm("        LDA _uitemp2+1"); //is hi byte?

  asm("        CMP ptr1+1");

  asm("        BNE @S1");        //no, go back

 

 

  asm("@S4:    LDX $13");        //init timeout

  asm("        INX");

  asm("        INX");

  asm("@S5:    CPX $13");        //check time

  asm("        BEQ @TERR");

  asm("        LDA $D20E");      //IRQST

  asm("        BPL @BERR");      //break key?

  asm("        AND #$20");      //byte received?

  asm("        BNE @S5");        //no, wait some more

 

  asm("        LDA $D20D");      //SERIN read byte

  asm("        STA _ack");      //store checksum in ack temporarily

 

  //_set_irqen_off();

 

  return;

 

  asm("@TERR: NOP");

  _set_irqen_off();

  printf("timeout in _getbuff\n");

  _set_irqen_off();

  return;

 

  asm("@BERR: NOP");

  _set_irqen_off();

  printf("break in _getbuff\n");

  _set_irqen_off();

  return;

}

 

void _sendbuff( void )

{

  _set_pokey_write();

  _set_irqen_xmit();

 

  asm("        LDY #0");

  asm("        STY _chksum");

 

  asm("        LDA (ptr1),y");  //prime the pump

  asm("        STA $D20D");      //SEROUT send byte

  asm("        TAX");            //save it for checksum

  asm("        JMP @S25");

 

                                  //_init_timeout(); 

  asm("@S1:    LDX $13");        //init timeout

  asm("        INX");

  asm("        INX");

 

  asm("@S2:    CPX $13");        //check time

  asm("        BEQ @TERR");

  asm("        LDA $D20E");      //IRQST

  asm("        BPL @BERR");      //break key?

  asm("        AND #$10");      //byte needed?

  asm("        BNE @S2");        //no, wait some more

 

                                  //_set_irqen_xmit();

  asm("        LDA #$EF");      //1110 1111

  asm("        STA $D20E");      //IRQEN

  asm("        LDA #$D0");      //1101 0000

  asm("        STA $D20E");      //IRQEN

 

  asm("        LDA (ptr1),y");

  asm("        STA $D20D");      //SEROUT send byte

  asm("        TAX");            //save it for checksum

 

  asm("@S25:    INC ptr1");      //inc low byte of addr

  asm("        BNE @S3");

  asm("        INC ptr1+1");    //inc high byte

  asm("@S3:    LDA _uitemp2");  //is low byte equal?

  asm("        CMP ptr1");

  asm("        BNE @S4");        //no, do csum and go back

  asm("        LDA _uitemp2+1"); //is hi byte?

  asm("        CMP ptr1+1");

  asm("        BNE @S4");        //no, go do checksum and then go back

  asm("        JMP @S5");        //we must be done, go send checksum

 

  asm("@S4:    TXA");            //put byte back in a

  asm("        CLC");            //do checksum

  asm("        ADC _chksum");

  asm("        ADC #0");

  asm("        STA _chksum");

  asm("        JMP @S1");        //go back to top

 

  asm("@S5:    LDA _chksum");    //all done, send chksum

  asm("        STA $D20D");      //SEROUT send byte

 

  _wait_xmit_done();

 

  return;

 

  asm("@TERR: NOP");

  //_set_irqen_off();

  printf("timeout in _send_buff\n");

  return;

 

  asm("@BERR: NOP");

  //_set_irqen_off();

  printf("break in _send_buff\n");

  return;

 

}

 

void _getack( void )

{

  ack=0;

  _set_pokey_read();

  _set_irqen_recv();

  _init_timeout();

  asm("@M1:    LDA $D20E");    //IRQST

  asm("        BPL @BERR");    // jump out on break key

  asm("        CPX $13");      // timed out?

  asm("        BEQ @TERR");    // yep

  asm("        AND #$20");      // byte ready?

  asm("        BNE @M1");      // nope, wait some more

  asm("        LDA $D20D");    // read byte

  asm("        STA _ack");      // save it

  _set_irqen_off();

 

//  printf("_getack : %c\n",ack);

 

  return;

 

  asm("@TERR: NOP");

  //_set_irqen_off();

  printf("timeout in _get_ack\n");

  return;

 

  asm("@BERR: NOP");

  //_set_irqen_off();

  printf("break in _get_ack\n");

  return;

}

 

void _ssio_sleep( unsigned char jiffies ) {

  int x;

  for(x=0;x<jiffies;x++)

  {

    asm("    LDX #0");

    asm("@s1: INX");

    asm("    BNE @s1");

  }

}

 

void _sendcommand( unsigned char *cmd )

{

  //send command

  //set up send vars

  uitemp1=(unsigned int)&cmd[0];        //buffer start

  uitemp2=((unsigned int)&cmd[0])+4+1;  //buffer end+1

  asm("        LDA _uitemp1");     

  asm("        STA ptr1");

  asm("        LDA _uitemp1+1");

  asm("        STA ptr1+1");

  _command_on();

  _ssio_sleep(1);

  _sendbuff();     

  _command_off();

  _ssio_sleep(1);

  _getack();

}

 

void _senddata( unsigned char *buff, unsigned int length ) {

  //send command

  //set up send vars

  uitemp1=(unsigned int)&buff[0];            //buffer start

  uitemp2=((unsigned int)&buff[0])+length+1;  //buffer end+1

  asm("        LDA _uitemp1");     

  asm("        STA ptr1");

  asm("        LDA _uitemp1+1");

  asm("        STA ptr1+1");

  _sendbuff();     

  _getack();

}

 

void _getdata( unsigned char *buff, unsigned int length ) {

  //send command

  //set up send vars

  uitemp1=(unsigned int)&buff[0];            //buffer start

  uitemp2=((unsigned int)&buff[0])+length; //buffer end

  asm("        LDA _uitemp1");     

  asm("        STA ptr1");

  asm("        LDA _uitemp1+1");

  asm("        STA ptr1+1");

  _getbuff();     

}

 

void _command_on( void )

{

  *(unsigned char *)PBCTL=0x34; // 0011 0100 pull command low ( active )

}

 

void _command_off( void )

{

  *(unsigned char *)PBCTL=0x3C; // 0011 1100 pull command high ( inactive )

}               

 

void _ssio( unsigned char *cmd,

            unsigned char *buff,

            unsigned int  sendl,

            unsigned int  *recvl )

{

 

  _setup();

 

  tries=0;                           

  while( tries < maxtries )

  {

    _sendcommand(cmd);

    if ( ack != 'A' )

      tries++;

    else

      break;

  }

 

  tries=0;                           

  while( tries < maxtries )

  {

    _senddata(buff,sendl);

    if ( ack != 'A' )

      tries++;

    else

      break;

  }

 

if ( sendl > 0 )

{                                       

  tries=0;                           

  while( tries < maxtries )

  {

    _getdata(buff,*recvl);

    //printf("got %s\n",inbuff);   

    if ( chksum != ack ) //chksum was calced, ack was revcd

    {

      tries++;

      _sendnak();

    }else{

      _sendack();

      break;

    }

  }

}

 

  _takedown();

}

 

unsigned char cmd[4]={ 0xF1,0x64,0x02,0x02 }; unsigned char inbuff[1024]; unsigned int  sendl; unsigned int  recvl;

 

unsigned char *default_ip    ="192.168.1.120";               

unsigned char *default_netmask="255.255.255.0";               

unsigned char *default_gateway="192.168.1.1";               

unsigned char *default_dns1  ="68.13.16.25";               

unsigned char *default_dns2  ="";               

 

unsigned char ssio_init( char *ip,

                        char *netmask,

                        char *gateway,

                        char *dns1,

                        char *dns2 )

{

  unsigned char rc;                       

  unsigned int    length;

 

  mbuffer_init(1024); 

 

  if ( ip == NULL )

  {

    ip=default_ip;

  }

  if ( netmask == NULL )

  {

    netmask=default_netmask;

  }

  if ( gateway == NULL )

  {

    gateway=default_gateway;

  }

  if ( dns1 == NULL )

  {

    dns1=default_dns1;

  }

  if ( dns2 == NULL )

  {

    dns2=default_dns2;

  }

 

  mbuffer_addfield(strlen(ip)+1,ip);

  mbuffer_addfield(strlen(netmask)+1,netmask);

  mbuffer_addfield(strlen(gateway)+1,gateway);

  mbuffer_addfield(strlen(dns1)+1,dns1);

  mbuffer_addfield(strlen(dns2)+1,dns2);

 

  cmd[1]=0x64;

  cmd[2]=((mbuffer_size() >> 4)+1);

  cmd[3]=0x10;

  sendl=cmd[2] << 4;

  recvl=cmd[3] << 4;

  _ssio(cmd,mbuffer(),sendl,&recvl);

 

  mbuffer_rewind();                                           

 

  mbuffer_getfield(&length,&(sock_status[0]));

  mbuffer_getfield(&length,&(sock_data[0]));

  mbuffer_getfield(&length,&rc);

//  printf("ssio_init got rc %i\n",rc);

 

  return rc;

}

 

socket ssio_connect( char *host,

                    unsigned int port,

                    unsigned int timeout,

                    unsigned char *rc,

                    int *status,

                    char *msg )

{

  socket sock;

  unsigned int length;

 

  mbuffer_init(1024);

  mbuffer_addfield(strlen(host)+1,host);

  mbuffer_addfield(sizeof(port),&port);

  mbuffer_addfield(sizeof(timeout),&timeout);

  cmd[1]=0x65;

  cmd[2]=((mbuffer_size() >> 4)+1);

  cmd[3]=0x10;

  sendl=cmd[2] << 4;

  recvl=cmd[3] << 4;

  _ssio(cmd,mbuffer(),sendl,&recvl);

  mbuffer_rewind();                                           

 

  mbuffer_getfield(&length,&(sock_status[0]));

  mbuffer_getfield(&length,&(sock_data[0]));

  mbuffer_getfield(&length,&sock);

  mbuffer_getfield(&length,rc);

  mbuffer_getfield(&length,status);

  mbuffer_getfield(&length,msg);

 

//  printf("socket : %i\n",sock);

//  printf("rc    : %i\n",*rc);

//  printf("status : %i\n",*status);

//  printf("msg    : %s\n",msg);

 

  return sock;

}

 

unsigned char ssio_listen( socket        sock,

                          unsigned int  lport,

                          unsigned long ina,

                          unsigned int  port )

{

  unsigned int length;

  unsigned char rc;                       

 

  mbuffer_init(1024);

  mbuffer_addfield(sizeof(sock),&sock);

  mbuffer_addfield(sizeof(lport),&lport);

  mbuffer_addfield(sizeof(ina),&ina);

  mbuffer_addfield(sizeof(port),&port);

  cmd[1]=102;

  cmd[2]=((mbuffer_size() >> 4)+1);

  cmd[3]=0x10;

  sendl=cmd[2] << 4;

  recvl=cmd[3] << 4;

  _ssio(cmd,mbuffer(),sendl,&recvl);

  mbuffer_rewind();                                           

 

  mbuffer_getfield(&length,&(sock_status[0]));

  mbuffer_getfield(&length,&(sock_data[0]));

  mbuffer_getfield(&length,&rc);

 

  return rc;

}

 

unsigned char ssio_readline( socket sock, char *data, int max, int *count)

{

  unsigned int length;

  unsigned char rc;

 

  *count=0;

  max=255;

 

  mbuffer_init(1024);

  mbuffer_addfield(sizeof(sock),&sock);

  mbuffer_addfield(sizeof(max),&max);

  mbuffer_addfield(sizeof(count),count);

 

  cmd[1]=109;

  cmd[2]=((mbuffer_size() >> 4)+1);

  cmd[3]=0x20;

  sendl=cmd[2] << 4;

  recvl=cmd[3] << 4;

  _ssio(cmd,mbuffer(),sendl,&recvl);

 

  mbuffer_rewind();                                           

  mbuffer_getfield(&length,&(sock_status[0]));

  mbuffer_getfield(&length,&(sock_data[0]));

  mbuffer_getfield(&length,&rc);

  mbuffer_getfield(&length,count);

  data[0]=0x0;

  mbuffer_getfield(&length,data);

 

//  printf("ssio_readline : rc %i\n",rc);

//  printf("ssio_readline : count %i\n",*count);

 

  return rc;

}

 

unsigned char ssio_read( socket sock, char *data, int max, int *count)

{

  unsigned int length;

  unsigned char rc;

 

  *count=0;

  max=255;

 

  mbuffer_init(1024);

  mbuffer_addfield(sizeof(sock),&sock);

  mbuffer_addfield(sizeof(max),&max);

 

  cmd[1]=103;

  cmd[2]=((mbuffer_size() >> 4)+1);

  cmd[3]=0x20;

  sendl=cmd[2] << 4;

  recvl=cmd[3] << 4;

  _ssio(cmd,mbuffer(),sendl,&recvl);

 

  mbuffer_rewind();                                           

  mbuffer_getfield(&length,&(sock_status[0]));

  mbuffer_getfield(&length,&(sock_data[0]));

  mbuffer_getfield(&length,&rc);

  mbuffer_getfield(&length,count);

  data[0]=0x0;

  mbuffer_getfield(&length,data);

 

//  printf("ssio_read : rc %i\n",rc);

//  printf("ssio_read : count %i\n",*count);

 

  return rc;

}

 

unsigned char ssio_writeline( socket sock, char *data)

{

  unsigned char rc;

  unsigned int  length;

 

  mbuffer_init(1024);

  mbuffer_addfield(sizeof(sock),&sock);

  length=strlen(data)+1;

  mbuffer_addfield(sizeof(length),&length);

  mbuffer_addfield(rc+1,data);

 

  cmd[1]=110;

  cmd[2]=((mbuffer_size() >> 4)+1);

  cmd[3]=0x20;

  sendl=cmd[2] << 4;

  recvl=cmd[3] << 4;

  _ssio(cmd,mbuffer(),sendl,&recvl);

  mbuffer_rewind();                                           

 

  mbuffer_getfield(&length,&(sock_status[0]));

  mbuffer_getfield(&length,&(sock_data[0]));

  mbuffer_getfield(&length,&rc);

 

//  printf("ssio_writeline : rc %i\n",rc);

 

  return rc;

}

 

unsigned char ssio_write( socket sock, char *data, int size)

{

  unsigned char rc;

  unsigned int  length;

 

  mbuffer_init(1024);

  mbuffer_addfield(sizeof(sock),&sock);

  mbuffer_addfield(sizeof(size),&size);

  mbuffer_addfield(size,data);

 

  cmd[1]=104;

  cmd[2]=((mbuffer_size() >> 4)+1);

  cmd[3]=0x20;

  sendl=cmd[2] << 4;

  recvl=cmd[3] << 4;

  _ssio(cmd,mbuffer(),sendl,&recvl);

  mbuffer_rewind();                                           

 

  mbuffer_getfield(&length,&(sock_status[0]));

  mbuffer_getfield(&length,&(sock_data[0]));

  mbuffer_getfield(&length,&rc);

 

  printf("ssio_write : rc %i\n",rc);

 

  return rc;

}

 

unsigned int ssio_close( socket sock )

{

  unsigned int  length;

  int          status;

 

  mbuffer_init(1024); 

 

  mbuffer_addfield(sizeof(sock),&sock);

 

  cmd[1]=105;

  cmd[2]=((mbuffer_size() >> 4)+1);

  cmd[3]=0x10;

  sendl=cmd[2] << 4;

  recvl=cmd[3] << 4;

  _ssio(cmd,mbuffer(),sendl,&recvl);

  mbuffer_rewind();                                           

 

  mbuffer_getfield(&length,&(sock_status[0]));

  mbuffer_getfield(&length,&(sock_data[0]));

  mbuffer_getfield(&length,&status);

 

//  printf("ssio_close : rc %i\n",status);

  return status;

}

 

void ssio_poll( void )

{

  unsigned int  length;

 

  mbuffer_init(1024); 

 

  cmd[1]=106;

  cmd[2]=((mbuffer_size() >> 4)+1);

  cmd[3]=0x03;

  sendl=cmd[2] << 4;

  recvl=cmd[3] << 4;

  _ssio(cmd,mbuffer(),sendl,&recvl);

  mbuffer_rewind();                                           

 

  mbuffer_getfield(&length,sock_status);

  mbuffer_getfield(&length,sock_data);

 

//  for(x=0;x<8;x++)

//  {

//    printf("sock %i data %i %s\n",x,sock_data[x],tcp_state_names[sock_status[x]]);

//  }

 

//  printf("ssio_poll\n");

 

}

 

socket ssio_socket( int sock_type )

{

  unsigned int  length;

  socket sock;

  int rc;

 

  mbuffer_init(1024); 

  mbuffer_addfield(sizeof(sock_type),&sock_type);

 

  cmd[1]=107;

  cmd[2]=((mbuffer_size() >> 4)+1);

  cmd[3]=0x03;

  sendl=cmd[2] << 4;

  recvl=cmd[3] << 4;

  _ssio(cmd,mbuffer(),sendl,&recvl);

  mbuffer_rewind();                                           

 

  mbuffer_getfield(&length,&(sock_status[0]));

  mbuffer_getfield(&length,&(sock_data[0]));

  mbuffer_getfield(&length,&sock);

  mbuffer_getfield(&length,&rc);

 

 

//  printf("ssio_socket\n");

  return sock;

 

}

 

socket ssio_sockmode( socket sock, unsigned char mode )

{

  unsigned int  length;

  int rc;

 

  mbuffer_init(1024); 

  mbuffer_addfield(sizeof(sock),&sock);

  mbuffer_addfield(sizeof(mode),&mode);

 

  cmd[1]=108;

  cmd[2]=((mbuffer_size() >> 4)+1);

  cmd[3]=0x03;

  sendl=cmd[2] << 4;

  recvl=cmd[3] << 4;

  _ssio(cmd,mbuffer(),sendl,&recvl);

  mbuffer_rewind();                                           

 

  mbuffer_getfield(&length,&(sock_status[0]));

  mbuffer_getfield(&length,&(sock_data[0]));

  mbuffer_getfield(&length,&rc);

 

 

//  printf("ssio_sockmode %i\n",rc);

  return sock;

 

}

 

void show_socks( void )

{

  int x;

 

  *((unsigned char *)84)=0;

  *((unsigned char *)85)=0;

  printf("---------------------------------------\n");

  for(x=0;x<8;x++)

  {

    printf("sock %i data %i %s\n",x,sock_data[x],tcp_state_names[sock_status[x]]);

  }

}

 

void show_sock( socket sock )

{

  sprintf(data,"sock %i data %i %s\n",sock,sock_data[sock],tcp_state_names[sock_status[sock]]);

  cputsxy(0,0,data);

}

 

int ssio_waitline( socket sock, int seconds ) {

  int x;

  for(x=0;x<seconds;x++)

  {

    ssio_poll();

    if ( sock_data[sock] ) return sock_data[sock];

    sleep(1);

  }

  return 0;

}

 

void main( void )

{

  unsigned char rc;

  socket sock;

  int count;

  int index=0;

  unsigned int next;

 

  rc=ssio_init(NULL,NULL,NULL,NULL,NULL);

           

  sock=ssio_socket(SSIO_TCP);

  if ( sock != 0xFF )

  {

    ssio_listen(sock,23,0,0);

  }

 

  ssio_sockmode(sock,TCP_MODE_NONAGLE);

  ssio_sockmode(sock,TCP_MODE_ASCII);

 

  while(1)

  {

    sleep(1);

    ssio_poll();

    if ( sock_status[sock]==3 )

    {

      sprintf(msg,"Hi there. Welcome to AEtherboard Chat!");

      ssio_writeline(sock,msg);

      break;

    } 

  }

 

  while(1)

  {

    if ( sock_status[sock]!=3 )

      break;

    if ( sock_data[sock] > 0 ) 

    {

      ssio_readline(sock, msg, 255, &count);

      msg[count]=0x0;

      printf("%s\n",msg);

      fflush(stdout);

    } 

    if ( kbhit() )

    {

      data[index]=cgetc();

      cputc(data[index]);

//printf("%x %c\n",data[index],data[index]);     

      if ( data[index]==0x9B )

      {

        data[index]=0x0;

        ssio_writeline(sock,data);

        index=0;

      }

      index++;

    }else{

      if ( next < clock() )

      {

        ssio_poll();

        next=clock()+60;

      } 

    } 

  }

 

}

Edited by danwinslow
Link to comment
Share on other sites

 

Ah, jkmicro. I did a project with their $70 PC. Included an interface for a 320x200x4gray LCD implemented with a Cypress PSOC micro and a Xilinx 9536XL. The PSOC does nothing except generate some periodic timing signals; if I were doing the project again I'd use a PIC 12C508. Unlike many such projects which use a controller like the Epson 1330 series, this one uses DMA to read the display data direct from memory at 100 frames/second. Although this imposes about a 10% CPU overhead, it means that display updates are lightning-fast.

Link to comment
Share on other sites

If someone is interested in testing this afternoon ( 1pm-5pm CST ) please email me at danwinslow@cox.net or PM me here. You will need either a telnet client or could also use APE internet modem with a 8bit.

1013181[/snapback]

 

I thinkn your project looks VERY interesting. I am not going to be available today to do anything but I am usually here at the keyboard most nights after 9p EST. I have an ATASCII telnet client I use or I can use the ASCII one built into windows.

:P

Link to comment
Share on other sites

Well, I don't think anyone is exactly chomping at the bit to test this, but it's stable enough now that I can leave it up with some assurance of success. If you want to try it, telnet or internet modem to

IP 68.13.120.27, port 2300 through 2303

So for telnet you would type

telnet 68.13.120.27 230x

replacing x with either 0,1,2 or 3. The most likely thing will be that you will not get anything back. This would be because of any one or all of the following :

1. I didn't forward stuff right through the firewall

2. The atari locked up

3. The port you chose is already in use ( unlikely ). Try them all just to make sure.

 

If you see this :

**************************************************

* Welcome to the Aetherboard chat demonstration. *

* This simple chat facility is a test bed for the*

* Ethernet functionality of the Aetherboard on an*

* Atari 130XE. All application protocol is being *

* run directly on the 130XE. *

* You may have to adjust your CR/LF settings to *

* display correctly. This is only a first test, *

* you can expect problems. *

* This version can theoretically handle up to 5 *

* simultaneous connections ( 4 + Console ) *

**************************************************

 

Then you know it worked, and I will be very surprised. If you get on, yuo can type stuff in and press return, and everyone who is connected, including the console, will see it. Most likely no one else will be on though, or, even more likely, it will have locked up.

 

*edit*

If you do get on, please let me know here. I have logging coming out but expect the atari to crash at some point.

Edited by danwinslow
Link to comment
Share on other sites

Supercat, you probably needed local echo on.

 

Well someone was on (gcude) using the wintel telnet, and it worked pretty well. This 'telnet' is incredibly primitive, but is just a proof of concept. Seems to work basically ok, we had 3 connections going.

 

The lockups are pretty bad, though, and while I will leave it up I don't expect it to live too long.

Link to comment
Share on other sites

If you do get on, please let me know here. I have logging coming out but expect the atari to crash at some point.

1014190[/snapback]

 

I got on, but nothing I typed showed up.

 

It would be nice if you could send carriage returns with newlines.

1014195[/snapback]

 

 

I saw the same with two of the ports I tried, but was able to get on with two other port numbers. You might just be hitting the same port someone else has already grabbed.

 

Keep trying, the siteadmin is in and will chat with you when you connect.

Link to comment
Share on other sites

If you do get on, please let me know here. I have logging coming out but expect the atari to crash at some point.

1014190[/snapback]

 

I tried two different clients: #1-AT_Telnet which is an ATASCII telnet client; #2-Hyperterm in WinXP.

 

Neither one could connect on 2300.

 

#1 connected to ports 2301,2302,2303 but I saw nothing.

 

Tried #2 immediately after #1. With #2 I connected to none of the ports.

Link to comment
Share on other sites

If you do get on, please let me know here.

 

this is a nice project. Do you think it's is possible, once the network adapter is installed, to telnet or even ftp to any server just by connecting the 8bit with a network? How would you configure the network settings (IP, DNS, Gateway, etc.) , could this be done by the XE also?

 

I like this project. I prefer to have a real network adapter then 'just' bypassing the actual data using APE. At the end you could internet enable every Atari without the need of additional hardware than just a single floppy drive or cart. sounds cool to me :-)

 

\thomas

Link to comment
Share on other sites

Thanks for the info guys. Thomas, this is not really a network adapter as you may be thinking. It is actually a very small intel 386 computer, fitted into the case of my 130xe, with a network adapter built into it. I have software running on it that handles moving the traffic back and forth. The actual TCP stack is running on the board, while everything from layer 4 up is on the Atari. So, technically, it really is about the same as using internet modem from APE, but with having to mess around trying to fool the Atari into thinking its a serial connection. Its a way we can write TCP applications like chat, telnet, ping, ftp, etc for the Atari in standard socket calls without having to host the overhead from a complete TCP stack on the Atari side. The current library is a simplified one for CC65, but I plan on an Action and a Basic one.

 

For controlling the IP, DNS, etc., the current C library call looks like this :

 

unsigned char ssio_init(char *ip, char *gateway, char *netmask, char *nameserver );

 

so a call like

 

ssio_init("192.168.1.120","192.168.1.1","255.255.255.0","68.15.16.25");

 

would set it up.

 

Supercat, me calling it a 'telnet' program is a bit of a stretch...it really was just a test harness designed for use by a telnet client. I just wanted to see if the general ideas I was having would work out. Things like echo and other niceties I hadn't even worried about yet.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...