Index: firmware/debug.c
===================================================================
--- firmware/debug.c	(revision 194)
+++ firmware/debug.c	(nonexistent)
@@ -1,177 +0,0 @@
-#include "debug.h"
-#include "pause.h"
-
-int xpos;
-int ypos;
-int onoff; // perhaps we can plot to another address buffer, which we can scroll through in the monitor?
-
-int debugoffsetval;
-
-void topofscreen()
-{
-	xpos = 0;
-	ypos = 0;
-}
-
-void setxpos(int val)
-{
-	xpos = val;
-}
-
-void setypos(int val)
-{
-	ypos = val;
-}
-
-void initdebug(int onoff_in)
-{
-	xpos = 0;
-	ypos = 0;
-	onoff = onoff_in;
-}
-
-void nextline()
-{
-	int i;
-	xpos=0;
-	ypos+=1;
-	if (ypos==24)
-		ypos = 0;
-	for (i=0;i!=40;++i)
-		plot(0,i,ypos);
-
-	//Delay100usX(5000);
-}
-
-unsigned char toatarichar(int val)
-{
-	int inv = val>=128;
-	if (inv)
-	{
-		val-=128;
-	}
-	if (val>='A' && val<='Z')
-	{
-		val+=-'A'+33;
-	}
-	else if (val>='a' && val<='z')
-	{
-		val+=-'a'+33+64;
-	}
-	else if (val>='0' && val<='9')
-	{
-		val+=-'0'+16;	
-	}
-	else if (val>=32 && val<=47)
-	{
-		val+=-32;
-	}
-	else
-	{
-		val = 0;
-	}
-	if (inv)
-	{
-		val+=128;
-	}
-	return val;
-}
-unsigned char hextoatarichar(int val)
-{
-	if (val>=0 && val<=9)
-	{
-		val+=+16;	
-	}
-	else if (val>=10 && val<=15)
-	{
-		val+=-10+33;
-	}
-	return val;
-}
-void plot(unsigned char val, int x, int y)
-{
-	if (onoff == 0) return;
-
-	unsigned char volatile * baseaddr = (unsigned char volatile *)(screen_address + atari_regbase);
-	*(baseaddr + y*40+x) = val+debugoffsetval;
-}
-void debugoffset(int x)
-{
-	debugoffsetval = x;
-}
-void debug(char const * str)
-{
-	while (1)
-	{
-		int val = *str++;
-		if (val==0) break;
-		if (val=='\n') {nextline();continue;};
-
-		plot(toatarichar(val),xpos,ypos);
-		++xpos;
-		if (xpos==40)
-		{
-			nextline();
-		}
-	}
-	debugoffsetval = 0;
-}
-
-void plotnext(unsigned char val)
-{
-	plot(val,xpos,ypos);
-
-	++xpos;
-	if (xpos==40) nextline();
-}
-
-void plotnextnumber(unsigned short val)
-{
-	plotnext(hextoatarichar((val&0xf000)>>12));
-	plotnext(hextoatarichar((val&0x0f00)>>8));
-	plotnext(hextoatarichar((val&0x00f0)>>4));
-	plotnext(hextoatarichar((val&0x000f)>>0));
-	debugoffsetval = 0;
-}
-
-void hexdump(unsigned void const * str, int length)
-{
-	nextline();
-
-	for (;length>0;--length)
-	{
-		unsigned char val= *str++;
-		
-		// LH 10 cols = char
-		// RH 20 cols = hex
-
-		plot(toatarichar(val),xpos,ypos);
-		plot(hextoatarichar((val&0xf0) >> 4),xpos*2+20,ypos);
-		plot(hextoatarichar(val&0xf),xpos*2+21,ypos);
-
-		++xpos;
-		if (xpos==10)
-		{
-			nextline();
-		}
-	}
-	nextline();
-}
-
-void hexdump_pure(unsigned void const * str, int length)
-{
-	xpos = xpos&0xfffe;
-	for (;length>0;--length)
-	{
-		unsigned char val= *str++;
-		
-		plot(hextoatarichar((val&0xf0) >> 4),xpos++,ypos);
-		plot(hextoatarichar(val&0xf),xpos++,ypos);
-
-		if (xpos==40)
-		{
-			nextline();
-		}
-	}
-}
-
Index: firmware/debug.h
===================================================================
--- firmware/debug.h	(revision 194)
+++ firmware/debug.h	(nonexistent)
@@ -1,20 +0,0 @@
-#ifndef debug_h
-#define debug_h
-
-void topofscreen();
-void setxpos(int val);
-void setypos(int val);
-unsigned char toatarichar(int val);
-unsigned char hextoatarichar(int val);
-void plot(unsigned char val, int x, int y);
-void plotnext(unsigned char val);
-void plotnextnumber(unsigned short val);
-void debugoffset(int x);
-void debug(char const * str);
-
-void hexdump(char const * str, int length);
-void hexdump_pure(char const * str, int length);
-
-void initdebug(int onoff_in);
-
-#endif //debug_h
Index: firmware/5200/mainmenu.c
===================================================================
--- firmware/5200/mainmenu.c	(revision 194)
+++ firmware/5200/mainmenu.c	(revision 195)
@@ -127,7 +127,8 @@
 			{
 				if (joy.x_ || joy.fire_)
 				{
-					filter = filter_roms;
+					fil_type = fil_type_rom;
+					filter = filter_specified;
 					file_selector(files[5]);
 					loadosrom();
 				}
@@ -139,7 +140,8 @@
 			{
 				if (joy.fire_)
 				{
-					filter = filter_bins;
+					fil_type = fil_type_bin;
+					filter = filter_specified;
 					file_selector(files[4]);
 					//loadrom_indir(entries,"acid5200.rom",0x8000,(void *)0x004000); // XXX - just for 5200 test... do not commit!
 					if (row == 3)
Index: firmware/Makefile
===================================================================
--- firmware/Makefile	(revision 194)
+++ firmware/Makefile	(revision 195)
@@ -51,7 +51,7 @@
 MINSTARTUP_SRC = mycrt0.s
 MINSTARTUP_OBJ = $(patsubst $(STARTUP_DIR)/%.s,$(BUILD_DIR)/%.o,$(MINSTARTUP_SRC))
 
-COMMON_SRC = fileutils.c fileselector.c pokey/uart.c hexdump.c printf/printf.c fat/pff_file.c fat/pff.c common/utils.c
+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
 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 a800/regs.c
@@ -110,7 +110,7 @@
 
 HOST_CFLAGS += -I. -Isd_direct -Iprintf -Ifat -Icommon -Isdram_common -DDISABLE_UART_RX
 
-LFLAGS  = -nostartfiles -Wl,--relax -g -Os
+LFLAGS  = -nostartfiles -Wl,--relax -g -Os -Wl,-Map=out.map
 #LFLAGS  = -nostartfiles -Os
 
 
Index: firmware/a800/freeze.c
===================================================================
--- firmware/a800/freeze.c	(revision 194)
+++ firmware/a800/freeze.c	(revision 195)
@@ -11,6 +11,23 @@
 // TODO - almost the same as 5200 one
 // skctl, chbase and lack of portb to merge into one file...
 
+void memset8(void * address, int value, int length);
+
+// Moving this outside function removes gcc pulling in memcpy
+unsigned char dl[] = {
+	0x70,
+	0x70,
+	0x47,0x40,0x2c,
+	0x70,
+	0x42,0x68,0x2c,
+	0x2,0x2,0x2,0x2,0x2,
+	0x2,0x2,0x2,0x2,0x2,
+	0x2,0x2,0x2,0x2,0x2,
+	0x2,0x2,0x2,0x2,0x2,
+	0x2,0x2,
+	0x41,0x00,0x06
+};
+
 void freeze_init(void * memory)
 {
 	store_mem = (unsigned volatile char *)memory;
@@ -19,6 +36,14 @@
 	atari_base = (unsigned volatile char *)atari_regbase;
 }
 
+void memcp8(char const volatile * from, char volatile * to, int offset, int len)
+{
+	from+=offset;
+	to+=offset;
+	while (len--)
+		*to++ = *from++;
+}
+
 void freeze()
 {
 	int i;
@@ -25,24 +50,18 @@
 	// store custom chips
 	store_portb = *atari_portb;
 	{
+		//backup last value written to custom chip regs
 		//gtia
-		for (i=0xd000; i!=0xd020; i++)
-		{
-			store_mem[i] = custom_mirror[i];
-			atari_base[i] = 0;
-		}
+		memcp8(custom_mirror,store_mem,0xd000,0x20);
 		//pokey1/2
-		for (i=0xd200; i!=0xd220; i++)
-		{
-			store_mem[i] = custom_mirror[i];
-			atari_base[i] = 0;
-		}
+		memcp8(custom_mirror,store_mem,0xd200,0x20);
 		//antic
-		for (i=0xd400; i!=0xd410; i++)
-		{
-			store_mem[i] = custom_mirror[i];
-			atari_base[i] = 0;
-		}
+		memcp8(custom_mirror,store_mem,0xd400,0x10);
+
+		// Write 0 to custom chip regs
+		memset8(atari_base+0xd000,0,0x20);
+		memset8(atari_base+0xd200,0,0x20);
+		memset8(atari_base+0xd400,0,0x10);
 	}
 
 	*atari_portb = 0xff;
@@ -49,14 +68,8 @@
 
 	// Copy 64k ram to sdram
 	// Atari screen memory...
-	for (i=0x0; i!=0xd000; ++i)
-	{
-		store_mem[i] = atari_base[i];
-	}
-	for (i=0xd800; i!=0x10000; ++i)
-	{
-		store_mem[i] = atari_base[i];
-	}
+	memcp8(atari_base,store_mem,0,0xd000);
+	memcp8(atari_base,store_mem,0xd800,0x2800);
 
 	//Clear, except dl (first 0x40 bytes)
 	clearscreen();
@@ -63,24 +76,7 @@
 
 	// Put custom chips in a safe state
 	// write a display list at 0600
-	unsigned char dl[] = {
-		0x70,
-		0x70,
-		0x47,0x40,0x2c,
-		0x70,
-		0x42,0x68,0x2c,
-		0x2,0x2,0x2,0x2,0x2,
-		0x2,0x2,0x2,0x2,0x2,
-		0x2,0x2,0x2,0x2,0x2,
-		0x2,0x2,0x2,0x2,0x2,
-		0x2,0x2,
-		0x41,0x00,0x06
-	};
-	int j = 0;
-	for (i=0x0600; j!=sizeof(dl); ++i,++j)
-	{
-		atari_base[i] = dl[j];
-	}
+	memcp8(dl,atari_base+0x600,0,sizeof(dl));
 
 	// point antic at my display list
 	*atari_dlisth = 0x06;
@@ -100,35 +96,18 @@
 
 void restore()
 {
-	int i;
-
 	// Restore memory
-	for (i=0x0; i!=0xd000; ++i)
-	{
-		atari_base[i] = store_mem[i];
-	}
-	for (i=0xd800; i!=0x10000; ++i)
-	{
-		atari_base[i] = store_mem[i];
-	}
+	memcp8(store_mem,atari_base,0,0xd000);
+	memcp8(store_mem,atari_base,0xd800,0x2800);
 
 	// Restore custom chips
 	{
-		//gtia
-		for (i=0xd000; i!=0xd020; i++)
-		{
-			atari_base[i] = store_mem[i];
-		}
-		//pokey1/2
-		for (i=0xd200; i!=0xd220; i++)
-		{
-			atari_base[i] = store_mem[i];
-		}
-		//antic
-		for (i=0xd400; i!=0xd410; i++)
-		{
-			atari_base[i] = store_mem[i];
-		}
+		// gtia
+		memcp8(store_mem,atari_base,0xd000,0x20);
+		// pokey
+		memcp8(store_mem,atari_base,0xd200,0x20);
+		// antic
+		memcp8(store_mem,atari_base,0xd400,0x10);
 	}
 
 	*atari_portb = store_portb;
Index: firmware/a800/mainmenu.c
===================================================================
--- firmware/a800/mainmenu.c	(revision 194)
+++ firmware/a800/mainmenu.c	(revision 195)
@@ -136,7 +136,7 @@
 
 		debug_pos = 400;
 		debug_adjust = row==7 ? 128 : 0;
-		printf("Cartridge 8k simple");
+		printf("Cart: %s", get_cart_select() ? file_name(files[4]) : "NONE");
 
 		debug_pos = 480;
 		debug_adjust = row==8 ? 128 : 0;
@@ -177,7 +177,8 @@
 			{
 				if (joy.x_ || joy.fire_)
 				{
-					filter = filter_roms;
+					fil_type = fil_type_rom;
+					filter = filter_specified;
 					file_selector(files[5]);
 					loadosrom();
 				}
@@ -221,13 +222,20 @@
 			break;
 		case 7:
 			{
-				if (joy.fire_)
-				{
-					filter = filter_roms;
+				if (joy.x_>0) {
+					fil_type = fil_type_car;
+					filter = filter_specified;
 					file_selector(files[4]);
-					loadrom(file_name(files[4]),0x2000,0x700000);
-					return 1;
+					unsigned char mode = 0; // TODO load_car(files[4]);
+					set_cart_select(mode);
+					if (mode) {
+						return 1;
+					}
 				}
+				else if (joy.x_<0) {
+					file_init(files[4]);
+					set_cart_select(0);
+				}
 			}
 			break;
 		case 8:
Index: firmware/aeon_lite/memory.h
===================================================================
--- firmware/aeon_lite/memory.h	(revision 194)
+++ firmware/aeon_lite/memory.h	(revision 195)
@@ -13,9 +13,13 @@
 #define DIR_INIT_MEMSIZE 65536
 #define FREEZE_MEM (SDRAM_BASE + 0xa0000)
 
+// disabled
+#define CARTRIDGE_MEM ((void*) 0)
+
 // offset in SDRAM area
 #define ROM_OFS 0xc0000
 
+
 #define atari_regbase  ((void*) 0x10000)
 #define atari_regmirror  ((void*) 0x20000)
 #define config_regbase ((void*) 0x40000)
Index: firmware/atari_drive_emulator.c
===================================================================
--- firmware/atari_drive_emulator.c	(revision 194)
+++ firmware/atari_drive_emulator.c	(revision 195)
@@ -110,6 +110,7 @@
 void getCommand(struct command * cmd)
 {
 	int expchk;
+	int i;
 
 	//printf("Waiting for command\n");
 	//USART_Data_Ready();
@@ -123,11 +124,13 @@
 	{
 		actions();
 	}
-	cmd->deviceId = USART_Receive_Byte();
+	for (i=0;i!=5;++i)
+		((char *)cmd)[i] = USART_Receive_Byte();
+	/*cmd->deviceId = USART_Receive_Byte();
 	cmd->command = USART_Receive_Byte();
 	cmd->aux1 = USART_Receive_Byte();
 	cmd->aux2 = USART_Receive_Byte();
-	cmd->chksum = USART_Receive_Byte();
+	cmd->chksum = USART_Receive_Byte();*/
 	while (0 == USART_Command_Line())
 	{
 		actions();
Index: firmware/cartridge.c
===================================================================
--- firmware/cartridge.c	(nonexistent)
+++ firmware/cartridge.c	(revision 195)
@@ -0,0 +1,125 @@
+#include "memory.h"
+#include "simpledir.h"
+#include "cartridge.h"
+#include "log.h"
+
+struct CartDef {
+	unsigned char carttype;	// type from CAR header
+	unsigned char mode;		// mode used in cartridge emulation
+	unsigned short size;		// size in k
+};
+
+// 8k modes (0xA000-$BFFF)
+#define TC_MODE_OFF             0x00           // cart disabled
+#define TC_MODE_8K              0x01           // 8k banks at $A000
+#define TC_MODE_ATARIMAX1       0x02           // 8k using Atarimax 1MBit compatible banking
+#define TC_MODE_ATARIMAX8       0x03           // 8k using Atarimax 8MBit compatible banking
+#define TC_MODE_OSS             0x04           // 16k OSS cart, M091 banking
+
+#define TC_MODE_SDX64           0x08           // SDX 64k cart, $D5Ex banking
+#define TC_MODE_DIAMOND64       0x09           // Diamond GOS 64k cart, $D5Dx banking
+#define TC_MODE_EXPRESS64       0x0A           // Express 64k cart, $D57x banking
+
+#define TC_MODE_ATRAX128        0x0C           // Atrax 128k cart
+#define TC_MODE_WILLIAMS64      0x0D           // Williams 64k cart
+
+// 16k modes (0x8000-$BFFF)
+//#define TC_MODE_FLEXI           0x20           // flexi mode
+#define TC_MODE_16K             0x21           // 16k banks at $8000-$BFFF
+#define TC_MODE_MEGAMAX16       0x22           // MegaMax 16k mode (up to 2MB)
+#define TC_MODE_BLIZZARD        0x23           // Blizzard 16k
+#define TC_MODE_SIC             0x24           // Sic!Cart 512k
+
+#define TC_MODE_MEGA_16         0x28           // switchable MegaCarts
+#define TC_MODE_MEGA_32         0x29
+#define TC_MODE_MEGA_64         0x2A
+#define TC_MODE_MEGA_128        0x2B
+#define TC_MODE_MEGA_256        0x2C
+#define TC_MODE_MEGA_512        0x2D
+#define TC_MODE_MEGA_1024       0x2E
+#define TC_MODE_MEGA_2048       0x2F
+
+#define TC_MODE_XEGS_32         0x30           // non-switchable XEGS carts
+#define TC_MODE_XEGS_64         0x31
+#define TC_MODE_XEGS_128        0x32
+#define TC_MODE_XEGS_256        0x33
+#define TC_MODE_XEGS_512        0x34
+#define TC_MODE_XEGS_1024       0x35
+
+#define TC_MODE_SXEGS_32        0x38           // switchable XEGS carts
+#define TC_MODE_SXEGS_64        0x39
+#define TC_MODE_SXEGS_128       0x3A
+#define TC_MODE_SXEGS_256       0x3B
+#define TC_MODE_SXEGS_512       0x3C
+#define TC_MODE_SXEGS_1024      0x3D
+
+static struct CartDef cartdef[] = {
+        { 1, TC_MODE_8K, 8 },
+        { 2, TC_MODE_16K, 16 },
+        { 8, TC_MODE_WILLIAMS64, 64 },
+        { 9, TC_MODE_EXPRESS64, 64 },
+        { 10, TC_MODE_DIAMOND64, 64 },
+        { 11, TC_MODE_SDX64, 64 },
+        { 12, TC_MODE_XEGS_32, 32 },
+        { 13, TC_MODE_XEGS_64, 64 },
+        { 14, TC_MODE_XEGS_128, 128 },
+        { 15, TC_MODE_OSS, 16 },
+        { 17, TC_MODE_ATRAX128, 128 },
+        { 23, TC_MODE_XEGS_256, 256 },
+        { 24, TC_MODE_XEGS_512, 512 },
+        { 26, TC_MODE_MEGA_16, 16 },
+        { 27, TC_MODE_MEGA_32, 32 },
+        { 28, TC_MODE_MEGA_64, 64 },
+        { 29, TC_MODE_MEGA_128, 128 },
+        { 30, TC_MODE_MEGA_256, 256 },
+        { 31, TC_MODE_MEGA_512, 512 },
+        { 33, TC_MODE_SXEGS_32, 32 },
+        { 34, TC_MODE_SXEGS_64, 64 },
+        { 35, TC_MODE_SXEGS_128, 128 },
+        { 36, TC_MODE_SXEGS_256, 256 },
+        { 37, TC_MODE_SXEGS_512, 512 },
+        { 40, TC_MODE_BLIZZARD, 16 },
+        { 41, TC_MODE_ATARIMAX1, 128 },
+        { 42, TC_MODE_ATARIMAX8, 1024 },
+        { 56, TC_MODE_SIC, 512 },
+	{ 0, 0, 0 }
+};
+
+int load_car(struct SimpleFile* file)
+{
+	if (CARTRIDGE_MEM == 0) {
+		LOG("no cartridge memory\n");
+		return 0;
+	}
+	int len;
+	enum SimpleFileStatus ok;
+	unsigned char header[16];
+	ok = file_read(file, header, 16, &len);
+	if (ok != SimpleFile_OK || len != 16) {
+		LOG("cannot read cart header\n");
+		return 0;
+	}
+	unsigned char carttype = header[7];
+
+	// search for cartridge definition
+	struct CartDef* def = cartdef;
+	while (def->carttype && def->carttype != carttype) {
+		def++;
+	}
+	if (def->carttype == 0) {
+		LOG("illegal cart type %d\n", carttype);
+		return 0;
+	}
+	// read data in 8k chunks
+	unsigned int block;
+	for(block = 0; block < def->size >> 3; block++) {
+		ok = file_read(file, CARTRIDGE_MEM + block * 0x2000, 0x2000, &len);
+		if (ok != SimpleFile_OK || len != 0x2000) {
+			LOG("cannot read cart data\n");
+			return 0;
+		}
+	}
+	LOG("cart type: %d size: %dk\n",
+		 def->mode, def->size);
+	return def->mode;
+}
Index: firmware/cartridge.h
===================================================================
--- firmware/cartridge.h	(nonexistent)
+++ firmware/cartridge.h	(revision 195)
@@ -0,0 +1,6 @@
+#ifndef CARTRIDGE_H
+#define CARTRIDGE_H
+#include "simplefile.h"
+
+int load_car(struct SimpleFile* file);
+#endif
Index: firmware/fat/pff_file.c
===================================================================
--- firmware/fat/pff_file.c	(revision 194)
+++ firmware/fat/pff_file.c	(revision 195)
@@ -185,7 +185,7 @@
 
 	file_check_open(file);
 
-	pf_lseek(offsetFromStart);
+	res = pf_lseek(offsetFromStart);
 	return translateStatus(res);
 }
 
Index: firmware/fileselector.c
===================================================================
--- firmware/fileselector.c	(revision 194)
+++ firmware/fileselector.c	(revision 195)
@@ -23,20 +23,17 @@
 	return res;
 }
 
-int filter_roms(struct SimpleDirEntry * entry)
+char const * fil_type = 0;
+char const * fil_type_rom = "ROM";
+char const * fil_type_bin = "BIN";
+char const * fil_type_car = "CAR";
+int filter_specified(struct SimpleDirEntry * entry)
 {
 	if (dir_is_subdir(entry)) return 1;
 	char const * f = dir_filename(entry);
-	return (compare_ext(f,"ROM"));
+	return (compare_ext(f,fil_type));
 }
 
-int filter_bins(struct SimpleDirEntry * entry)
-{
-	if (dir_is_subdir(entry)) return 1;
-	char const * f = dir_filename(entry);
-	return (compare_ext(f,"BIN"));
-}
-
 void dir_of(char * dir, char const * path); // TODO - into simpledir
 
 void file_selector(struct SimpleFile * file)
Index: firmware/fileselector.h
===================================================================
--- firmware/fileselector.h	(revision 194)
+++ firmware/fileselector.h	(revision 195)
@@ -3,8 +3,11 @@
 void file_selector(struct SimpleFile * file);
 
 int filter_disks(struct SimpleDirEntry * entry);
-int filter_roms(struct SimpleDirEntry * entry);
-int filter_bins(struct SimpleDirEntry * entry);
+extern char const * fil_type;
+extern char const * fil_type_rom;
+extern char const * fil_type_bin;
+extern char const * fil_type_car;
+int filter_specified(struct SimpleDirEntry * entry);
 
 extern int (* filter)(struct SimpleDirEntry * entry);
 
Index: firmware/linux/curses_screen.c
===================================================================
--- firmware/linux/curses_screen.c	(revision 194)
+++ firmware/linux/curses_screen.c	(revision 195)
@@ -83,10 +83,11 @@
 	snprintf(tmpstr, MAXSTR, "out1: %08x", out1);
 	mvwaddstr(status_window, 0, 1, tmpstr);
 
-	snprintf(tmpstr, MAXSTR, "- - tur %02x ram %02x rom %02x",
+	snprintf(tmpstr, MAXSTR, "- - tur %02x ram %02x rom %02x car %02x",
 		(out1 >> 2) & 0x3f,
 		(out1 >> 8) & 0x07,
-		(out1 >> 11) & 0x3f);
+		(out1 >> 11) & 0x3f,
+		(out1 >> 17) & 0x3f);
 	if (out1 & 1) {
 		tmpstr[0] = 'P';
 	}
Index: firmware/linux/linux_memory.c
===================================================================
--- firmware/linux/linux_memory.c	(revision 194)
+++ firmware/linux/linux_memory.c	(revision 195)
@@ -64,11 +64,13 @@
 void* atari_regbase;
 void* atari_regmirror;
 void* config_regbase;
+void* CARTRIDGE_MEM;
 
 #define SRAM_SIZE (512*1024)
 #define SDRAM_SIZE (8*1024*1024)
 #define ATARI_SIZE (64*1024)
 #define CONFIG_SIZE (256)
+#define CARTRIDGE_SIZE (2*1024*1024)
 
 uint8_t sram_memory[SRAM_SIZE];
 uint32_t sdram_memory[SDRAM_SIZE / 4];
@@ -75,6 +77,7 @@
 uint8_t atari_memory[ATARI_SIZE];
 uint8_t atari_mirror_memory[ATARI_SIZE];
 uint32_t config_memory[CONFIG_SIZE/4];
+uint32_t cartridge_memory[CARTRIDGE_SIZE / 4];
 
 void init_memory(void)
 {
@@ -83,6 +86,7 @@
 	memset(atari_memory, ATARI_SIZE, 0);
 	memset(atari_mirror_memory, ATARI_SIZE, 0);
 	memset(config_memory, CONFIG_SIZE, 0);
+	memset(cartridge_memory, CARTRIDGE_SIZE, 0);
 
 	SRAM_BASE = sram_memory;
 	SDRAM_BASE = sdram_memory;
@@ -89,6 +93,7 @@
 	atari_regbase = atari_memory;
 	atari_regmirror = atari_mirror_memory;
 	config_regbase = config_memory;
+	CARTRIDGE_MEM = cartridge_memory;
 
 	zpu_in1 = (int *)(0*4+config_regbase);
 	zpu_in2 = (int *)(1*4+config_regbase);
Index: firmware/linux/memory.h
===================================================================
--- firmware/linux/memory.h	(revision 194)
+++ firmware/linux/memory.h	(revision 195)
@@ -3,6 +3,7 @@
 
 extern void* SDRAM_BASE;
 extern void* SRAM_BASE;
+extern void* CARTRIDGE_MEM;
 
 // Memory usage...
 // 0x410000-0x44FFFF (0xc10000 in zpu space) = directory cache - 256k
Index: firmware/log.h
===================================================================
--- firmware/log.h	(nonexistent)
+++ firmware/log.h	(revision 195)
@@ -0,0 +1,11 @@
+#ifndef LOG_H
+#define LOG_H
+
+#ifdef LINUX_BUILD
+#include "curses_screen.h"
+#define LOG(x...) print_log(x)
+#else
+#define LOG(x...) do { } while(0)
+#endif
+
+#endif
Index: firmware/main.h
===================================================================
--- firmware/main.h	(revision 194)
+++ firmware/main.h	(revision 195)
@@ -10,6 +10,7 @@
 #include "simpledir.h"
 #include "simplefile.h"
 #include "fileselector.h"
+#include "cartridge.h"
 
 #ifdef LINUX_BUILD
 #include "curses_screen.h"
@@ -74,6 +75,7 @@
 BIT_REG(,0x3f,2,turbo_6502,zpu_out1)
 BIT_REG(,0x7,8,ram_select,zpu_out1)
 BIT_REG(,0x3f,11,rom_select,zpu_out1)
+BIT_REG(,0x3f,17,cart_select,zpu_out1)
 
 BIT_REG_RO(,0x1,8,hotkey_softboot,zpu_in1)
 BIT_REG_RO(,0x1,9,hotkey_coldboot,zpu_in1)
@@ -240,6 +242,7 @@
 	set_turbo_6502(1);
 	set_rom_select(1);
 	set_ram_select(2);
+	set_cart_select(0);
 
 	init_printf(0, char_out);
 
Index: firmware/sdram_common/memory.h
===================================================================
--- firmware/sdram_common/memory.h	(revision 194)
+++ firmware/sdram_common/memory.h	(revision 195)
@@ -12,6 +12,7 @@
 #define DIR_INIT_MEM (SDRAM_BASE + 0x410000)
 #define DIR_INIT_MEMSIZE 262144
 #define FREEZE_MEM (SDRAM_BASE + 0x450000)
+#define CARTRIDGE_MEM (SDRAM_BASE + 0x500000)
 
 // offset into SDRAM
 #define ROM_OFS 0x700000
Index: firmware/test_freeze.c
===================================================================
--- firmware/test_freeze.c	(revision 194)
+++ firmware/test_freeze.c	(revision 195)
@@ -1,14 +1,29 @@
+#include "memory.h"
 #include "regs.h"
 
+void clearscreen()
+{
+/*	unsigned volatile char * screen;
+	for (screen=(unsigned volatile char *)(screen_address+atari_regbase); screen!=(unsigned volatile char *)(atari_regbase+screen_address+1024); ++screen)
+		*screen = 0x00;*/
+}
+
 #include "stdlib.h"
 #include "stdio.h"
 
+void memset8(void * address, int value, int length)
+{
+	char * mem = address;
+	while (length--)
+		*mem++=value;
+}
+
 #undef atari_regbase
 static char * atari_regbase = (char *)malloc(65536);
 #undef atari_regmirror
 static char * atari_regmirror = (char *)malloc(65536);
 #include "freeze.h"
-#include "freeze.c"
+#include "a800/freeze_ci.c"
 #include "regs.c"
 
 int main(void)
@@ -25,16 +40,23 @@
 	{
 		*((atari_regmirror+i)) = i%256-2;
 	}
+
 	freeze();
-	/*for (int i=0; i!=64*1024; ++i)
+
+	for (int i=0; i!=64*1024; ++i)
 	{
-		fprintf(stderr,"i:%x val:%x\n",i,*((unsigned char *)(buffer+i)));
-		if (i%256!=*((unsigned char *)(buffer+i)))
+		fprintf(stderr,"i:%x stored:%x regbase:%x mirror:%x\n",i,
+			*((unsigned char *)(buffer+i)),
+			*((unsigned char *)(atari_regbase+i)),
+			*((unsigned char *)(atari_regmirror+i))
+		);
+/*		if (i%256!=*((unsigned char *)(buffer+i)))
 		{
 			fprintf(stderr,"!!FAIL!%d %d %d", i, i%256, *(unsigned char *)(atari_regbase+i));
 			return -1;
-		}
-	}*/
+		}*/
+	}
+	return 0;
 
 	for (int i=0;i!=0xd000; ++i)
 	{
