Index: firmware/Makefile
===================================================================
--- firmware/Makefile	(revision 182)
+++ firmware/Makefile	(revision 183)
@@ -5,6 +5,19 @@
 CP      = $(BASE)-objcopy
 DUMP    = $(BASE)-objdump
 
+HOST_CC	= gcc
+HOST_LD	= gcc
+
+HOST_CFLAGS	= -g -DLINUX_BUILD -DLITTLE_ENDIAN -fno-builtin
+HOST_CFLAGS	+= -W -Wall
+HOST_LDFLAGS	= -g
+
+#HOST_CFLAGS	+= -m32
+#HOST_LDFLAGS	+= -m32
+
+HOST_CFLAGS	+= $(shell pkg-config --cflags ncurses)
+HOST_LDFLAGS	+= $(shell pkg-config --libs ncurses)
+
 # we use mincrt0.s from here
 STARTUP_DIR = .
 
@@ -19,6 +32,7 @@
 CHAMELEON_DIR = chameleon
 MCC_DIR = mcc
 MIST_DIR = mist
+LINUXSIM_DIR = linux
 
 AEON_LITE_BUILD_DIR = $(BUILD_DIR)/$(AEON_LITE_DIR)
 DE1_BUILD_DIR = $(BUILD_DIR)/$(DE1_DIR)
@@ -25,36 +39,45 @@
 CHAMELEON_BUILD_DIR = $(BUILD_DIR)/$(CHAMELEON_DIR)
 MCC_BUILD_DIR = $(BUILD_DIR)/$(MCC_DIR)
 MIST_BUILD_DIR = $(BUILD_DIR)/$(MIST_DIR)
+LINUXSIM_BUILD_DIR = $(BUILD_DIR)/$(LINUXSIM_DIR)
 
 #MINSTARTUP_SRC = mincrt0.s
 MINSTARTUP_SRC = mycrt0.s
 MINSTARTUP_OBJ = $(patsubst $(STARTUP_DIR)/%.s,$(BUILD_DIR)/%.o,$(MINSTARTUP_SRC))
 
-COMMON_SRC = main.c regs.c freeze.c joystick.c fileutils.c fileselector.c atari_drive_emulator.c pokey/uart.c hexdump.c printf/printf.c fat/pff_file.c fat/pff.c common/utils.c
+COMMON_SRC = main.c freeze.c fileutils.c fileselector.c atari_drive_emulator.c pokey/uart.c hexdump.c printf/printf.c fat/pff_file.c fat/pff.c common/utils.c
+ZPU_SRC = regs.c joystick.c
 SDCARD_SRC = sd_direct/diskio_mmc.c sd_direct/spi.c sd_direct/mmc2.c
 
 AEON_LITE_PRJ = AEON_LITE
-AEON_LITE_SRC = $(COMMON_SRC) $(SDCARD_SRC) de1/dirs.c
+AEON_LITE_SRC = $(COMMON_SRC) $(SDCARD_SRC) $(ZPU_SRC) de1/dirs.c
 AEON_LITE_OBJ = $(patsubst %.c,$(AEON_LITE_BUILD_DIR)/%.o,$(AEON_LITE_SRC))
 
 DE1_PRJ = DE1
-DE1_SRC = $(COMMON_SRC) $(SDCARD_SRC) de1/dirs.c
+DE1_SRC = $(COMMON_SRC) $(SDCARD_SRC) $(ZPU_SRC) de1/dirs.c
 DE1_OBJ = $(patsubst %.c,$(DE1_BUILD_DIR)/%.o,$(DE1_SRC))
 
 CHAMELEON_PRJ = CHAMELEON
-CHAMELEON_SRC = $(COMMON_SRC) $(SDCARD_SRC) chameleon/dirs.c
+CHAMELEON_SRC = $(COMMON_SRC) $(SDCARD_SRC) $(ZPU_SRC) chameleon/dirs.c
 CHAMELEON_OBJ = $(patsubst %.c,$(CHAMELEON_BUILD_DIR)/%.o,$(CHAMELEON_SRC))
 
 MCC_PRJ = MCC216
-MCC_SRC = $(COMMON_SRC) $(SDCARD_SRC) mcc/dirs.c
+MCC_SRC = $(COMMON_SRC) $(SDCARD_SRC) $(ZPU_SRC) mcc/dirs.c
 MCC_OBJ = $(patsubst %.c,$(MCC_BUILD_DIR)/%.o,$(MCC_SRC))
 
 MIST_PRJ = MIST
