|
|
|
/***************************************************************************
|
|
|
|
* 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 <tqlabel.h>
|
|
|
|
|
|
|
|
#include <kmainwindow.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
|
|
|
|
#include <kmenubar.h>
|
|
|
|
#include <tqlayout.h>
|
|
|
|
#include <tqkeysequence.h>
|
|
|
|
#include <knuminput.h>
|
|
|
|
#include <tqnamespace.h>
|
|
|
|
#include <kportview.h>
|
|
|
|
#include <tqdockwindow.h>
|
|
|
|
#include <kstatusbar.h>
|
|
|
|
#include <kiconloader.h>
|
|
|
|
#include "kexportdialog.h"
|
|
|
|
#include "kjtagdialog.h"
|
|
|
|
#include <kfiledialog.h>
|
|
|
|
#include <kmessagebox.h>
|
|
|
|
#include <tqlayout.h>
|
|
|
|
#include <ksimpleconfig.h>
|
|
|
|
#include <khelpmenu.h>
|
|
|
|
#include <kaboutdata.h>
|
|
|
|
|
|
|
|
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() : KMainWindow( 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 KListView( m_splitter, "messages" ) ;
|
|
|
|
m_simulator = new KSimulator( TQT_TQOBJECT(this) ) ;
|
|
|
|
m_processorView = new KProcessorView( this ) ;
|
|
|
|
|
|
|
|
m_tabWidget->addTab( m_editor, "Source" ) ;
|
|
|
|
addDockWindow( m_processorView, DockLeft ) ;
|
|
|
|
|
|
|
|
m_splitter->setOrientation( Qt::Vertical ) ;
|
|
|
|
setCentralWidget( m_splitter ) ;
|
|
|
|
m_messages->setAllColumnsShowFocus( true ) ;
|
|
|
|
m_messages->setFullWidth( true ) ;
|
|
|
|
m_messages->resize( m_messages->width(), m_splitter->height() / 5 ) ;
|
|
|
|
|
|
|
|
buildMenu() ;
|
|
|
|
|
|
|
|
KToolBar *toolbar = new KToolBar( this ) ;
|
|
|
|
addDockWindow( toolbar ) ;
|
|
|
|
|
|
|
|
toolbar->insertButton( "filenew", -1, TQT_SIGNAL( clicked() ), TQT_TQOBJECT(m_editor), TQT_SLOT( slotNewFile() ), true, "New" ) ;
|
|
|
|
toolbar->insertButton( "fileopen", -1, TQT_SIGNAL( clicked() ), TQT_TQOBJECT(m_editor), TQT_SLOT( slotOpen() ), true, "Open" ) ;
|
|
|
|
toolbar->insertButton( "filesave", -1, TQT_SIGNAL( clicked() ), TQT_TQOBJECT(m_editor), TQT_SLOT( slotSave() ), true, "Save" ) ;
|
|
|
|
toolbar->insertButton( "filesaveas", -1, TQT_SIGNAL( clicked() ), TQT_TQOBJECT(m_editor), TQT_SLOT( slotSaveAs() ), true, "Save As" ) ;
|
|
|
|
|
|
|
|
m_debugBar = new KToolBar( this ) ;
|
|
|
|
addDockWindow( m_debugBar ) ;
|
|
|
|
m_debugBar->insertButton( UserIcon( "rebuild" ), COMPILE_ID, TQT_SIGNAL( clicked() ), TQT_TQOBJECT(this), TQT_SLOT( compile() ), true, "Compile" ) ;
|
|
|
|
m_debugBar->insertButton( "run", START_SIM_ID, TQT_SIGNAL( clicked() ), TQT_TQOBJECT(this), TQT_SLOT( startSim() ), true, "Start/Stop Debug" ) ;
|
|
|
|
m_debugBar->insertSeparator() ;
|
|
|
|
m_debugBar->insertButton( UserIcon( "continue" ), RUN_ID, TQT_SIGNAL( clicked() ), TQT_TQOBJECT(this), TQT_SLOT( startStop() ), false, "Continue" ) ;
|
|
|
|
|
|
|
|
m_debugBar->insertButton( UserIcon( "next" ), NEXT_ID, TQT_SIGNAL( clicked() ), m_simulator, TQT_SLOT( next() ), false, "Next" ) ;
|
|
|
|
m_debugBar->insertButton( UserIcon( "interrupt" ), INTERRUPT_ID, TQT_SIGNAL( clicked() ), m_simulator, TQT_SLOT( interrupt() ), false, "Interrupt" ) ;
|
|
|
|
m_debugBar->insertButton( UserIcon( "reset" ), RESET_ID, TQT_SIGNAL( clicked() ), m_simulator, TQT_SLOT( reset() ), false, "Reset" ) ;
|
|
|
|
|
|
|
|
connect( TQT_TQOBJECT(this), TQT_SIGNAL( run() ), m_simulator, TQT_SLOT( run() ) );
|
|
|
|
connect( TQT_TQOBJECT(this), TQT_SIGNAL( stop() ), m_simulator, TQT_SLOT( stop() ) ) ;
|
|
|
|
connect( m_simulator, TQT_SIGNAL( stepped( unsigned int ) ), TQT_TQOBJECT(this), TQT_SLOT( stepped( unsigned int ) ) ) ;
|
|
|
|
connect( m_processorView, TQT_SIGNAL( processorRegsChanged() ), TQT_TQOBJECT(this), TQT_SLOT( updateProcessorRegs() ) ) ;
|
|
|
|
connect( m_processorView, TQT_SIGNAL( processorFlagsChanged() ), TQT_TQOBJECT(this), TQT_SLOT( updateProcessorFlags() ) ) ;
|
|
|
|
connect( m_messages, TQT_SIGNAL( clicked( TQListViewItem * ) ), TQT_TQOBJECT(this), TQT_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( "tqStatus: Stopped" ), 1 ) ;
|
|
|
|
statusBar()->insertItem( TQString( "Instructions: 0" ), 2 ) ;
|
|
|
|
|
|
|
|
m_templateFile = "" ;
|
|
|
|
m_outputDir = "" ;
|
|
|
|
m_entityName = "mpu_rom" ;
|
|
|
|
|
|
|
|
|
|
|
|
openGUI() ;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void KPicoSim::buildMenu()
|
|
|
|
{
|
|
|
|
KIconLoader * ldr = KGlobal::iconLoader() ;
|
|
|
|
|
|
|
|
KPopupMenu * exportMenu = new KPopupMenu( this ) ;
|
|
|
|
|
|
|
|
exportMenu->insertItem( "VHDL", TQT_TQOBJECT(this), TQT_SLOT( fileExportVHDL() ) ) ;
|
|
|
|
// exportMenu->insertItem( "COE", TQT_TQOBJECT(this), TQT_SLOT( fileExportCOE() ) ) ;
|
|
|
|
exportMenu->insertItem( "MEM", TQT_TQOBJECT(this), TQT_SLOT( fileExportMEM() ) ) ;
|
|
|
|
exportMenu->insertItem( "HEX", TQT_TQOBJECT(this), TQT_SLOT( fileExportHEX() ) ) ;
|
|
|
|
|
|
|
|
m_fileMenu = new KPopupMenu( this ) ;
|
|
|
|
m_fileMenu->insertItem( ldr->loadIcon( "filenew", KIcon::Small ), "New", TQT_TQOBJECT(this), TQT_SLOT( slotFileNew() ) ) ;
|
|
|
|
m_fileMenu->insertItem( ldr->loadIcon( "fileopen", KIcon::Small ), "Open", TQT_TQOBJECT(m_editor), TQT_SLOT( slotOpen() ) ) ;
|
|
|
|
m_fileMenu->insertSeparator() ;
|
|
|
|
m_fileMenu->insertItem( ldr->loadIcon( "filesave", KIcon::Small ), "Save", TQT_TQOBJECT(m_editor), TQT_SLOT( slotSave() ), TQKeySequence( "CTRL+S" ) ) ;
|
|
|
|
m_fileMenu->insertItem( ldr->loadIcon( "filesaveas", KIcon::Small ), "Save As...", TQT_TQOBJECT(m_editor), TQT_SLOT( slotSaveAs() ) ) ;
|
|
|
|
m_fileMenu->insertSeparator() ;
|
|
|
|
m_fileMenu->insertItem( ldr->loadIcon( "fileprint", KIcon::Small ), "Print...", TQT_TQOBJECT(m_editor), TQT_SLOT( slotPrint() ), TQKeySequence( "CTRL+P" ) ) ;
|
|
|
|
m_fileMenu->insertSeparator() ;
|
|
|
|
m_fileMenu->insertItem( "Export", exportMenu ) ;
|
|
|
|
m_fileMenu->insertSeparator() ;
|
|
|
|
m_fileMenu->insertItem( ldr->loadIcon( "fileclose", KIcon::Small ), "Quit", TQT_TQOBJECT(this), TQT_SLOT( slotClose() ) ) ;
|
|
|
|
|
|
|
|
m_editMenu = new KPopupMenu( this ) ;
|
|
|
|
m_editMenu->insertItem( ldr->loadIcon( "undo", KIcon::Small ), "Undo", TQT_TQOBJECT(m_editor), TQT_SLOT( slotUndo() ),TQKeySequence( "CTRL+Z" ) ) ;
|
|
|
|
m_editMenu->insertItem( ldr->loadIcon( "redo", KIcon::Small ), "Redo", TQT_TQOBJECT(m_editor), TQT_SLOT( slotRedo() ),TQKeySequence( "CTRL+SHIFT+Z" ) ) ;
|
|
|
|
m_editMenu->insertSeparator() ;
|
|
|
|
m_editMenu->insertItem( "Select All", TQT_TQOBJECT(m_editor), TQT_SLOT( slotSelectAll() ),TQKeySequence( "CTRL+A" ) ) ;
|
|
|
|
m_editMenu->insertSeparator() ;
|
|
|
|
m_editMenu->insertItem( ldr->loadIcon( "editcut", KIcon::Small ), "Cut", TQT_TQOBJECT(m_editor), TQT_SLOT( slotCut() ),TQKeySequence( "CTRL+X" ) ) ;
|
|
|
|
m_editMenu->insertItem( ldr->loadIcon( "editcopy", KIcon::Small ), "Copy", TQT_TQOBJECT(m_editor), TQT_SLOT( slotCopy() ),TQKeySequence( "CTRL+C" ) ) ;
|
|
|
|
m_editMenu->insertItem( ldr->loadIcon( "editpaste", KIcon::Small ), "Paste", TQT_TQOBJECT(m_editor), TQT_SLOT( slotPaste() ),TQKeySequence( "CTRL+V" ) ) ;
|
|
|
|
m_editMenu->insertSeparator() ;
|
|
|
|
m_editMenu->insertItem( ldr->loadIcon( "tqfind", KIcon::Small ), "Find...", TQT_TQOBJECT(m_editor), TQT_SLOT( slotFind() ), TQKeySequence( "CTRL+F" ) ) ;
|
|
|
|
m_editMenu->insertItem( "Find Next", TQT_TQOBJECT(m_editor), TQT_SLOT( slotFindNext() ), TQKeySequence( "F3" ) ) ;
|
|
|
|
|
|
|
|
|
|
|
|
m_debugMenu = new KPopupMenu( this ) ;
|
|
|
|
m_debugMenu->insertSeparator() ;
|
|
|
|
m_debugMenu->insertItem( ldr->loadIcon( "rebuild", KIcon::Small ), "Compile", TQT_TQOBJECT(this), TQT_SLOT( compile() ), TQKeySequence( "SHIFT+F9" ) ) ;
|
|
|
|
m_debugMenu->insertItem( ldr->loadIcon( "run", KIcon::Small ), "Start Debug", TQT_TQOBJECT(this), TQT_SLOT( startSim() ), TQKeySequence( "F9" ) , START_SIM_ID ) ;
|
|
|
|
|
|
|
|
m_debugMenu->insertSeparator() ;
|
|
|
|
m_debugMenu->insertItem( "Continue", TQT_TQOBJECT(this), TQT_SLOT( startStop() ), TQKeySequence( "F10" ) , RUN_ID ) ;
|
|
|
|
m_debugMenu->insertItem( "Next", m_simulator, TQT_SLOT( next() ), TQKeySequence( "F5" ) , NEXT_ID ) ;
|
|
|
|
m_debugMenu->insertItem( "Interrupt", m_simulator, TQT_SLOT( interrupt() ), TQKeySequence( "F4" ) , INTERRUPT_ID ) ;
|
|
|
|
m_debugMenu->insertItem( "Reset", m_simulator, TQT_SLOT( reset() ), TQKeySequence( "F11" ) , RESET_ID ) ;
|
|
|
|
|
|
|
|
m_debugMenu->insertSeparator() ;
|
|
|
|
m_debugMenu->insertItem( "Toggle Breakpoint", TQT_TQOBJECT(m_editor), TQT_SLOT( slotToggleBreakpoint() ), TQKeySequence( "F8" ) ) ;
|
|
|
|
|
|
|
|
m_settingsMenu = new KPopupMenu( this ) ;
|
|
|
|
m_settingsMenu->insertItem( "Configure Editor...", TQT_TQOBJECT(m_editor), TQT_SLOT( slotShowConfig() ) ) ;
|
|
|
|
|
|
|
|
m_peripheralMenu = new KPopupMenu( this ) ;
|
|
|
|
m_peripheralMenu->insertItem( "I/O Port", TQT_TQOBJECT(this), TQT_SLOT( newIOPort() ) ) ;
|
|
|
|
m_peripheralMenu->insertItem( "Scratchpad", TQT_TQOBJECT(this), TQT_SLOT( showScratchpad() ), 0, VIEW_SCRATCHPAD_ID ) ;
|
|
|
|
m_peripheralMenu->insertItem( "Serial port", TQT_TQOBJECT(this), TQT_SLOT( showSerialPort() ), 0, VIEW_SERIAL_ID ) ;
|
|
|
|
|
|
|
|
m_jtagMenu = new KPopupMenu( this ) ;
|
|
|
|
m_jtagMenu->insertItem( "Download", TQT_TQOBJECT(this), TQT_SLOT( jtagDownload() ) ) ;
|
|
|
|
|
|
|
|
KAboutData *aboutData = new KAboutData(
|
|
|
|
"kpicosim",
|
|
|
|
"kpicosim",
|
|
|
|
version,
|
|
|
|
"IDE for the picoblaze\n\nCopyright (c) 2005 Mark Six",
|
|
|
|
KAboutData::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 ) ;
|
|
|
|
KPopupMenu *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, TQT_SIGNAL( closing( KPortView* ) ), TQT_TQOBJECT(this), TQT_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( "tqStatus: 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( "tqStatus: 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()
|
|
|
|
{
|
|
|
|
KIconLoader * ldr = KGlobal::iconLoader() ;
|
|
|
|
|
|
|
|
if ( !m_simulationMode ) {
|
|
|
|
if ( compile() ) {
|
|
|
|
setCaption( m_editor->getFilename() + " [Debugging]" ) ;
|
|
|
|
m_debugMenu->changeItem( START_SIM_ID, ldr->loadIcon( "stop", KIcon::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( "run", KIcon::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, TQT_SIGNAL( closing( KPortView* ) ), TQT_TQOBJECT(this), TQT_SLOT( removeIOPort( KPortView* ) ) ) ;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "kpicosim.moc"
|