Index: firmware/Makefile
===================================================================
--- firmware/Makefile	(revision 308)
+++ firmware/Makefile	(revision 309)
@@ -5,6 +5,13 @@
 CP      = $(BASE)-objcopy
 DUMP    = $(BASE)-objdump
 
+SOCKIT_CC = arm-linux-gnueabihf-gcc
+SOCKIT_LD = arm-linux-gnueabihf-gcc
+
+SOCKIT_CFLAGS = -g -DLITTLE_ENDIAN -O2
+SOCKIT_CFLAGS+= -W -Wall
+SOCKIT_LDFLAGS = -g
+
 HOST_CC	= gcc
 HOST_LD	= gcc
 
@@ -39,9 +46,11 @@
 MIST_5200_DIR = mist_5200
 LINUXSIM_DIR = linux
 LINUXSIM_5200_DIR = linux_5200
+SOCKIT_DIR = sockit
 
 AEON_LITE_BUILD_DIR = $(BUILD_DIR)/$(AEON_LITE_DIR)
 DE1_BUILD_DIR = $(BUILD_DIR)/$(DE1_DIR)
+SOCKIT_BUILD_DIR = $(BUILD_DIR)/$(SOCKIT_DIR)
 DE1_5200_BUILD_DIR = $(BUILD_DIR)/$(DE1_5200_DIR)
 CHAMELEON_BUILD_DIR = $(BUILD_DIR)/$(CHAMELEON_DIR)
 MCC_BUILD_DIR = $(BUILD_DIR)/$(MCC_DIR)
@@ -57,10 +66,12 @@
 MINSTARTUP_SRC = mycrt0.s
 MINSTARTUP_OBJ = $(patsubst $(STARTUP_DIR)/%.s,$(BUILD_DIR)/%.o,$(MINSTARTUP_SRC))
 
-COMMON_SRC = cartridge.c fileutils.c fileselector.c pokey/uart.c hexdump.c printf/printf.c fat/pff_file.c fat/pff.c common/utils.c
+CORE_SRC = cartridge.c fileutils.c fileselector.c pokey/uart.c hexdump.c common/utils.c printf/printf.c 
+FAT_SRC = fat/pff_file.c fat/pff.c 
+COMMON_SRC = ${FAT_SRC} ${CORE_SRC}
 SDCARD_SRC = sd_direct/diskio_mmc.c sd_direct/spi.c sd_direct/mmc2.c
-A800_SRC_LIGHT = a800/freeze.c  a800/mainmenu.c atari_drive_emulator.c
-A800_SRC = ${A800_SRC_LIGHT} a800/joystick.c libgcc_divmod.c
+A800_SRC_LIGHT = a800/freeze.c  a800/mainmenu.c atari_drive_emulator.c libgcc_divmod.c
+A800_SRC = ${A800_SRC_LIGHT} a800/joystick.c 
 5200_SRC_LIGHT = 5200/freeze.c  5200/mainmenu.c
 5200_SRC = ${5200_SRC_LIGHT} 5200/joystick.c
 USB_SRC = usb/hid.c  usb/hidparser.c  usb/hub.c usb/timer.c  usb/usb.c
@@ -107,6 +118,10 @@
 MIST_5200_SRC = $(COMMON_SRC) $(SDCARD_SRC) $(5200_SRC) mist_5200/dirs.c
 MIST_5200_OBJ = $(patsubst %.c,$(MIST_5200_BUILD_DIR)/%.o,$(MIST_5200_SRC))
 
+SOCKIT_PRJ = SOCKIT
+SOCKIT_SRC = $(CORE_SRC) a800/freeze.c  a800/mainmenu.c atari_drive_emulator.c a800/joystick.c sockit/dirs.c sockit/linuxfile.c sockit/linuxdir.c sockit/memory.c
+SOCKIT_OBJ = $(patsubst %.c,$(SOCKIT_BUILD_DIR)/%.o,$(SOCKIT_SRC))
+
 LINKMAP  = ./standalone_simple.ld
 LINKMAP_LARGE  = ./standalone_simple_large.ld
 
@@ -130,6 +145,8 @@
 ZPUOPTS =
 CFLAGS  = -I. -Isd_direct -Iprintf -Ifat -Icommon -Isdram_common -c -g -Os $(ZPUOPTS) -DDISABLE_UART_RX
 
+SOCKIT_CFLAGS += -I. -Icommon -Isockit -Iprintf 
+
 HOST_CFLAGS += -I. -Isd_direct -Iprintf -Ifat -Icommon -Isdram_common -DDISABLE_UART_RX -DUSB -Iusb
 
 LFLAGS  = -nostartfiles -nostdlib -Wl,--relax -g -Os -Wl,-Map=out.map