-MIST_SRC = $(COMMON_SRC) mist/diskio_sectorrequest.c mist/dirs.c
+MIST_SRC = $(COMMON_SRC) $(ZPU_SRC) mist/diskio_sectorrequest.c mist/dirs.c
 MIST_OBJ = $(patsubst %.c,$(MIST_BUILD_DIR)/%.o,$(MIST_SRC))
 
 LINKMAP  = ./standalone_simple.ld
 
+LINUXSIM_EXE	= linuxsim
+LINUXSIM_SRC	= $(COMMON_SRC) linux/main.c linux/mmc.c \
+	sd_direct/diskio_mmc.c linux/dirs.c linux/linux_memory.c linux/curses_screen.c \
+	linux/linux_helper.c
+
+LINUXSIM_OBJ	= $(patsubst %.c,$(LINUXSIM_BUILD_DIR)/%.o,$(LINUXSIM_SRC))
+
 # Commandline options for each tool.
 
 #ZPUOPTS= -mno-poppcrel -mno-pushspadd -mno-callpcrel -mno-shortop -mno-neg # No-neg requires bugfixed toolchain
@@ -62,6 +85,8 @@
 ZPUOPTS =
 CFLAGS  = -I. -Isd_direct -Iprintf -Ifat -Icommon -Isdram_common -c -g -Os $(ZPUOPTS) -DDISABLE_UART_RX
 
+HOST_CFLAGS += -I. -Isd_direct -Iprintf -Ifat -Icommon -Isdram_common -DDISABLE_UART_RX
+
 LFLAGS  = -nostartfiles -Wl,--relax -g -Os
 #LFLAGS  = -nostartfiles -Os
 
@@ -82,8 +107,11 @@
 
 mist: $(BUILD_DIR) $(MIST_PRJ).bin $(MIST_PRJ).rpt
 
+.PHONY: linux
+linux: $(BUILD_DIR) $(LINUXSIM_EXE)
+
 clean:
