diff --git a/LEGO1/mxioinfo.cpp b/LEGO1/mxioinfo.cpp
index 2d55ef36..c834f33d 100644
--- a/LEGO1/mxioinfo.cpp
+++ b/LEGO1/mxioinfo.cpp
@@ -1,9 +1,15 @@
 #include "mxioinfo.h"
+#include "decomp.h"
+
+// This class should be 72 bytes in size, same as the MMIOINFO struct.
+// The current implementation has MMIOINFO as the only member of the class,
+// but this assert will enforce the size if we decide to change that.
+DECOMP_SIZE_ASSERT(MXIOINFO, sizeof(MMIOINFO));
 
 // OFFSET: LEGO1 0x100cc800
 MXIOINFO::MXIOINFO()
 {
-  memset(&m_info, 0, sizeof(MMIOINFO));
+  memset(&m_info, 0, sizeof(m_info));
 }
 
 // OFFSET: LEGO1 0x100cc820
@@ -13,37 +19,427 @@ MXIOINFO::~MXIOINFO()
 }
 
 // OFFSET: LEGO1 0x100cc830
-MxU16 MXIOINFO::Open(const char *filename, DWORD fdwOpen)
+MxU16 MXIOINFO::Open(const char *p_filename, MxULong p_flags)
 {
-  return 0;
+  OFSTRUCT _unused;
+  MxU16 result = 0;
+
+  m_info.lBufOffset = 0;
+  m_info.lDiskOffset = 0;
+
+  // Cast of p_flags to u16 forces the `movzx` instruction
+  m_info.hmmio = (HMMIO)OpenFile(p_filename, &_unused, (MxU16)p_flags);
+  
+  if ((HFILE)m_info.hmmio != HFILE_ERROR) {
+    m_info.dwFlags = p_flags;
+    if (p_flags & MMIO_ALLOCBUF) {
+
+      // Default buffer length of 8k if none specified
+      int len = m_info.cchBuffer ? m_info.cchBuffer : 8192;
+      HPSTR buf = new char[len];
+
+      if (!buf) {
+        result = MMIOERR_OUTOFMEMORY;
+        m_info.cchBuffer = 0;
+        m_info.dwFlags &= ~MMIO_ALLOCBUF;
+        m_info.pchBuffer = 0;
+      } else {
+        m_info.pchBuffer = buf;
+        m_info.cchBuffer = len;
+      }
+
+      m_info.pchEndRead = m_info.pchBuffer;
+      m_info.pchNext = m_info.pchBuffer;
+      m_info.pchEndWrite = m_info.pchBuffer + m_info.cchBuffer;
+    }
+  } else {
+    result = MMIOERR_CANNOTOPEN;
+  }
+
+  return result;
 }
 
 // OFFSET: LEGO1 0x100cc8e0
-void MXIOINFO::Close(MxLong arg)
+MxU16 MXIOINFO::Close(MxLong p_unused)
 {
-  
+  MxU16 result = 0;
+
+  if (m_info.hmmio) {
+    result = Flush(0);
+    _lclose((HFILE)m_info.hmmio);
+    m_info.hmmio = 0;
+
+    if (m_info.dwFlags & MMIO_ALLOCBUF)
+      delete[] m_info.pchBuffer;
+
+    m_info.pchEndWrite = 0;
+    m_info.pchEndRead = 0;
+    m_info.pchBuffer = 0;
+    m_info.dwFlags = 0;
+  }
+
+  return result;
 }
 
 // OFFSET: LEGO1 0x100cc930
-MxULong MXIOINFO::Read(HPSTR pch, LONG cch)
+MxLong MXIOINFO::Read(void *p_buf, MxLong p_len)
 {
-  return 0;
+  MxLong bytes_read = 0;
+
+  if (m_info.pchBuffer) {
+
+    int bytes_left = m_info.pchEndRead - m_info.pchNext;
+    while (p_len > 0) {
+
+      if (bytes_left > 0) {
+        if (p_len < bytes_left)
+          bytes_left = p_len;
+        
+        memcpy(p_buf, m_info.pchNext, bytes_left);
+        p_len -= bytes_left;
+        
+        m_info.pchNext += bytes_left;
+        bytes_read += bytes_left;
+      }
+
+      if (p_len <= 0 || Advance(0))
+        break;
+
+      bytes_left = m_info.pchEndRead - m_info.pchNext;
+      if (bytes_left <= 0)
+        break;
+    }
+  } else if (m_info.hmmio && p_len > 0) {
+    bytes_read = _hread((HFILE)m_info.hmmio, p_buf, p_len);
+
+    if (bytes_read == -1) {
+      bytes_read = 0;
+      m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, 0, SEEK_CUR);
+    } else {
+      m_info.lDiskOffset += bytes_read;
+    }
+  }
+
+  return bytes_read;
 }
 
 // OFFSET: LEGO1 0x100cca00