@@ -144,7 +161,7 @@
 HOST_CFLAGS_5200 = $(HOST_CFLAGS) -DFIRMWARE_5200
 
 # Our target.
-all: mcc mcctv mist de1 aeon_lite chameleon  de1_5200 mist_5200 mcc_5200 mcctv_5200
+all: mcc mcctv mist de1 aeon_lite chameleon  de1_5200 mist_5200 mcc_5200 mcctv_5200 sockit
 
 install:
 	cd ../common/romgen && ./createall && cd ../../firmware
@@ -169,6 +186,8 @@
 
 mist_5200: $(BUILD_DIR) $(MIST_5200_PRJ).bin $(MIST_5200_PRJ).rpt
 
+sockit: $(BUILD_DIR) $(SOCKIT_PRJ).elf
+
 .PHONY: linux
 linux: $(BUILD_DIR) $(LINUXSIM_EXE)
 
@@ -225,6 +244,9 @@
 $(MIST_5200_PRJ).elf: $(MINSTARTUP_OBJ) $(MIST_5200_OBJ)
 	$(LD) $(LFLAGS_5200) -T $(LINKMAP) -o $@ $+ $(LIBS)
 
+$(SOCKIT_PRJ).elf: $(SOCKIT_OBJ)
+	$(SOCKIT_LD) $(SOCKIT_LDFLAGS) -o $@ $+
+
 $(LINUXSIM_EXE): $(LINUXSIM_OBJ)
 	$(HOST_LD) $(HOST_LDFLAGS) -o $@ $+
 
@@ -271,6 +293,10 @@
 	mkdir -p `dirname $@`
 	$(CC) -I$(MIST_5200_DIR) $(CFLAGS_5200)  -o $@ -c $<
 
+$(SOCKIT_BUILD_DIR)/%.o: %.c Makefile
+	mkdir -p `dirname $@`
+	$(SOCKIT_CC) -I$(SOCKIT_DIR) $(SOCKIT_CFLAGS)  -o $@ -c $<
+
 $(LINUXSIM_BUILD_DIR)/%.o: %.c Makefile
 	@mkdir -p `dirname $@`
 	$(HOST_CC) -I$(LINUXSIM_DIR) $(HOST_CFLAGS)  -o $@ -c $<
