Replace common segment/offset pairs with struct segoff_s.

Introduce 'struct segoff_s' to more places.
diff --git a/TODO b/TODO
index b7f6b61..760360a 100644
--- a/TODO
+++ b/TODO
@@ -16,8 +16,6 @@
     -- lots of mouse changes, logo, scsi/etherboot hooks, int 1589,
        floppy data rate?, int19 calls post
 
-Possibly introduce a data type for the many seg/off pairs.
-
 Audit all sti/cli calls.  Audit all call16 calls to make sure flags is
 setup properly with respect to irqs.
 
diff --git a/src/asm-offsets.c b/src/asm-offsets.c
index c324151..5035cef 100644
--- a/src/asm-offsets.c
+++ b/src/asm-offsets.c
@@ -20,7 +20,7 @@
     OFFSET(BREGS_esi, bregs, esi);
     OFFSET(BREGS_edi, bregs, edi);
     OFFSET(BREGS_flags, bregs, flags);
-    OFFSET(BREGS_ip, bregs, ip);
+    OFFSET(BREGS_code, bregs, code);
 
     COMMENT("BDA");
     OFFSET(BDA_ebda_seg, bios_data_area_s, ebda_seg);
diff --git a/src/biosvar.h b/src/biosvar.h
index b200645..d6a7a15 100644
--- a/src/biosvar.h
+++ b/src/biosvar.h
@@ -11,17 +11,6 @@
 #include "config.h" // CONFIG_*
 #include "disk.h" // struct chs_s
 
-struct segoff_s {
-    union {
-        struct {
-            u16 offset;
-            u16 seg;
-        };
-        u32 segoff;
-    };
-};
-#define SEGOFF(s,o) ({struct segoff_s __so; __so.offset=(o); __so.seg=(s); __so;})
-
 
 /****************************************************************
  * Interupt vector table
@@ -33,8 +22,8 @@
 
 #define GET_IVT(vector)                                         \
     GET_FARVAR(SEG_IVT, ((struct rmode_IVT *)0)->ivec[vector])
-#define SET_IVT(vector, seg, off)                                       \
-    SET_FARVAR(SEG_IVT, ((struct rmode_IVT *)0)->ivec[vector].segoff, ((seg) << 16) | (off))
+#define SET_IVT(vector, segoff)                                         \
+    SET_FARVAR(SEG_IVT, ((struct rmode_IVT *)0)->ivec[vector], segoff)
 
 
 /****************************************************************
@@ -77,8 +66,7 @@
     u16 crtc_address;
     u8 video_msr;
     u8 video_pal;
-    u16 jump_ip;
-    u16 jump_cs;
+    struct segoff_s jump;
     u8 other_6b;
     u32 timer_counter;
     // 40:70
@@ -110,13 +98,12 @@
     u8 floppy_track[2];
     u8 kbd_mode;
     u8 kbd_led;
-    u32 ptr_user_wait_complete_flag;
+    struct segoff_s user_wait_complete_flag;
     u32 user_wait_timeout;
     // 40:A0
     u8 rtc_wait_flag;
     u8 other_a1[7];
-    u16 video_savetable_ptr;
-    u16 video_savetable_seg;
+    struct segoff_s video_savetable;
     u8 other_ac[4];
     // 40:B0
     u8 other_b0[10];
@@ -204,7 +191,7 @@
 struct extended_bios_data_area_s {
     u8 size;
     u8 reserved1[0x21];
-    u32 far_call_pointer;
+    struct segoff_s far_call_pointer;
     u8 mouse_flag1;
     u8 mouse_flag2;
     u8 mouse_data[0x08];
diff --git a/src/block.c b/src/block.c
index c96daaf..3550dcd 100644
--- a/src/block.c
+++ b/src/block.c
@@ -163,11 +163,11 @@
     fdpt->checksum -= checksum(fdpt, sizeof(*fdpt));
 
     if (driveid == 0)
-        SET_IVT(0x41, get_ebda_seg()
-                , offsetof(struct extended_bios_data_area_s, fdpt[0]));
+        SET_IVT(0x41, SEGOFF(get_ebda_seg(), offsetof(
+                                 struct extended_bios_data_area_s, fdpt[0])));
     else
-        SET_IVT(0x46, get_ebda_seg()
-                , offsetof(struct extended_bios_data_area_s, fdpt[1]));
+        SET_IVT(0x46, SEGOFF(get_ebda_seg(), offsetof(
+                                 struct extended_bios_data_area_s, fdpt[1])));
 }
 
 // Map a drive (that was registered via add_bcv_hd)
diff --git a/src/boot.c b/src/boot.c
index 9a08d26..af2a893 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -323,8 +323,7 @@
 
     struct bregs br;
     memset(&br, 0, sizeof(br));
-    br.ip = bootip;
-    br.cs = bootseg;
+    br.code = SEGOFF(bootseg, bootip);
     // Set the magic number in ax and the boot drive in dl.
     br.dl = bootdrv;
     br.ax = 0xaa55;
diff --git a/src/bregs.h b/src/bregs.h
index e59a7f4..3042ab2 100644
--- a/src/bregs.h
+++ b/src/bregs.h
@@ -21,6 +21,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include "farptr.h" // struct segoff_s
+
 /****************************************************************
  * Registers saved/restored in romlayout.S
  ****************************************************************/
