Index: emu/cpu.c
===================================================================
--- emu/cpu.c	(revision 67fecc358073769f00f225ecdf43fd63be6167c7)
+++ emu/cpu.c	(revision 0d83ce850449ee30f8f5afb8971700ed04346d97)
@@ -24,4 +24,6 @@
 int32_t cpu_verbose = 0;
 
+#define MIDAS_ABS "midas.abs"
+
 #define CPU_FREQ 7000000
 #define PER_SEC 100000
@@ -51,4 +53,15 @@
 	hw_write_t write;
 } hw_t;
+
+typedef struct {
+	uint32_t text_loc;
+	uint32_t text_len;
+	uint32_t data_loc;
+	uint32_t data_len;
+	uint32_t bss_loc;
+	uint32_t bss_len;
+	size_t load_len;
+	SDL_RWops *ops;
+} abs_t;
 
 static uint64_t freq;
@@ -136,63 +149,103 @@
 }
 
+static void open_abs(const char *path, abs_t *abs)
+{
+	abs->ops = SDL_RWFromFile(path, "rb");
+
+	if (abs->ops == NULL) {
+		fail("error while opening .abs file %s", path);
+	}
+
+	if (SDL_ReadBE16(abs->ops) != 0x601b) {
+		fail("invalid .abs file %s", path);
+	}
+
+	abs->text_len = SDL_ReadBE32(abs->ops);
+	abs->data_len = SDL_ReadBE32(abs->ops);
+	abs->bss_len = SDL_ReadBE32(abs->ops);
+
+	SDL_ReadBE32(abs->ops);
+	SDL_ReadBE32(abs->ops);
+
+	abs->text_loc = SDL_ReadBE32(abs->ops);
+
+	SDL_ReadBE16(abs->ops);
+
+	abs->data_loc = SDL_ReadBE32(abs->ops);
+	abs->bss_loc = SDL_ReadBE32(abs->ops);
+
+	inf("text 0x%x:0x%x data 0x%x:0x%x bss 0x%x:0x%x",
+			abs->text_loc, abs->text_len, abs->data_loc, abs->data_len, abs->bss_loc, abs->bss_len);
+
+	abs->load_len = (size_t)SDL_RWsize(abs->ops) - 36;
+}
+
+static void load_abs(const char *path, abs_t *abs, uint8_t *data)
+{
+	size_t loaded = 0;
+
+	while (loaded < abs->load_len) {
+		size_t n_rd = SDL_RWread(abs->ops, data + loaded, 1, abs->load_len - loaded);
+
+		if (n_rd == 0) {
+			fail("error while reading .abs file %s", path);
+		}
+
+		loaded += n_rd;
+	}
+
+	SDL_RWclose(abs->ops);
+}
+
 static void bios_init(void)
 {
 	inf("loading BIOS file %s", bios);
 
-	SDL_RWops *ops = SDL_RWFromFile(bios, "rb");
-
-	if (ops == NULL) {
-		fail("error while opening BIOS file %s", bios);
-	}
-
-	if (SDL_ReadBE16(ops) != 0x601b) {
+	abs_t abs;
+	open_abs(bios, &abs);
+
+	if (abs.text_loc != ROM_START || abs.text_loc + abs.text_len != abs.data_loc ||
+			abs.load_len != abs.text_len + abs.data_len || abs.load_len > ROM_SIZE) {
 		fail("invalid BIOS file %s", bios);
 	}
 
-	uint32_t text_len = SDL_ReadBE32(ops);
-	uint32_t data_len = SDL_ReadBE32(ops);
-	uint32_t bss_len = SDL_ReadBE32(ops);
-
-	SDL_ReadBE32(ops);
-	SDL_ReadBE32(ops);
-
-	uint32_t text_loc = SDL_ReadBE32(ops);
-
-	SDL_ReadBE16(ops);
-
-	uint32_t data_loc = SDL_ReadBE32(ops);
-	uint32_t bss_loc = SDL_ReadBE32(ops);
-
-	inf("BIOS text 0x%x:0x%x data 0x%x:0x%x bss 0x%x:0x%x",
-			text_loc, text_len, data_loc, data_len, bss_loc, bss_len);
-
-	size_t load_len = (size_t)SDL_RWsize(ops) - 36;
-
-	if (text_loc != ROM_START || text_loc + text_len != data_loc ||
-			load_len != text_len + data_len || load_len > ROM_SIZE) {
-		fail("invalid BIOS file %s", bios);
-	}
-
-	size_t loaded = 0;
-
-	while (loaded < load_len) {
-		size_t n_rd = SDL_RWread(ops, rom_data + loaded, 1, load_len - loaded);
-
-		if (n_rd == 0) {
-			fail("error while reading BIOS file %s", bios);
-		}
-
-		loaded += n_rd;
-	}
-
-	SDL_RWclose(ops);
-
-	rom_ro_beg = text_loc;
-	rom_ro_end = text_loc + text_len + data_len;
-	rom_rw_beg = bss_loc;
-	rom_rw_end = bss_loc + bss_len;
+	load_abs(bios, &abs, rom_data);
+
+	rom_ro_beg = abs.text_loc;
+	rom_ro_end = abs.text_loc + abs.text_len + abs.data_len;
+	rom_rw_beg = abs.bss_loc;
+	rom_rw_end = abs.bss_loc + abs.bss_len;
 
 	ver("rom_ro_beg 0x%08x rom_ro_end 0x%08x", rom_ro_beg, rom_ro_end);
 	ver("rom_rw_beg 0x%08x rom_rw_end 0x%08x", rom_rw_beg, rom_rw_end);
+}
+
+static void midas_init(void)
+{
+	SDL_RWops *ops = SDL_RWFromFile(MIDAS_ABS, "rb");
+
+	if (ops == NULL) {
+		return;
+	}
+
+	SDL_RWclose(ops);
+
+	inf("loading MIDAS file " MIDAS_ABS);
+
+	abs_t abs;
+	open_abs(MIDAS_ABS, &abs);
+
+	if (abs.text_loc != APP_START ||
+			abs.text_loc + abs.text_len != abs.data_loc ||
+			abs.data_loc + abs.data_len != abs.bss_loc ||
+			abs.load_len != abs.text_len + abs.data_len ||
+			abs.bss_loc + abs.bss_len > RAM_SIZE) {
+		fail("invalid MIDAS file " MIDAS_ABS);
+	}
+
+	load_abs(MIDAS_ABS, &abs, ram_data + APP_START - RAM_START);
+
+	ram_ro_beg = ram_rw_beg = APP_START;
+	ram_ro_end = ram_rw_end = RAM_START + RAM_SIZE;
 }
 
@@ -666,4 +719,5 @@
 	hw_init();
 	bios_init();
+	midas_init();
 
 	m68k_init();
