/**
   * Instantiate and attach a dynamic PLPSimBusModule-based module to this I/O registry and to the
   * bus of the given simulation core. PLPDynamicModuleFramework is called to create a new instance
   * of the module.
   *
   * @param index Index of the dynamic module CLASS
   * @param addr Starting address of the module's memory map
   * @param size Number of registers
   * @param isWordAligned Denote whether the module's address space is word aligned
   * @param frame Frame object associated with this module
   * @return PLP_OK on completion, or PLP_DBUSMOD_INSTANTIATION_ERROR if the module object failed to
   *     initialize
   */
  public int attachDynamicModule(
      int index, long startAddr, long endAddr, boolean isWordAligned, Object frame) {
    moduleFrames.add(frame);
    PLPSimBusModule module = DynamicModuleFramework.newBusModuleInstance(index);

    if (module == null) return Constants.PLP_DMOD_INSTANTIATION_ERROR;

    module.setNewParameters(startAddr, endAddr, isWordAligned);
    modules.add(module);
    type.add(-1); // -1 for dynamic module
    regSize.add(isWordAligned ? (endAddr - startAddr) / 4 + 1 : endAddr - startAddr + 1);
    module.enable();
    positionInBus.add(plp.sim.bus.add(module));

    return Constants.PLP_OK;
  }
  /**
   * Instantiate and attach a PLPSimBusModule-based module to this I/O registry and to the bus of
   * the given simulation core. This method also associates a module with its internal frame, if GUI
   * representation is implemented. Module developers will have to write their module's
   * initialization here.
   *
   * @param index Module type as registered in the constructor.
   * @param addr The starting address of the module's address space.
   * @param size The size of the module's address space.
   * @return PLP_OK on completion, or PLP_SIM_INVALID_MODULE if invalid index is specified.
   */
  public int attachModuleToBus(int index, long addr, long size) {
    // we're not loading dynamic modules from here (index -1)
    if (index < 0) return Constants.PLP_OK;

    PLPSimBusModule module = null;
    Object moduleFrame = null;

    Msg.D("Loading " + mods[index][0], 3, this);

    switch (index) {

        // This is where the modules are initialized when the simulator
        // requests an I/O module instance to be created.

        /** *************************************************************** */
        // PLPSimMemModule is summoned
      case 0:
        module = new MemModule(addr, size, true);

        break;

        /** *************************************************************** */
        // LEDArray is summoned
      case 1:
        module = new LEDArray(addr);
        if (plp.g()) {
          moduleFrame = new LEDArrayFrame();
          attachModuleFrameListeners((JFrame) moduleFrame, plp, Constants.PLP_TOOLFRAME_SIMLEDS);
        }

        break;

        /** *************************************************************** */
        // Switches is summoned
      case 2:
        module = new Switches(addr);
        if (plp.g()) {
          moduleFrame = new SwitchesFrame((Switches) module);
          attachModuleFrameListeners(
              (JFrame) moduleFrame, plp, Constants.PLP_TOOLFRAME_SIMSWITCHES);
        }

        break;

        /** *************************************************************** */
        // FTrace is requested, he doesn't respond to summons
      case 3:
        module = new FTracer(addr, size);
        break;

        /** *************************************************************** */
        // PLPID is summoned
      case 4:
        module = new PLPID(addr);
        if (plp.g()) {
          moduleFrame = new PLPIDFrame((PLPID) module);
          attachModuleFrameListeners((JFrame) moduleFrame, plp, Constants.PLP_TOOLFRAME_SIMPLPID);
        }
        break;

        /** *************************************************************** */
        // DummyMemory is summoned
      case 5:
        module = new DummyMemory(addr, size, true);
        break;

        /** *************************************************************** */
        // VGA is summoned
      case 6:
        if (plp.g()) {
          moduleFrame = new VGAFrame();
          attachModuleFrameListeners((JFrame) moduleFrame, plp, Constants.PLP_TOOLFRAME_SIMVGA);
        }
        module = new VGA(addr, plp.sim.bus, (VGAFrame) moduleFrame);
        module.threaded = plptool.Config.threadedModEnabled;
        module.stop = false;
        if (module.threaded) module.start();
        break;

        /** *************************************************************** */
        // Timer is summoned
      case 7:
        module = new Timer(addr, plp.sim);
        break;

        /** *************************************************************** */
        // UART is summoned
      case 8:
        if (plp.g()) {
          moduleFrame = new UARTFrame();
          attachModuleFrameListeners((JFrame) moduleFrame, plp, Constants.PLP_TOOLFRAME_SIMUART);
        }
        module = new UART(addr, (UARTFrame) moduleFrame, plp.sim);
        break;

        /** *************************************************************** */
        // Seven Segments is summoned
      case 9:
        module = new SevenSegments(addr);
        if (plp.g()) {
          moduleFrame = new SevenSegmentsFrame();
          attachModuleFrameListeners(
              (JFrame) moduleFrame, plp, Constants.PLP_TOOLFRAME_SIMSEVENSEGMENTS);
        }

        break;

        /** *************************************************************** */
        // Interrupt Controller is summoned
      case 10:
        module = new InterruptController(addr, plp.sim);

        break;

        /** *************************************************************** */
        // Bus monitor is summoned
      case 11:
        module = new BusMonitor(plp.sim);
        if (plp.g()) {
          moduleFrame = new BusMonitorFrame((BusMonitor) module, null);
        }

        break;

        /** *************************************************************** */
        // GPIO is summoned
      case 12:
        module = new GPIO(addr);
        if (plp.g()) {
          moduleFrame = new GPIOFrame((GPIO) module);
          attachModuleFrameListeners((JFrame) moduleFrame, plp, Constants.PLP_TOOLFRAME_SIMGPIO);
        }

        break;

        // ADD YOUR MODULE INITIALIZATION HERE

        // ...3rd party code...//

        /** DO NOT EDIT ANYTHING BELOW THIS * */
      default:
        return Msg.E(
            "attachModuleToBus(): invalid module ID.", Constants.PLP_SIM_INVALID_MODULE, this);
    }

    moduleFrames.add(moduleFrame);
    modules.add(module);
    type.add(index);
    regSize.add(size);
    module.enable();
    positionInBus.add(plp.sim.bus.add(module));

    // if(moduleFrame != null && moduleFrame instanceof JFrame) {
    // attachModuleFrameListeners((JFrame) moduleFrame, plp);
    // simDesktop.add((JFrame) moduleFrame);
    // ((JFrame) moduleFrame).setVisible(true);
    // }

    return Constants.PLP_OK;
  }