@@ -42,8 +44,7 @@
     UREG(edx, dx, dh, dl);
     UREG(ecx, cx, ch, cl);
     UREG(eax, ax, ah, al);
-    u16 ip;
-    u16 cs;
+    struct segoff_s code;
     u16 flags;
 } PACKED;
 
diff --git a/src/clock.c b/src/clock.c
index c95f0a1..9009d49 100644
--- a/src/clock.c
+++ b/src/clock.c
@@ -454,7 +454,7 @@
 
     // Interval not already set.
     SET_BDA(rtc_wait_flag, RWS_WAIT_PENDING);  // Set status byte.
-    SET_BDA(ptr_user_wait_complete_flag, (seg << 16) | offset);
+    SET_BDA(user_wait_complete_flag, SEGOFF(seg, offset));
     SET_BDA(user_wait_timeout, usecs);
 
     // Turn on the Periodic Interrupt timer
@@ -561,11 +561,11 @@
     u32 time = GET_BDA(user_wait_timeout);  // Time left in microseconds.
     if (time < 0x3D1) {
         // Done waiting - write to specified flag byte.
-        u32 segoff = GET_BDA(ptr_user_wait_complete_flag);
-        u16 segment = segoff >> 16;
-        u16 offset = segoff & 0xffff;
-        u8 oldval = GET_FARVAR(segment, *(u8*)(offset+0));
-        SET_FARVAR(segment, *(u8*)(offset+0), oldval | 0x80);
+        struct segoff_s segoff = GET_BDA(user_wait_complete_flag);
+        u16 ptr_seg = segoff.seg;
+        u8 *ptr_far = (u8*)(segoff.offset+0);
+        u8 oldval = GET_FARVAR(ptr_seg, *ptr_far);
+        SET_FARVAR(ptr_seg, *ptr_far, oldval | 0x80);
 
         clear_usertimer();
     } else {
diff --git a/src/disk.c b/src/disk.c
index 014701a..b021c40 100644
--- a/src/disk.c
+++ b/src/disk.c
@@ -180,9 +180,7 @@
         return;
     }
 
-    u16 segment = GET_INT13EXT(regs, segment);
-    u16 offset = GET_INT13EXT(regs, offset);
-    dop.buf_fl = MAKE_FLATPTR(segment, offset);
+    dop.buf_fl = SEGOFF_TO_FLATPTR(GET_INT13EXT(regs, data));
     dop.count = GET_INT13EXT(regs, count);
 
     int status = send_disk_op(&dop);
diff --git a/src/disk.h b/src/disk.h
index 96bc509..36941b7 100644
--- a/src/disk.h
+++ b/src/disk.h
@@ -8,6 +8,7 @@
 
 #include "types.h" // u8
 #include "config.h" // CONFIG_*
+#include "farptr.h" // struct segoff_s
 
 #define DISK_RET_SUCCESS       0x00
 #define DISK_RET_EPARAM        0x01
@@ -35,8 +36,7 @@
     u8  size;
     u8  reserved;
     u16 count;
