/*************************************************************************** * Copyright (C) 2005 by Mark Six * * marksix@xs4all.nl * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ /* Revision History * V0.1: - Initial Version * V0.2: * ADDED * - Improved debugging. Added Execution and Breakpoint icons in border. * - Show more compiler messages. * - Improved Syntax Highlighting (Now automatically installed). * - Improved the assembler. (Code is still a mess!) * - Added icons. * - Installation of the .desktop file is now in 'Development' * V0.3: * ADDED * - Export to HEX and MEM files * V0.4: * ADDED * - Expanded the debug toolbar. * V0.5: * BUG FIX * - Assembler: 'ORR sX, sY' assembled to 'ORR sX, kk' where kk was undefined * - Simulator: SUBCY sX, sY simulated wrongly (undefined behaviour) * SUBCY sX, kk simulated wrongly (undefined behaviour) * IMPROVED * - Change port ID per port and in serial window. * ADDED * - Save/Restore settings. * - Clear serial view popupmenu * * V0.6: * ADDED * - Debian packaging support by "Adrian Knoth" * - Initial JTAG support * - Initial Help * * IDEAS (Oct 9, 2005) * - Multiple picoblaze support * - IO ports (and irq) can be changed from other software. * - Download mem file with JTAG */ #include "kpicosim.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "kexportdialog.h" #include "kjtagdialog.h" #include #include #include #include #include #include const char version[] = "0.6" ; enum IDs { START_SIM_ID = 0, COMPILE_ID, RUN_ID, NEXT_ID, INTERRUPT_ID, RESET_ID, VIEW_SERIAL_ID, VIEW_SCRATCHPAD_ID } ; KPicoSim::KPicoSim() : TDEMainWindow( 0, "KPicoSim" ) { // set the shell's ui resource file // setXMLFile("kpicosimui.rc"); m_splitter = new TQSplitter( this ) ; m_tabWidget = new TQTabWidget( m_splitter ) ; m_editor = new CodeEditor( m_tabWidget ) ; m_messages = new TDEListView( m_splitter, "messages" ) ; m_simulator = new KSimulator( this ) ; m_processorView = new TDEProcessorView( this ) ; m_tabWidget->addTab( m_editor, "Source" ) ; addDockWindow( m_processorView, DockLeft ) ; m_splitter->setOrientation( TQt::Vertical ) ; setCentralWidget( m_splitter ) ; m_messages->setAllColumnsShowFocus( true ) ; m_messages->setFullWidth( true ) ; m_messages->resize( m_messages->width(), m_splitter->height() / 5 ) ; buildMenu() ; TDEToolBar *toolbar = new TDEToolBar( this ) ; addDockWindow( toolbar ) ; toolbar->insertButton( "document-new", -1, TQ_SIGNAL( clicked() ), m_editor, TQ_SLOT( slotNewFile() ), true, "New" ) ; toolbar->insertButton( "document-open", -1, TQ_SIGNAL( clicked() ), m_editor, TQ_SLOT( slotOpen() ), true, "Open" ) ; toolbar->insertButton( "document-save", -1, TQ_SIGNAL( clicked() ), m_editor, TQ_SLOT( slotSave() ), true, "Save" ) ; toolbar->insertButton( "document-save-as", -1, TQ_SIGNAL( clicked() ), m_editor, TQ_SLOT( slotSaveAs() ), true, "Save As" ) ; m_debugBar = new TDEToolBar( this ) ; addDockWindow( m_debugBar ) ; m_debugBar->insertButton( UserIcon( "rebuild" ), COMPILE_ID, TQ_SIGNAL( clicked() ), this, TQ_SLOT( compile() ), true, "Compile" ) ; m_debugBar->insertButton( "system-run", START_SIM_ID, TQ_SIGNAL( clicked() ), this, TQ_SLOT( startSim() ), true, "Start/Stop Debug" ) ; m_debugBar->insertSeparator() ; m_debugBar->insertButton( UserIcon( "continue" ), RUN_ID, TQ_SIGNAL( clicked() ), this, TQ_SLOT( startStop() ), false, "Continue" ) ; m_debugBar->insertButton( UserIcon( "next" ), NEXT_ID, TQ_SIGNAL( clicked() ), m_simulator, TQ_SLOT( next() ), false, "Next" ) ; m_debugBar->insertButton( UserIcon( "interrupt" ), INTERRUPT_ID, TQ_SIGNAL( clicked() ), m_simulator, TQ_SLOT( interrupt() ), false, "Interrupt" ) ; m_debugBar->insertButton( UserIcon( "reset" ), RESET_ID, TQ_SIGNAL( clicked() ), m_simulator, TQ_SLOT( reset() ), false, "Reset" ) ; connect( this, TQ_SIGNAL( run() ), m_simulator, TQ_SLOT( run() ) ); connect( this, TQ_SIGNAL( stop() ), m_simulator, TQ_SLOT( stop() ) ) ; connect( m_simulator, TQ_SIGNAL( stepped( unsigned int ) ), this, TQ_SLOT( stepped( unsigned int ) ) ) ; connect( m_processorView, TQ_SIGNAL( processorRegsChanged() ), this, TQ_SLOT( updateProcessorRegs() ) ) ; connect( m_processorView, TQ_SIGNAL( processorFlagsChanged() ), this, TQ_SLOT( updateProcessorFlags() ) ) ; connect( m_messages, TQ_SIGNAL( clicked( TQListViewItem * ) ), this, TQ_SLOT( messageListClicked( TQListViewItem * ) ) ) ; m_messages->addColumn( "Line" ) ; m_messages->addColumn( "Description" ) ; m_messages->setSorting( -1, FALSE ) ; m_simulator->setMessageList( m_messages ) ; m_simulationMode = false ; m_scratchpadView = NULL ; m_serialView = NULL ; statusBar()->insertItem( TQString( "Mode: Edit" ), 0 ) ; statusBar()->insertItem( TQString( "Status: Stopped" ), 1 ) ; statusBar()->insertItem( TQString( "Instructions: 0" ), 2 ) ; m_templateFile = "" ; m_outputDir = "" ; m_entityName = "mpu_rom" ; openGUI() ; } void KPicoSim::buildMenu() { TDEIconLoader * ldr = TDEGlobal::iconLoader() ; TDEPopupMenu * exportMenu = new TDEPopupMenu( this ) ; exportMenu->insertItem( "VHDL", this, TQ_SLOT( fileExportVHDL() ) ) ; // exportMenu->insertItem( "COE", this, TQ_SLOT( fileExportCOE() ) ) ; exportMenu->insertItem( "MEM", this, TQ_SLOT( fileExportMEM() ) ) ; exportMenu->insertItem( "HEX", this, TQ_SLOT( fileExportHEX() ) ) ; m_fileMenu = new TDEPopupMenu( this ) ; m_fileMenu->insertItem( ldr->loadIcon( "document-new", TDEIcon::Small ), "New", this, TQ_SLOT( slotFileNew() ) ) ; m_fileMenu->insertItem( ldr->loadIcon( "document-open", TDEIcon::Small ), "Open", m_editor, TQ_SLOT( slotOpen() ) ) ; m_fileMenu->insertSeparator() ; m_fileMenu->insertItem( ldr->loadIcon( "document-save", TDEIcon::Small ), "Save", m_editor, TQ_SLOT( slotSave() ), TQKeySequence( "CTRL+S" ) ) ; m_fileMenu->insertItem( ldr->loadIcon( "document-save-as", TDEIcon::Small ), "Save As...", m_editor, TQ_SLOT( slotSaveAs() ) ) ; m_fileMenu->insertSeparator() ; m_fileMenu->insertItem( ldr->loadIcon( "document-print", TDEIcon::Small ), "Print...", m_editor, TQ_SLOT( slotPrint() ), TQKeySequence( "CTRL+P" ) ) ; m_fileMenu->insertSeparator() ; m_fileMenu->insertItem( "Export", exportMenu ) ; m_fileMenu->insertSeparator() ; m_fileMenu->insertItem( ldr->loadIcon( "window-close", TDEIcon::Small ), "Quit", this, TQ_SLOT( slotClose() ) ) ; m_editMenu = new TDEPopupMenu( this ) ; m_editMenu->insertItem( ldr->loadIcon( "edit-undo", TDEIcon::Small ), "Undo", m_editor, TQ_SLOT( slotUndo() ),TQKeySequence( "CTRL+Z" ) ) ; m_editMenu->insertItem( ldr->loadIcon( "edit-redo", TDEIcon::Small ), "Redo", m_editor, TQ_SLOT( slotRedo() ),TQKeySequence( "CTRL+SHIFT+Z" ) ) ; m_editMenu->insertSeparator() ; m_editMenu->insertItem( "Select All", m_editor, TQ_SLOT( slotSelectAll() ),TQKeySequence( "CTRL+A" ) ) ; m_editMenu->insertSeparator() ; m_editMenu->insertItem( ldr->loadIcon( "edit-cut", TDEIcon::Small ), "Cut", m_editor, TQ_SLOT( slotCut() ),TQKeySequence( "CTRL+X" ) ) ; m_editMenu->insertItem( ldr->loadIcon( "edit-copy", TDEIcon::Small ), "Copy", m_editor, TQ_SLOT( slotCopy() ),TQKeySequence( "CTRL+C" ) ) ; m_editMenu->insertItem( ldr->loadIcon( "edit-paste", TDEIcon::Small ), "Paste", m_editor, TQ_SLOT( slotPaste() ),TQKeySequence( "CTRL+V" ) ) ; m_editMenu->insertSeparator() ; m_editMenu->insertItem( ldr->loadIcon( "edit-find", TDEIcon::Small ), "Find...", m_editor, TQ_SLOT( slotFind() ), TQKeySequence( "CTRL+F" ) ) ; m_editMenu->insertItem( "Find Next", m_editor, TQ_SLOT( slotFindNext() ), TQKeySequence( "F3" ) ) ; m_debugMenu = new TDEPopupMenu( this ) ; m_debugMenu->insertSeparator() ; m_debugMenu->insertItem( ldr->loadIcon( "rebuild", TDEIcon::Small ), "Compile", this, TQ_SLOT( compile() ), TQKeySequence( "SHIFT+F9" ) ) ; m_debugMenu->insertItem( ldr->loadIcon( "system-run", TDEIcon::Small ), "Start Debug", this, TQ_SLOT( startSim() ), TQKeySequence( "F9" ) , START_SIM_ID ) ; m_debugMenu->insertSeparator() ; m_debugMenu->insertItem( "Continue", this, TQ_SLOT( startStop() ), TQKeySequence( "F10" ) , RUN_ID ) ; m_debugMenu->insertItem( "Next", m_simulator, TQ_SLOT( next() ), TQKeySequence( "F5" ) , NEXT_ID ) ; m_debugMenu->insertItem( "Interrupt", m_simulator, TQ_SLOT( interrupt() ), TQKeySequence( "F4" ) , INTERRUPT_ID ) ; m_debugMenu->insertItem( "Reset", m_simulator, TQ_SLOT( reset() ), TQKeySequence( "F11" ) , RESET_ID ) ; m_debugMenu->insertSeparator() ; m_debugMenu->insertItem( "Toggle Breakpoint", m_editor, TQ_SLOT( slotToggleBreakpoint() ), TQKeySequence( "F8" ) ) ; m_settingsMenu = new TDEPopupMenu( this ) ; m_settingsMenu->insertItem( "Configure Editor...", m_editor, TQ_SLOT( slotShowConfig() ) ) ; m_peripheralMenu = new TDEPopupMenu( this ) ; m_peripheralMenu->insertItem( "I/O Port", this, TQ_SLOT( newIOPort() ) ) ; m_peripheralMenu->insertItem( "Scratchpad", this, TQ_SLOT( showScratchpad() ), 0, VIEW_SCRATCHPAD_ID ) ; m_peripheralMenu->insertItem( "Serial port", this, TQ_SLOT( showSerialPort() ), 0, VIEW_SERIAL_ID ) ; m_jtagMenu = new TDEPopupMenu( this ) ; m_jtagMenu->insertItem( "Download", this, TQ_SLOT( jtagDownload() ) ) ; TDEAboutData *aboutData = new TDEAboutData( "kpicosim", "kpicosim", version, "IDE for the picoblaze\n\nCopyright (c) 2005 Mark Six", TDEAboutData::License_GPL, 0, 0, "http://www.xs4all.nl/~marksix", "m6@xs4all.nl" ) ; aboutData->addAuthor( "Mark Six", "m6@xs4all.nl", "http://www.xs4all.nl/~marksix" ) ; KHelpMenu *helpMenu = new KHelpMenu( this, aboutData, false ) ; TDEPopupMenu *help = helpMenu->menu() ; menuBar()->insertItem( "File", m_fileMenu ) ; menuBar()->insertItem( "Edit", m_editMenu ) ; menuBar()->insertItem( "Debug", m_debugMenu ) ; menuBar()->insertItem( "Peripheral", m_peripheralMenu ) ; menuBar()->insertItem( "JTAG", m_jtagMenu ) ; menuBar()->insertItem( "Settings", m_settingsMenu ) ; menuBar()->insertItem( "Help", help ) ; m_debugMenu->setItemEnabled( RUN_ID, false ) ; m_debugMenu->setItemEnabled( NEXT_ID, false ) ; m_debugMenu->setItemEnabled( INTERRUPT_ID, false ) ; m_debugMenu->setItemEnabled( RESET_ID, false ) ; m_peripheralMenu->setCheckable( true ); m_peripheralMenu->setItemChecked( VIEW_SERIAL_ID, false ) ; m_peripheralMenu->setItemChecked( VIEW_SCRATCHPAD_ID, false ) ; menuBar()->show() ; } void KPicoSim::jtagDownload() { /* JTAG is still in its infancy. This code works for me. I'm using the Xilinx Spartan-3 * development board. If it works for you, great, if not too bad... */ KJTAGDialog dlg( this ) ; dlg.setFilename( m_bitfile ) ; dlg.exec() ; m_bitfile = dlg.getFilename() ; } void KPicoSim::fileExportCOE() { KMessageBox::information( this, "This function is not supported yet", "Export COE" ) ; // if ( compile() ) { //m_simulator->exportCOE() ; // } } void KPicoSim::fileExportHEX() { TQString filename = KFileDialog::getSaveFileName( TQString(), "*.hex|HEX files\n*|All files", this, "Export HEX" ) ; if ( filename != "" && compile() ) { m_simulator->exportHEX( filename.ascii(), FALSE ) ; } } void KPicoSim::fileExportMEM() { TQString filename = KFileDialog::getSaveFileName( TQString(), "*.mem|MEM files\n*|All files", this, "Export MEM" ) ; if ( filename != "" && compile() ) { m_simulator->exportHEX( filename.ascii(), TRUE ) ; } } void KPicoSim::fileExportVHDL() { KExportDialog dlg( this ) ; dlg.setTemplateFile( m_templateFile ) ; dlg.setOutputDir( m_outputDir ) ; dlg.setEntityName( m_entityName ) ; dlg.modal() ; if ( dlg.isCanceled() ) return ; m_templateFile = dlg.getTemplateFile() ; m_outputDir = dlg.getOutputDir() ; m_entityName = dlg.getEntityName() ; if ( compile() && m_simulator->exportVHDL( m_templateFile.ascii(), m_outputDir.ascii(), m_entityName.ascii() ) ) { appendMessage( "File '" + m_outputDir + "/" + m_entityName + ".vhd' exported" ) ; appendMessage( "Template file '" + m_templateFile + "' used" ) ; appendMessage( "***Export Success***" ) ; } else { appendMessage( "***Export failed***" ) ; } } void KPicoSim::slotFileNew() { if ( m_editor->close() ) m_editor->slotNewFile() ; } void KPicoSim::slotClose() { close() ; } void KPicoSim::closeEvent( TQCloseEvent * e ) { if ( m_editor->close() ) e->accept() ; // Save filename last opened // Save windows IO Ports, peripherals et al. closeGUI() ; } void KPicoSim::newIOPort() { KPortView * ioport = new KPortView( m_simulator->getCpu(), 0 ) ; /* port id is 0 */ // m_ioList.append( ioport ) ; addDockWindow( ioport, DockRight ) ; // connect( ioport, TQ_SIGNAL( closing( KPortView* ) ), this, TQ_SLOT( removeIOPort( KPortView* ) ) ) ; } void KPicoSim::showSerialPort() { if ( m_serialView == NULL ) { m_serialView = new KSerialView( m_simulator->getCpu(), m_tabWidget ) ; m_tabWidget->addTab( m_serialView, "Serial" ) ; m_peripheralMenu->setItemChecked( VIEW_SERIAL_ID, true ) ; } else { m_peripheralMenu->setItemChecked( VIEW_SERIAL_ID, false ) ; delete m_serialView ; m_serialView = NULL ; } } void KPicoSim::showScratchpad() { if ( m_scratchpadView == NULL ) { m_scratchpadView = new KScratchpadView( this ) ; updateScratchpadView() ; addDockWindow( m_scratchpadView, DockRight ) ; m_peripheralMenu->setItemChecked( VIEW_SCRATCHPAD_ID, true ) ; } else { m_peripheralMenu->setItemChecked( VIEW_SCRATCHPAD_ID, false ) ; delete m_scratchpadView ; m_scratchpadView = NULL ; } } KPicoSim::~KPicoSim() { // Delete dockwindows // These are the IO ports, scratchpad and the processorview dockWindows().setAutoDelete( true ) ; dockWindows().clear() ; if ( m_serialView ) delete m_serialView ; delete m_simulator ; delete m_debugMenu ; delete m_editMenu ; delete m_peripheralMenu ; delete m_fileMenu ; delete m_settingsMenu ; } void KPicoSim::startStop() { if ( m_simulationMode ) { if ( !m_simulator->isRunning() ) { m_debugMenu->changeItem( RUN_ID, "Stop" ) ; m_editor->clearExecutionMarker() ; m_simulator->run() ; statusBar()->changeItem( TQString( "Status: Running" ), 1 ) ; m_debugBar->setButton( RUN_ID, true ) ; } else { m_simulator->stop() ; updateViews() ; m_debugMenu->changeItem( RUN_ID, "Continue" ) ; m_editor->setExecutionMarker( m_simulator->getNextSourceLine() ) ; statusBar()->changeItem( TQString( "Status: Stopped" ), 1 ) ; TQString str ; str.sprintf( "Instructions: %u", m_nrInstructions ) ; statusBar()->changeItem( str, 2 ) ; m_debugBar->setButton( RUN_ID, false ) ; } } } void KPicoSim::messageListClicked( TQListViewItem *item ) { if ( item ) { bool ok ; int line = item->text(0).toInt( &ok, 10 ) ; if ( ok ) m_editor->setCursor( line - 1 ) ; // C-programmers do it from zero } } void KPicoSim::updateProcessorRegs() { unsigned char regValues[ 16 ] ; m_processorView->getRegisterValues( regValues ) ; m_simulator->setRegisterValues( regValues ) ; } void KPicoSim::updateProcessorFlags() { m_simulator->setFlags( m_processorView->getFlags() ) ; } void KPicoSim::updateViews() { unsigned char regValues[ 16 ] ; m_simulator->getRegisterValues( regValues ) ; m_processorView->setRegisterValues( regValues ) ; m_processorView->setFlags( m_simulator->getFlags() ) ; updateScratchpadView() ; TQString str ; str.sprintf( "Instructions: %u", m_nrInstructions ) ; statusBar()->changeItem( str, 2 ) ; } void KPicoSim::updateScratchpadView() { if ( m_scratchpadView != NULL ) { unsigned char sp_ram[ 64 ] ; m_simulator->getScratchpad( sp_ram ) ; m_scratchpadView->setContent( sp_ram, sizeof( sp_ram ) ) ; } } void KPicoSim::stepped( unsigned int line ) { m_nrInstructions++ ; if ( m_simulator->isRunning() ) { if ( m_editor->isBreakpoint( line ) ) { ; startStop() ; m_editor->setExecutionMarker( line ) ; } else if ( (m_nrInstructions % 100 ) == 0 ) { updateViews() ; } } else { m_editor->setExecutionMarker( line ) ; updateViews() ; } } void KPicoSim::appendMessage( TQString str ) { TQListViewItem *item = new TQListViewItem( m_messages, m_messages->lastChild() ) ; item->setText( 0, "" ) ; item->setText( 1, str ) ; } bool KPicoSim::compile() { m_simulator->clear() ; m_messages->clear() ; if ( !m_editor->save() ) return FALSE; appendMessage( "File '" + m_editor->getFilename() + "' saved" ) ; m_simulator->setFilename( m_editor->getFilename().ascii() ) ; if ( m_simulator->compile() == TRUE ) { appendMessage( "***Compile Success*** " ) ; return TRUE ; } else { appendMessage( "***Compile Failed*** " ) ; return FALSE ; } } void KPicoSim::startSim() { TDEIconLoader * ldr = TDEGlobal::iconLoader() ; if ( !m_simulationMode ) { if ( compile() ) { setCaption( m_editor->getFilename() + " [Debugging]" ) ; m_debugMenu->changeItem( START_SIM_ID, ldr->loadIcon( "process-stop", TDEIcon::Small ), "Stop Debug" ) ; m_debugBar->setButton( START_SIM_ID, true ) ; m_simulator->reset() ; m_nrInstructions = 0 ; m_simulationMode = TRUE ; } } else { if ( m_simulator->isRunning() ) startStop() ; setCaption( m_editor->getFilename() ) ; m_debugMenu->changeItem( START_SIM_ID, ldr->loadIcon( "system-run", TDEIcon::Small ), "Start Debug" ) ; m_debugBar->setButton( START_SIM_ID, false ) ; m_editor->clearExecutionMarker() ; m_simulationMode = FALSE ; } if ( m_simulationMode ) { statusBar()->changeItem( TQString( "Mode: Debug" ), 0 ) ; } else { statusBar()->changeItem( TQString( "Mode: Edit" ), 0 ) ; } m_debugMenu->setItemEnabled( RUN_ID, m_simulationMode ) ; m_debugMenu->setItemEnabled( NEXT_ID, m_simulationMode ) ; m_debugMenu->setItemEnabled( INTERRUPT_ID, m_simulationMode ) ; m_debugMenu->setItemEnabled( RESET_ID, m_simulationMode ) ; m_debugBar->setItemEnabled( RUN_ID, m_simulationMode ) ; m_debugBar->setItemEnabled( NEXT_ID, m_simulationMode ) ; m_debugBar->setItemEnabled( INTERRUPT_ID, m_simulationMode ) ; m_debugBar->setItemEnabled( RESET_ID, m_simulationMode ) ; } /* void KPicoSim::removeIOPort( KPortView* ioport ) { m_ioList.removeRef( ioport ) ; } */ void KPicoSim::closeGUI() { KSimpleConfig config( "kpicosim" ) ; config.setGroup( "Peripherals" ) ; config.writeEntry( "serial", m_serialView != NULL ) ; config.writeEntry( "scratchpad", m_scratchpadView != NULL ) ; config.writeEntry( "filename", m_editor->getFilename() ) ; config.writeEntry( "bitfile", m_bitfile ) ; /* config.writeEntry( "numIOPorts", m_ioList.count() ) ; for ( int i = 0 ; i < m_ioList.count() ; i++ ) { TQString group ; group.sprintf( "IO Port %d", i ) ; m_ioList.at(i)->writeConfig( config, group ) ; } */ } void KPicoSim::openGUI() { KSimpleConfig config( "kpicosim" ) ; config.setGroup( "Peripherals" ) ; if ( config.readPropertyEntry( "serial", TQVariant::Bool ).toBool() ) showSerialPort() ; if ( config.readPropertyEntry( "scratchpad", TQVariant::Bool ).toBool() ) showScratchpad() ; m_editor->open( config.readEntry( "filename" ) ) ; m_bitfile = config.readEntry( "bitfile" ) ; /* int nports = config.readPropertyEntry( "numIOPorts", TQVariant::Int ).toInt() ; for ( int i = 0 ; i < nports ; i++ ) { TQString group ; group.sprintf( "IO Port %d", i ) ; KPortView * ioport = new KPortView( m_simulator->getCpu(), 0 ) ; ioport->readConfig( config, group ) ; m_ioList.append( ioport ) ; addDockWindow( ioport, DockRight ) ; connect( ioport, TQ_SIGNAL( closing( KPortView* ) ), this, TQ_SLOT( removeIOPort( KPortView* ) ) ) ; } */ } #include "kpicosim.moc"