Jump to content
tschak909

#AtariWiFi - an Atari Network Adapter

Recommended Posts

Here is the WIFISCAN.BAS source:

100 REM WIFI SCAN TEST PROGRAM #11
101 DIM SCAN$(360)
110 GOSUB 1000:REM COPY CHARSET
120 ? CHR$(125)
130 ? "Scanning Network..."
140 DCB=768
150 POKE DCB,112:REM DEVICE $70
160 POKE DCB+1,1:REM DUNIT 1
170 POKE DCB+2,35:REM DCOMND = SCAN
180 POKE DCB+3,64:REM READ
190 ADDR=24576
200 ADDRH=INT(ADDR/256)
210 ADDRL=ADDR-(ADDRH*256)
220 POKE DCB+4,ADDRL:REM BUFFER LO
230 POKE DCB+5,ADDRH:REM BUFFER HI
240 POKE DCB+6,31:REM TIMEOUT
250 POKE DCB+8,74:REM 330 BYTES
260 POKE DCB+9,1
270 POKE DCB+10,0:REM AUX1=0
280 POKE DCB+11,0:REM AUX2=0
290 X=USR(ADR("h Yd`"))
300 FOR X=0 TO 9
310 IF PEEK((X*32)+ADDR)=0 THEN GOTO 400

320 ? X;": ";
330 FOR Y=0 TO 31
331 IF PEEK(X*32+Y+ADDR)=0 THEN GOTO 350

340 PRINT CHR$(PEEK(X*32+Y+ADDR));
350 NEXT Y
360 RSSI=PEEK(ADDR+320+X):POSITION 32,X+
2
370 IF RSSI>200 THEN ? "???":GOTO 400
380 IF RSSI>180 THEN ? "?? ":GOTO 400
390 ? "?  "
400 NEXT X
410 END
1000 MEMTOP=PEEK(106)
1010 GRTOP=MEMTOP-4
1020 POKE 106,GRTOP
1030 GRAPHICS 0:REM RESET
1040 CHROM=PEEK(756)*256
1050 POKE 756,GRTOP
1060 CHRAM=GRTOP*256
1070 PRINT "PLEASE WAIT..."
1080 FOR N=0 TO 1023
1090 POKE CHRAM+N,PEEK(CHROM+N)
1100 NEXT N
1110 REM ADD BARS TO CHARSET.
1111 RESTORE 1200
1120 FOR N=0 TO 23
1130 READ B
1140 POKE CHRAM+520+N,B
1150 NEXT N
1160 RETURN
1200 DATA 0,0,0,0,0,0,3,51
1210 DATA 0,0,3,3,51,51,51,51
1220 DATA 48,48,48,48,48,48,48,48

C version coming shortly.

-Thom

Share this post


Link to post
Share on other sites

To any Atari programming gods: One aspect of #FujiNet that needs to be dealt with, any DLI timing will go askew when SIO is being used. How can we best deal with that?

Share this post


Link to post
Share on other sites

Can anyone see something odd happening here? this is only happening with the C programs that I am writing, it seems that when calling SIOV after a certain point, the SIO output routine gets stuck waiting for something which never happens:

 

/**
 * WIFISCAN - show WiFi networks returned
 * from a SIO WIFI SCAN call
 */

#include <atari.h>
#include <6502.h>
#include <string.h>
#include <peekpoke.h>

#define SetChar(x,y,a) video_ptr[(x)+(y)*40]=(a);
#define GetChar(x,y) video_ptr[(x)+(y)*40]
#define GRAPHICS_0_SCREEN_SIZE (40*25)
#define DISPLAY_LIST 0x0600
#define DISPLAY_MEMORY 0x3C00

union 
{
  struct
  {
    char ssid[10][32];
    char rssi[10];
  };
  unsigned char rawData[330];
} ssidInfo;