-LONG MXIOINFO::Seek(LONG lOffset, int iOrigin)
+MxLong MXIOINFO::Seek(MxLong p_offset, int p_origin)
 {
-  return 0;
+  MxLong result = -1;
+
+  // If buffered I/O
+  if (m_info.pchBuffer) {
+    if (p_origin == SEEK_CUR) {
+      if (!p_offset) {
+        // don't seek at all and just return where we are.
+        return m_info.lBufOffset + (m_info.pchNext - m_info.pchBuffer);
+      } else {
+        // With SEEK_CUR, p_offset is a relative offset.
+        // Get the absolute position instead and use SEEK_SET.
+        p_offset += m_info.lBufOffset + (m_info.pchNext - m_info.pchBuffer);
+        p_origin = SEEK_SET;
+      }
+    } else if (p_origin == SEEK_END) {
+      // not possible with buffered I/O
+      return -1;
+    }
+    
+    // else p_origin == SEEK_SET.
+
+    // is p_offset between the start and end of the buffer?
+    // i.e. can we do the seek without reading more from disk?
+    if (p_offset >= m_info.lBufOffset && p_offset < m_info.lBufOffset + m_info.cchBuffer) {
+      m_info.pchNext = m_info.pchBuffer + (p_offset - m_info.lBufOffset);
+      result = p_offset;
+    } else {
+      // we have to read another chunk from disk.
+      if (m_info.hmmio && !Flush(0)) {
+        m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, p_offset, p_origin);
+
+        if (m_info.lDiskOffset == -1) {
+          m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, 0, SEEK_CUR);
+        } else {
+
+          // align offset to buffer size
+          int new_offset = p_offset - (p_offset % m_info.cchBuffer);
+          m_info.lBufOffset = new_offset;
+
+          // do we need to seek again?
+          // (i.e. are we already aligned to buffer size?)
+          if (p_offset != new_offset) {
+            m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, new_offset, SEEK_SET);
+
+            if (m_info.lDiskOffset == -1) {
+              m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, 0, SEEK_CUR);
+            }
+          }
+
+          if (m_info.lBufOffset == m_info.lDiskOffset) {
+            // is the file open for writing only?
+            if ((m_info.dwFlags & MMIO_RWMODE) &&
+                ((m_info.dwFlags & MMIO_RWMODE) != MMIO_READWRITE)) {
+
+              m_info.pchNext = m_info.pchBuffer - m_info.lBufOffset + p_offset;
+              
+              result = p_offset;
+            } else {
+              // We can read from the file. Fill the buffer.
+              int bytes_read = _hread((HFILE)m_info.hmmio, m_info.pchBuffer, m_info.cchBuffer);
+              
+              if (bytes_read == -1) {
+                m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, 0, SEEK_CUR);
+              } else {
+                m_info.lDiskOffset += bytes_read;
+                m_info.pchNext = p_offset - m_info.lBufOffset + m_info.pchBuffer;
+                m_info.pchEndRead = m_info.pchBuffer + bytes_read;
+
+                if (m_info.pchNext < m_info.pchEndRead) {
+                  result = p_offset;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  } else {
+    // No buffer so just seek the file directly (if we have a valid handle)
+    if (m_info.hmmio) {
+      // i.e. if we just want to get the current file position
+      if (p_origin == SEEK_CUR && p_offset == 0) {
+        return m_info.lDiskOffset;
+      } else {
+        m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, p_offset, p_origin);
+
+        result = m_info.lDiskOffset;
+
+        if (result == -1) {
+          m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, 0, SEEK_CUR);
+        }
+      }
+    }
+  }
+
+  return result;
 }
 
 // OFFSET: LEGO1 0x100ccbc0