-	rm -rf $(BUILD_DIR)/* *.hex *.elf *.map *.lst *.srec *.bin *.rpt
+	rm -rf $(BUILD_DIR)/* *.hex *.elf *.map *.lst *.srec *.bin *.rpt $(LINUXSIM_EXE)
 
 
 # Convert ELF binary to bin file.
@@ -116,6 +144,9 @@
 $(MIST_PRJ).elf: $(MINSTARTUP_OBJ) $(MIST_OBJ)
 	$(LD) $(LFLAGS) -T $(LINKMAP) -o $@ $+ $(LIBS)
 
+$(LINUXSIM_EXE): $(LINUXSIM_OBJ)
+	$(HOST_LD) $(HOST_LDFLAGS) -o $@ $+
+
 $(AEON_LITE_BUILD_DIR)/%.o: %.c Makefile
 	mkdir -p `dirname $@`
 	$(CC) -I$(AEON_LITE_DIR) $(CFLAGS)  -o $@ -c $<
@@ -136,6 +167,10 @@
 	mkdir -p `dirname $@`
 	$(CC) -I$(MIST_DIR) $(CFLAGS)  -o $@ -c $<
 
+$(LINUXSIM_BUILD_DIR)/%.o: %.c Makefile
+	@mkdir -p `dirname $@`
+	$(HOST_CC) -I$(LINUXSIM_DIR) $(HOST_CFLAGS)  -o $@ -c $<
+
 $(BUILD_DIR)/%.o: %.s
 	$(AS) -o $@ $<
 
Index: firmware/joystick.h
===================================================================
--- firmware/joystick.h	(revision 182)
+++ firmware/joystick.h	(revision 183)
@@ -1,4 +1,5 @@
-#pragma once
+#ifndef JOYSTICK_H
+#define JOYSTICK_H
 
 struct joystick_status
 {
@@ -12,3 +13,4 @@
 void joystick_poll(struct joystick_status * status);
 void joystick_wait(struct joystick_status * status, enum JoyWait waitFor);
 
+#endif
Index: firmware/linux/curses_screen.c
===================================================================
--- firmware/linux/curses_screen.c	(nonexistent)
+++ firmware/linux/curses_screen.c	(revision 183)
@@ -0,0 +1,197 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <curses.h>
+#include "curses_screen.h"
+#include "linux_helper.h"
+#include "regs.h"
+
+static WINDOW* atari_window;
+static WINDOW* status_window;
+static WINDOW* log_window;
+
+static attr_t atari_color;
+static attr_t atari_inverse_color;
+static attr_t status_color;
+static attr_t log_color;
+
+int init_curses_screen(void)
+{
+	int height;
+	int width;
+
+	initscr();
+
+	getmaxyx(stdscr, height, width);
+
+	if (height < 24 || width < 80) {
+		fprintf(stderr, "screen is too small (must be 80x24)\n");
+		return 1;
+	}
+
+	nonl();
+	cbreak();
+	noecho();
+
+	atari_window = newwin(24, 40, 0, 0);
+	status_window = newwin(4, width - 40, 0, 40);
+	log_window = newwin(height - 4, width - 40, 4, 40);
+
+	atari_color = 0;
+	atari_inverse_color = A_REVERSE;
+	if (has_colors()) {
+		start_color();
+		init_pair(1, COLOR_YELLOW, COLOR_BLUE);
+		init_pair(2, COLOR_YELLOW, COLOR_BLACK);
+		status_color = COLOR_PAIR(1);
+		log_color = COLOR_PAIR(2);
+	} else {
+		status_color = A_REVERSE;
+		log_color = 0;
+	}
+	wbkgdset(atari_window, atari_color | ' ');
+	wbkgdset(log_window, log_color | ' ');
+	wbkgdset(status_window, status_color | ' ');
+	wbkgdset(log_window, log_color | ' ');
+
+	keypad(stdscr, TRUE);
+	scrollok(log_window, TRUE);
+
+	werase(atari_window);
+	werase(status_window);
+	werase(log_window);
+
+	curs_set(0);
+
+	refresh();
+	return 0;
+}
+
+void deinit_curses_screen(void)
+{
+	endwin();
+}
+
+#define MAXSTR 256
+static char tmpstr[MAXSTR];
+
+void display_out_regs(void)
+{
+	uint32_t out1 = *zpu_out1;
+
+	werase(status_window);
+	snprintf(tmpstr, MAXSTR, "out1: %08x", out1);
+	mvwaddstr(status_window, 0, 1, tmpstr);
+
+	snprintf(tmpstr, MAXSTR, "- - tur %02x ram %02x rom %02x",
+		(out1 >> 2) & 0x3f,
+		(out1 >> 8) & 0x07,
+		(out1 >> 11) & 0x3f);
+	if (out1 & 1) {
+		tmpstr[0] = 'P';
+	}
+	if (out1 & 2) {
+		tmpstr[2] = 'R';
+	}
+	mvwaddstr(status_window, 1, 1, tmpstr);
+
+	wrefresh(status_window);
+}
+
+void display_char(int x, int y, char c, int inverse)
+{
+	if (inverse) {
+		wattrset(atari_window, atari_inverse_color);
+	}
+	mvwaddch(atari_window, y, x, c);
+	wattrset(atari_window, atari_color);
+
+	wrefresh(atari_window);
+}
+
+void clearscreen(void)
+{
+	wattrset(atari_window, atari_color);
+	werase(atari_window);
+	wrefresh(atari_window);
+}
+
+void check_keys(void)
+{
+	int ch;
+	*zpu_in1 = 0;
+
+	while (1) {
+		ch = wgetch(stdscr);
+
+		switch (ch) {
+		case KEY_F(12):
+			*zpu_in1 = 1<<11; return;
+		case 27: // ESCAPE:
+			longjmp(exit_jmp_buf, 1);
+		}
+	}
+}
+
+void joystick_poll(struct joystick_status * status)
+{
+	// we are blocking instead of polling
+	int ch = wgetch(stdscr);
+
+	status->x_ = 0;
+	status->y_ = 0;
+	status->fire_ = 0;
+
+
+	switch (ch) {
+	case KEY_UP: status->y_ = -1; break;
+	case KEY_DOWN: status->y_ = 1; break;
+	case KEY_LEFT: status->x_ = -1; break;
+	case KEY_RIGHT: status->x_ = 1; break;
+	case KEY_ENTER:
+	case 13:
+		status->fire_ = 1; break;
+	case 27: // ESCAPE:
+		longjmp(exit_jmp_buf, 1);
+	default: break;
+	}
+}
+
+void joystick_wait(struct joystick_status * status, enum JoyWait waitFor)
+{
+	if (waitFor == WAIT_QUIET)
+	{
+		status->x_ = 0;
+		status->y_ = 0;
+		status->fire_ = 0;
+		return;
+	}
+	while (1)
+	{
+		joystick_poll(status);
+		switch (waitFor)
+		{
+		case WAIT_QUIET:
+			break;
+		case WAIT_FIRE:
+			if (status->fire_ == 1) return;
+			break;
+		case WAIT_EITHER:
+			if (status->fire_ == 1) return;
+			// fall through
+		case WAIT_MOVE:
+			if (status->x_ !=0 || status->y_ != 0) return;
+			break;
+		}
+	}
+}
+
+void print_log(const char* format, ...)
+{
+	va_list arg;
+	va_start(arg, format);
+	vw_printw(log_window, format, arg);
+	va_end(arg);
+	wrefresh(log_window);
+}
+
Index: firmware/linux/curses_screen.h
===================================================================
--- firmware/linux/curses_screen.h	(nonexistent)
+++ firmware/linux/curses_screen.h	(revision 183)
@@ -0,0 +1,19 @@
+#ifndef CURSES_SCREEN_H
+#define CURSES_SCREEN_H
+#include "joystick.h"
+
+int init_curses_screen(void);
+
+void deinit_curses_screen(void);
+
+void display_out_regs(void);
+
+void display_char(int x, int y, char c, int inverse);
+
+void clearscreen(void);
+
+void check_keys(void);
+
+void print_log(const char* format, ...) __attribute__ ((format (printf, 1, 2))) ;
+
+#endif
Index: firmware/linux/dirs.c
===================================================================
--- firmware/linux/dirs.c	(nonexistent)
+++ firmware/linux/dirs.c	(revision 183)
@@ -0,0 +1,2 @@
+char USER_DIR[]="/atari800/user";
+char ROM_DIR[]="/atari800/rom";
Index: firmware/linux/linux_helper.c
===================================================================
--- firmware/linux/linux_helper.c	(nonexistent)
+++ firmware/linux/linux_helper.c	(revision 183)
@@ -0,0 +1,5 @@
+#include "linux_helper.h"
+
+jmp_buf exit_jmp_buf;
+
+char* sdcard_filename = 0;
Index: firmware/linux/linux_helper.h
===================================================================
--- firmware/linux/linux_helper.h	(nonexistent)
+++ firmware/linux/linux_helper.h	(revision 183)
@@ -0,0 +1,9 @@
+#ifndef LINUX_HELPER_H
+#define LINUX_HELPER_H
+#include <setjmp.h>
+
+extern jmp_buf exit_jmp_buf;
+
+extern char* sdcard_filename;
+
+#endif
Index: firmware/linux/linux_memory.c
===================================================================
--- firmware/linux/linux_memory.c	(nonexistent)
+++ firmware/linux/linux_memory.c	(revision 183)
@@ -0,0 +1,153 @@
+#include <stdint.h>
+#include <string.h>
+#include "regs.h"
+#include "memory.h"
+#include "linux_memory.h"
+
+int volatile * zpu_in1;
+int volatile * zpu_in2;
+int volatile * zpu_in3;
+int volatile * zpu_in4;
+
+int volatile * zpu_out1;
+int volatile * zpu_out2;
+int volatile * zpu_out3;
+int volatile * zpu_out4;
+
+int volatile * zpu_pause;
+
+int volatile * zpu_spi_data;
+int volatile * zpu_spi_state;
+
+int volatile * zpu_sio;
+
+int volatile * zpu_board;
+
+int volatile * zpu_spi_dma;
+
+unsigned char volatile * zpu_pokey_audf0;
+unsigned char volatile * zpu_pokey_audc0;
+unsigned char volatile * zpu_pokey_audf1;
+unsigned char volatile * zpu_pokey_audc1;
+unsigned char volatile * zpu_pokey_audf2;
+unsigned char volatile * zpu_pokey_audc2;
+unsigned char volatile * zpu_pokey_audf3;
+unsigned char volatile * zpu_pokey_audc3;
+
+unsigned char volatile * zpu_pokey_audctl;
+
+unsigned char volatile * zpu_pokey_skrest;
+unsigned char volatile * zpu_pokey_serout;
+unsigned char volatile * zpu_pokey_irqen;
+unsigned char volatile * zpu_pokey_skctl;
+
+unsigned char volatile * atari_nmien;
+unsigned char volatile * atari_dlistl;
+unsigned char volatile * atari_dlisth;
+unsigned char volatile * atari_colbk;
+unsigned char volatile * atari_colpf1;
+unsigned char volatile * atari_colpf2;
+unsigned char volatile * atari_colpf3;
+unsigned char volatile * atari_colpf0;
+unsigned char volatile * atari_prior;
+unsigned char volatile * atari_random;
+unsigned char volatile * atari_porta;
+unsigned char volatile * atari_portb;
+unsigned char volatile * atari_trig0;
+unsigned char volatile * atari_chbase;
+unsigned char volatile * atari_chactl;
+unsigned char volatile * atari_dmactl;
+unsigned char volatile * atari_skctl;
+
+void* SRAM_BASE;
+void* SDRAM_BASE;
+void* atari_regbase;
+void* atari_regmirror;
+void* config_regbase;
+
+#define SRAM_SIZE (512*1024)
+#define SDRAM_SIZE (8*1024*1024)
+#define ATARI_SIZE (64*1024)
+#define CONFIG_SIZE (256)
+
+uint8_t sram_memory[SRAM_SIZE];
+uint32_t sdram_memory[SDRAM_SIZE / 4];
+uint8_t atari_memory[ATARI_SIZE];
+uint8_t atari_mirror_memory[ATARI_SIZE];
+uint32_t config_memory[CONFIG_SIZE/4];
+
+void init_memory(void)
+{
+	memset(sram_memory, SRAM_SIZE, 0);
+	memset(sdram_memory, SDRAM_SIZE, 0);
+	memset(atari_memory, ATARI_SIZE, 0);
+	memset(atari_mirror_memory, ATARI_SIZE, 0);
+	memset(config_memory, CONFIG_SIZE, 0);
+
+	SRAM_BASE = sram_memory;
+	SDRAM_BASE = sdram_memory;
+	atari_regbase = atari_memory;
+	atari_regmirror = atari_mirror_memory;
+	config_regbase = config_memory;
+
+	zpu_in1 = (int *)(0*4+config_regbase);
+	zpu_in2 = (int *)(1*4+config_regbase);
+	zpu_in3 = (int *)(2*4+config_regbase);
+	zpu_in4 = (int *)(3*4+config_regbase);
+
+	zpu_out1 = (int *)(4*4+config_regbase);
+	zpu_out2 = (int *)(5*4+config_regbase);
+	zpu_out3 = (int *)(6*4+config_regbase);
+	zpu_out4 = (int *)(7*4+config_regbase);
+
+	zpu_pause = (int *)(8*4+config_regbase);
+
+	zpu_spi_data = (int *)(9*4+config_regbase);
+	zpu_spi_state = (int *)(10*4+config_regbase);
+
+	zpu_sio = (int *)(11*4+config_regbase);
+
+	zpu_board = (int *)(12*4+config_regbase);
+
+	zpu_spi_dma = (int *)(13*4+config_regbase);
+
+	zpu_pokey_audf0 = (unsigned char *)(0x10*4+config_regbase);
+	zpu_pokey_audc0 = (unsigned char *)(0x11*4+config_regbase);
+	zpu_pokey_audf1 = (unsigned char *)(0x12*4+config_regbase);
+	zpu_pokey_audc1 = (unsigned char *)(0x13*4+config_regbase);
+	zpu_pokey_audf2 = (unsigned char *)(0x14*4+config_regbase);
+	zpu_pokey_audc2 = (unsigned char *)(0x15*4+config_regbase);
+	zpu_pokey_audf3 = (unsigned char *)(0x16*4+config_regbase);
+	zpu_pokey_audc3 = (unsigned char *)(0x17*4+config_regbase);
+
+	zpu_pokey_audctl = (unsigned char *)(0x18*4+config_regbase);
+
+	zpu_pokey_skrest = (unsigned char *)(0x1a*4+config_regbase);
+	zpu_pokey_serout = (unsigned char *)(0x1d*4+config_regbase);
+	zpu_pokey_irqen = (unsigned char *)(0x1e*4+config_regbase);
+	zpu_pokey_skctl = (unsigned char *)(0x1f*4+config_regbase);
+
+	atari_nmien = (unsigned char *)(0xd40e + atari_regbase);
+	atari_dlistl = (unsigned char *)(0xd402 + atari_regbase);
+	atari_dlisth = (unsigned char *)(0xd403 + atari_regbase);
+	atari_colbk = (unsigned char *)(0xd01a + atari_regbase);
+	atari_colpf1 = (unsigned char *)(0xd017 + atari_regbase);
+	atari_colpf2 = (unsigned char *)(0xd018 + atari_regbase);
+	atari_colpf3 = (unsigned char *)(0xd019 + atari_regbase);
+	atari_colpf0 = (unsigned char *)(0xd016 + atari_regbase);
+	atari_prior = (unsigned char *)(0xd01b + atari_regbase);
+	atari_random = (unsigned char *)(0xd20a + atari_regbase);
+	atari_porta = (unsigned char *)(0xd300 + atari_regbase);
+	atari_portb = (unsigned char *)(0xd301 + atari_regbase);
+	atari_trig0 = (unsigned char *)(0xd010 + atari_regbase);
+	atari_chbase = (unsigned char *)(0xd409 + atari_regbase);
+	atari_chactl = (unsigned char *)(0xd401 + atari_regbase);
+	atari_dmactl = (unsigned char *)(0xd400 + atari_regbase);
+	atari_skctl = (unsigned char *)(0xd20f + atari_regbase);
+
+	// command line is high
+	*zpu_sio = 1;
+	// no trigger pressed
+	*atari_trig0 = 1;
+}
+
Index: firmware/linux/linux_memory.h
===================================================================
--- firmware/linux/linux_memory.h	(nonexistent)
+++ firmware/linux/linux_memory.h	(revision 183)
@@ -0,0 +1,6 @@
+#ifndef LINUX_MEMORY_H
+#define LINUX_MEMORY_H
+
+void init_memory();
+
+#endif
Index: firmware/linux/main.c
===================================================================
--- firmware/linux/main.c	(nonexistent)
+++ firmware/linux/main.c	(revision 183)
@@ -0,0 +1,30 @@
+#include <stdio.h>
+
+#include "curses_screen.h"
+#include "linux_helper.h"
+#include "linux_memory.h"
+
+int zpu_main(void);
+
+extern char* sdcard_filename;
+
+int main(int argc, char** argv)
+{
+	if (argc > 1) {
+		sdcard_filename = argv[1];
+	}
+
+	if (init_curses_screen()) {
+		return 1;
+	}
+
+	init_memory();
+
+	if (setjmp(exit_jmp_buf) == 0) {
+		print_log("starting zpu_main\n");
+		zpu_main();
+	}
+
+	deinit_curses_screen();
+	return 0;
+}
Index: firmware/linux/memory.h
===================================================================
--- firmware/linux/memory.h	(nonexistent)
+++ firmware/linux/memory.h	(revision 183)
@@ -0,0 +1,25 @@
+#ifndef MEMORY_H
+#define MEMORY_H
+
+extern void* SDRAM_BASE;
+extern void* SRAM_BASE;
+
+// 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 DIR_INIT_MEM (SDRAM_BASE + 0x410000)
+#define DIR_INIT_MEMSIZE 262144
+#define FREEZE_MEM (SDRAM_BASE + 0x450000)
+
+// offset into SDRAM
+#define ROM_OFS 0x700000
+
+extern void* atari_regbase;
+extern void* atari_regmirror;
+extern void* config_regbase;
+
+void init_memory(void);
+
+#endif
Index: firmware/linux/mmc.c
===================================================================
--- firmware/linux/mmc.c	(nonexistent)
+++ firmware/linux/mmc.c	(revision 183)
@@ -0,0 +1,90 @@
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include "mmc.h"
+#include "curses_screen.h"
+#include "linux_helper.h"
+
+#define LOG(x...) print_log(x)
+
+FILE * disk_image = NULL;
+
+char mmc_sector_buffer[512];
+
+void set_spi_clock_freq()
+{
+}
+
+//! Initialize AVR<->MMC hardware interface.
+/// Prepares hardware for MMC access.
+
+void mmcInit(void)
+{
+	if (!sdcard_filename) {
+		LOG("no sdcard\n");
+		return;
+	}
+	disk_image = fopen(sdcard_filename,"r+");
+	if (!disk_image) {
+		LOG("cannot open %s\n", sdcard_filename);
+	} else {
+		LOG("opened sdcard %s\n", sdcard_filename);
+	}
+}
+
+void mmc_init()
+{
+	mmcInit();
+}
+
+
+//! Initialize the card and prepare it for use.
+/// Returns zero if successful.
+u08 mmcReset(void){ return 0;}
+
+//! Read 512-byte sector from card to buffer
+/// Returns zero if successful.
+u08 mmcRead(u32 sector)
+{
+	if (!disk_image) {
+		goto no_data;
+	}
+	//fprintf(stderr,"mmcRead:%x\n",sector);
+
+	if (fseek(disk_image, sector*512, SEEK_SET)) {
+		LOG("seek to sector %d failed\n", sector);
+		goto no_data;
+	}
+	if (fread(&mmc_sector_buffer,512,1,disk_image) != 1) {
+		LOG("reading sector %d failed\n", sector);
+		goto no_data;
+	}
+
+	return 0;
+no_data:
+	memset(&mmc_sector_buffer, 0, 512);
+	return 0;
+}
+
+//! Write 512-byte sector from buffer to card
+/// Returns zero if successful.
+u08 mmcWrite(u32 sector)
+{
+	if (!disk_image) {
+		goto no_data;
+	}
+	//fprintf(stderr,"mmcWrite:%x\n",sector);
+
+	if (fseek(disk_image, sector*512, SEEK_SET)) {
+		LOG("seek to sector %d failed\n", sector);
+		goto no_data;
+	}
+	if (fwrite(&mmc_sector_buffer,512,1,disk_image) != 1) {
+		LOG("reading sector %d failed\n", sector);
+		goto no_data;
+	}
+	return 0;
+no_data:
+	return 0;
+}
+
Index: firmware/main.c
===================================================================
--- firmware/main.c	(revision 182)
+++ firmware/main.c	(revision 183)
@@ -1,3 +1,4 @@
+#include <alloca.h>
 #include <sys/types.h>
 #include "integer.h"
 #include "regs.h"
@@ -10,6 +11,13 @@
 #include "simplefile.h"
 #include "fileselector.h"
 
+#ifdef LINUX_BUILD
+#include "curses_screen.h"
+#define after_set_reg_hook() display_out_regs()
+#else
+#define after_set_reg_hook() do { } while(0)
+#endif
+
 #include "atari_drive_emulator.h"
 #include "memory.h"
 
@@ -48,6 +56,7 @@
 	val |= op(param)<<shift; \
 	 \
 	*reg = val; \
+	after_set_reg_hook(); \
 }
 
 #define BIT_REG_RO(op,mask,shift,name,reg) \
@@ -148,6 +157,19 @@
 int debug_adjust;
 unsigned char volatile * baseaddr;
 
+#ifdef LINUX_BUILD
+void char_out(void* p, char c)
+{
+	// get rid of unused parameter p warning
+	(void)(p);
+	int x, y;
+	x = debug_pos % 40;
+	y = debug_pos / 40;
+	display_char(x, y, c, debug_adjust == 128);
+	debug_pos++;
+}
+
+#else
 void clearscreen()
 {
 	unsigned volatile char * screen;
@@ -164,6 +186,7 @@
 		++debug_pos;
 	}
 }
+#endif
 
 struct SimpleFile * files[6];
 void loadromfile(struct SimpleFile * file, int size, size_t ram_address)
@@ -201,7 +224,11 @@
 	}
 }
 
+#ifdef LINUX_BUILD
+int zpu_main(void)
+#else
 int main(void)
+#endif
 {
 /*	disk_initialize();
 	{
@@ -555,6 +582,9 @@
 
 void actions()
 {
+#ifdef LINUX_BUILD
+	check_keys();
+#endif
 	// Show some activity!
 	//*atari_colbk = *atari_random;
 	
Index: firmware/printf/printf.h
===================================================================
--- firmware/printf/printf.h	(revision 182)
+++ firmware/printf/printf.h	(revision 183)
@@ -115,8 +115,8 @@
 
 void tfp_format(void* putp,void (*putf) (void*,char),char *fmt, va_list va);
 
-#define printf tfp_printf 
-#define sprintf tfp_sprintf 
+#define printf(x...) tfp_printf(x)
+#define sprintf(x...) tfp_sprintf(x)
 
 #endif
 