-    u16 offset;
-    u16 segment;
+    struct segoff_s data;
     u64 lba;
 } PACKED;
 
diff --git a/src/farptr.h b/src/farptr.h
index 1f3df9d..acc9d59 100644
--- a/src/farptr.h
+++ b/src/farptr.h
@@ -190,4 +190,23 @@
 
 #endif
 
+// Definition for common 16bit segment/offset pointers.
+struct segoff_s {
+    union {
+        struct {
+            u16 offset;
+            u16 seg;
+        };
+        u32 segoff;
+    };
+};
+#define SEGOFF(s,o) ({struct segoff_s __so; __so.offset=(o); __so.seg=(s); __so;})
+
+static inline struct segoff_s FLATPTR_TO_SEGOFF(void *p) {
+    return SEGOFF(FLATPTR_TO_SEG(p), FLATPTR_TO_OFFSET(p));
+}
+static inline void *SEGOFF_TO_FLATPTR(struct segoff_s so) {
+    return MAKE_FLATPTR(so.seg, so.offset);
+}
+
 #endif // farptr.h
diff --git a/src/mouse.c b/src/mouse.c
index e6abbb9..e7ec0c1 100644
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -235,10 +235,10 @@
 static void
 mouse_15c207(struct bregs *regs)
 {
-    u32 farptr = (regs->es << 16) | regs->bx;
+    struct segoff_s farptr = SEGOFF(regs->es, regs->bx);
     u16 ebda_seg = get_ebda_seg();
     u8 mouse_flags_2 = GET_EBDA2(ebda_seg, mouse_flag2);
-    if (! farptr) {
+    if (! farptr.segoff) {
         /* remove handler */
         if ((mouse_flags_2 & 0x80) != 0) {
             mouse_flags_2 &= ~0x80;
@@ -311,7 +311,7 @@
     u16 Y      = GET_EBDA2(ebda_seg, mouse_data[2]);
     SET_EBDA2(ebda_seg, mouse_flag1, 0);
 
-    u32 func = GET_EBDA2(ebda_seg, far_call_pointer);
+    struct segoff_s func = GET_EBDA2(ebda_seg, far_call_pointer);
 
     asm volatile(
         "sti\n"
@@ -327,7 +327,7 @@
         "cli\n"
         "cld\n"
         :
-        : "r"(func), "r"(status), "r"(X), "r"(Y)
+        : "r"(func.segoff), "r"(status), "r"(X), "r"(Y)
         : "cc"
         );
 }
diff --git a/src/optionroms.c b/src/optionroms.c
index 0a5d85c..cd8f9d1 100644
--- a/src/optionroms.c
+++ b/src/optionroms.c
@@ -92,8 +92,7 @@
     br.dx = 0xffff;
     br.es = SEG_BIOS;
     br.di = get_pnp_offset();
-    br.cs = seg;
-    br.ip = offset;
+    br.code = SEGOFF(seg, offset);
     call16big(&br);
 
     debug_serial_setup();
diff --git a/src/output.c b/src/output.c
index 1cd0b8c..6a164e1 100644
--- a/src/output.c
+++ b/src/output.c
@@ -327,7 +327,7 @@
             , regs->ds, regs->es, GET_SEG(SS));
     dprintf(1, "  si=%08x di=%08x bp=%08x sp=%08x cs=%04x ip=%04x  f=%04x\n"
             , regs->esi, regs->edi, regs->ebp, (u32)&regs[1]
-            , regs->cs, regs->ip, regs->flags);
+            , regs->code.seg, regs->code.offset, regs->flags);
 }
 
 // Report entry to an Interrupt Service Routine (ISR).
diff --git a/src/post.c b/src/post.c
index 69aeb93..7edd1f6 100644
--- a/src/post.c
+++ b/src/post.c
@@ -23,7 +23,7 @@
 void
 __set_irq(int vector, void *loc)
 {
-    SET_IVT(vector, SEG_BIOS, (u32)loc - BUILD_BIOS_ADDR);
+    SET_IVT(vector, SEGOFF(SEG_BIOS, (u32)loc - BUILD_BIOS_ADDR));
 }
 
 #define set_irq(vector, func) do {              \
@@ -64,7 +64,7 @@
 
     // set vector 0x79 to zero
     // this is used by 'gardian angel' protection system