-void MXIOINFO::SetBuffer(LPSTR pchBuffer, LONG cchBuffer, LONG unk)
+MxU16 MXIOINFO::SetBuffer(char *p_buf, MxLong p_len, MxLong p_unused)
 {
-  
+  MxU16 result = Flush(0);
+
+  if (m_info.dwFlags & MMIO_ALLOCBUF) {
+    m_info.dwFlags &= ~MMIO_ALLOCBUF;
+    delete[] m_info.pchBuffer;
+  }
+
+  m_info.pchBuffer = p_buf;
+  m_info.cchBuffer = p_len;
+  m_info.pchEndWrite = m_info.pchBuffer + m_info.cchBuffer;
+  m_info.pchEndRead = m_info.pchBuffer;
+
+  return result;
+}
+
+// OFFSET: LEGO1 0x100ccc10
+MxU16 MXIOINFO::Flush(MxU16 p_unused)
+{
+  MxU16 result = 0;
+
+  // if buffer is dirty
+  if (m_info.dwFlags & MMIO_DIRTY) {
+    // if we have allocated an IO buffer
+    if (m_info.pchBuffer) {
+      // if we have a file open for writing
+      if (m_info.hmmio && (m_info.dwFlags & MMIO_RWMODE)) {
+        // (pulling this value out into a variable forces it into EBX)
+        MxLong cchBuffer = m_info.cchBuffer;
+        if (cchBuffer > 0) {
+          if (m_info.lBufOffset != m_info.lDiskOffset) {
+            m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, m_info.lBufOffset, SEEK_SET);
+          }
+
+          // Was the previous seek (if required) successful?
+          if (m_info.lBufOffset != m_info.lDiskOffset) {
+            result = MMIOERR_CANNOTSEEK;
+            m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, 0, SEEK_CUR);
+          } else {
+            MxLong bytes_written = _hwrite((HFILE)m_info.hmmio, m_info.pchBuffer, cchBuffer);
+
+            if (bytes_written != -1 && bytes_written == cchBuffer) {
+              m_info.lDiskOffset += bytes_written;
+              m_info.pchNext = m_info.pchBuffer;
+              m_info.dwFlags &= ~MMIO_DIRTY;
+            } else {
+              result = MMIOERR_CANNOTWRITE;
+              m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, 0, SEEK_CUR);
+            }
+          }
+        }
+      } else {
+        result = MMIOERR_CANNOTWRITE;
+      }
+    } else {
+      result = MMIOERR_UNBUFFERED;
+    }
+  }
+
+  return result;
+}
+
+// OFFSET: LEGO1 0x100ccd00
+MxU16 MXIOINFO::Advance(MxU16 p_option)
+{
+  MxU16 result = 0;
+  MxULong rwmode = m_info.dwFlags & MMIO_RWMODE;
+
+  if (m_info.pchBuffer) {
+    MxLong cch = m_info.cchBuffer;
+
+    // If we can and should write to the file,
+    // if we are being asked to write to the file,
+    // and if there is a buffer *to* write:
+    if ((rwmode == MMIO_WRITE || rwmode == MMIO_READWRITE) &&
+        (m_info.dwFlags & MMIO_DIRTY) && 
+        ((p_option & MMIO_WRITE) || (rwmode == MMIO_READWRITE)) &&
+        cch > 0) {
+
+      if (m_info.lBufOffset != m_info.lDiskOffset) {
+        m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, m_info.lBufOffset, SEEK_SET);
+      }
+
+      if (m_info.lBufOffset != m_info.lDiskOffset) {
+        result = MMIOERR_CANNOTSEEK;
+      } else {
+        MxLong bytes_written = _hwrite((HFILE)m_info.hmmio, m_info.pchBuffer, cch);
+
+        if (bytes_written != -1 && bytes_written == cch) {
+          m_info.lDiskOffset += bytes_written;
+          m_info.pchNext = m_info.pchBuffer;
+          m_info.pchEndRead = m_info.pchBuffer;
+          m_info.dwFlags &= ~MMIO_DIRTY;
+        } else {
+          result = MMIOERR_CANNOTWRITE;
+        }
+      }  
+
+      m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, 0, SEEK_CUR);
+
+    }
+
+    m_info.lBufOffset += cch;
+    if ((!rwmode || rwmode == MMIO_READWRITE) && cch > 0) {
+      if (m_info.lBufOffset != m_info.lDiskOffset) {
+        m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, m_info.lBufOffset, SEEK_SET);
+      }
+
+      // if previous seek failed
+      if (m_info.lBufOffset != m_info.lDiskOffset) {
+        result = MMIOERR_CANNOTSEEK;
+        m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, 0, SEEK_CUR);
+      } else {
+        int bytes_read = _hread((HFILE)m_info.hmmio, m_info.pchBuffer, cch);
+
+        if (bytes_read == -1) {
+          result = MMIOERR_CANNOTREAD;
+          m_info.lDiskOffset = _llseek((HFILE)m_info.hmmio, 0, SEEK_CUR);
+        } else {
+          m_info.lDiskOffset += bytes_read;
+          m_info.pchNext = m_info.pchBuffer;
+          m_info.pchEndRead = m_info.pchBuffer + bytes_read;
+        }
+      }
+    }
+  } else {
+    result = MMIOERR_UNBUFFERED;
+  }
+
+  return result;
 }
 
 // OFFSET: LEGO1 0x100cce60