void dlist=
  {
   DL_BLK8,
   DL_BLK8,
   DL_BLK8,
   DL_LMS(DL_CHR20x8x2),
   DISPLAY_MEMORY,

   DL_CHR20x8x2,
   DL_CHR40x8x1,
   DL_CHR40x8x1,
   DL_CHR40x8x1,
   DL_CHR40x8x1,
   DL_CHR40x8x1,
   DL_CHR40x8x1,
   DL_CHR40x8x1,
   DL_CHR40x8x1,
   DL_CHR40x8x1,
   DL_CHR40x8x1,
   DL_CHR40x8x1,
   DL_CHR40x8x1,
   DL_CHR40x8x1,
   DL_CHR40x8x1,
   DL_CHR40x8x1,
   DL_CHR40x8x1,
   DL_CHR40x8x1,
   DL_CHR40x8x1,
   DL_CHR40x8x1,
   DL_CHR40x8x1,
   DL_CHR20x8x2,
   DL_CHR20x8x2,
   
   DL_JVB,
   0x600
  };

static unsigned char* video_ptr;
static unsigned char* dlist_ptr;
static unsigned short screen_memory;

const char* title="   WIFI NETWORKS:   ";
const char* scan="SCANNING NETWORKS...";

void clear_screen()
{
  memset(video_ptr,0,GRAPHICS_0_SCREEN_SIZE);
}

/**
 * Print ATASCII string to display memory
 */
void print_string(unsigned char x,unsigned char y,char *s)
{
  unsigned char inverse;
  char offset;
  
  do
    {
      inverse=*s&0x80;
      *s-=inverse;
      
      if (*s < 32)
	{
	  offset=64;
	}
      else if (*s<96)
	{
	  offset=-32;
	}
      else
	{
	  offset=0;
	}
      
      *s+=inverse;
      SetChar(x++,y,*s+offset);

      ++s;
      
    } while(*s!=0);
}

/**
 * Setup screen
 */
void setup()
{
  OS.coldst=1;    // Reset coldstart flag to force coldstart on RESET.
  OS.sdmctl=0x00; // Turn off DMA
  memcpy((void *)DISPLAY_LIST,&dlist,sizeof(dlist)); // copy display list to $0600
  OS.sdlst=(void *)DISPLAY_LIST;                     // and use it.
  
  dlist_ptr=(unsigned char *)OS.sdlst;               // Set up the vars for the screen output macros
  screen_memory=PEEKW(560)+4;
  video_ptr=(unsigned char*)(PEEKW(screen_memory));
  
  // TODO: come back here and set some colors
  // OS.color0=0x12;
  // OS.color1=0x34;
  // OS.color2=0x56;
  // OS.color3=0x78;

  OS.sdmctl=0x22; // Turn on DMA, normal playfield, no P/M.

  clear_screen();
  print_string(0,0,(char *)title);
  print_string(0,21,(char *)scan);
}

/**
 * Do the WiFi Scan
 */
unsigned char sio_wifi_scan(void)
{
  struct regs r;
  OS.dcb.ddevic=0x70;             // Network Device
  OS.dcb.dunit=1;                 //
  OS.dcb.dcomnd='#';              // Network Scan
  OS.dcb.dstats=0x40;             // Read from peripheral
  OS.dcb.dbuf=&ssidInfo.rawData;  // The scan results buffer.
  OS.dcb.dtimlo=0x20;             // Timeout
  OS.dcb.dbyt=330;                // 330 byte payload
  OS.dcb.daux=0;                  // aux1/aux2 = 0

  // Call SIOV
  r.pc=0xE459;
  _sys(&r);
  
  return OS.dcb.dstats;  // Return command status
}

/**
 * Print the ssid at index i
 */
void print_ssid(unsigned char i)
{
  char out[3]="0:";
  out[0]=i+0x30; // Turn number into printable number.
  print_string(1,i+3,out);
  print_string(4,i+3,(char *)ssidInfo.ssid);
}


/**
 * Print the RSSI at index i
 */