-    SET_IVT(0x79, 0, 0);
+    SET_IVT(0x79, SEGOFF(0, 0));
 
     __set_irq(0x1E, &diskette_param_table2);
 }
diff --git a/src/resume.c b/src/resume.c
index cfe26cd..097bb6f 100644
--- a/src/resume.c
+++ b/src/resume.c
@@ -60,12 +60,12 @@
         eoi_pic2();
         // NO BREAK
     case 0x0a:
-#define BDA_JUMP_IP (((struct bios_data_area_s *)0)->jump_ip)
+#define BDA_JUMP (((struct bios_data_area_s *)0)->jump)
         // resume execution by jump via 40h:0067h
         asm volatile(
             "movw %w1, %%ds\n"
             "ljmpw *%0\n"
-            : : "m"(BDA_JUMP_IP), "r"(SEG_BDA)
+            : : "m"(BDA_JUMP), "r"(SEG_BDA)
             );
         break;
 
@@ -75,7 +75,7 @@
             "movw %w1, %%ds\n"
             "lssw %0, %%sp\n"
             "iretw\n"
-            : : "m"(BDA_JUMP_IP), "r"(SEG_BDA)
+            : : "m"(BDA_JUMP), "r"(SEG_BDA)
             );
         break;
 
@@ -85,7 +85,7 @@
             "movw %w1, %%ds\n"
             "lssw %0, %%sp\n"
             "lretw\n"
-            : : "m"(BDA_JUMP_IP), "r"(SEG_BDA)
+            : : "m"(BDA_JUMP), "r"(SEG_BDA)
             );
         break;
     }
@@ -115,13 +115,11 @@
     memset(&br, 0, sizeof(br));
     if (s3_resume_vector) {
         dprintf(1, "Jump to resume vector (%x)\n", s3_resume_vector);
-        br.ip = FLATPTR_TO_OFFSET(s3_resume_vector);
-        br.cs = FLATPTR_TO_SEG(s3_resume_vector);
+        br.code = FLATPTR_TO_SEGOFF((void*)s3_resume_vector);
     } else {
         dprintf(1, "No resume vector set!\n");
         // Jump to the post vector to restart with a normal boot.
-        br.ip = (u32)reset_vector - BUILD_BIOS_ADDR;
-        br.cs = SEG_BIOS;
+        br.code = SEGOFF(SEG_BIOS, (u32)reset_vector - BUILD_BIOS_ADDR);
     }
     call16big(&br);
 }
diff --git a/src/romlayout.S b/src/romlayout.S
index d430d28..1bbdd9c 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -152,7 +152,7 @@
         pushw %cs
         pushw $1f               // return point
         pushw BREGS_flags(%eax) // flags
-        pushl BREGS_ip(%eax)    // CS:IP
+        pushl BREGS_code(%eax)  // CS:IP
 
         // Load calling registers.
         movl BREGS_edi(%eax), %edi
diff --git a/src/util.c b/src/util.c
index 283ec08..841c00a 100644
--- a/src/util.c
+++ b/src/util.c
@@ -42,10 +42,10 @@
 __call16_int(struct bregs *callregs, u16 offset)
 {
     if (MODE16)
-        callregs->cs = GET_SEG(CS);
+        callregs->code.seg = GET_SEG(CS);
     else
-        callregs->cs = SEG_BIOS;
-    callregs->ip = offset;
+        callregs->code.seg = SEG_BIOS;
+    callregs->code.offset = offset;
     call16(callregs);
 }
 
diff --git a/vgasrc/vga.c b/vgasrc/vga.c
index 88cbb01..6d06cd6 100644
--- a/vgasrc/vga.c
+++ b/vgasrc/vga.c
@@ -312,8 +312,8 @@
     SET_FARVAR(seg, info->video_pagestart, GET_BDA(video_pagestart));
     SET_FARVAR(seg, info->video_page, GET_BDA(video_page));
     /* current font */
-    SET_FARVAR(seg, *(u32*)&info->font0_off, GET_IVT(0x1f).segoff);
-    SET_FARVAR(seg, *(u32*)&info->font1_off, GET_IVT(0x43).segoff);
+    SET_FARVAR(seg, info->font0, GET_IVT(0x1f));
+    SET_FARVAR(seg, info->font1, GET_IVT(0x43));
 }
 
 static void