Index: firmware/sockit/dirs.c
===================================================================
--- firmware/sockit/dirs.c	(nonexistent)
+++ firmware/sockit/dirs.c	(revision 309)
@@ -0,0 +1,2 @@
+char USER_DIR[]="/home/root/atari800/user";
+char ROM_DIR[]="/home/root/atari800/rom";
Index: firmware/sockit/linuxdir.c
===================================================================
--- firmware/sockit/linuxdir.c	(nonexistent)
+++ firmware/sockit/linuxdir.c	(revision 309)
@@ -0,0 +1,286 @@
+#include "linuxdir.h"
+
+#include "linuxfile.h"
+
+#include <sys/types.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+enum SimpleFileStatus openfile(struct SimpleFile * file)
+{
+	char buffer[256];
+	strncpy(&buffer[0],file->path,sizeof(buffer));
+	strncat(&buffer[0],"/",sizeof(buffer));
+	strncat(&buffer[0],file->name,sizeof(buffer));
+
+	if (0==access(buffer,R_OK|W_OK))
+	{
+		file->file = fopen(buffer,"r+");
+	}
+	else if (0==access(buffer,R_OK))
+	{
+		file->file = fopen(buffer,"r");
+	}
+
+	if (file->file)
+	{
+		return SimpleFile_OK;
+	}
+	else
+	{
+		return SimpleFile_FAIL;
+	}
+}
+
+enum SimpleFileStatus file_open_name(char const * path, struct SimpleFile * file)
+{
+	strncpy(file->name,path,sizeof(file->name));
+	strncpy(file->path,path,sizeof(file->path));
+
+	return openfile(file);
+}
+
+enum SimpleFileStatus file_open_name_in_dir(struct SimpleDirEntry * entries, char const * filename, struct SimpleFile * file)
+{
+	//entries->filename + "/" + filename;
+	strncpy(&file->name[0],filename,sizeof(file->name));
+	strncpy(&file->path[0],entries->path,sizeof(file->name));
+
+	return openfile(file);
+}
+
+enum SimpleFileStatus file_open_dir(struct SimpleDirEntry * entry, struct SimpleFile * file)
+{
+	strncpy(&file->path[0],entry->path,sizeof(file->path));
+	strncpy(&file->name[0],entry->entry.d_name,sizeof(file->path));
+
+	return openfile(file);
+}
+
+// Reads entire dir into memory (i.e. give it a decent chunk of sdram)
+char * dir_mem;
+int dir_space;
+enum SimpleFileStatus dir_init(void * mem, int space)
+{
+	// Does own memory allow...
+	dir_mem = mem;
+	dir_space = space;
+	return SimpleFile_OK;
+}
+
+int dircmp(struct SimpleDirEntry * a, struct SimpleDirEntry * b)
+{
+	if (dir_is_subdir(a)==dir_is_subdir(b))
+		return strcmp(a->entry.d_name,b->entry.d_name);
+	else
+		return (dir_is_subdir(a)<dir_is_subdir(b));
+}
+
+void sort_ll(struct SimpleDirEntry * h)
+{
+//struct SimpleDirEntry
+//{
+//	char path[MAX_PATH_LENGTH];
+//	char * filename_ptr;
+//	int size;
+//	int is_subdir;
+//	struct SimpleDirEntry * next; // as linked list - want to allow sorting...
+//};
+
+	struct SimpleDirEntry * p,*temp,*prev;
+	int i,j,n,sorted=0;
+	temp=h;
+	prev=0;
+	for(n=0;temp!=0;temp=temp->next) n++;
+
+	for(i=0;i<n-1 && !sorted;i++){
+		p=h;sorted=1;
+		prev=0;
+		for(j=0;j<n-(i+1);j++){
+	//		printf("p->issubdir:%d(%s) p->next->issubdir:%d(%s)",p->is_subdir,p->path,p->next->is_subdir,p->next->path);
+
+			if(dircmp(p,p->next)>0) {
+	//			printf("SWITCH!\n");
+				struct SimpleDirEntry * a = p;
+				struct SimpleDirEntry * b = p->next;
+				a->next=b->next;
+				b->next=a;
+				if (prev)
+					prev->next=b;
+				p=b;
+
+				sorted=0;
+			}
+			prev=p;
+			p=p->next;
+		}
+	}
+
+	//temp=h;
+	//for(n=0;temp!=0;temp=temp->next) printf("POST:%s\n",temp->path);
+}
+
+struct SimpleDirEntry * dir_entries_filtered(char const * dirPath, int (*filter)(struct SimpleDirEntry *))
+{
+	struct SimpleDirEntry * entry = dir_entries(dirPath);
+	if (!entry) return 0;
+
+	struct SimpleDirEntry * temp1 = entry;
+	while (temp1)
+	{
+		printf("Entry_PRE filtered:%s\n",temp1->entry.d_name);
+		temp1 = temp1->next;
+	}
+
+	struct SimpleDirEntry * head = entry;
+	struct SimpleDirEntry * prev = 0;
+	while (entry)
+	{
+		if (!(*filter)(entry))
+		{
+			if (entry == head)
+				head = head->next;
+			else if (prev)
+				prev->next = entry->next;
+		}
+		else
+		{
+			prev = entry;
+		}
+
+		entry = entry->next;
+	}
+
+	struct SimpleDirEntry * temp = head;
+	while (temp)
+	{
+		printf("Entry_filtered:%s\n",temp->entry.d_name);
+		temp = temp->next;
+	}
+
+	printf("Sorting\n\n");
+
+	if (filter)
+	{
+		sort_ll((struct SimpleDirEntry *) head);
+	}
+
+	printf("sorted\n\n");
+	temp = head;
+	while (temp)
+	{
+		printf("Entry_sorted:%s\n",temp->entry.d_name);
+		temp = temp->next;
+	}
+
+	return head;
+}
+
+struct SimpleDirEntry * dir_entries(char const * dirPath)
+{
+	DIR * dir = opendir(dirPath);
+	if (!dir) return 0;
+
+	char * mem = dir_mem;
+	int remaining_space = dir_space;
+
+	struct SimpleDirEntry * head = (struct SimpleDirEntry *)(mem);
+	mem += sizeof(struct SimpleDirEntry);
+        remaining_space -= sizeof(struct SimpleDirEntry);
+
+	struct SimpleDirEntry * prev = head;
+        while (1)
+        {
+		if (remaining_space < (int)sizeof(struct SimpleDirEntry))
+		{
+			prev->next = 0;
+			return head;
+		}
+
+		struct SimpleDirEntry * myentry = (struct SimpleDirEntry *)(mem);
+		myentry->next = 0;
+
+		struct dirent * result;
+		readdir_r(dir,&myentry->entry,&result);
+
+		if (!result)
+		{
+			break;
+		}
+
+		if (strcmp(".",myentry->entry.d_name) == 0) continue;
+		if (strcmp("..",myentry->entry.d_name) == 0) 
+		{
+			strcpy(head->path,myentry->path);
+			head->entry = myentry->entry;
+			continue;
+		}
+
+		mem += sizeof(struct SimpleDirEntry);
+		remaining_space -= sizeof(struct SimpleDirEntry);
+
+		strncpy(myentry->path,dirPath,sizeof(myentry->path));
+
+		if (!head) head = myentry;
+		if (prev) prev->next = myentry;
+		prev = myentry;
+
+		printf("Entry:%s :%d\n",myentry->entry.d_name,dir_is_subdir(myentry));
+	}
+
+	closedir(dir);
+
+	printf("All done\n\n");
+
+	return head;
+}
+
+char const * dir_filename(struct SimpleDirEntry * entry)
+{
+	return &entry->entry.d_name[0];
+}
+
+char dir_buffer[256];
+char const * dir_path(struct SimpleDirEntry * entry)
+{
+	strncpy(&dir_buffer[0],entry->path,sizeof(dir_buffer));
+	strncat(&dir_buffer[0],"/",sizeof(dir_buffer));
+	strncat(&dir_buffer[0],entry->entry.d_name,sizeof(dir_buffer));
+	
+	return &dir_buffer[0];
+}
+
+int dir_filesize(struct SimpleDirEntry * entry)
+{
+	char buffer[256];
+	strncpy(&buffer[0],entry->path,sizeof(buffer));
+	strncat(&buffer[0],"/",sizeof(buffer));
+	strncat(&buffer[0],entry->entry.d_name,sizeof(buffer));
+
+	struct stat buf;
+	stat(buffer, &buf);
+	return buf.st_size;
+}
+
+struct SimpleDirEntry * dir_next(struct SimpleDirEntry * entry)
+{
+	return entry->next;
+}
+
+int dir_is_subdir(struct SimpleDirEntry * entry)
+{
+	char buffer[256];
+	strncpy(&buffer[0],entry->path,sizeof(buffer));
+	strncat(&buffer[0],"/",sizeof(buffer));
+	strncat(&buffer[0],entry->entry.d_name,sizeof(buffer));
+
+	struct stat buf;
+	stat(buffer, &buf);
+	return S_ISDIR(buf.st_mode);
+}
+
Index: firmware/sockit/linuxdir.h
===================================================================
--- firmware/sockit/linuxdir.h	(nonexistent)
+++ firmware/sockit/linuxdir.h	(revision 309)
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "simpledir.h"
+
+// Extends simple dir with way of opening files and looking at dirs!
+// Not all systems provide this...
+
+#include <dirent.h>
+
+struct SimpleDirEntry
+{
+        struct dirent entry;
+	char path[256];
+	struct SimpleDirEntry * next;
+};
+
+
Index: firmware/sockit/linuxfile.c
===================================================================
--- firmware/sockit/linuxfile.c	(nonexistent)
+++ firmware/sockit/linuxfile.c	(revision 309)
@@ -0,0 +1,105 @@
+#include <stdio.h>
+#include "linuxfile.h"
+#include "simplefile.h"
+#include <sys/stat.h>
+#include <unistd.h>
+
+char const * file_of(char const * path)
+{
+        char const * start = path + strlen(path);
+        while (start!=path)
+        {
+                --start;
+                if (*start == '/')
+                {
+                        ++start;
+                        break;
+                }
+        }
+        return start;
+}
+
+void dir_of(char * dir, char const * path)
+{
+        char const * end = file_of(path);
+        if (end != path)
+        {
+                int len = end-path;
+                while (len--)
+                {
+                        *dir++ = *path++;
+                }
+                --dir;
+        }
+
+        *dir = '\0';
+        return;
+}
+
+
+int file_struct_size()
+{
+	return sizeof(struct SimpleFile);
+}
+
+void file_init(struct SimpleFile * file)
+{
+	file->file = 0;
+	file->name[0] = '\0';
+	file->path[0] = '\0';
+}
+
+char const * file_path(struct SimpleFile * file)
+{
+	return &file->path[0];
+}
+
+char const * file_name(struct SimpleFile * file)
+{
+	return &file->name[0];
+}
+
+enum SimpleFileStatus file_read(struct SimpleFile * file, void * buffer, int bytes, int * bytesread)
+{
+	*bytesread = fread(buffer,1,bytes,file->file);
+	return SimpleFile_OK;
+}
+
+enum SimpleFileStatus file_seek(struct SimpleFile * file, int offsetFromStart)
+{
+	//printf("file_seek:%d\n",offsetFromStart);
+	fseek(file->file,offsetFromStart,SEEK_SET);
+	return SimpleFile_OK;
+}
+
+int file_size(struct SimpleFile * file)
+{
+/*	int pos = ftell(file->file);
+	fseek(file->file,0L,SEEK_SEND);
+	int size = ftell(file->file);
+	fseek(file->file,pos,SEEK_SET);*/
+
+	struct stat buf;
+	fstat(fileno(file->file),&buf);
+	return buf.st_size;
+}
+
+int file_readonly(struct SimpleFile * file)
+{
+	return (0==access(file->path,W_OK)) ? 0 : 1;
+}
+
+
+enum SimpleFileStatus file_write(struct SimpleFile * file, void * buffer, int bytes, int * byteswritten)
+{
+	//printf("file_write:%d\n",bytes);
+	*byteswritten = fwrite(buffer,1,bytes,file->file);
+	//printf("written:%d\n",*byteswritten);
+	return SimpleFile_OK;
+}
+
+enum SimpleFileStatus file_write_flush()
+{
+	return SimpleFile_OK;
+}
+
Index: firmware/sockit/linuxfile.h
===================================================================
--- firmware/sockit/linuxfile.h	(nonexistent)
+++ firmware/sockit/linuxfile.h	(revision 309)
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "simplefile.h"
+
+#include <stdio.h>
+
+struct SimpleFile
+{
+	FILE * file;
+	char path[256];
+	char name[256];
+};
+
Index: firmware/sockit/memory.c
===================================================================
--- firmware/sockit/memory.c	(nonexistent)
+++ firmware/sockit/memory.c	(revision 309)
@@ -0,0 +1,32 @@
+#include "sockit/memory.h"
+
+#include <stdio.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/select.h>
+#include <sched.h>
+
+unsigned char volatile * virtual_base;
+unsigned char volatile * zpu_base;
+
+unsigned int addr = 0xc0000000;
+unsigned int span = 0x1002000;
+
+void init_bridge()
+{
+	int fd = open("/dev/mem",(O_RDWR|O_SYNC));
+	virtual_base = (unsigned char volatile *)mmap(NULL,span,(PROT_READ|PROT_WRITE),MAP_SHARED,fd,addr);
+	printf("ADDR:%x %x\n",(int)virtual_base, (int)addr);
+
+	zpu_base = (unsigned char *)virtual_base + 0x1000000; 
+	//pokey_regbase = (unsigned char *)virtual_base + 0x1000400;
+
+	//struct sched_param param;
+	//param.sched_priority = 50;
+	//sched_setscheduler(0,SCHED_RR,&param);
+}
+
Index: firmware/sockit/memory.h
===================================================================
--- firmware/sockit/memory.h	(nonexistent)
+++ firmware/sockit/memory.h	(revision 309)
@@ -0,0 +1,34 @@
+#ifndef MEMORY_H
+#define MEMORY_H
+
+#include "stdlib.h"
+
+extern unsigned char volatile * virtual_base;
+extern unsigned char volatile * zpu_base;
+
+#define SRAM_BASE ((void*) virtual_base+0x200000)
+#define SDRAM_BASE ((void*) virtual_base+0x800000)
+
+// Memory usage...
+// 0x410000-0x44FFFF (0xc10000 in zpu space) = directory cache - 256k
+// 0x450000-0x46FFFF (0xc50000 in zpu space) = freeze backup
+// 0x700000-0x77FFFF (0xf00000 in zpu space) = os rom/basic rom
+
+#define INIT_MEM init_bridge();
+void init_bridge();
+
+#define DIR_INIT_MEMSIZE 262144
+#define DIR_INIT_MEM (char *)malloc(DIR_INIT_MEMSIZE)
+#define FREEZE_MEM (char unsigned *)malloc(128*1024)
+
+#define CARTRIDGE_MEM (SDRAM_BASE + 0x500000)
+
+// offset into SDRAM
+#define ROM_OFS 0x700000
+
+#define atari_regbase  ((void*) virtual_base + 0x10000)
+#define atari_regmirror  ((void*) virtual_base + 0x20000)
+#define zpu_regbase ((void*) zpu_base)
+#define pokey_regbase ((void*) zpu_base + 0x400)
+
+#endif
