Update e820 map in place instead of copying it.

Allocate the e820 map space in the 0xf0000 segment and do all updates
    in place.  This reduces the need to access external memory during
    post.
Also, move e820 pointer and count from ebda to variables in 0xf0000.
diff --git a/src/biosvar.h b/src/biosvar.h
index 7ea038f..6dfcbc7 100644
--- a/src/biosvar.h
+++ b/src/biosvar.h
@@ -275,8 +275,6 @@
     // Physical memory available.
     u32 ram_size;        // Amount of continuous ram under 4Gig
     u64 ram_size_over4G; // Amount of continuous ram >4Gig
-    u16 e820_count;
-    u32 e820_loc;
     u32 pir_loc;
 
     // ATA Driver data
diff --git a/src/config.h b/src/config.h
index fa7ae9e..39a796d 100644
--- a/src/config.h
+++ b/src/config.h
@@ -64,6 +64,8 @@
 #define CONFIG_ACPI 1
 // Support bios callbacks specific to via vgabios.
 #define CONFIG_VGAHOOKS 1
+// Maximum number of map entries in the e820 map
+#define CONFIG_MAX_E820 32
 
 /* define it if the (emulated) hardware supports SMM mode */
 #define CONFIG_USE_SMM 1
diff --git a/src/memmap.c b/src/memmap.c
index e02745f..f74f4f2 100644
--- a/src/memmap.c
+++ b/src/memmap.c
@@ -8,10 +8,6 @@
 #include "util.h" // dprintf.h
 #include "biosvar.h" // SET_EBDA
 
-// Temporary storage used during map building.
-static struct e820entry e820_list[64];
-static int e820_count;
-
 // Remove an entry from the e820_list.
 static void
 remove_e820(int i)
@@ -25,7 +21,7 @@
 static void
 insert_e820(int i, u64 start, u64 size, u32 type)
 {
-    if (e820_count >= ARRAY_SIZE(e820_list)) {
+    if (e820_count >= CONFIG_MAX_E820) {
         dprintf(1, "Overflowed e820 list!\n");
         return;
     }
@@ -139,6 +135,15 @@
     bios_table_end_addr = (u32)&freespace2_end;
     dprintf(1, "bios_table_addr: 0x%08x end=0x%08x\n",
             bios_table_cur_addr, bios_table_end_addr);
+
+    bios_table_cur_addr = ALIGN(bios_table_cur_addr, 4);
+    u32 msize = CONFIG_MAX_E820 * sizeof(e820_list[0]);
+    if (bios_table_cur_addr + msize > bios_table_end_addr) {
+        dprintf(1, "No room for e820 map!\n");
+        return;
+    }
+    e820_list = (void*)bios_table_cur_addr;
+    bios_table_cur_addr += msize;
 }
 
 // Copy the temporary e820 map info to its permanent location.
@@ -147,16 +152,6 @@
 {
     dump_map();
 
-    u32 msize = e820_count * sizeof(e820_list[0]);
-    if (bios_table_cur_addr + msize > bios_table_end_addr) {
-        dprintf(1, "No room for e820 map!\n");
-        return;
-    }
-    memcpy((void*)bios_table_cur_addr, e820_list, msize);
-    SET_EBDA(e820_loc, bios_table_cur_addr);
-    SET_EBDA(e820_count, e820_count);
-    bios_table_cur_addr += msize;
-
     dprintf(1, "final bios_table_addr: 0x%08x (used %d%%)\n"
             , bios_table_cur_addr
             , (100 * (bios_table_cur_addr - (u32)&freespace2_start)
diff --git a/src/memmap.h b/src/memmap.h
index b5e1d0d..8a6bd79 100644
--- a/src/memmap.h
+++ b/src/memmap.h
@@ -20,6 +20,10 @@
 void memmap_setup();
 void memmap_finalize();
 
+// e820 map storage (defined in system.c)
+extern struct e820entry *e820_list;
+extern int e820_count;
+
 // Space for exported bios tables.
 extern u32 bios_table_cur_addr, bios_table_end_addr;
 
diff --git a/src/system.c b/src/system.c
index 04cd6ac..f4e4263 100644
--- a/src/system.c
+++ b/src/system.c
@@ -266,23 +266,29 @@
     set_success(regs);
 }
 
+#if MODE16
+// Info on e820 map location and size.
+struct e820entry *e820_list VISIBLE16;
+int e820_count VISIBLE16;
+#endif
+
 static void
 handle_15e820(struct bregs *regs)
 {
-    int count = GET_EBDA(e820_count);
+    int count = GET_VAR(CS, e820_count);
     if (regs->edx != 0x534D4150 || regs->bx >= count) {
         set_code_fail(regs, RET_EUNSUPPORTED);
         return;
     }
 
-    struct e820entry *e = &((struct e820entry *)GET_EBDA(e820_loc))[regs->bx];
-    memcpy_far(MAKE_FARPTR(regs->es, regs->di), e, sizeof(*e));
+    struct e820entry *l = GET_VAR(CS, e820_list);
+    memcpy_far(MAKE_FARPTR(regs->es, regs->di), &l[regs->bx], sizeof(l[0]));
     if (regs->bx == count-1)
         regs->ebx = 0;
     else
         regs->ebx++;
     regs->eax = 0x534D4150;
-    regs->ecx = sizeof(*e);
+    regs->ecx = sizeof(l[0]);
     set_success(regs);
 }