@@ -335,10 +335,8 @@
     SET_BDA(video_pagestart, GET_FARVAR(seg, info->video_pagestart));
     SET_BDA(video_page, GET_FARVAR(seg, info->video_page));
     /* current font */
-    SET_IVT(0x1f, GET_FARVAR(seg, info->font0_seg)
-            , GET_FARVAR(seg, info->font0_off));
-    SET_IVT(0x43, GET_FARVAR(seg, info->font1_seg)
-            , GET_FARVAR(seg, info->font1_off));
+    SET_IVT(0x1f, GET_FARVAR(seg, info->font0));
+    SET_IVT(0x43, GET_FARVAR(seg, info->font1));
 }
 
 
@@ -425,8 +423,8 @@
 
     // FIXME We nearly have the good tables. to be reworked
     SET_BDA(dcc_index, 0x08);   // 8 is VGA should be ok for now
-    SET_BDA(video_savetable_ptr, (u32)video_save_pointer_table);
-    SET_BDA(video_savetable_seg, get_global_seg());
+    SET_BDA(video_savetable
+            , SEGOFF(get_global_seg(), (u32)video_save_pointer_table));
 
     // FIXME
     SET_BDA(video_msr, 0x00); // Unavailable on vanilla vga, but...
@@ -451,17 +449,17 @@
         call16_vgaint(0x1103, 0);
     }
     // Set the ints 0x1F and 0x43
-    SET_IVT(0x1f, get_global_seg(), (u32)&vgafont8[128 * 8]);
+    SET_IVT(0x1f, SEGOFF(get_global_seg(), (u32)&vgafont8[128 * 8]));
 
     switch (cheight) {
     case 8:
-        SET_IVT(0x43, get_global_seg(), (u32)vgafont8);
+        SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont8));
         break;
     case 14:
-        SET_IVT(0x43, get_global_seg(), (u32)vgafont14);
+        SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont14));
         break;
     case 16:
-        SET_IVT(0x43, get_global_seg(), (u32)vgafont16);
+        SET_IVT(0x43, SEGOFF(get_global_seg(), (u32)vgafont16));
         break;
     }
 }
@@ -1103,8 +1101,10 @@
     SET_FARVAR(seg, info->static_functionality_seg, get_global_seg());
 
     // Hard coded copy from BIOS area. Should it be cleaner ?
-    memcpy_far(seg, info->bda_0x49, SEG_BDA, (void*)0x49, 30);
-    memcpy_far(seg, info->bda_0x84, SEG_BDA, (void*)0x84, 3);
+    memcpy_far(seg, info->bda_0x49, SEG_BDA, (void*)0x49
+               , sizeof(info->bda_0x49));
+    memcpy_far(seg, info->bda_0x84, SEG_BDA, (void*)0x84
+               , sizeof(info->bda_0x84));
 
     SET_FARVAR(seg, info->dcc_index, GET_BDA(dcc_index));
     SET_FARVAR(seg, info->colors, 16);
@@ -1368,7 +1368,7 @@
         vbe_init();
 
     extern void entry_10(void);
-    SET_IVT(0x10, get_global_seg(), (u32)entry_10);
+    SET_IVT(0x10, SEGOFF(get_global_seg(), (u32)entry_10));
 
     if (CONFIG_CIRRUS)
         cirrus_init();
diff --git a/vgasrc/vgatables.h b/vgasrc/vgatables.h
index 87b8043..e5f3309 100644
--- a/vgasrc/vgatables.h
+++ b/vgasrc/vgatables.h
@@ -2,6 +2,7 @@
 #define __VGATABLES_H
 
 #include "types.h" // u8
+#include "farptr.h" // struct segoff_s
 
 /*
  *
@@ -123,10 +124,8 @@
     u16 video_pagestart;
     u8 video_page;
     /* current font */
-    u16 font0_off;
-    u16 font0_seg;
-    u16 font1_off;
-    u16 font1_seg;
+    struct segoff_s font0;
+    struct segoff_s font1;
 };
 
 struct saveDACcolors {