boardCircuit :: forall clk. (Clock clk)
             => (CPUSocketIn clk -> CPUSocketOut clk)
             -> (ROMAddr -> Byte)
             -> Signal clk (Pipe VAddr Nybble)
boardCircuit cpu romContents = vpipe
  where
    CPUSocketOut{..} = cpu CPUSocketIn{..}

    mpipe :: Signal clk (Pipe RAMAddr Byte)
    mpipe = packEnabled (isEnabled csMemW .&. isRAM) $
            pack (unsigned csMemA, enabledVal csMemW)
    ram = writeMemory mpipe

    ramR = syncRead ram (unsigned csMemA)

    vpipe :: Signal clk (Pipe VAddr U4)
    vpipe = packEnabled (isEnabled csMemW .&&. isVideo) $
            pack (unsigned (csMemA - 0x0200), unsigned $ enabledVal csMemW)

    romR = rom (unsigned csMemA) (Just . romContents)

    isVideo = 0x0200 .<=. csMemA .&&. csMemA .<. 0x0600
    isRAM = csMemA .<. 0x4000
    isROM = 0xF000 .<=. csMemA

    csMemR = forceDefined 0 $
             memoryMapping [ (isRAM, ramR)
                           , (isROM, romR)
                           ]
boardCircuit :: forall clk. (Clock clk)
             => (CPUSocketIn clk -> CPUSocketOut clk)
             -> (ROMAddr -> Byte)
             -> Signal clk (Pipe VAddr Nybble)
boardCircuit cpu romContents = vpipe
  where
    CPUSocketOut{..} = cpu CPUSocketIn{..}

    mpipe :: Signal clk (Pipe RAMAddr Byte)
    mpipe = packEnabled (isEnabled csMemW .&. isRAM) $
            pack (unsigned csMemA, enabledVal csMemW)
    ram = writeMemory mpipe

    ramR = syncRead ram (unsigned csMemA)

    vpipe :: Signal clk (Pipe VAddr U4)
    vpipe = packEnabled (isEnabled csMemW .&&. isVideo) $
            pack (unsigned (csMemA - 0x0200), unsigned $ enabledVal csMemW)

    romR = rom (unsigned csMemA) (Just . romContents)

    isVideo = 0x0200 .<=. csMemA .&&. csMemA .<. 0x0600
    isRAM = csMemA .<. 0x4000
    isROM = 0xF000 .<=. csMemA

    csMemR = forceDefined 0 $
             memoryMapping [ (isRAM, ramR)
                           , (isROM, romR)
                           ]
boardCircuit cpu romContents = vpipe
  where
    CPUSocketOut{..} = cpu CPUSocketIn{..}

    mpipe :: Signal clk (Pipe RAMAddr Byte)
    mpipe = packEnabled (isEnabled csMemW .&. isRAM) $
            pack (unsigned csMemA, enabledVal csMemW)
    ram = writeMemory mpipe

    ramR = syncRead ram (unsigned csMemA)

    vpipe :: Signal clk (Pipe VAddr U4)
    vpipe = packEnabled (isEnabled csMemW .&&. isVideo) $
            pack (unsigned (csMemA - 0x0200), unsigned $ enabledVal csMemW)

    romR = rom (unsigned csMemA) (Just . romContents)

    isVideo = 0x0200 .<=. csMemA .&&. csMemA .<. 0x0600
    isRAM = csMemA .<. 0x4000
    isROM = 0xF000 .<=. csMemA

    csMemR = forceDefined 0 $
             memoryMapping [ (isRAM, ramR)
                           , (isROM, romR)
                           ]