Index: emu/cpu.c
===================================================================
--- emu/cpu.c	(revision 51b6cfd9417dce67ba591dd199456b68d1ea6fa6)
+++ emu/cpu.c	(revision ba36b71f48f2275239c71f2460753e61d62e9d3f)
@@ -28,4 +28,6 @@
 #define CYCLES 10
 
+#define VEC_SIZE 0x400
+
 #define RAM_START 0x0
 #define RAM_SIZE 0x100000
@@ -55,13 +57,13 @@
 static uint8_t rom_data[ROM_SIZE];
 
-static uint32_t ram_rd_beg = 0x10000000;
-static uint32_t ram_rd_end = 0x10000000;
-static uint32_t ram_wr_beg = 0x10000000;
-static uint32_t ram_wr_end = 0x10000000;
-
-static uint32_t rom_rd_beg;
-static uint32_t rom_rd_end;
-static uint32_t rom_wr_beg;
-static uint32_t rom_wr_end;
+static uint32_t ram_ro_beg = 0x1234;
+static uint32_t ram_ro_end = 0x1234;
+static uint32_t ram_rw_beg = 0x1234;
+static uint32_t ram_rw_end = 0x1234;
+
+static uint32_t rom_ro_beg;
+static uint32_t rom_ro_end;
+static uint32_t rom_rw_beg;
+static uint32_t rom_rw_end;
 
 static hw_t hw_map[] = {
@@ -91,5 +93,5 @@
 static void hw_init(void)
 {
-	ver("initializing hardware");
+	inf("initializing hardware");
 
 	for (int32_t i = 0; i < ARRAY_COUNT(hw_map); ++i) {
@@ -116,5 +118,5 @@
 static void bios_init(const char *bios)
 {
-	ver("loading BIOS file %s", bios);
+	inf("loading BIOS file %s", bios);
 
 	SDL_RWops *ops = SDL_RWFromFile(bios, "rb");
@@ -142,11 +144,12 @@
 	uint32_t bss_loc = SDL_ReadBE32(ops);
 
-	ver("text 0x%x@0x%x data 0x%x@0x%x bss 0x%x@0x%x",
-			text_len, text_loc, data_len, data_loc, bss_len, bss_loc);
+	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 (load_len != text_len + data_len) {
-		fail("corrupted BIOS file %s", bios);
+	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);
 	}
 
@@ -164,4 +167,12 @@
 
 	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;
+
+	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);
 }
 
@@ -185,12 +196,21 @@
 	ver("mem rd 0x%08x:8", addr);
 
-	if (addr >= ram_rd_beg && addr <= ram_rd_end - 1) {
+	if (addr >= ram_ro_beg && addr <= ram_ro_end - 1) {
 		return ram_data[addr - RAM_START];
 	}
 
-	if (addr >= rom_rd_beg && addr <= rom_rd_end - 1) {
+	if (addr >= ram_rw_beg && addr <= ram_rw_end - 1) {
+		return ram_data[addr - RAM_START];
+	}
+
+	if (addr >= rom_ro_beg && addr <= rom_ro_end - 1) {
 		return rom_data[addr - ROM_START];
 	}
 
+	if (addr >= rom_rw_beg && addr <= rom_rw_end - 1) {
+		// ROM has its BSS section in RAM.
+		return ram_data[addr - RAM_START];
+	}
+
 	hw_t *hw = hw_by_addr(addr);
 
@@ -199,4 +219,8 @@
 	}
 
+	if (addr <= VEC_SIZE - 1) {
+		return ram_data[addr];
+	}
+
 	fail("invalid read 0x%08x:8", addr);
 }
@@ -206,5 +230,5 @@
 	ver("mem rd 0x%08x:16", addr);
 
-	if (addr >= ram_rd_beg && addr <= ram_rd_end - 2) {
+	if (addr >= ram_ro_beg && addr <= ram_ro_end - 2) {
 		return
 				((uint32_t)ram_data[addr - RAM_START + 0] << 8) |
@@ -212,5 +236,11 @@
 	}
 
-	if (addr >= rom_rd_beg && addr <= rom_rd_end - 2) {
+	if (addr >= ram_rw_beg && addr <= ram_rw_end - 2) {
+		return
+				((uint32_t)ram_data[addr - RAM_START + 0] << 8) |
+				((uint32_t)ram_data[addr - RAM_START + 1] << 0);
+	}
+
+	if (addr >= rom_ro_beg && addr <= rom_ro_end - 2) {
 		return
 				((uint32_t)rom_data[addr - ROM_START + 0] << 8) |
@@ -218,8 +248,21 @@
 	}
 
+	if (addr >= rom_rw_beg && addr <= rom_rw_end - 2) {
+		// ROM has its BSS section in RAM.
+		return
+				((uint32_t)ram_data[addr - RAM_START + 0] << 8) |
+				((uint32_t)ram_data[addr - RAM_START + 1] << 0);
+	}
+
 	hw_t *hw = hw_by_addr(addr);
 
 	if (hw != NULL) {
 		return hw->read(hw_off(hw, addr), 2);
+	}
+
+	if (addr <= VEC_SIZE - 2) {
+		return
+				((uint32_t)ram_data[addr - 0] << 8) |
+				((uint32_t)ram_data[addr - 1] << 0);
 	}
 
@@ -245,5 +288,5 @@
 	}
 
-	if (addr >= ram_rd_beg && addr <= ram_rd_end - 4) {
+	if (addr >= ram_ro_beg && addr <= ram_ro_end - 4) {
 		return
 				((uint32_t)ram_data[addr - RAM_START + 0] << 24) |
@@ -253,5 +296,13 @@
 	}
 
-	if (addr >= rom_rd_beg && addr <= rom_rd_end - 4) {
+	if (addr >= ram_rw_beg && addr <= ram_rw_end - 4) {
+		return
+				((uint32_t)ram_data[addr - RAM_START + 0] << 24) |
+				((uint32_t)ram_data[addr - RAM_START + 1] << 16) |
+				((uint32_t)ram_data[addr - RAM_START + 2] <<  8) |
+				((uint32_t)ram_data[addr - RAM_START + 3] <<  0);
+	}
+
+	if (addr >= rom_ro_beg && addr <= rom_ro_end - 4) {
 		return
 				((uint32_t)rom_data[addr - ROM_START + 0] << 24) |
@@ -261,4 +312,13 @@
 	}
 
+	if (addr >= rom_rw_beg && addr <= rom_rw_end - 4) {
+		// ROM has its BSS section in RAM.
+		return
+				((uint32_t)ram_data[addr - RAM_START + 0] << 24) |
+				((uint32_t)ram_data[addr - RAM_START + 1] << 16) |
+				((uint32_t)ram_data[addr - RAM_START + 2] <<  8) |
+				((uint32_t)ram_data[addr - RAM_START + 3] <<  0);
+	}
+
 	hw_t *hw = hw_by_addr(addr);
 
@@ -267,4 +327,12 @@
 	}
 
+	if (addr <= VEC_SIZE - 4) {
+		return
+				((uint32_t)ram_data[addr + 0] << 24) |
+				((uint32_t)ram_data[addr + 1] << 16) |
+				((uint32_t)ram_data[addr + 2] <<  8) |
+				((uint32_t)ram_data[addr + 3] <<  0);
+	}
+
 	fail("invalid read 0x%08x:32", addr);
 }
@@ -274,10 +342,10 @@
 	ver("mem wr 0x%08x:8 0x%02x", addr, val);
 
-	if (addr >= ram_wr_beg && addr <= ram_wr_end - 1) {
+	if (addr >= ram_rw_beg && addr <= ram_rw_end - 1) {
 		ram_data[addr - RAM_START] = (uint8_t)val;
 		return;
 	}
 
-	if (addr >= rom_wr_beg && addr <= rom_wr_end - 1) {
+	if (addr >= rom_rw_beg && addr <= rom_rw_end - 1) {
 		// ROM has its BSS section in RAM.
 		ram_data[addr - RAM_START] = (uint8_t)val;
@@ -292,4 +360,9 @@
 	}
 
+	if (addr <= VEC_SIZE - 1) {
+		ram_data[addr] = (uint8_t)val;
+		return;
+	}
+
 	fail("invalid write 0x%08x:8 0x%02x", addr, val);
 }
@@ -299,5 +372,5 @@
 	ver("mem wr 0x%08x:16 0x%04x", addr, val);
 
-	if (addr >= ram_wr_beg && addr <= ram_wr_end - 2) {
+	if (addr >= ram_rw_beg && addr <= ram_rw_end - 2) {
 		ram_data[addr - RAM_START + 0] = (uint8_t)(val >> 8);
 		ram_data[addr - RAM_START + 1] = (uint8_t)(val >> 0);
@@ -305,5 +378,5 @@
 	}
 
-	if (addr >= rom_wr_beg && addr <= rom_wr_end - 2) {
+	if (addr >= rom_rw_beg && addr <= rom_rw_end - 2) {
 		// ROM has its BSS section in RAM.
 		ram_data[addr - RAM_START + 0] = (uint8_t)(val >> 8);
@@ -319,4 +392,10 @@
 	}
 
+	if (addr <= VEC_SIZE - 2) {
+		ram_data[addr + 0] = (uint8_t)(val >> 8);
+		ram_data[addr + 1] = (uint8_t)(val >> 0);
+		return;
+	}
+
 	fail("invalid write 0x%08x:16 0x%04x", addr, val);
 }
@@ -326,5 +405,5 @@
 	ver("mem wr 0x%08x:32 0x%08x", addr, val);
 
-	if (addr >= ram_wr_beg && addr <= ram_wr_end - 4) {
+	if (addr >= ram_rw_beg && addr <= ram_rw_end - 4) {
 		ram_data[addr - RAM_START + 0] = (uint8_t)(val >> 24);
 		ram_data[addr - RAM_START + 1] = (uint8_t)(val >> 16);
@@ -334,5 +413,5 @@
 	}
 
-	if (addr >= rom_wr_beg && addr <= rom_wr_end - 4) {
+	if (addr >= rom_rw_beg && addr <= rom_rw_end - 4) {
 		// ROM has its BSS section in RAM.
 		ram_data[addr - RAM_START + 0] = (uint8_t)(val >> 24);
@@ -350,4 +429,12 @@
 	}
 
+	if (addr <= VEC_SIZE - 4) {
+		ram_data[addr + 0] = (uint8_t)(val >> 24);
+		ram_data[addr + 1] = (uint8_t)(val >> 16);
+		ram_data[addr + 2] = (uint8_t)(val >>  8);
+		ram_data[addr + 3] = (uint8_t)(val >>  0);
+		return;
+	}
+
 	fail("invalid write 0x%08x:32 0x%08x", addr, val);
 }
@@ -355,10 +442,8 @@
 void cpu_loop(const char *bios)
 {
-	ver("entering CPU loop");
-
 	hw_init();
 	bios_init(bios);
 
-	ver("starting CPU");
+	inf("entering CPU loop");
 	m68k_init();
 	m68k_set_cpu_type(M68K_CPU_TYPE_68000);
