diff --git a/System/Random/Mersenne/Pure64.hs b/System/Random/Mersenne/Pure64.hs
new file mode 100644
--- /dev/null
+++ b/System/Random/Mersenne/Pure64.hs
@@ -0,0 +1,118 @@
+{-# LANGUAGE CPP, ForeignFunctionInterface #-}
+--------------------------------------------------------------------
+-- |
+-- Module     : System.Random.Mersenne.Pure64
+-- Copyright  : Copyright (c) 2008, Don Stewart <dons@galois.com>
+-- License    : BSD3
+-- Maintainer : Don Stewart <dons@galois.com>
+-- Stability  : experimental
+-- Portability: CPP, FFI
+-- Tested with: GHC 6.8.2
+--
+-- A purely functional binding 64 bit binding to the classic mersenne
+-- twister random number generator. This is more flexible than the 
+-- impure 'mersenne-random' library, at the cost of being much slower.
+-- This generator is however, many times faster than System.Random,
+-- and yields high quality randoms with a long period.
+--
+-- This generator may be used with System.Random, however, that is
+-- likely to be slower than using it directly.
+--
+module System.Random.Mersenne.Pure64 (
+
+    -- * The random number generator
+    PureMT          -- abstract: RandomGen
+
+    -- * Introduction
+    , pureMT        -- :: Word64 -> PureMT
+    , newPureMT     -- :: IO PureMT
+
+    -- $instance
+
+    -- * Low level access to the generator
+
+    -- $notes
+    , randomInt     -- :: PureMT -> (Int   ,PureMT)
+    , randomWord    -- :: PureMT -> (Word  ,PureMT)
+    , randomInt64   -- :: PureMT -> (Int64 ,PureMT)
+    , randomWord64  -- :: PureMT -> (Word64,PureMT)
+    , randomDouble  -- :: PureMT -> (Double,PureMT)
+
+    ) where
+
+------------------------------------------------------------------------
+
+import System.Random.Mersenne.Pure64.MTBlock
+import System.Random
+import Data.Word
+import Data.Int
+import System.Time
+import System.CPUTime
+
+-- | Create a PureMT generator from a 'Word64' seed.
+pureMT :: Word64 -> PureMT
+pureMT = mkPureMT . seedBlock . fromIntegral
+
+-- | Create a new PureMT generator, using the clocktime as the base for the seed.
+newPureMT :: IO PureMT
+newPureMT = do
+    ct             <- getCPUTime
+    (TOD sec psec) <- getClockTime
+    return $ pureMT (fromIntegral $ sec * 1013904242 + psec + ct)
+
+------------------------------------------------------------------------
+-- System.Random interface.
+
+-- $instance
+--
+-- Being purely functional, the PureMT generator is an instance of
+-- RandomGen. However, it doesn't support 'split' yet.
+
+instance RandomGen PureMT where
+   next  = randomInt
+   split = error "System.Random.Mersenne.Pure: unable to split the mersenne twister"
+
+------------------------------------------------------------------------
+-- Direct access to Int, Word and Double types
+
+-- | Yield a new 'Int' value from the generator, returning a new
+-- generator and that 'Int'. The full 64 bits will be used on a 64 bit machine.
+randomInt :: PureMT -> (Int,PureMT)
+randomInt g = (fromIntegral i, g')
+        where (i,g') = randomWord64 g
+
+-- | Yield a new 'Word' value from the generator, returning a new
+-- generator and that 'Word'.
+randomWord :: PureMT -> (Word,PureMT)
+randomWord g = (fromIntegral i, g')
+        where (i,g') = randomWord64 g
+
+-- | Yield a new 'Int64' value from the generator, returning a new
+-- generator and that 'Int64'.
+randomInt64 :: PureMT -> (Int64,PureMT)
+randomInt64 g = (fromIntegral i, g')
+        where (i,g') = randomWord64 g
+
+-- | Efficiently yield a new 53-bit precise 'Double' value, and a new generator.
+randomDouble :: PureMT -> (Double,PureMT)
+randomDouble g = (fromIntegral (i `div` 2048) / 9007199254740992, g')
+        where (i,g') = randomWord64 g
+
+-- | Yield a new 'Word64' value from the generator, returning a new
+-- generator and that 'Word64'.
+randomWord64 :: PureMT -> (Word64,PureMT)
+randomWord64 (PureMT block i nxt) = (mixWord64 (block `lookupBlock` i), mt)
+  where
+    mt | i < blockLen-1 = PureMT block (i+1) nxt
+       | otherwise      = mkPureMT nxt
+
+-- | 'PureMT', a pure mersenne twister pseudo-random number generator
+--
+data PureMT  = PureMT !MTBlock !Int MTBlock
+
+instance Show PureMT where
+    show _ = show "<PureMT>"
+
+-- create a new PureMT from an MTBlock
+mkPureMT :: MTBlock -> PureMT
+mkPureMT block = PureMT block 0 (nextBlock block)
diff --git a/System/Random/Mersenne/Pure64.hsc b/System/Random/Mersenne/Pure64.hsc
deleted file mode 100644
--- a/System/Random/Mersenne/Pure64.hsc
+++ /dev/null
@@ -1,198 +0,0 @@
-{-# LANGUAGE CPP, ForeignFunctionInterface #-}
---------------------------------------------------------------------
--- |
--- Module     : System.Random.Mersenne.Pure64
--- Copyright  : Copyright (c) 2008, Don Stewart <dons@galois.com>
--- License    : BSD3
--- Maintainer : Don Stewart <dons@galois.com>
--- Stability  : experimental
--- Portability: CPP, FFI
--- Tested with: GHC 6.8.2
---
--- A purely functional binding 64 bit binding to the classic mersenne
--- twister random number generator. This is more flexible than the 
--- impure 'mersenne-random' library, at the cost of being much slower.
--- This generator is however, many times faster than System.Random,
--- and yields high quality randoms with a long period.
---
--- This generator may be used with System.Random, however, that is
--- likely to be slower than using it directly.
---
-module System.Random.Mersenne.Pure64 (
-
-    -- * The random number generator
-    PureMT          -- abstract: RandomGen
-
-    -- * Introduction
-    , pureMT        -- :: Word -> PureMT
-    , newPureMT     -- :: IO PureMT
-
-    -- $instance
-
-    -- * Low level access to the generator
-
-    -- $notes
-    , randomInt     -- :: PureMT -> (Int   ,PureMT)
-    , randomWord    -- :: PureMT -> (Word  ,PureMT)
-    , randomInt64   -- :: PureMT -> (Int64 ,PureMT)
-    , randomWord64  -- :: PureMT -> (Word64,PureMT)
-    , randomDouble  -- :: PureMT -> (Double,PureMT)
-
-    ) where
-
-------------------------------------------------------------------------
-
-#include "mt19937-64.h"
-
-------------------------------------------------------------------------
-
-import System.Random.Mersenne.Pure64.Base
-
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 605
-import GHC.ForeignPtr           (mallocPlainForeignPtrBytes)
-#else
-import Foreign.ForeignPtr       (mallocForeignPtrBytes)
-#endif
-
-import Foreign.C.Types
-import Foreign
-
-import System.CPUTime	( getCPUTime )
-import System.Time
-import System.IO.Unsafe
-import Control.Monad
-
-import System.Random
-
-import Data.Word
-import Data.Int
-
-------------------------------------------------------------------------
-
--- | Create a PureMT generator from a 'Word' seed.
-pureMT :: Word -> PureMT
-pureMT = init_genrand64 . fromIntegral
-
--- | Create a new PureMT generator, using the clocktime as the base for the seed.
-newPureMT :: IO PureMT
-newPureMT = do
-    ct             <- getCPUTime
-    (TOD sec psec) <- getClockTime
-    return $ pureMT (fromIntegral $ sec * 1013904242 + psec + ct)
-
-------------------------------------------------------------------------
--- System.Random interface.
-
--- $instance 
--- 
--- Being purely functional, the PureMT generator is an instance of
--- RandomGen. However, it doesn't support 'split' yet.
-
-instance RandomGen PureMT where
-   next  = randomInt
-   split = error "System.Random.Mersenne.Pure: unable to split the mersenne twister"
-
-------------------------------------------------------------------------
--- Direct access to Int, Word and Double types
-
--- | Yield a new 'Int' value from the generator, returning a new
--- generator and that 'Int'. The full 64 bits will be used on a 64 bit machine.
-randomInt :: PureMT -> (Int,PureMT)
-randomInt g = (fromIntegral i, g')
-        where (i,g') = genrand64_int64 g
-
--- | Yield a new 'Word' value from the generator, returning a new
--- generator and that 'Word'. 
-randomWord :: PureMT -> (Word,PureMT)
-randomWord g = (fromIntegral i, g')
-        where (i,g') = genrand64_int64 g
-
--- | Yield a new 'Int64' value from the generator, returning a new
--- generator and that 'Int64'. 
-randomInt64 :: PureMT -> (Int64,PureMT)
-randomInt64 g = (fromIntegral i, g')
-        where (i,g') = genrand64_int64 g
-
--- | Yield a new 'Word64' value from the generator, returning a new
--- generator and that 'Word64'. 
-randomWord64 :: PureMT -> (Word64,PureMT)
-randomWord64 g = (fromIntegral i, g')
-        where (i,g') = genrand64_int64 g
-
--- | Efficiently yield a new 53-bit precise 'Double' value, and a new generator.
-randomDouble :: PureMT -> (Double,PureMT)
-randomDouble g = (realToFrac i, g')
-        where (i,g') = genrand64_real2 g
-
-------------------------------------------------------------------------
--- We can have only one mersenne supply in a program.
-
--- You have to commit at initialisation time to call either
--- rand_gen32 or rand_gen64, and correspondingly, real2 or res53
--- for doubles.
---
-
--- | 'PureMT', a pure mersenne twister pseudo-random number generator
---
-newtype PureMT  = PureMT (ForeignPtr MTState)
-
-instance Show PureMT where
-    show _ = show "<PureMT>"
-
-sizeof_MTState :: Int
-sizeof_MTState = (#const (sizeof (struct mt_state_t))) -- 2504 bytes
-
-------------------------------------------------------------------------
--- Low level interface
-
-init_genrand64 :: UInt64 -> PureMT
-init_genrand64 seed = unsafePerformIO $ do
-    fp <- mallocFastBytes sizeof_MTState
-    withForeignPtr fp $ \p -> c_init_genrand64 p seed -- fill it
-    return $ PureMT fp
-
-genrand64_int64 :: PureMT -> (UInt64, PureMT)
-genrand64_int64 o   = unsafePerformIO $ do
-    PureMT n <- copyPureMT o
-    v        <- withForeignPtr n $ c_genrand64_int64
-    n `seq` v `seq`
-        return (v,PureMT n)
-{-# INLINE genrand64_int64 #-}
-
-genrand64_real2 :: PureMT -> (CDouble, PureMT)
-genrand64_real2 o   = unsafePerformIO $ do
-    PureMT n <- copyPureMT o
-    v        <- withForeignPtr n $ c_genrand64_real2
-    n `seq` v `seq`
-        return (v,PureMT n)
-{-# INLINE genrand64_real2 #-}
-
--- ---------------------------------------------------------------------
--- Memory management
-
---
--- | Wrapper of mallocForeignPtrBytes with faster implementation
--- Allocate pinned heap memory for the state.
---
-mallocFastBytes :: Int -> IO (ForeignPtr a)
-mallocFastBytes s = do
-#if __GLASGOW_HASKELL__ >= 605 && !defined(SLOW_FOREIGN_PTR)
-    mallocPlainForeignPtrBytes s
-#else
-    mallocForeignPtrBytes s
-#endif
-{-# INLINE mallocFastBytes #-}
-
---
--- Duplicate a random state, prior to permuting it.
---
-copyPureMT :: PureMT -> IO PureMT
-copyPureMT (PureMT oldfp) = do
-    newfp <- mallocFastBytes sizeof_MTState
-    withForeignPtr newfp $ \p ->
-        withForeignPtr oldfp $ \q ->
-            c_memcpy (castPtr p) (castPtr q) (fromIntegral sizeof_MTState)
-    return $! PureMT newfp
-{-# INLINE copyPureMT #-}
-
-
diff --git a/System/Random/Mersenne/Pure64/Base.hsc b/System/Random/Mersenne/Pure64/Base.hsc
--- a/System/Random/Mersenne/Pure64/Base.hsc
+++ b/System/Random/Mersenne/Pure64/Base.hsc
@@ -1,7 +1,7 @@
 {-# LANGUAGE EmptyDataDecls, CPP, ForeignFunctionInterface #-}
 --------------------------------------------------------------------
 -- |
--- Module     : System.Random.Mersenne.Pure64
+-- Module     : System.Random.Mersenne.Pure64.Base
 -- Copyright  : Copyright (c) 2008, Don Stewart <dons@galois.com>
 -- License    : BSD3
 -- Maintainer : Don Stewart <dons@galois.com>
@@ -17,6 +17,7 @@
 --
 module System.Random.Mersenne.Pure64.Base where
 
+#include "mt19937-64-block.h"
 #include "mt19937-64.h"
 #include "mt19937-64-unsafe.h"
 
@@ -38,6 +39,28 @@
 
 foreign import ccall unsafe "genrand64_real2"
     c_genrand64_real2 :: Ptr MTState -> IO CDouble
+
+sizeof_MTState :: Int
+sizeof_MTState = (#const (sizeof (struct mt_state_t))) -- 2504 bytes
+
+------------------------------------------------------------------------
+-- block based version:
+foreign import ccall unsafe "mix_bits"
+    c_mix_word64 :: Word64 -> Word64
+
+foreign import ccall unsafe "seed_genrand64_block"
+    c_seed_genrand64_block :: Ptr a -> Word64 -> IO ()
+
+foreign import ccall unsafe "next_genrand64_block"
+    c_next_genrand64_block :: Ptr a -> Ptr a -> IO ()
+
+-- | length of an MT block
+blockLen :: Int
+blockLen = (# const NN )
+
+-- | size of an MT block, in bytes
+blockSize :: Int
+blockSize = (# const sizeof(mt_block_struct) )
 
 ------------------------------------------------------------------------
 -- model: (for testing purposes)
diff --git a/System/Random/Mersenne/Pure64/MTBlock.hs b/System/Random/Mersenne/Pure64/MTBlock.hs
new file mode 100644
--- /dev/null
+++ b/System/Random/Mersenne/Pure64/MTBlock.hs
@@ -0,0 +1,86 @@
+{-# LANGUAGE MagicHash, UnboxedTuples #-}
+--------------------------------------------------------------------
+-- |
+-- Module     : System.Random.Mersenne.Pure64
+-- Copyright  : Copyright (c) 2008, Bertram Felgenhauer <dons@galois.com>
+-- License    : BSD3
+-- Maintainer : Don Stewart <dons@galois.com>
+-- Stability  : experimental
+-- Portability: 
+-- Tested with: GHC 6.8.2
+--
+module System.Random.Mersenne.Pure64.MTBlock (
+    -- * Block type
+    MTBlock,
+
+    -- * Block functions
+    seedBlock,
+    nextBlock,
+    lookupBlock,
+
+    -- * Misc functions
+    blockLen,
+    mixWord64,
+) where
+
+import GHC.Exts
+import GHC.IOBase
+import GHC.Word
+import System.Random.Mersenne.Pure64.Base
+
+data MTBlock = MTBlock ByteArray#
+
+allocateBlock :: IO MTBlock
+allocateBlock =
+    IO $ \s0 -> case newPinnedByteArray# blockSize# s0 of
+        (# s1, b0 #) -> case unsafeFreezeByteArray# b0 s1 of
+            (# s2, b1 #) -> (# s2, MTBlock b1 #)
+  where
+    I# blockSize# = blockSize
+
+blockAsPtr :: MTBlock -> Ptr a
+blockAsPtr (MTBlock b) = Ptr (byteArrayContents# b)
+
+-- | create a new MT block, seeded with the given Word64 value
+seedBlock :: Word64 -> MTBlock
+seedBlock seed = unsafePerformIO $ do
+    b <- allocateBlock
+    c_seed_genrand64_block (blockAsPtr b) seed
+    c_next_genrand64_block (blockAsPtr b) (blockAsPtr b)
+    touch b
+    return b
+
+-- | step: create a new MTBlock buffer from the previous one
+nextBlock :: MTBlock -> MTBlock
+nextBlock b = unsafePerformIO $ do
+    new <- allocateBlock
+    c_next_genrand64_block (blockAsPtr b) (blockAsPtr new)
+    touch b
+    touch new
+    return new
+
+-- stolen from GHC.ForeignPtr - make sure the argument is still alive.
+touch :: a -> IO ()
+touch r = IO $ \s0 -> case touch# r s0 of s1 -> (# s1, () #)
+
+-- | look up an element of an MT block
+lookupBlock :: MTBlock -> Int -> Word64
+lookupBlock (MTBlock b) (I# i) = W64# (indexWord64Array# b i)
+
+-- | MT's word mix function.
+--
+-- (MT applies this function to each Word64 from the buffer before returning it)
+mixWord64 :: Word64 -> Word64
+mixWord64 = c_mix_word64
+
+-- Alternative implementation - it's probably faster on 64 bit machines, but
+-- on Athlon XP it loses.
+{-
+mixWord64 (W64# x0) = let
+    W64# x1 = W64# x0 `xor` (W64# (x0 `uncheckedShiftRL64#` 28#) .&. 0x5555555555555555)
+    W64# x2 = W64# x1 `xor` (W64# (x1 `uncheckedShiftL64#` 17#) .&. 0x71D67FFFEDA60000)
+    W64# x3 = W64# x2 `xor` (W64# (x2 `uncheckedShiftL64#` 37#) .&. 0xFFF7EEE000000000)
+    W64# x4 = W64# x3 `xor` (W64# (x3 `uncheckedShiftRL64#` 43#))
+  in
+    W64# x4
+-}
diff --git a/TODO b/TODO
--- a/TODO
+++ b/TODO
@@ -1,4 +1,12 @@
 -fvia-C seems to break things!
+   The problem is that the prototypes of the imported functions don't get
+   propagated properly, leading to warnings like this:
+
+   /tmp/ghc7602_0/ghc7602_0.hc:718:0:
+        warning: implicit declaration of function 'mix_bits'
+
+   This is actually an error on 32 bit machines - the default return type
+   int is not large enough to hold the 64 bit result.
 Check sequences are repeatable
 check behaviour on 32 bits
 profile/benchmark
diff --git a/cbits/mt19937-64-block.c b/cbits/mt19937-64-block.c
new file mode 100644
--- /dev/null
+++ b/cbits/mt19937-64-block.c
@@ -0,0 +1,99 @@
+/* 
+   A C-program for MT19937-64 (2004/9/29 version).
+   Coded by Takuji Nishimura and Makoto Matsumoto.
+
+   This is a 64-bit version of Mersenne Twister pseudorandom number
+   generator.
+
+   Copyright (C) 2004, Makoto Matsumoto and Takuji Nishimura,
+   All rights reserved.                          
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+     1. Redistributions of source code must retain the above copyright
+        notice, this list of conditions and the following disclaimer.
+
+     2. Redistributions in binary form must reproduce the above copyright
+        notice, this list of conditions and the following disclaimer in the
+        documentation and/or other materials provided with the distribution.
+
+     3. The names of its contributors may not be used to endorse or promote 
+        products derived from this software without specific prior written 
+        permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+   References:
+   T. Nishimura, ``Tables of 64-bit Mersenne Twisters''
+     ACM Transactions on Modeling and 
+     Computer Simulation 10. (2000) 348--357.
+   M. Matsumoto and T. Nishimura,
+     ``Mersenne Twister: a 623-dimensionally equidistributed
+       uniform pseudorandom number generator''
+     ACM Transactions on Modeling and 
+     Computer Simulation 8. (Jan. 1998) 3--30.
+
+   Any feedback is very welcome.
+   http://www.math.hiroshima-u.ac.jp/~m-mat/MT/emt.html
+   email: m-mat @ math.sci.hiroshima-u.ac.jp (remove spaces)
+
+   Modified by Don Stewart to use non-global state.
+   Modified by Bertram Felgenhauer to provide block oriented functions only.
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "mt19937-64-block.h"
+
+/*
+ * When passed an empty state, initialize the states' mt[NN] with a seed
+ */
+void seed_genrand64_block(mt_block st, unsigned long long seed)
+{
+    int i;
+    st->mt[0] = seed;
+    for (i=1; i<NN; i++) 
+        st->mt[i] =  (6364136223846793005ULL * 
+                                (st->mt[i-1] ^ (st->mt[i-1] >> 62)) + i);
+}
+
+/* generates a new state buffer from the previous one */
+void next_genrand64_block(mt_block st, mt_block newst)
+{
+    int i;
+    unsigned long long x;
+    static unsigned long long mag01[2]={0ULL, MATRIX_A};
+
+    for (i=0; i<NN-MM; i++) {
+        x = (st->mt[i]&UM)|(st->mt[i+1]&LM);
+        newst->mt[i] = st->mt[i+MM] ^ (x>>1) ^ mag01[(int)(x&1ULL)];
+    }
+    for (; i<NN-1; i++) {
+        x = (st->mt[i]&UM)|(st->mt[i+1]&LM);
+        newst->mt[i] = newst->mt[i+(MM-NN)] ^ (x>>1) ^ mag01[(int)(x&1ULL)];
+    }
+    x = (st->mt[NN-1]&UM)|(newst->mt[0]&LM);
+    newst->mt[NN-1] = newst->mt[MM-1] ^ (x>>1) ^ mag01[(int)(x&1ULL)];
+}
+
+unsigned long long mix_bits(unsigned long long x)
+{
+    x ^= (x >> 29) & 0x5555555555555555ULL;
+    x ^= (x << 17) & 0x71D67FFFEDA60000ULL;
+    x ^= (x << 37) & 0xFFF7EEE000000000ULL;
+    x ^= (x >> 43);
+    return x;
+}
diff --git a/include/mt19937-64-block.h b/include/mt19937-64-block.h
new file mode 100644
--- /dev/null
+++ b/include/mt19937-64-block.h
@@ -0,0 +1,73 @@
+/* 
+   A C-program for MT19937-64 (2004/9/29 version).
+   Coded by Takuji Nishimura and Makoto Matsumoto.
+
+   This is a 64-bit version of Mersenne Twister pseudorandom number
+   generator.
+
+   Before using, initialize the state by using init_genrand64(seed)  
+   or init_by_array64(init_key, key_length).
+
+   Copyright (C) 2004, Makoto Matsumoto and Takuji Nishimura,
+   All rights reserved.                          
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+     1. Redistributions of source code must retain the above copyright
+        notice, this list of conditions and the following disclaimer.
+
+     2. Redistributions in binary form must reproduce the above copyright
+        notice, this list of conditions and the following disclaimer in the
+        documentation and/or other materials provided with the distribution.
+
+     3. The names of its contributors may not be used to endorse or promote 
+        products derived from this software without specific prior written 
+        permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+   References:
+   T. Nishimura, ``Tables of 64-bit Mersenne Twisters''
+     ACM Transactions on Modeling and 
+     Computer Simulation 10. (2000) 348--357.
+   M. Matsumoto and T. Nishimura,
+     ``Mersenne Twister: a 623-dimensionally equidistributed
+       uniform pseudorandom number generator''
+     ACM Transactions on Modeling and 
+     Computer Simulation 8. (Jan. 1998) 3--30.
+
+   Any feedback is very welcome.
+   http://www.math.hiroshima-u.ac.jp/~m-mat/MT/emt.html
+   email: m-mat @ math.sci.hiroshima-u.ac.jp (remove spaces)
+*/
+
+#define NN 312
+#define MM 156
+#define MATRIX_A 0xB5026F5AA96619E9ULL
+#define UM 0xFFFFFFFF80000000ULL /* Most significant 33 bits */
+#define LM 0x7FFFFFFFULL /* Least significant 31 bits */
+
+/* The array for the state vector */
+typedef struct mt_block_t {
+    unsigned long long mt[NN]; 
+} mt_block_struct, *mt_block;
+
+/* initializes mt[NN] with a seed */
+void seed_genrand64_block(mt_block st, unsigned long long seed);
+
+/* calculate new block of random data */
+void next_genrand64_block(mt_block st, mt_block newst);
+
+unsigned long long mix_bits(unsigned long long x);
diff --git a/mersenne-random-pure64.cabal b/mersenne-random-pure64.cabal
--- a/mersenne-random-pure64.cabal
+++ b/mersenne-random-pure64.cabal
@@ -1,5 +1,5 @@
 name:            mersenne-random-pure64
-version:         0.1.1
+version:         0.2
 homepage:        http://code.haskell.org/~dons/code/mt19937-random
 synopsis:        Generate high quality pseudorandom numbers purely using a Mersenne Twister
 description:
@@ -25,7 +25,7 @@
 author:          Don Stewart
 maintainer:      Don Stewart <dons@galois.com>
 cabal-version: >= 1.2.0
-build-type:      Configure
+build-type:      Simple
 tested-with:     GHC ==6.8.2
 
 flag small_base
@@ -35,6 +35,7 @@
 library
     exposed-modules: System.Random.Mersenne.Pure64
                      System.Random.Mersenne.Pure64.Base
+                     System.Random.Mersenne.Pure64.MTBlock
     extensions:      CPP, ForeignFunctionInterface
 
     if flag(small_base)
@@ -46,11 +47,13 @@
         -O3 -finline-functions -fomit-frame-pointer
         -fno-strict-aliasing --param max-inline-insns-single=1800
 
-    ghc-options:     -Wall -O2 -fvia-C -fexcess-precision
+    ghc-options:     -Wall -O2 -fexcess-precision
 
     c-sources:        cbits/mt19937-64.c
                       cbits/mt19937-64-unsafe.c
+                      cbits/mt19937-64-block.c
     include-dirs:     include
     includes:
     install-includes: mt19937-64.h
                       mt19937-64-unsafe.h
+                      mt19937-64-block.h