void print_rssi(unsigned char i)
{
  char out[4]={0x20,0x20,0x20};

  if (ssidInfo.rssi[i]>200)
    {
      out[0]='*';
    }
  else if (ssidInfo.rssi[i]>160)
    {
      out[0]='*';
      out[1]='*';
    }
  else if (ssidInfo.rssi[i]>140)
    {
      out[0]='*';
      out[1]='*';
      out[2]='*';
    }

  print_string(35,i+3,out);
}

/**
 * Print the available networks
 */
void print_networks(void)
{
  unsigned char i;
  for (i=0;i<10;i++)
    {
      if (ssidInfo.ssid[i][0]!=0x00) // Only print if not empty.
	{
	  print_ssid(i);
	  print_rssi(i);
	}
    }
}

/**
 * Print error
 */
void print_error(unsigned char s)
{
  if (s==138)
    {
      print_string(0,21,"  NO FUJINET FOUND  ");
    }
  else if (s==139)
    {
      print_string(0,21,"    FUJINET NAK!    ");
    }
}

/**
 * Sit and wait
 */
void sit_and_spin(void)
{
  for (;;) { }
}

/**
 * main program
 */
void main(void)
{
  unsigned char s; // status
  setup();

  s=sio_wifi_scan();

  if (s==1)
    {
      print_networks();
    }
  else
    {
      print_error(s);
    }

  sit_and_spin();
}

Binary is also attached, am I doing something unbelievably stupid to cause this?

@sanny @phaeron

 

-Thom

wifiscan.com

Edited by tschak909
whoops :)

Share this post


Link to post
Share on other sites
9 minutes ago, tschak909 said:

I've attached it to the post

OK: I just ran it in Altirra and the interrupt disable flag is set by a PLP at $23D3. This causes the VBI to get stuck in a loop waiting for XMTDON ($3A) to be non-zero.

 

Note sure what the code is doing but here it is:

 

Capture.thumb.PNG.9b932098c0e2d2bc74a0d79fc96a86f3.PNG

 

Just setting a breakpoint and forcibly clearing the I flag in the debugger allowed the program to execute correctly.

 

Edited by flashjazzcat
typo
  • Like 1

Share this post


Link to post
Share on other sites

ok, so changing the _sys() call to just be:

 

asm("CLI; JSR $E459"); 


was sufficient, to work through this now.. I will file a ticket with the CC65 ppls :) Thanks Jon!

 

  • Like 1

Share this post


Link to post
Share on other sites

I'm not sure if I'm reading the CC65 _sys.s source right, but it seems to imply that it expects the user to set regs.flags. Since your struct is allocated off the stack, I assume the contents of the other struct fields are uninitialised.

Edited by flashjazzcat

Share this post


Link to post
Share on other sites

That would make sense.

 

For now, I will do the inline asm to do the JSR, going forward, espeically since adding _sys() is very generalized, and what I need can be done with fewer bytes. :)

 

Share this post


Link to post
Share on other sites

Another bug: in  setup()
  pinMode(PIN_INT, INPUT);
  pinMode(PIN_PROC, INPUT);

 

should be:

  pinMode(PIN_INT, OUTPUT);  // these are "inputs" on the Atari side...
  pinMode(PIN_PROC, OUTPUT);

Share this post


Link to post
Share on other sites
Just now, AtariGeezer said:

Another bug: in  setup()
  pinMode(PIN_INT, INPUT);
  pinMode(PIN_PROC, INPUT);

 

should be:

  pinMode(PIN_INT, OUTPUT);  // these are "inputs" on the Atari side...
  pinMode(PIN_PROC, OUTPUT);

Ah, good catch, thanks :)

-Thom

Share this post


Link to post
Share on other sites

As a contrast, here is the same program written in C, and spiced up slightly. You can see it is much faster. The protocol has also been amended so that it works better (sends one SSID at a time, with an indication if there is more). 

 

 

  • Like 5

Share this post


Link to post
Share on other sites

With the Name change, this thread has been moved to here:

I formally ask moderators to lock this thread. Thank you.

 

-Thom

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...