cleanly separate peripherals from IO controller