-MxU16 MXIOINFO::Descend(LPMMCKINFO pmmcki, const MMCKINFO *pmmckiParent, UINT fuDescend)
+MxU16 MXIOINFO::Descend(MMCKINFO *p_chunkInfo, const MMCKINFO *p_parentInfo, MxU16 p_descend)
 {
-  return 0;
+  MxU16 result = 0;
+  
+  if (!p_chunkInfo) 
+    return MMIOERR_BASE; // ?
+
+  if (!p_descend) {
+    p_chunkInfo->dwFlags = 0;
+    if (Read(p_chunkInfo, 8) != 8) {
+      result = MMIOERR_CANNOTREAD;
+    } else {
+      if (m_info.pchBuffer) {
+        p_chunkInfo->dwDataOffset = m_info.pchNext - m_info.pchBuffer + m_info.lBufOffset;
+      } else {
+        p_chunkInfo->dwDataOffset = m_info.lDiskOffset;
+      }
+
+      if (p_chunkInfo->ckid == FOURCC_RIFF || p_chunkInfo->ckid == FOURCC_LIST) {
+        if (Read(&p_chunkInfo->fccType, 4) != 4) {
+          result = MMIOERR_CANNOTREAD;
+        }
+      }
+    }
+  } else {
+    MxULong ofs = MAXLONG;
+
+    if (p_parentInfo)
+      ofs = p_parentInfo->cksize + p_parentInfo->dwDataOffset;
+
+    BOOL running = TRUE;
+    BOOL read_ok = FALSE;
+    MMCKINFO tmp;
+    tmp.dwFlags = 0;
+
+    // This loop is... something
+    do {
+      if (Read(&tmp, 8) != 8) {
+        // If the first read fails, report read error. Else EOF.
+        result = read_ok ? MMIOERR_CHUNKNOTFOUND : MMIOERR_CANNOTREAD;
+        running = FALSE;
+      } else {
+        read_ok = TRUE;
+        if (m_info.pchBuffer) {
+          tmp.dwDataOffset = m_info.pchNext - m_info.pchBuffer + m_info.lBufOffset;
+        } else {
+          tmp.dwDataOffset = m_info.lDiskOffset;
+        }
+
+        if (ofs < tmp.dwDataOffset) {
+          result = MMIOERR_CHUNKNOTFOUND;
+          running = FALSE;
+        } else {
+          if ((p_descend == MMIO_FINDLIST && tmp.ckid == FOURCC_LIST) ||
+              (p_descend == MMIO_FINDRIFF && tmp.ckid == FOURCC_RIFF)) {
+            if (Read(&tmp.fccType, 4) != 4) {
+              result = MMIOERR_CANNOTREAD;
+            } else {
+              if (p_chunkInfo->fccType != tmp.fccType)
+                continue;
+            }
+            running = FALSE;
+          } else {
+            if (p_chunkInfo->ckid != tmp.ckid) {
+              if (Seek((tmp.cksize&1)+tmp.cksize, SEEK_CUR) != -1) {
+                continue;
+              } else {
+                result = MMIOERR_CANNOTSEEK;
+              }
+            }
+            running = FALSE;
+          }
+        }
+      }
+
+    } while (running);
+
+    if (!result)
+      memcpy(p_chunkInfo, &tmp, sizeof(MMCKINFO));
+
+  }
+
+  return result;
 }
diff --git a/LEGO1/mxioinfo.h b/LEGO1/mxioinfo.h
index 5ce0947a..83da930a 100644
--- a/LEGO1/mxioinfo.h
+++ b/LEGO1/mxioinfo.h
@@ -12,13 +12,17 @@ public:
   MXIOINFO();
   __declspec(dllexport) ~MXIOINFO();
 
-  MxU16 Open(const char *filename, DWORD fdwOpen);
-  void Close(MxLong arg);
-  LONG Seek(LONG lOffset, int iOrigin);
-  MxULong Read(HPSTR pch, LONG cch);
-  void SetBuffer(LPSTR pchBuffer, LONG cchBuffer, LONG unk);
-  MxU16 Descend(LPMMCKINFO pmmcki, const MMCKINFO *pmmckiParent, UINT fuDescend);
+  MxU16 Open(const char *, MxULong);
+  MxU16 Close(MxLong);
+  MxLong Read(void *, MxLong);
+  MxLong Seek(MxLong, int);
+  MxU16 SetBuffer(char *, MxLong, MxLong);
+  MxU16 Flush(MxU16);
+  MxU16 Advance(MxU16);
+  MxU16 Descend(MMCKINFO *, const MMCKINFO *, MxU16);
 
+  // NOTE: In MXIOINFO, the `hmmio` member of MMIOINFO is used like
+  // an HFILE (int) instead of an HMMIO (WORD).
   MMIOINFO m_info;
 };