content: -- Sample code to demonstrate how to emulate m68k code
  
  import Unicorn
  import Unicorn.Hook
  import qualified Unicorn.CPU.M68k as M68k
  
  import qualified Data.ByteString as BS
  import Data.Word
  import qualified Numeric as N (showHex)
  
  -- Code to be emulated
  --
  -- movq #-19, %d3
  m68kCode :: BS.ByteString
  m68kCode = BS.pack [0x76, 0xed]
  
  -- Memory address where emulation starts
  address :: Word64
  address = 0x10000
  
  -- Pretty-print integral as hex
  showHex :: (Integral a, Show a) => a -> String
  showHex =
      flip N.showHex ""
  
  -- Calculate code length
  codeLength :: Num a => BS.ByteString -> a
  codeLength =
      fromIntegral . BS.length
  
  hookBlock :: BlockHook ()
  hookBlock _ addr size _ =
      putStrLn $ ">>> Tracing basic block at 0x" ++ showHex addr ++
                 ", block size = 0x" ++ (maybe "0" showHex size)
  
  hookCode :: CodeHook ()
  hookCode _ addr size _ =
      putStrLn $ ">>> Tracing instruction at 0x" ++ showHex addr ++
                 ", instruction size = 0x" ++ (maybe "0" showHex size)
  
  testM68k :: IO ()
  testM68k = do
      putStrLn "Emulate M68K code"
  
      result <- runEmulator $ do
          -- Initialize emulator in M68K mode
          uc <- open ArchM68k [ModeBigEndian]
  
          -- Map 2MB memory for this emulation
          memMap uc address (2 * 1024 * 1024) [ProtAll]
  
          -- Write machine code to be emulated to memory
          memWrite uc address m68kCode
  
          -- Initialize machine registers
          regWrite uc M68k.D0 0x0000
          regWrite uc M68k.D1 0x0000
          regWrite uc M68k.D2 0x0000
          regWrite uc M68k.D3 0x0000
          regWrite uc M68k.D4 0x0000
          regWrite uc M68k.D5 0x0000
          regWrite uc M68k.D6 0x0000
          regWrite uc M68k.D7 0x0000
  
          regWrite uc M68k.A0 0x0000
          regWrite uc M68k.A1 0x0000
          regWrite uc M68k.A2 0x0000
          regWrite uc M68k.A3 0x0000
          regWrite uc M68k.A4 0x0000
          regWrite uc M68k.A5 0x0000
          regWrite uc M68k.A6 0x0000
          regWrite uc M68k.A7 0x0000
  
          regWrite uc M68k.Pc 0x0000
          regWrite uc M68k.Sr 0x0000
  
          -- Tracing all basic blocks with customized callback
          blockHookAdd uc hookBlock () 1 0
  
          -- Tracing all instruction
          codeHookAdd uc hookCode () 1 0
  
          -- Emulate machine code in infinite time (last param = Nothing), or
          -- when finishing all the code
          let codeLen = codeLength m68kCode
          start uc address (address + codeLen) Nothing Nothing
  
          -- Return the results
          d0 <- regRead uc M68k.D0
          d1 <- regRead uc M68k.D1
          d2 <- regRead uc M68k.D2
          d3 <- regRead uc M68k.D3
          d4 <- regRead uc M68k.D4
          d5 <- regRead uc M68k.D5
          d6 <- regRead uc M68k.D6
          d7 <- regRead uc M68k.D7
  
          a0 <- regRead uc M68k.A0
          a1 <- regRead uc M68k.A1
          a2 <- regRead uc M68k.A2
          a3 <- regRead uc M68k.A3
          a4 <- regRead uc M68k.A4
          a5 <- regRead uc M68k.A5
          a6 <- regRead uc M68k.A6
          a7 <- regRead uc M68k.A7
  
          pc <- regRead uc M68k.Pc
          sr <- regRead uc M68k.Sr
  
          return (d0, d1, d2, d3, d4, d5, d6, d7,
                  a0, a1, a2, a3, a4, a5, a6, a7,
                  pc, sr)
      case result of
          Right (d0, d1, d2, d3, d4, d5, d6, d7,
                 a0, a1, a2, a3, a4, a5, a6, a7,
                 pc, sr) -> do
              -- Now print out some registers
              putStrLn ">>> Emulation done. Below is the CPU context"
              putStrLn $ ">>> A0 = 0x" ++ showHex a0 ++
                         "\t\t>>> D0 = 0x" ++ showHex d0
              putStrLn $ ">>> A1 = 0x" ++ showHex a1 ++
                         "\t\t>>> D1 = 0x" ++ showHex d1
              putStrLn $ ">>> A2 = 0x" ++ showHex a2 ++
                         "\t\t>>> D2 = 0x" ++ showHex d2
              putStrLn $ ">>> A3 = 0x" ++ showHex a3 ++
                         "\t\t>>> D3 = 0x" ++ showHex d3
              putStrLn $ ">>> A4 = 0x" ++ showHex a4 ++
                         "\t\t>>> D4 = 0x" ++ showHex d4
              putStrLn $ ">>> A5 = 0x" ++ showHex a5 ++
                         "\t\t>>> D5 = 0x" ++ showHex d5
              putStrLn $ ">>> A6 = 0x" ++ showHex a6 ++
                         "\t\t>>> D6 = 0x" ++ showHex d6
              putStrLn $ ">>> A7 = 0x" ++ showHex a7 ++
                         "\t\t>>> D7 = 0x" ++ showHex d7
              putStrLn $ ">>> PC = 0x" ++ showHex pc
              putStrLn $ ">>> SR = 0x" ++ showHex sr
          Left err -> putStrLn $ "Failed with error: " ++ show err ++ " (" ++
                                 strerror err ++ ")"
  
  main :: IO ()
  main =
      testM68k
  