summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-19 18:45:49 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-19 18:45:49 +0000
commit09a528fd59d3ea5f69575a92574f7a87898dc068 (patch)
tree9e465c49fbbe65f70d4feca3fcfb2ab3a7cf00d4 /src
downloadkpicosim-09a528fd59d3ea5f69575a92574f7a87898dc068.tar.gz
kpicosim-09a528fd59d3ea5f69575a92574f7a87898dc068.zip
Added old abandoned (but very good!) KDE3 KPicoSim application
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kpicosim@1092928 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am45
-rwxr-xr-xsrc/cassembler.cpp754
-rwxr-xr-xsrc/cassembler.h147
-rwxr-xr-xsrc/cinstruction.cpp907
-rwxr-xr-xsrc/cinstruction.h607
-rwxr-xr-xsrc/codeeditor.cpp426
-rwxr-xr-xsrc/codeeditor.h98
-rwxr-xr-xsrc/cpicoblaze.cpp436
-rwxr-xr-xsrc/cpicoblaze.h154
-rwxr-xr-xsrc/hexcodes.h64
-rwxr-xr-xsrc/hi16-app-kpicosim.pngbin0 -> 416 bytes
-rwxr-xr-xsrc/hi32-app-kpicosim.pngbin0 -> 968 bytes
-rw-r--r--src/jtag.cpp326
-rw-r--r--src/jtag.h63
-rw-r--r--src/jtagdevice.cpp31
-rw-r--r--src/jtagdevice.h40
-rw-r--r--src/jtagprogrammer.cpp233
-rw-r--r--src/jtagprogrammer.h53
-rwxr-xr-xsrc/kexportdialog.cpp158
-rwxr-xr-xsrc/kexportdialog.h63
-rw-r--r--src/kjtagdialog.cpp117
-rw-r--r--src/kjtagdialog.h63
-rwxr-xr-xsrc/kpicosim.cpp631
-rwxr-xr-xsrc/kpicosim.desktop8
-rwxr-xr-xsrc/kpicosim.h119
-rwxr-xr-xsrc/kpicosimconfig.h37
-rwxr-xr-xsrc/kpicosimui.rc8
-rwxr-xr-xsrc/kport.cpp48
-rwxr-xr-xsrc/kport.h51
-rwxr-xr-xsrc/kportview.cpp185
-rwxr-xr-xsrc/kportview.h66
-rwxr-xr-xsrc/kprocessorview.cpp208
-rwxr-xr-xsrc/kprocessorview.h61
-rwxr-xr-xsrc/kscratchpadview.cpp59
-rwxr-xr-xsrc/kscratchpadview.h39
-rwxr-xr-xsrc/kserialview.cpp321
-rwxr-xr-xsrc/kserialview.h110
-rwxr-xr-xsrc/ksimulator.cpp151
-rwxr-xr-xsrc/ksimulator.h91
-rwxr-xr-xsrc/main.cpp70
-rw-r--r--src/pics/Makefile.am5
-rw-r--r--src/pics/continue.pngbin0 -> 1356 bytes
-rw-r--r--src/pics/interrupt.pngbin0 -> 1190 bytes
-rw-r--r--src/pics/next.pngbin0 -> 1310 bytes
-rw-r--r--src/pics/rebuild.pngbin0 -> 633 bytes
-rw-r--r--src/pics/reset.pngbin0 -> 1419 bytes
-rw-r--r--src/psm.xml120
-rwxr-xr-xsrc/types.h9
48 files changed, 7182 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..26a6105
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,45 @@
+# set the include path for X, qt and KDE
+INCLUDES = -I$(top_srcdir)/debian $(all_includes)
+
+# these are the headers for your project
+noinst_HEADERS = kpicosim.h codeeditor.h ksimulator.h kserialview.h kportview.h \
+ kport.h kexportdialog.h cassembler.h cinstruction.h cpicoblaze.h hexcodes.h \
+ types.h kprocessorview.h jtagdevice.h kjtagdialog.h jtagprogrammer.h
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/kpicosim.pot
+
+KDE_ICON = kpicosim
+
+#########################################################################
+# APPLICATION SECTION
+#########################################################################
+# this is the program that gets installed. it's name is used for all
+# of the other Makefile.am variables
+bin_PROGRAMS = kpicosim
+
+# the application source, library search path, and link libraries
+kpicosim_SOURCES = main.cpp kpicosim.cpp codeeditor.cpp ksimulator.cpp \
+ kprocessorview.cpp kserialview.cpp kportview.cpp kscratchpadview.cpp kscratchpadview.h \
+ kport.cpp kexportdialog.cpp cassembler.cpp cinstruction.cpp cpicoblaze.cpp \
+ jtagdevice.cpp kjtagdialog.cpp jtag.cpp jtag.h jtagprogrammer.cpp
+kpicosim_LDFLAGS = $(KDE_RPATH) $(all_libraries)
+kpicosim_LDADD = -lkio $(LIB_KDEUI)
+
+# this is where the desktop file will go
+shelldesktopdir = $(kde_appsdir)/Development
+shelldesktop_DATA = kpicosim.desktop
+
+# this is where the shell's XML-GUI resource file goes
+shellrcdir = $(kde_datadir)/kpicosim
+shellrc_DATA = kpicosimui.rc
+
+katepartdir = $(kde_datadir)/katepart/syntax
+katepart_DATA = psm.xml
+icondirdir = $(kde_icondir)
+kde_icon_KDEICON = hi22-action-dbgrun.png hi22-action-simrun.png \
+ hi22-action-simrun.png hi22-action-dbgrun.png hi22-action-dbgrun.png
+SUBDIRS = pics
diff --git a/src/cassembler.cpp b/src/cassembler.cpp
new file mode 100755
index 0000000..1175181
--- /dev/null
+++ b/src/cassembler.cpp
@@ -0,0 +1,754 @@
+/* The assembler works, but it ain't a pretty sight.
+ * Some day, I'll rewrite this part.
+ * -- M6
+ */
+
+#include "cassembler.h"
+#include "cpicoblaze.h"
+
+#include <stdio.h>
+
+#define NO_LINE_NR 0xFFFFFFFF
+
+const char *instructions[] = {
+ "ADD", "ADDCY", "AND", "CALL", "COMPARE", "DISABLE", "ENABLE", "FETCH", "INPUT",
+ "JUMP", "LOAD", "OR", "OUTPUT", "RETURN", "RETURNI", "ROTATE", "RL", "RR", "SL0",
+ "SL1", "SLA", "SLX", "SR0", "SR1", "SRA", "SRX", "STORE", "SUB", "SUBCY", "TEST",
+ "XOR"
+} ;
+
+/* Helper function to make a string uppercase */
+string toUpper( string str )
+{
+ string upperStr ;
+ unsigned int i ;
+
+ upperStr = "" ;
+ for ( i = 0 ; i < str.length() ; i++ )
+ upperStr += toupper( str[ i ] ) ;
+
+ return upperStr ;
+}
+
+CAssembler::CAssembler()
+{
+ m_messageList = 0 ;
+}
+
+CAssembler::~CAssembler()
+{
+}
+
+void CAssembler::error( unsigned int line, const char *description )
+{
+ cout << line << ": " << description << "\r\n" ;
+
+ if ( m_messageList ) {
+ char str[ 128 ] ;
+ sprintf( str, "%u", line + 1 ) ;
+ QListViewItem *item = new QListViewItem( m_messageList, m_messageList->lastChild() ) ;
+
+ if ( line != NO_LINE_NR )
+ item->setText( 0, str ) ;
+ item->setText( 1, description ) ;
+ }
+}
+
+int CAssembler::getRegister( string name )
+{
+ if ( name[ 0 ] != 's' || name.length() <= 1 )
+ return -1 ;
+
+ int reg ;
+
+ if ( sscanf( name.c_str() + 1, "%X", &reg ) != 1 )
+ return -1 ;
+
+ if ( reg < 0 || reg > 15 )
+ return -1 ;
+
+ return reg ;
+
+}
+
+int CAssembler::getInstruction( string name )
+{
+ unsigned int i ;
+ string str = toUpper( name ) ;
+ for ( i = 0 ; i < sizeof( instructions ) / sizeof( char *); i++ )
+ if ( str == instructions[ i ] )
+ return i ;
+ return -1 ;
+}
+
+bool CAssembler::buildSymbolTable()
+{
+ list<CSourceLine*>::iterator it ;
+ unsigned int address = 0 ;
+ bool ret = TRUE ;
+
+ for ( it = m_source.begin() ; it != m_source.end() ; it++ ) {
+ string name = toUpper( (*it)->getColumn( 0 ) ) ; // case insensitive
+
+ if ( name == "NAMEREG" ) {
+ if ( !(*it)->isColumn( 3 ) ) {
+ error( (*it)->m_lineNr, "'NAMEREG registername, newname' expected" ) ;
+ ret = FALSE ;
+ }
+
+ if ( (*it)->isColumn( 4 ) ) {
+ error( (*it)->m_lineNr, "Rubbish found at end of line" ) ;
+ ret = FALSE ;
+ }
+
+ if ( (*it)->getColumn( 2 ) != "," ) {
+ error( (*it)->m_lineNr, "Comma expected" ) ;
+ ret = FALSE ;
+ }
+
+
+ CNamereg *nr = new CNamereg ;
+ nr->reg = (*it)->getColumn( 1 ) ;
+ nr->name = (*it)->getColumn( 3 ) ;
+ m_registerTable.push_back( nr ) ;
+ (*it)->m_type = CSourceLine::stNamereg ;
+
+ } else if ( name == "CONSTANT" ) {
+ if ( !(*it)->isColumn( 3 ) ) {
+ error( (*it)->m_lineNr, "'CONSTANT name, valued' expected" ) ;
+ ret = FALSE ;
+ }
+
+ if ( (*it)->isColumn( 4 ) ) {
+ error( (*it)->m_lineNr, "Rubbish found at end of line" ) ;
+ ret = FALSE ;
+ }
+
+
+ if ( (*it)->getColumn( 2 ) != "," ) {
+ error( (*it)->m_lineNr, "Comma expected" ) ;
+ ret = FALSE ;
+ }
+
+ CConstant *nr = new CConstant ;
+ nr->value = (*it)->getColumn( 3 ) ;
+ nr->name = (*it)->getColumn( 1 ) ; ;
+ m_constantTable.push_back( nr ) ;
+ (*it)->m_type = CSourceLine::stConstant ;
+ } else if ( name == "ADDRESS" ) {
+ if ( !(*it)->isColumn( 1 ) ) {
+ error( (*it)->m_lineNr, "Value expected" ) ;
+ ret = FALSE ;
+ }
+
+ if ( (*it)->isColumn( 4 ) ) {
+ error( (*it)->m_lineNr, "Rubbish found at end of line" ) ;
+ ret = FALSE ;
+ }
+
+ if ( sscanf( (*it)->getColumn( 1 ).c_str(), "%X", &address ) != 1 ) {
+ error( (*it)->m_lineNr, "Invalid address" ) ;
+ ret = FALSE ;
+ }
+ (*it)->m_type = CSourceLine::stAddress ;
+ (*it)->m_address = address ;
+
+ } else if ( getInstruction( (*it)->getColumn( 0 ) ) < 0 ) {
+ CLabel *label = new CLabel ;
+ label->name = (*it)->getColumn( 0 ) ;
+ char buf[ 32 ] ;
+ sprintf( buf, "%d", address ) ;
+ label->value = buf ;
+ m_labelTable.push_back( label ) ;
+
+ (*it)->m_type = CSourceLine::stLabel ;
+ (*it)->m_address = address ;
+ if ( (*it)->isColumn( 1 ) && (*it)->getColumn( 1 ) == ":" ) {
+ if ( (*it)->isColumn( 2 ) ) {
+ if ( getInstruction( (*it)->getColumn( 2 ) ) < 0 ) {
+ error( (*it)->m_lineNr, "Instruction expected" ) ;
+ ret = FALSE ;
+ } else {
+ address = address + 1 ;
+ }
+ }
+ } else {
+ error( (*it)->m_lineNr, "Label or Instruction expected" ) ;
+ ret = FALSE ;
+ }
+ } else {
+ (*it)->m_address = address ;
+ address = address + 1 ;
+ }
+ }
+
+ cout << "Constants :\r\n" ;
+ list<CConstant*>::iterator it0 ;
+ for ( it0 = m_constantTable.begin() ; it0 != m_constantTable.end() ; it0++ ) {
+ cout << (*it0)->name << " = " << (*it0)->value << "\r\n" ;
+ }
+
+ cout << "Namereg :\r\n" ;
+ list<CNamereg*>::iterator it1 ;
+ for ( it1 = m_registerTable.begin() ; it1 != m_registerTable.end() ; it1++ ) {
+ cout << (*it1)->reg << " = " << (*it1)->name << "\r\n" ;
+ }
+
+ cout << "labels :\r\n" ;
+ list<CLabel*>::iterator it2 ;
+ for ( it2 = m_labelTable.begin() ; it2 != m_labelTable.end() ; it2++ ) {
+ cout << (*it2)->name << " = " << (*it2)->value << "\r\n" ;
+ }
+ return ret ;
+}
+
+string CAssembler::translateRegister( string name )
+{
+ list<CNamereg*>::iterator it1 ;
+ for ( it1 = m_registerTable.begin() ; it1 != m_registerTable.end() ; it1++ ) {
+ if ( (*it1)->name == name )
+ return (*it1)->reg ;
+ }
+
+ return name ;
+
+}
+
+string CAssembler::translateConstant( string name )
+{
+ list<CConstant*>::iterator it1 ;
+ for ( it1 = m_constantTable.begin() ; it1 != m_constantTable.end() ; it1++ ) {
+ if ( (*it1)->name == name )
+ return (*it1)->value ;
+ }
+
+ return name ;
+}
+
+string CAssembler::translateLabel( string label )
+{
+ list<CLabel*>::iterator it1 ;
+ for ( it1 = m_labelTable.begin() ; it1 != m_labelTable.end() ; it1++ ) {
+ if ( (*it1)->name == label )
+ return (*it1)->value ;
+ }
+
+ return label ;
+}
+
+bool CAssembler::addInstruction( instrNumber instr, CSourceLine sourceLine, int offset )
+{
+ char err_desc[ 256 ] ;
+ unsigned int address = sourceLine.m_address ;
+ int maxColumn = 0 ;
+ string s1 = sourceLine.getColumn( offset + 1 ) ;
+ string s2 = sourceLine.getColumn( offset + 2 ) ;
+ string s3 = sourceLine.getColumn( offset + 3 ) ;
+ int line = sourceLine.m_lineNr ;
+
+ uint32_t code ;
+ string s ;
+ bool b ;
+ switch( instr ) {
+
+ case ENABLE:
+ case DISABLE:
+ if ( toUpper( s1 ) != "INTERRUPT" ) {
+ error( line, "'INTERRUPT' expected" ) ;
+ return FALSE ;
+ }
+ if ( instr == ENABLE )
+ code = instrENABLE_INTERRUPT ;
+ else
+ code = instrDISABLE_INTERRUPT ;
+
+ maxColumn = 2 ;
+
+ break ;
+ case RETURNI:
+ if ( toUpper( s1 ) == "ENABLE" ) {
+ code = instrRETURNI_ENABLE ;
+ } else if ( toUpper( s1 ) == "DISABLE" ) {
+ code = instrRETURNI_DISABLE ;
+ } else {
+ error( line, "'ENABLE' or 'DISABLE' expected" ) ;
+ }
+ maxColumn = 2 ;
+
+ break ;
+
+ // Almost the same instructions
+ case CALL:
+ case JUMP:
+ case RETURN:
+ b = TRUE ;
+ maxColumn= 2 ;
+ if ( toUpper( s1 ) == "C" ) {
+ switch( instr ) {
+ case CALL : code = instrCALLC ; break ;
+ case JUMP : code = instrJUMPC ; break ;
+ case RETURN : code = instrRETURNC ; break ;
+ default: error( line, "'CALL', 'JUMP' or 'RETURN' expected" ) ; return FALSE ;
+ }
+ } else if ( toUpper( s1 ) == "NC" ) {
+ switch( instr ) {
+ case CALL : code = instrCALLNC ; break ;
+ case JUMP : code = instrJUMPNC ; break ;
+ case RETURN : code = instrRETURNNC ; break ;
+ default: error( line, "'CALL', 'JUMP' or 'RETURN' expected" ) ; return FALSE ;
+ }
+ } else if ( toUpper( s1 ) == "NZ" ) {
+ switch( instr ) {
+ case CALL : code = instrCALLNZ ; break ;
+ case JUMP : code = instrJUMPNZ ; break ;
+ case RETURN : code = instrRETURNNZ ; break ;
+ default: error( line, "'CALL', 'JUMP' or 'RETURN' expected" ) ; return FALSE ;
+ }
+ } else if ( toUpper( s1 ) == "Z" ) {
+ switch( instr ) {
+ case CALL : code = instrCALLZ ; break ;
+ case JUMP : code = instrJUMPZ ; break ;
+ case RETURN : code = instrRETURNZ ; break ;
+ default: error( line, "'CALL', 'JUMP' or 'RETURN' expected" ) ; return FALSE ;
+ }
+ } else {
+ switch( instr ) {
+ case CALL : code = instrCALL ; break ;
+ case JUMP : code = instrJUMP ; break ;
+ case RETURN : code = instrRETURN ; break ;
+ default: error( line, "'CALL', 'JUMP' or 'RETURN' expected" ) ; return FALSE ;
+ }
+ b = FALSE ;
+ maxColumn = 1 ;
+ }
+
+
+ if ( instr != RETURN ) {
+ if ( b ) {
+ if ( s2 != "," ) {
+ error( line, "Comma expected" ) ;
+ return FALSE ;
+ }
+ s = s3 ;
+ } else
+ s = s1 ;
+
+ maxColumn = b ? 4 : 2 ;
+
+ s = translateLabel( s ) ;
+ int labelVal ;
+
+ if ( sscanf( s.c_str(), "%d", &labelVal ) != 1 ) {
+ error( line, "Invalid label" ) ;
+ return FALSE ;
+ }
+
+ code |= labelVal ;
+ }
+ break ;
+
+ // Instruction that expect first an registername
+ default:
+ int reg = getRegister( translateRegister( s1 ) ) ;
+ if ( reg < 0 ) {
+ error( line, "Registername expected" ) ;
+ return FALSE ;
+ }
+
+ code = instrROTATE | (reg<<8) ;
+ maxColumn = 2 ;
+ switch ( instr ) {
+ case RL: code |= instrRL_SX ; break ;
+ case RR: code |= instrRR_SX ; break ;
+ case SL0: code |= instrSL0_SX ; break ;
+ case SL1: code |= instrSL1_SX ; break ;
+ case SLA: code |= instrSLA_SX ; break ;
+ case SLX: code |= instrSLX_SX ; break ;
+ case SR0: code |= instrSR0_SX ; break ;
+ case SR1: code |= instrSR1_SX ; break ;
+ case SRA: code |= instrSRA_SX ; break ;
+ case SRX: code |= instrSRX_SX ; break ;
+
+ // Instructions that expect a registername and then a comma
+ default:
+ if ( s2 != "," ) {
+ error( line, "Comma expected" ) ;
+ return FALSE ;
+ }
+
+ switch( instr ) {
+ // Instruction Register Comma '(' or value
+ case STORE:
+ case OUTPUT:
+ case INPUT:
+ case FETCH:
+ if ( sourceLine.getColumn( offset + 3 ) == "(" ) {
+ if ( !sourceLine.isColumn( offset + 5 ) || sourceLine.getColumn( offset + 5 ) != ")" ) {
+ error( line, "')' expected" ) ;
+ return FALSE ;
+ }
+
+ int reg2 = getRegister( translateRegister( sourceLine.getColumn( offset + 4 ) ) ) ;
+ if ( reg2 < 0 ) {
+ error( line, "Register expected" ) ;
+ return FALSE ;
+ }
+ code = (reg << 8) | (reg2 << 4) ;
+ switch( instr ) {
+ case STORE : code |= instrSTORE_SX_SY ; break ;
+ case OUTPUT: code |= instrOUTPUT_SX_SY ; break ;
+ case INPUT : code |= instrINPUT_SX_SY ; break ;
+ case FETCH : code |= instrFETCH_SX_SY ; break ;
+ default: error( line, "'STORE', 'OUTPUT', 'INPUT' or 'FETCH' expected" ) ; return FALSE ;
+ }
+ maxColumn = 6 ;
+ } else {
+
+ unsigned int value ;
+ if ( sscanf( translateConstant( s3 ).c_str(), "%X", &value ) != 1 ) {
+ sprintf( err_desc, "Value or (regname) expected, but \"%s\" found.", s3.c_str() ) ;
+ error( line, err_desc ) ;
+ return FALSE ;
+ }
+
+ code = (reg << 8) | value ;
+ switch( instr ) {
+ case STORE : code |= instrSTORE_SX_SS ; break ;
+ case OUTPUT: code |= instrOUTPUT_SX_PP ; break ;
+ case INPUT : code |= instrINPUT_SX_PP ; break ;
+ case FETCH : code |= instrFETCH_SX_SS ; break ;
+ default: error( line, "'STORE', 'OUTPUT', 'INPUT' or 'FETCH' expected" ) ; return FALSE ;
+ }
+ maxColumn = 4 ;
+ }
+ break ;
+ default:
+ // Instruction register comma register or value
+ int reg2 = getRegister( translateRegister( s3 ) ) ;
+
+ maxColumn = 4 ;
+ if ( reg2 < 0 ) {
+ unsigned int value ;
+ if ( sscanf( translateConstant( s3 ).c_str(), "%X", &value ) != 1 ) {
+ sprintf( err_desc, "Value expected, but \"%s\" found.", s3.c_str() ) ;
+ error( line, err_desc ) ;
+ return FALSE ;
+ }
+ code = (reg << 8) | value ;
+ switch( instr ) {
+ case ADD : code |= instrADD_SX_KK ; break ;
+ case ADDCY : code |= instrADDCY_SX_KK ; break ;
+ case AND : code |= instrAND_SX_KK ; break ;
+ case COMPARE : code |= instrCOMPARE_SX_KK ; break ;
+ case LOAD : code |= instrLOAD_SX_KK ; break ;
+ case OR : code |= instrOR_SX_KK ; break ;
+ case SUB : code |= instrSUB_SX_KK ; break ;
+ case SUBCY : code |= instrSUBCY_SX_KK ; break ;
+ case TEST : code |= instrTEST_SX_KK ; break ;
+ case XOR : code |= instrXOR_SX_KK ; break ;
+ default : error( line, "Unknown instruction" ) ; return FALSE ;
+ }
+ } else {
+ code = ( reg << 8 ) | ( reg2 << 4 ) ;
+ switch( instr ) {
+ case ADD : code |= instrADD_SX_SY ; break ;
+ case ADDCY : code |= instrADDCY_SX_SY ; break ;
+ case AND : code |= instrAND_SX_SY ; break ;
+ case COMPARE: code |= instrCOMPARE_SX_SY ; break ;
+ case LOAD : code |= instrLOAD_SX_SY ; break ;
+ case OR : code |= instrOR_SX_SY ; break ;
+ case SUB : code |= instrSUB_SX_SY ; break ;
+ case SUBCY : code |= instrSUBCY_SX_SY ; break ;
+ case TEST : code |= instrTEST_SX_SY ; break ;
+ case XOR : code |= instrXOR_SX_SY ; break ;
+ default : error( line, "Unknown instruction" ) ; return FALSE ;
+ }
+ }
+ }
+ }
+ }
+
+ // Check if there's is rubbish at the end of the line
+ if ( sourceLine.isColumn( maxColumn + offset ) ) {
+ sprintf( err_desc, "'%s' found at end of instruction", sourceLine.getColumn( maxColumn + offset ).c_str() ) ;
+ error( line, err_desc ) ;
+ return FALSE ;
+ }
+
+ // Finally
+ m_code->setInstruction( address, code, line ) ;
+
+ return TRUE ;
+}
+
+
+bool CAssembler::exportVHDL( string templateFile, string outputDir, string entityName )
+{
+ int addr, i, j, k, l, n ;
+ unsigned char INIT[ 32 ][ 64 ] ; /* 32 * 64 = 2048 bytes */
+ unsigned char INITP[ 32 ][ 8 ] ; /* 32 * 8 = 256 bytes (Parity Table)*/
+ unsigned int d ; /* 2304 Bytes Total = (18b * 1024 ) / 8 (1 instr = 18 bits )*/
+
+ CInstruction *instr ;
+
+ for ( i = 0 ; i < 32 ; i++ )
+ for( j = 0 ; j < 32 ; j++ )
+ INIT[ i ][ j ] = 0 ;
+
+ for ( i = 0 ; i < 32 ; i++ )
+ for ( j = 0 ; j < 8 ; j++ )
+ INITP[ i ][ j ] = 0 ;
+
+ /* Build up BRAM in memory */
+ for ( addr = i = j = k = l = 0, n = 0 ; addr < 1024 ; addr++ ) {
+ instr = m_code->getInstruction( addr ) ;
+
+ if ( instr == NULL ) d = 0 ;
+ else d = instr->getHexCode() ;
+
+
+ INIT[ i++ ][ j ] = d ; // instruction( 15 downto 0 )
+ INIT[ i++ ][ j ] = d >> 8;
+
+ INITP[ k ][ l ] |= ( ( d >> 16 ) & 0x3 ) << n ; // instruction( 17 downto 16 ) ;
+ n += 2 ;
+
+ if ( n >= 8 ) {
+ n = 0 ;
+ k++ ;
+ if ( k >= 32 ) {
+ l++ ;
+ k = 0 ;
+ }
+ }
+
+ if ( i >= 32 ) {
+ i = 0 ;
+ j++ ;
+ }
+ }
+
+ FILE * infile = fopen( templateFile.c_str(), "r" ) ;
+ if ( infile == NULL ) {
+ error( NO_LINE_NR, string( "Unable to open VHDL template file '" + templateFile + "'" ).c_str() ) ;
+ return FALSE ;
+ }
+
+ string exportFile = outputDir + "/" + entityName + ".vhd" ;
+ FILE * outfile = fopen( exportFile.c_str(), "w" ) ;
+ if ( outfile == NULL ) {
+ error( NO_LINE_NR , string( "Unable to open VHDL template file '%s'" + exportFile + ".vhd").c_str() ) ;
+ return FALSE ;
+ }
+
+ bool store = false, copy = false;
+ char varname[ 64 ] ;
+ int p = 0 ;
+ int line, c ;
+ while ( ( c = fgetc( infile ) ) != EOF ) {
+ if ( store && p < 64 )
+ varname[ p++ ] = c ;
+
+ if ( c == '{' ) {
+ store = true ;
+ p = 0 ;
+ }
+
+ if ( !store && copy )
+ fputc( c, outfile ) ;
+
+ if ( c == '}' ) {
+ store = false ;
+ if ( p > 0 )
+ varname[ p - 1 ] = '\0' ;
+ else
+ varname[ 0 ] = '\0' ;
+ if ( strncmp( "INIT_", varname, 5 ) == 0 ) {
+ sscanf( varname, "INIT_%02X", &line ) ;
+ if ( line >= 0 && line < 64 ) {
+ for( j = 31 ; j >= 0 ; j-- )
+ fprintf( outfile, "%02X", INIT[ j ][ line ] ) ;
+ }
+ } else if ( strncmp( "INITP_", varname, 6 ) == 0 ) {
+ sscanf( varname, "INITP_%02X", &line ) ;
+ if ( line >= 0 && line < 8 )
+ for( j = 31 ; j >= 0 ; j-- )
+ fprintf( outfile, "%02X", INITP[ j ][ line ] ) ;
+ } else if ( strcmp( "name", varname ) == 0 ) {
+ fprintf( outfile, entityName.c_str() ) ;
+ } else if ( strcmp( "begin template", varname ) == 0 ) {
+ copy = true ;
+ }
+ }
+ }
+
+ fclose( infile ) ;
+ fclose( outfile ) ;
+
+ return TRUE ;
+}
+
+bool CAssembler::exportHEX( string filename, bool mem )
+{
+ FILE * file = fopen( filename.c_str(), "w" ) ;
+ if ( file == NULL ) {
+ error( NO_LINE_NR , string( "Unable to write to file '" + filename + "'").c_str() ) ;
+ return FALSE ;
+ }
+
+ CInstruction * instr ;
+ uint32_t d ;
+ uint32_t addr ;
+
+ /* A mem file requires the @ sign */
+ if ( mem )
+ fprintf( file, "@0\r\n" ) ;
+
+ for ( addr = 0 ; addr < 1024 ; addr++ ) {
+ instr = m_code->getInstruction( addr ) ;
+
+ if ( instr == NULL ) d = 0 ;
+ else d = instr->getHexCode() ;
+
+ fprintf( file, "%05X\r\n", d ) ;
+ }
+
+ fclose( file ) ;
+
+ return TRUE ;
+}
+
+
+bool CAssembler::createOpcodes()
+{
+ list<CSourceLine*>::iterator it ;
+ int columnOffset ;
+ bool ret = TRUE ;
+
+ for ( it = m_source.begin() ; it != m_source.end() ; it++ ) {
+ if ( (*it)->m_type == CSourceLine::stNamereg ||
+ (*it)->m_type == CSourceLine::stConstant ||
+ (*it)->m_type == CSourceLine::stAddress )
+ continue ;
+
+ if ( (*it)->m_type == CSourceLine::stLabel )
+ columnOffset = 2 ;
+ else
+ columnOffset = 0 ;
+
+ if ( !(*it)->isColumn( columnOffset + 0 ) ) // just a label
+ continue ;
+
+ int instr = getInstruction( (*it)->getColumn( columnOffset + 0 ) ) ;
+
+ if ( instr < 0 ) {
+ error( (*it)->m_lineNr, "Unknown instruction" ) ;
+ ret = FALSE ;
+ }
+
+ if ( addInstruction( (instrNumber) instr, **it, columnOffset ) == FALSE )
+ ret = FALSE ;
+
+ }
+ return ret ;
+}
+
+bool CAssembler::assemble( )
+{
+ bool r1, r2 ;
+ if ( loadFile() == FALSE )
+ return FALSE ;
+
+ r1 = buildSymbolTable() ; // Even continue if symbol table failed..
+ r2 = createOpcodes() ; // .. this way we get the most errors/warnings in 1 compile cycle.
+ return ( r1 && r2 ) ;
+
+}
+
+char * CAssembler::getWord( char *s, char *word ) {
+ char *start, *end ;
+
+ *word = '\0' ;
+
+ while ( *s == ' ' || *s == '\t' ) // skip whitespaces
+ s++ ;
+
+ start = s ;
+
+ if ( *start == '\0' || *start == '\r' || *start == '\n' || *start == ';' ) // end of line
+ return NULL ;
+
+ while ( *s != ' ' && *s != '\t' && *s != '\0' && *s != '\r' && *s != '\n' &&
+ *s != ';' && *s != ',' && *s != ':' && *s != '(' && *s != ')' )
+ s++ ;
+
+ end = s ;
+
+ if ( start != end ) {
+ while ( start < end )
+ *word++ = *start++ ;
+ *word = '\0' ;
+ return end ;
+ } else if ( *s == ',' || *s == ':' || *s == '(' || *s == ')' ) {
+ *word++ = *s ;
+ *word = '\0' ;
+ return end + 1 ;
+ } else
+ return NULL ;
+}
+
+CSourceLine * CAssembler::formatLine( int lineNr, char *s )
+{
+ CSourceLine *sourceLine = new CSourceLine( lineNr ) ;
+ char *next, word[ 256 ] ;
+
+ next = getWord( s, word ) ;
+ if ( word[ 0 ] == '\0' ) { // empty line
+ delete sourceLine ;
+ return NULL ;
+ }
+
+ do {
+ sourceLine->addColumn( word ) ;
+ next = getWord( next, word ) ;
+ if ( word[ 0 ] == '\0' )
+ break ;
+ } while ( next != NULL ) ;
+
+ return sourceLine ;
+}
+
+bool CAssembler::loadFile()
+{
+ FILE *f ;
+
+ f = fopen( m_filename.c_str(), "r" ) ;
+
+ if ( f == NULL ) {
+ string str = "Unable to load file '" + m_filename + "'";
+ error( NO_LINE_NR, str.c_str() ) ; // No linenumber information
+ return FALSE ;
+ }
+ char buf[ 256 ] ;
+ int linenr = 0 ;
+ while( fgets( buf, sizeof( buf ), f ) ) {
+ CSourceLine *sourceLine = formatLine( linenr++, buf ) ;
+ if ( sourceLine != NULL )
+ m_source.push_back( sourceLine ) ;
+ }
+
+ list<CSourceLine*>::iterator it ;
+
+ for ( it = m_source.begin() ; it != m_source.end() ; it++ ) {
+ cout << "(" << (*it)->m_lineNr << ")" ;
+ int j = 0 ;
+ while ( (*it)->isColumn( j ) )
+ cout << "[" << (*it)->getColumn( j++ ) << "]";
+ cout << "\r\n" ;
+ }
+
+ cout << "File " << m_filename << " succesfully loaded\r\n" ;
+
+ return TRUE ;
+}
+
diff --git a/src/cassembler.h b/src/cassembler.h
new file mode 100755
index 0000000..893569a
--- /dev/null
+++ b/src/cassembler.h
@@ -0,0 +1,147 @@
+#include <iostream>
+#include <string>
+#include <list>
+#include <vector>
+#include <klistview.h>
+#include <algorithm>
+#include <cctype>
+
+#include "types.h"
+
+class CCode ;
+
+using namespace std ;
+
+enum instrNumber {
+ ADD, ADDCY, AND, CALL, COMPARE, DISABLE, ENABLE, FETCH, INPUT,
+ JUMP, LOAD, OR, OUTPUT, RETURN, RETURNI, ROTATE, RL, RR, SL0,
+ SL1, SLA, SLX, SR0, SR1, SRA, SRX, STORE, SUB, SUBCY, TEST,
+ XOR
+} ;
+
+class CNamereg {
+ public:
+ CNamereg() {} ;
+ ~CNamereg() {} ;
+
+ string reg ;
+ string name ;
+} ;
+
+class CConstant {
+ public:
+ CConstant() {}
+ ~CConstant() {}
+
+ string value ;
+ string name ;
+} ;
+
+class CLabel {
+ public:
+ CLabel() {}
+ ~CLabel() ;
+
+ string value ;
+ string name ;
+} ;
+
+class CSourceLine {
+ public:
+ enum SymbolType {
+ stNone,
+ stLabel,
+ stNamereg,
+ stConstant,
+ stAddress
+ } ;
+
+ CSourceLine( unsigned int lineNr ) : m_lineNr( lineNr )
+ {
+ m_type = stNone ;
+ }
+ ~CSourceLine() {} ;
+
+ void addColumn( string word )
+ {
+/* int i ; // Case sensitive
+ for ( i = 0 ; i < word.length(); i++ )
+ word[ i ] = toupper( word[ i ] ) ;
+*/ m_line.push_back( word ) ;
+ }
+
+ bool isColumn( unsigned int index )
+ {
+ return m_line.size() > index ;
+ }
+
+ string getColumn( int index )
+ {
+ if ( !isColumn( index ) )
+ return "" ;
+ else
+ return m_line[index] ;
+ }
+
+ unsigned int m_lineNr;
+ vector<string> m_line ;
+ unsigned int m_address ;
+ SymbolType m_type ;
+} ;
+
+
+class CAssembler {
+ public:
+ CAssembler() ;
+ ~CAssembler() ;
+
+ void setCode( CCode *code )
+ {
+ m_code = code ;
+ }
+ void setFilename( string filename )
+ {
+ m_filename = filename ;
+ }
+ bool assemble() ;
+
+ void clear() {
+ m_source.clear() ;
+ m_registerTable.clear() ;
+ m_labelTable.clear() ;
+ m_constantTable.clear() ;
+ }
+ void setMessageList( KListView *messageList )
+ {
+ m_messageList = messageList ;
+ }
+
+ bool exportVHDL( string templateFile, string outputDir, string entityName ) ;
+ bool exportHEX( string filename, bool mem ) ;
+
+ protected:
+ list<CSourceLine*> m_source ;
+ list<CNamereg*> m_registerTable ;
+ list<CConstant*> m_constantTable ;
+ list<CLabel*> m_labelTable ;
+ string m_filename ;
+ bool buildSymbolTable() ;
+ bool loadFile() ;
+
+ void error( unsigned int line, const char *description ) ;
+ int getRegister( string name ) ;
+
+ char * getWord( char *s, char *word ) ;
+ CSourceLine * formatLine( int lineNr, char *s ) ;
+
+ int getInstruction( string name ) ;
+ bool createOpcodes() ;
+
+ string translateLabel( string name ) ;
+ string translateConstant( string name ) ;
+ string translateRegister( string name ) ;
+ bool addInstruction( instrNumber instr, CSourceLine sourceLine, int offset ) ;
+
+ CCode * m_code ;
+ KListView *m_messageList ;
+} ;
diff --git a/src/cinstruction.cpp b/src/cinstruction.cpp
new file mode 100755
index 0000000..9c6fba8
--- /dev/null
+++ b/src/cinstruction.cpp
@@ -0,0 +1,907 @@
+
+#include "cinstruction.h"
+#include "iostream"
+
+using namespace std ;
+
+
+CInstruction::CInstruction()
+{
+ m_cpu = (CPicoBlaze*) 0 ;
+}
+
+CInstruction::CInstruction( CPicoBlaze *cpu, uint32_t opcode )
+{
+ m_cpu = cpu ;
+
+ sX = ( opcode & 0x0f00 ) >> 8 ;
+ sY = ( opcode & 0x00f0 ) >> 4 ;
+ kk = ( opcode & 0x00ff ) >> 0 ;
+ pp = ( opcode & 0x00ff ) >> 0 ;
+ ss = ( opcode & 0x003f ) >> 0 ;
+ address = ( opcode & 0x03ff ) >> 0 ;
+
+ hexcode = opcode ;
+}
+
+CInstruction::~CInstruction()
+{
+}
+
+void CInstruction::Print()
+{
+ cout << "Unknown instruction" ;
+}
+
+void ADD_SX_KK::Execute()
+{
+ uint16_t val = m_cpu->s[ sX ] + kk ;
+
+ m_cpu->flags.carry = ( val > 255 ) ;
+ m_cpu->flags.zero = ( val == 0 ) || ( val == 256 ) ;
+
+ m_cpu->s[ sX ] = val ;
+ m_cpu->pc->Next() ;
+}
+
+void ADD_SX_KK::Print()
+{
+ cout << "ADD " << "s" << sX << "," << kk ;
+}
+
+void ADD_SX_SY::Execute()
+{
+ uint16_t val = m_cpu->s[ sX ] + m_cpu->s[ sY ] ;
+
+ m_cpu->flags.carry = ( val > 255 ) ;
+ m_cpu->flags.zero = ( val == 0 ) || ( val == 256 ) ;
+
+ m_cpu->s[ sX ] = val ;
+ m_cpu->pc->Next() ;
+
+}
+
+void ADD_SX_SY::Print()
+{
+ cout << "ADD " << "s" << sX << "," << "s" << sY ;
+}
+
+void ADDCY_SX_KK::Execute()
+{
+ uint16_t val = m_cpu->s[ sX ] + 1 + kk ;
+
+ if ( m_cpu->flags.carry )
+ val = m_cpu->s[ sX ] + 1 + kk ;
+ else
+ val = m_cpu->s[ sX ] + kk ;
+
+ m_cpu->s[ sX ] = val ;
+ m_cpu->flags.carry = (val > 255) ;
+ m_cpu->flags.zero = (val == 0) || (val == 256) ;
+
+ m_cpu->pc->Next() ;
+}
+
+void ADDCY_SX_KK::Print()
+{
+ cout << "ADDCY " << "s" << sX << "," << sY ;
+}
+
+void ADDCY_SX_SY::Execute()
+{
+ uint16_t val ;
+
+ if ( m_cpu->flags.carry )
+ val = m_cpu->s[ sX ] + 1 + m_cpu->s[ sY ] ;
+ else
+ val = m_cpu->s[ sX ] + m_cpu->s[ sY ] ;
+
+ m_cpu->s[ sX ] = val ;
+ m_cpu->flags.carry = (val > 255) ;
+ m_cpu->flags.zero = (val == 0) || (val == 256) ;
+
+ m_cpu->pc->Next() ;
+}
+
+void ADDCY_SX_SY::Print()
+{
+ cout << "ADDCY " << "s" << sX << "," << "s" << sY ;
+}
+
+void AND_SX_KK::Execute()
+{
+
+ m_cpu->s[ sX ] = m_cpu->s[ sX ] & kk ;
+ m_cpu->flags.carry = 0 ;
+ m_cpu->flags.zero = m_cpu->s[ sX ] == 0 ;
+
+ m_cpu->pc->Next() ;
+}
+
+void AND_SX_KK::Print()
+{
+ cout << "AND " << "s" << sX << "," << sY ;
+}
+
+void AND_SX_SY::Execute()
+{
+
+ m_cpu->s[ sX ] = m_cpu->s[ sX ] & m_cpu->s[ sY ] ;
+ m_cpu->flags.carry = 0 ;
+ m_cpu->flags.zero = m_cpu->s[ sX ] == 0 ;
+
+ m_cpu->pc->Next() ;
+}
+
+void AND_SX_SY::Print()
+{
+ cout << "AND " << "s" << sX << "," << "s" << sY ;
+}
+
+void CALL::Execute()
+{
+ m_cpu->stack->Push( ( m_cpu->pc->Get() + 1) % 0x400 ) ;
+ m_cpu->pc->Set( address ) ;
+}
+
+void CALL::Print()
+{
+ cout << "CALL " << address ;
+}
+
+void CALLC::Execute()
+{
+ if ( m_cpu->flags.carry ) {
+ m_cpu->stack->Push( m_cpu->pc->Get() ) ;
+ m_cpu->pc->Set( address ) ;
+ } else
+ m_cpu->pc->Next() ;
+}
+
+void CALLC::Print()
+{
+ cout << "CALL C " << address ;
+}
+
+void CALLNC::Execute()
+{
+ if ( !m_cpu->flags.carry ) {
+ m_cpu->stack->Push( m_cpu->pc->Get() ) ;
+ m_cpu->pc->Set( address ) ;
+ } else
+ m_cpu->pc->Next() ;
+}
+
+void CALLNC::Print()
+{
+ cout << "CALL NC " << address ;
+}
+
+void CALLNZ::Execute()
+{
+ if ( !m_cpu->flags.zero ) {
+ m_cpu->stack->Push( m_cpu->pc->Get() ) ;
+ m_cpu->pc->Set( address ) ;
+ } else
+ m_cpu->pc->Next() ;
+}
+
+void CALLNZ::Print()
+{
+ cout << "CALL NZ " << address ;
+}
+
+void CALLZ::Execute()
+{
+ if ( m_cpu->flags.zero ) {
+ m_cpu->stack->Push( m_cpu->pc->Get() ) ;
+ m_cpu->pc->Set( address ) ;
+ } else
+ m_cpu->pc->Next() ;
+}
+
+void CALLZ::Print()
+{
+ cout << "CALL Z " << address ;
+}
+
+
+void COMPARE_SX_KK::Execute()
+{
+ m_cpu->flags.carry = kk > m_cpu->s[ sX ] ;
+ m_cpu->flags.zero = kk == m_cpu->s[ sX ] ;
+
+ m_cpu->pc->Next() ;
+}
+
+void COMPARE_SX_KK::Print()
+{
+ cout << "COMPARE s" << sX << ", " << kk ;
+}
+
+void COMPARE_SX_SY::Execute()
+{
+ m_cpu->flags.carry = m_cpu->s[ sY ] > m_cpu->s[ sX ] ;
+ m_cpu->flags.zero = m_cpu->s[ sY ] == m_cpu->s[ sX ] ;
+
+ m_cpu->pc->Next() ;
+}
+
+void COMPARE_SX_SY::Print()
+{
+ cout << "COMPARE s" << sX << ", s" << kk ;
+}
+
+void DISABLE_INTERRUPT::Execute()
+{
+ m_cpu->flags.interrupt_enable = false ;
+ m_cpu->pc->Next() ;
+}
+
+void DISABLE_INTERRUPT::Print()
+{
+ cout << "DISABLE INTERRUPT" ;
+}
+
+void ENABLE_INTERRUPT::Execute()
+{
+ m_cpu->flags.interrupt_enable = true ;
+ m_cpu->pc->Next() ;
+}
+
+void ENABLE_INTERRUPT::Print()
+{
+ cout << "ENABLE INTERRUPT" ;
+}
+
+void FETCH_SX_SS::Execute()
+{
+ m_cpu->s[ sX ] = m_cpu->scratch->Get( ss ) ;
+ m_cpu->pc->Next() ;
+}
+
+void FETCH_SX_SS::Print()
+{
+ cout << "FETCH " << "s" << sX << ", " << ss ;
+}
+
+void FETCH_SX_SY::Execute()
+{
+ m_cpu->s[ sX ] = m_cpu->scratch->Get( m_cpu->s[ sY ] & 0x3f ) ;
+ m_cpu->pc->Next() ;
+
+
+}
+
+void FETCH_SX_SY::Print() {
+ cout << "FETCH " << "s" << sX << ", " << "s" << sY ;
+}
+
+void INPUT_SX_SY::Execute()
+{
+ m_cpu->port->PortID( m_cpu->s[ sY ] ) ;
+ m_cpu->s[ sX ] = m_cpu->port->PortIn() ;
+ m_cpu->pc->Next() ;
+}
+
+void INPUT_SX_SY::Print()
+{
+ cout << "INPUT " << "s" << sX << ", " << "s" << sY ;
+}
+
+void INPUT_SX_PP::Execute()
+{
+ m_cpu->port->PortID( pp ) ;
+ m_cpu->s[ sX ] = m_cpu->port->PortIn() ;
+ m_cpu->pc->Next() ;
+}
+
+void INPUT_SX_PP::Print()
+{
+ cout << "INPUT " << "s" << sX << ", " << pp ;
+}
+
+void JUMP::Execute()
+{
+ m_cpu->pc->Set( address ) ;
+}
+
+void JUMP::Print()
+{
+ cout << "JUMP " << address ;
+}
+
+void JUMPC::Execute()
+{
+ if ( m_cpu->flags.carry )
+ m_cpu->pc->Set( address ) ;
+ else
+ m_cpu->pc->Next() ;
+}
+
+void JUMPC::Print()
+{
+ cout << "JUMP C " << address ;
+}
+
+void JUMPNC::Execute()
+{
+ if ( !m_cpu->flags.carry )
+ m_cpu->pc->Set( address ) ;
+ else
+ m_cpu->pc->Next() ;
+}
+
+void JUMPNC::Print()
+{
+ cout << "JUMP NC " << address ;
+}
+
+void JUMPNZ::Execute()
+{
+ if ( !m_cpu->flags.zero )
+ m_cpu->pc->Set( address ) ;
+ else
+ m_cpu->pc->Next() ;
+}
+
+void JUMPNZ::Print()
+{
+ cout << "JUMP NZ " << address ;
+}
+
+void JUMPZ::Execute()
+{
+ if ( m_cpu->flags.zero )
+ m_cpu->pc->Set( address ) ;
+ else
+ m_cpu->pc->Next() ;
+}
+
+void JUMPZ::Print()
+{
+ cout << "JUMP Z " << address ;
+}
+
+void LOAD_SX_KK::Execute()
+{
+ m_cpu->s[ sX ] = kk ;
+ m_cpu->pc->Next() ;
+}
+
+void LOAD_SX_KK::Print()
+{
+ cout << "LOAD " << "s" << sX << ", " << kk ;
+}
+
+void LOAD_SX_SY::Execute()
+{
+ m_cpu->s[ sX ] = m_cpu->s[ sY ] ;
+ m_cpu->pc->Next() ;
+}
+
+void LOAD_SX_SY::Print()
+{
+ cout << "LOAD " << "s" << sX << ", " << "s" << sY ;
+}
+
+void OR_SX_KK::Execute()
+{
+ m_cpu->s[ sX ] = m_cpu->s[ sX ] | kk ;
+ m_cpu->flags.carry = 0 ;
+ m_cpu->flags.zero = m_cpu->s[ sX ] == 0 ;
+ m_cpu->pc->Next() ;
+}
+
+void OR_SX_KK::Print()
+{
+ cout << "OR " << "s" << sX << ", " << kk ;
+}
+
+void OR_SX_SY::Execute()
+{
+ m_cpu->s[ sX ] = m_cpu->s[ sX ] | m_cpu->s[ sY ] ;
+ m_cpu->flags.carry = 0 ;
+ m_cpu->flags.zero = m_cpu->s[ sX ] == 0 ;
+ m_cpu->pc->Next() ;
+}
+
+void OR_SX_SY::Print()
+{
+ cout << "OR " << "s" << sX << ", " << "s" << sY ;
+}
+
+void OUTPUT_SX_SY::Execute()
+{
+ m_cpu->port->PortID( m_cpu->s[ sY ] ) ;
+ m_cpu->port->PortOut( m_cpu->s[ sX ] ) ;
+ m_cpu->pc->Next() ;
+}
+
+void OUTPUT_SX_SY::Print()
+{
+ cout << "OUTPUT " << "s" << sX << ", " << "s" << sY ;
+}
+
+void OUTPUT_SX_PP::Execute()
+{
+ m_cpu->port->PortID( pp ) ;
+ m_cpu->port->PortOut( m_cpu->s[ sX ] ) ;
+ m_cpu->pc->Next() ;
+}
+
+void OUTPUT_SX_PP::Print()
+{
+ cout << "OUTPUT " << "s" << sX << ", " << pp ;
+}
+
+void RETURN::Execute()
+{
+ m_cpu->pc->Set( m_cpu->stack->Pop() ) ;
+}
+
+void RETURN::Print()
+{
+ cout << "RETURN" ;
+}
+
+void RETURNC::Execute()
+{
+ if ( m_cpu->flags.carry )
+ m_cpu->pc->Set( m_cpu->stack->Pop() ) ;
+ else
+ m_cpu->pc->Next() ;
+}
+
+void RETURNC::Print()
+{
+ cout << "RETURN C" ;
+}
+
+void RETURNNC::Execute()
+{
+ if ( !m_cpu->flags.carry )
+ m_cpu->pc->Set( m_cpu->stack->Pop() ) ;
+ else
+ m_cpu->pc->Next() ;
+}
+
+void RETURNNC::Print()
+{
+ cout << "RETURN NC" ;
+}
+
+void RETURNNZ::Execute()
+{
+ if ( !m_cpu->flags.zero )
+ m_cpu->pc->Set( m_cpu->stack->Pop() ) ;
+ else
+ m_cpu->pc->Next() ;
+}
+
+void RETURNNZ::Print()
+{
+ cout << "RETURN NZ" ;
+}
+
+void RETURNZ::Execute()
+{
+ if ( m_cpu->flags.zero )
+ m_cpu->pc->Set( m_cpu->stack->Pop() ) ;
+ else
+ m_cpu->pc->Next() ;
+}
+
+void RETURNZ::Print()
+{
+ cout << "RETURN Z" ;
+}
+
+void RETURNI_DISABLE::Execute()
+{
+ m_cpu->pc->Set( m_cpu->stack->Pop() ) ;
+ m_cpu->flags.carry = m_cpu->flags.preserved_carry ;
+ m_cpu->flags.zero = m_cpu->flags.preserved_zero ;
+ m_cpu->flags.interrupt_enable = false ;
+}
+
+void RETURNI_DISABLE::Print()
+{
+ cout << "RETURNI DISABLE" ;
+}
+
+void RETURNI_ENABLE::Execute()
+{
+ m_cpu->pc->Set( m_cpu->stack->Pop() ) ;
+ m_cpu->flags.carry = m_cpu->flags.preserved_carry ;
+ m_cpu->flags.zero = m_cpu->flags.preserved_zero ;
+ m_cpu->flags.interrupt_enable = true ;
+}
+
+void RETURNI_ENABLE::Print()
+{
+ cout << "RETURNI ENABLE" ;
+}
+
+void RL_SX::Execute()
+{
+ m_cpu->flags.carry = ( m_cpu->s[ sX ] & 0x80 ) != 0 ;
+
+ m_cpu->s[ sX ] <<= 1 ;
+ if ( m_cpu->flags.carry )
+ m_cpu->s[ sX ] |= 1 ;
+
+ m_cpu->flags.zero = m_cpu->s[ sX ] == 0 ;
+ m_cpu->pc->Next() ;
+}
+
+void RL_SX::Print()
+{
+ cout << "RL s" << sX ;
+}
+
+void RR_SX::Execute()
+{
+ m_cpu->flags.carry = ( m_cpu->s[ sX ] & 0x01 ) != 0 ;
+
+ m_cpu->s[ sX ] >>= 1 ;
+ if ( m_cpu->flags.carry )
+ m_cpu->s[ sX ] |= 0x80 ;
+
+ m_cpu->flags.zero = m_cpu->s[ sX ] == 0 ;
+ m_cpu->pc->Next() ;
+}
+
+void RR_SX::Print()
+{
+ cout << "RR s" << sX ;
+}
+
+
+void SL0_SX::Execute()
+{
+ m_cpu->flags.carry = ( m_cpu->s[ sX ] & 0x80 ) != 0 ;
+
+ m_cpu->s[ sX ] <<= 1 ;
+
+ m_cpu->flags.zero = m_cpu->s[ sX ] == 0 ;
+ m_cpu->pc->Next() ;
+}
+
+void SL0_SX::Print()
+{
+ cout << "SL0 s" << sX ;
+}
+
+void SL1_SX::Execute()
+{
+ m_cpu->flags.carry = ( m_cpu->s[ sX ] & 0x80 ) != 0 ;
+
+ m_cpu->s[ sX ] <<= 1 ;
+ m_cpu->s[ sX ] |= 1 ;
+
+ m_cpu->flags.zero = m_cpu->s[ sX ] == 0 ;
+ m_cpu->pc->Next() ;
+}
+
+void SL1_SX::Print()
+{
+ cout << "SL1 s" << sX ;
+}
+
+
+void SLA_SX::Execute()
+{
+ bool c ;
+
+ c = m_cpu->flags.carry ;
+
+ m_cpu->flags.carry = ( m_cpu->s[ sX ] & 0x80 ) != 0 ;
+
+ m_cpu->s[ sX ] <<= 1 ;
+ if ( c )
+ m_cpu->s[ sX ] |= 1 ;
+
+ m_cpu->flags.zero = m_cpu->s[ sX ] == 0 ;
+ m_cpu->pc->Next() ;
+}
+
+void SLA_SX::Print()
+{
+ cout << "SLA s" << sX ;
+}
+
+
+void SLX_SX::Execute()
+{
+ m_cpu->flags.carry = ( m_cpu->s[ sX ] & 0x80 ) != 0 ;
+
+ m_cpu->s[ sX ] <<= 1 ;
+ if ( m_cpu->s[ sX ] & 0x02 )
+ m_cpu->s[ sX ] |= 1 ;
+
+ m_cpu->flags.zero = m_cpu->s[ sX ] == 0 ;
+ m_cpu->pc->Next() ;
+}
+
+void SLX_SX::Print()
+{
+ cout << "SLX s" << sX ;
+}
+
+
+void SR0_SX::Execute()
+{
+ m_cpu->flags.carry = m_cpu->s[ sX ] & 0x01 ;
+ m_cpu->s[ sX ] >>= 1 ;
+ m_cpu->flags.zero = m_cpu->s[ sX ] == 0 ;
+ m_cpu->pc->Next() ;
+}
+
+void SR0_SX::Print()
+{
+ cout << "SR0 s" << sX ;
+}
+
+
+void SR1_SX::Execute()
+{
+ m_cpu->flags.carry = m_cpu->s[ sX ] & 0x01 ;
+ m_cpu->s[ sX ] >>= 1 ;
+ m_cpu->s[ sX ] |= 0x80 ;
+ m_cpu->flags.zero = m_cpu->s[ sX ] == 0 ;
+ m_cpu->pc->Next() ;
+}
+
+void SR1_SX::Print()
+{
+ cout << "SR1 s" << sX ;
+}
+
+
+void SRA_SX::Execute()
+{
+ bool c = m_cpu->flags.carry ;
+ m_cpu->flags.carry = m_cpu->s[ sX ] & 0x01 ;
+ m_cpu->s[ sX ] >>= 1 ;
+ if ( c )
+ m_cpu->s[ sX ] |= 0x80 ;
+ m_cpu->flags.zero = m_cpu->s[ sX ] == 0 ;
+ m_cpu->pc->Next() ;
+}
+
+void SRA_SX::Print()
+{
+ cout << "SRA s" << sX ;
+}
+
+
+void SRX_SX::Execute()
+{
+ m_cpu->flags.carry = m_cpu->s[ sX ] & 0x01 ;
+ m_cpu->s[ sX ] >>= 1 ;
+ if ( m_cpu->s[ sX ] & 0x40 )
+ m_cpu->s[ sX ] |= 0x80 ;
+ m_cpu->flags.zero = m_cpu->s[ sX ] == 0 ;
+ m_cpu->pc->Next() ;
+}
+
+void SRX_SX::Print()
+{
+ cout << "SRX s" << sX ;
+}
+
+
+void STORE_SX_SS::Execute()
+{
+ m_cpu->scratch->Set( ss, m_cpu->s[ sX ] ) ;
+ m_cpu->pc->Next() ;
+
+}
+
+void STORE_SX_SS::Print()
+{
+ cout << "STORE s" << sX << ", " << ss ;
+}
+
+
+void STORE_SX_SY::Execute()
+{
+ m_cpu->scratch->Set( m_cpu->s[ sY ], m_cpu->s[ sX ] ) ;
+ m_cpu->pc->Next() ;
+}
+
+void STORE_SX_SY::Print()
+{
+ cout << "STORE s" << sX << ", s" << sY ;
+}
+
+void SUB_SX_KK::Execute()
+{
+ int val ;
+
+ val = m_cpu->s[ sX ] ;
+ val -= kk ;
+
+ m_cpu->flags.carry = val < 0 ;
+ m_cpu->flags.zero = val == 0 ;
+
+ m_cpu->s[ sX ] -= kk ;
+
+ m_cpu->pc->Next() ;
+}
+
+void SUB_SX_KK::Print()
+{
+ cout << "SUB s" << sX << ", " << kk ;
+}
+
+void SUB_SX_SY::Execute()
+{
+ int val ;
+
+ val = m_cpu->s[ sX ] ;
+ val -= m_cpu->s[ sY ] ;
+
+ m_cpu->flags.carry = val < 0 ;
+ m_cpu->flags.zero = val == 0 ;
+
+ m_cpu->s[ sX ] -= m_cpu->s[ sY ] ;
+
+ m_cpu->pc->Next() ;
+}
+
+void SUB_SX_SY::Print()
+{
+ cout << "SUB s" << sX << ", s" << sY ;
+}
+
+
+void SUBCY_SX_KK::Execute()
+{
+ int val ;
+ bool c = m_cpu->flags.carry ;
+ val = m_cpu->s[ sX ] ;
+ val -= kk ;
+ if ( c )
+ val -= 1 ;
+
+ m_cpu->flags.carry = val < 0 ;
+ m_cpu->flags.zero = val == 0 ;
+
+ m_cpu->s[ sX ] = val ;
+
+ m_cpu->pc->Next() ;
+}
+
+void SUBCY_SX_KK::Print()
+{
+ cout << "SUBCY s" << sX << ", " << kk ;
+}
+
+void SUBCY_SX_SY::Execute()
+{
+ int val ;
+ bool c = m_cpu->flags.carry ;
+ val = m_cpu->s[ sX ] ;
+ val -= m_cpu->s[ sY ] ;
+ if ( c )
+ val -= 1 ;
+
+ m_cpu->flags.carry = val < 0 ;
+ m_cpu->flags.zero = val == 0 ;
+ m_cpu->s[ sX ] = val ;
+
+ m_cpu->pc->Next() ;
+}
+
+void SUBCY_SX_SY::Print()
+{
+ cout << "SUBCY s" << sX << ", s" << sY ;
+}
+
+void TEST_SX_KK::Execute()
+{
+ uint8_t and_test = ( m_cpu->s[ sX ] & kk ) ;
+ m_cpu->flags.zero = and_test == 0 ;
+
+ int i ;
+
+ uint8_t xor_test = 0, b ;
+
+ for ( i = 0 ; i < 7 ; i++ ) {
+ b = ( and_test & ( 1 << i ) ) != 0 ;
+ xor_test = b ^ xor_test ;
+ }
+
+ m_cpu->flags.carry = xor_test != 0 ;
+ m_cpu->pc->Next() ;
+}
+
+void TEST_SX_KK::Print()
+{
+ cout << "TEST s" << sX << ", " << kk ;
+}
+
+void TEST_SX_SY::Execute()
+{
+ uint8_t and_test = ( m_cpu->s[ sX ] & m_cpu->s[ sY ] ) ;
+ m_cpu->flags.zero = and_test == 0 ;
+
+ int i ;
+
+ uint8_t xor_test = 0, b ;
+
+ for ( i = 0 ; i < 7 ; i++ ) {
+ b = ( and_test & ( 1 << i ) ) != 0 ;
+ xor_test = b ^ xor_test ;
+ }
+
+ m_cpu->flags.carry = xor_test != 0 ;
+ m_cpu->pc->Next() ;
+}
+
+void TEST_SX_SY::Print()
+{
+ cout << "TEST s" << sX << ", s" << sY ;
+}
+
+void XOR_SX_KK::Execute()
+{
+ m_cpu->s[ sX ] ^= kk ;
+
+ m_cpu->flags.carry = false ;
+ m_cpu->flags.zero = m_cpu->s[ sX ] == 0 ;
+ m_cpu->pc->Next() ;
+}
+
+void XOR_SX_KK::Print()
+{
+ cout << "XOR s" << sX << ", " << kk ;
+}
+
+
+void XOR_SX_SY::Execute()
+{
+ m_cpu->s[ sX ] ^= m_cpu->s[ sY ] ;
+
+ m_cpu->flags.carry = false ;
+ m_cpu->flags.zero = m_cpu->s[ sX ] == 0 ;
+ m_cpu->pc->Next() ;
+}
+
+void XOR_SX_SY::Print()
+{
+ cout << "XOR s" << sX << ", s" << sY ;
+}
+
+void RESET_EVENT::Execute()
+{
+ m_cpu->pc->Set( 0 ) ;
+ m_cpu->flags.interrupt_enable = false ;
+ m_cpu->flags.zero = false ;
+ m_cpu->flags.carry = false ;
+ m_cpu->stack->Reset() ;
+}
+
+void RESET_EVENT::Print()
+{
+ cout << "(RESET EVENT)" ;
+}
+
+void INTERRUPT_EVENT::Execute()
+{
+ if ( m_cpu->flags.interrupt_enable ) {
+ m_cpu->flags.interrupt_enable = false ;
+ m_cpu->stack->Push( m_cpu->pc->Get() ) ;
+ m_cpu->flags.preserved_carry = m_cpu->flags.carry ;
+ m_cpu->flags.preserved_zero = m_cpu->flags.zero ;
+ m_cpu->pc->Set( 0x3FF ) ;
+ }
+}
+
+void INTERRUPT_EVENT::Print()
+{
+ cout << "(INTERRUPT EVENT)" ;
+}
+
diff --git a/src/cinstruction.h b/src/cinstruction.h
new file mode 100755
index 0000000..505eb25
--- /dev/null
+++ b/src/cinstruction.h
@@ -0,0 +1,607 @@
+
+#ifndef CINSTRUCTION
+#define CINSTRUCTION
+
+#include "types.h"
+#include "cpicoblaze.h"
+
+//class CPicoBlaze ;
+
+// CInstruction members :
+// adress = Absolute instruction address
+// sX = Register sX
+// sY = Register sY
+// kk = Immediate constant
+// pp = port
+// ss = Scratchpad RAM address
+
+class CInstruction {
+
+ public:
+ CInstruction() ;
+ CInstruction( CPicoBlaze *cpu, uint32_t opcode ) ;
+ virtual ~CInstruction() ;
+
+ virtual void Execute() = 0 ;
+ virtual void Print() ;
+
+ void setSourceLine( unsigned int line ) { sourceLine = line ; }
+ unsigned int getSourceLine() { return sourceLine ; }
+
+ uint32_t getHexCode() { return hexcode ; }
+ protected:
+ CPicoBlaze *m_cpu ;
+
+ uint16_t sX, sY, ss, pp, kk, address ;
+ uint32_t hexcode ;
+ unsigned int sourceLine ;
+} ;
+
+
+class ADD_SX_KK : public CInstruction {
+
+ public:
+ ADD_SX_KK( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class ADD_SX_SY : public CInstruction {
+
+ public:
+ ADD_SX_SY( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class ADDCY_SX_KK : public CInstruction {
+
+ public:
+ ADDCY_SX_KK( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class ADDCY_SX_SY : public CInstruction {
+
+ public:
+ ADDCY_SX_SY( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class AND_SX_KK : public CInstruction {
+
+ public:
+ AND_SX_KK( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class AND_SX_SY : public CInstruction {
+
+ public:
+ AND_SX_SY( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class CALL : public CInstruction {
+
+ public:
+ CALL( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class CALLC : public CInstruction {
+
+ public:
+ CALLC( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class CALLNC : public CInstruction {
+
+ public:
+ CALLNC( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class CALLNZ : public CInstruction {
+
+ public:
+ CALLNZ( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class CALLZ : public CInstruction {
+
+ public:
+ CALLZ( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class COMPARE_SX_KK : public CInstruction {
+
+ public:
+ COMPARE_SX_KK( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class COMPARE_SX_SY : public CInstruction {
+
+ public:
+ COMPARE_SX_SY( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class DISABLE_INTERRUPT : public CInstruction {
+
+ public:
+ DISABLE_INTERRUPT( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class ENABLE_INTERRUPT : public CInstruction {
+
+ public:
+ ENABLE_INTERRUPT( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class FETCH_SX_SS : public CInstruction {
+
+ public:
+ FETCH_SX_SS( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class FETCH_SX_SY : public CInstruction {
+
+ public:
+ FETCH_SX_SY( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class INPUT_SX_SY : public CInstruction {
+
+ public:
+ INPUT_SX_SY( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class INPUT_SX_PP : public CInstruction {
+
+ public:
+ INPUT_SX_PP( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class JUMP : public CInstruction {
+
+ public:
+ JUMP( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class JUMPC : public CInstruction {
+
+ public:
+ JUMPC( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class JUMPNC : public CInstruction {
+
+ public:
+ JUMPNC( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class JUMPNZ : public CInstruction {
+
+ public:
+ JUMPNZ( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class JUMPZ : public CInstruction {
+
+ public:
+ JUMPZ( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class LOAD_SX_KK : public CInstruction {
+
+ public:
+ LOAD_SX_KK( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class LOAD_SX_SY : public CInstruction {
+
+ public:
+ LOAD_SX_SY( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class OR_SX_KK : public CInstruction {
+
+ public:
+ OR_SX_KK( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class OR_SX_SY : public CInstruction {
+
+ public:
+ OR_SX_SY( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class OUTPUT_SX_SY : public CInstruction {
+
+ public:
+ OUTPUT_SX_SY( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class OUTPUT_SX_PP : public CInstruction {
+
+ public:
+ OUTPUT_SX_PP( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class RETURN : public CInstruction {
+
+ public:
+ RETURN( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class RETURNC : public CInstruction {
+
+ public:
+ RETURNC( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class RETURNNC : public CInstruction {
+
+ public:
+ RETURNNC( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class RETURNNZ : public CInstruction {
+
+ public:
+ RETURNNZ( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class RETURNZ : public CInstruction {
+
+ public:
+ RETURNZ( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class RETURNI_DISABLE : public CInstruction {
+
+ public:
+ RETURNI_DISABLE( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class RETURNI_ENABLE : public CInstruction {
+
+ public:
+ RETURNI_ENABLE( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class RL_SX : public CInstruction {
+
+ public:
+ RL_SX( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class RR_SX : public CInstruction {
+
+ public:
+ RR_SX( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class SL0_SX : public CInstruction {
+
+ public:
+ SL0_SX( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class SL1_SX : public CInstruction {
+
+ public:
+ SL1_SX( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class SLA_SX : public CInstruction {
+
+ public:
+ SLA_SX( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class SLX_SX : public CInstruction {
+
+ public:
+ SLX_SX( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class SR0_SX : public CInstruction {
+
+ public:
+ SR0_SX( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class SR1_SX : public CInstruction {
+
+ public:
+ SR1_SX( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class SRA_SX : public CInstruction {
+
+ public:
+ SRA_SX( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class SRX_SX : public CInstruction {
+
+ public:
+ SRX_SX( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class STORE_SX_SS : public CInstruction {
+
+ public:
+ STORE_SX_SS( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class STORE_SX_SY : public CInstruction {
+
+ public:
+ STORE_SX_SY( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class SUB_SX_KK : public CInstruction {
+
+ public:
+ SUB_SX_KK( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class SUB_SX_SY : public CInstruction {
+
+ public:
+ SUB_SX_SY( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class SUBCY_SX_KK : public CInstruction {
+
+ public:
+ SUBCY_SX_KK( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class SUBCY_SX_SY : public CInstruction {
+
+ public:
+ SUBCY_SX_SY( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class TEST_SX_KK : public CInstruction {
+
+ public:
+ TEST_SX_KK( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class TEST_SX_SY : public CInstruction {
+
+ public:
+ TEST_SX_SY( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class XOR_SX_KK : public CInstruction {
+
+ public:
+ XOR_SX_KK( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+
+} ;
+
+class XOR_SX_SY : public CInstruction {
+
+ public:
+ XOR_SX_SY( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class RESET_EVENT : public CInstruction {
+
+ public:
+ RESET_EVENT( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+class INTERRUPT_EVENT : public CInstruction {
+
+ public:
+ INTERRUPT_EVENT( CPicoBlaze *cpu, uint32_t opcode ) : CInstruction( cpu, opcode ) {} ;
+
+ void Execute() ;
+ void Print() ;
+} ;
+
+#endif
+
diff --git a/src/codeeditor.cpp b/src/codeeditor.cpp
new file mode 100755
index 0000000..2e5c086
--- /dev/null
+++ b/src/codeeditor.cpp
@@ -0,0 +1,426 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+#include "codeeditor.h"
+#include <klibloader.h>
+
+#include <qmessagebox.h>
+#include <kmessagebox.h>
+#include <qlayout.h>
+#include <kfiledialog.h>
+
+CodeEditor::CodeEditor(QWidget *parent, const char *name)
+ : QWidget(parent, name)
+{
+ QVBoxLayout *layout = new QVBoxLayout(this) ;
+
+ KLibFactory *factory = KLibLoader::self()->factory( "libkatepart" ) ;
+ m_doc = ( Kate::Document* ) factory->create( 0L, "kate", "KTextEditor::Document" ) ;
+ m_view = ( Kate::View * ) m_doc->createView( this ) ;
+ m_view->setIconBorder( true ) ;
+
+ connect( m_view, SIGNAL(cursorPositionChanged()), this, SLOT(slotCursorPositionChanged()) );
+
+ layout->addWidget( m_view ) ;
+
+ m_exeLine = 0 ;
+ m_filename = "" ;
+ m_bFilename = false ;
+ m_doc->setModified( false );
+
+ m_doc->setDescription((KTextEditor::MarkInterface::MarkTypes)Breakpoint, "Breakpoint");
+ m_doc->setPixmap((KTextEditor::MarkInterface::MarkTypes)Breakpoint, *inactiveBreakpointPixmap());
+ m_doc->setPixmap((KTextEditor::MarkInterface::MarkTypes)ActiveBreakpoint, *activeBreakpointPixmap());
+ m_doc->setPixmap((KTextEditor::MarkInterface::MarkTypes)ReachedBreakpoint, *reachedBreakpointPixmap());
+ m_doc->setPixmap((KTextEditor::MarkInterface::MarkTypes)DisabledBreakpoint, *disabledBreakpointPixmap());
+ m_doc->setPixmap((KTextEditor::MarkInterface::MarkTypes)ExecutionPoint, *executionPointPixmap());
+ m_doc->setMarksUserChangable( Bookmark | Breakpoint );
+
+ setHighlightMode() ;
+
+
+ m_statusBar = new KStatusBar( this ) ;
+ layout->addWidget( m_statusBar ) ;
+ m_statusBar->insertItem( "", 0, 0, true ) ;
+
+ slotCursorPositionChanged() ;
+}
+
+CodeEditor::~CodeEditor()
+{
+ if ( m_view->document()->views().count() == 1)
+ delete m_view->document();
+
+ delete m_statusBar ;
+}
+
+void CodeEditor::slotCursorPositionChanged()
+{
+ unsigned int line, column ;
+ m_view->cursorPosition( &line, &column ) ;
+ m_statusBar->changeItem( QString( " Line: %1 Col: %2 " ).arg( QString::number( line+1 ) ).arg( QString::number( column+1 ) ), 0 ) ;
+}
+
+void CodeEditor::slotToggleBreakpoint()
+{
+ unsigned int line, col ;
+
+ m_view->cursorPosition( &line, &col ) ;
+
+ if ( !isBreakpoint( line ) )
+ if ( m_doc->mark( m_exeLine ) & ExecutionPoint )
+ m_doc->setMark( line, Breakpoint | ExecutionPoint) ;
+ else
+ m_doc->setMark( line, Breakpoint ) ;
+ else
+ m_doc->removeMark( line, Breakpoint ) ;
+}
+
+void CodeEditor::clearExecutionMarker()
+{
+ m_doc->removeMark( m_exeLine, ExecutionPoint ) ;
+}
+
+void CodeEditor::setCursor( unsigned int line )
+{
+ m_view->setCursorPosition( line, 0 ) ;
+}
+
+void CodeEditor::setExecutionMarker( unsigned int line )
+{
+ m_doc->removeMark( m_exeLine,ExecutionPoint ) ;
+ m_exeLine = line ;
+ if ( isBreakpoint( line ) ) {
+ m_doc->setMark( m_exeLine, ExecutionPoint| Breakpoint ) ;
+ } else
+ m_doc->setMark( m_exeLine, ExecutionPoint ) ;
+
+ setCursor( line ) ; // KDevelop does this too!
+
+}
+
+bool CodeEditor::isBreakpoint( unsigned int line )
+{
+ return ( ( m_doc->mark( line ) & Breakpoint ) != 0 ) ;
+}
+
+void CodeEditor::slotNewFile()
+{
+ m_doc->clear() ;
+ m_doc->setModified( false ) ;
+ m_filename = "" ;
+ m_bFilename = false ;
+}
+
+void CodeEditor::slotSaveAs()
+{
+ if ( m_view->saveAs() == Kate::View::SAVE_OK ) {
+ m_filename = m_doc->url().path() ;
+ m_bFilename = true ;
+ }
+}
+
+bool CodeEditor::save()
+{
+ slotSave() ;
+ return m_bFilename ;
+}
+
+void CodeEditor::slotSave()
+{
+ if ( !m_bFilename )
+ slotSaveAs() ;
+ else if ( m_view->save() == Kate::View::SAVE_OK ) {
+ m_filename = m_doc->url().path() ;
+ m_bFilename = true ;
+ }
+}
+
+void CodeEditor::slotPrint()
+{
+ m_doc->print() ;
+}
+
+void CodeEditor::slotFind()
+{
+ m_view->find() ;
+}
+
+void CodeEditor::slotFindNext()
+{
+ m_view->findAgain() ;
+}
+
+void CodeEditor::slotShowConfig()
+{
+ m_doc->configDialog() ;
+}
+
+void CodeEditor::slotCut()
+{
+ m_view->cut() ;
+}
+
+void CodeEditor::slotCopy()
+{
+ m_view->copy() ;
+}
+
+void CodeEditor::slotPaste()
+{
+ m_view->paste() ;
+}
+
+void CodeEditor::slotSelectAll()
+{
+ m_doc->selectAll() ;
+}
+
+void CodeEditor::slotUndo()
+{
+ m_doc->undo() ;
+}
+
+void CodeEditor::slotRedo()
+{
+ m_doc->redo() ;
+}
+
+void CodeEditor::slotOpen()
+{
+ QString filename = KFileDialog::getOpenFileName( QString::null, QString( "*.psm|PicoBlaze assembly files" ) ) ;
+ if ( filename != "" ) {
+ m_filename = filename ;
+ m_bFilename = true ;
+ m_doc->openURL( filename ) ;
+ setHighlightMode() ;
+ }
+}
+
+void CodeEditor::open( QString filename )
+{
+ if ( filename != "" ) {
+ m_filename = filename ;
+ m_bFilename = true ;
+ m_doc->openURL( filename ) ;
+ setHighlightMode() ;
+ }
+}
+
+QString CodeEditor::getFilename()
+{
+ return m_filename ;
+}
+
+
+void CodeEditor::setHighlightMode()
+{
+ int i = 0;
+ int hlModeCount = m_doc->hlModeCount();
+ while ( i < hlModeCount ) {
+ if ( m_doc->hlModeName( i ) == "pblazeASM" ) {
+ m_doc->setHlMode( i ) ;
+ break ;
+ }
+ i++;
+ }
+}
+
+bool CodeEditor::askSave()
+{
+ QString filename ;
+ if ( m_bFilename )
+ filename = m_filename ;
+ else
+ filename = "Untitled" ;
+
+ int choice = KMessageBox::warningYesNoCancel( this, QString( "The document \'%1\' has been modified.\nDo you want to save it?").arg( filename ), "Save Document?", KGuiItem( "Save" ), KGuiItem( "Discard" ) );
+
+ if ( choice == KMessageBox::Yes )
+ save() ;
+
+ return ( choice != KMessageBox::Cancel ) ;
+}
+
+bool CodeEditor::close()
+{
+ if ( m_doc->isModified() )
+ return askSave() ;
+ return true ;
+}
+
+const QPixmap* CodeEditor::inactiveBreakpointPixmap()
+{
+ const char*breakpoint_gr_xpm[]={
+ "11 16 6 1",
+ "c c #c6c6c6",
+ "d c #2c2c2c",
+ "# c #000000",
+ ". c None",
+ "a c #ffffff",
+ "b c #555555",
+ "...........",
+ "...........",
+ "...#####...",
+ "..#aaaaa#..",
+ ".#abbbbbb#.",
+ "#abbbbbbbb#",
+ "#abcacacbd#",
+ "#abbbbbbbb#",
+ "#abcacacbd#",
+ "#abbbbbbbb#",
+ ".#bbbbbbb#.",
+ "..#bdbdb#..",
+ "...#####...",
+ "...........",
+ "...........",
+ "..........."};
+ static QPixmap pixmap( breakpoint_gr_xpm );
+ return &pixmap;
+}
+
+
+const QPixmap* CodeEditor::activeBreakpointPixmap()
+{
+ const char* breakpoint_xpm[]={
+ "11 16 6 1",
+ "c c #c6c6c6",
+ ". c None",
+ "# c #000000",
+ "d c #840000",
+ "a c #ffffff",
+ "b c #ff0000",
+ "...........",
+ "...........",
+ "...#####...",
+ "..#aaaaa#..",
+ ".#abbbbbb#.",
+ "#abbbbbbbb#",
+ "#abcacacbd#",
+ "#abbbbbbbb#",
+ "#abcacacbd#",
+ "#abbbbbbbb#",
+ ".#bbbbbbb#.",
+ "..#bdbdb#..",
+ "...#####...",
+ "...........",
+ "...........",
+ "..........."};
+ static QPixmap pixmap( breakpoint_xpm );
+ return &pixmap;
+}
+
+
+
+const QPixmap* CodeEditor::reachedBreakpointPixmap()
+{
+ const char*breakpoint_bl_xpm[]={
+ "11 16 7 1",
+ "a c #c0c0ff",
+ "# c #000000",
+ "c c #0000c0",
+ "e c #0000ff",
+ "b c #dcdcdc",
+ "d c #ffffff",
+ ". c None",
+ "...........",
+ "...........",
+ "...#####...",
+ "..#ababa#..",
+ ".#bcccccc#.",
+ "#acccccccc#",
+ "#bcadadace#",
+ "#acccccccc#",
+ "#bcadadace#",
+ "#acccccccc#",
+ ".#ccccccc#.",
+ "..#cecec#..",
+ "...#####...",
+ "...........",
+ "...........",
+ "..........."};
+ static QPixmap pixmap( breakpoint_bl_xpm );
+ return &pixmap;
+}
+
+
+const QPixmap* CodeEditor::disabledBreakpointPixmap()
+{
+ const char*breakpoint_wh_xpm[]={
+ "11 16 7 1",
+ "a c #c0c0ff",
+ "# c #000000",
+ "c c #0000c0",
+ "e c #0000ff",
+ "b c #dcdcdc",
+ "d c #ffffff",
+ ". c None",
+ "...........",
+ "...........",
+ "...#####...",
+ "..#ddddd#..",
+ ".#ddddddd#.",
+ "#ddddddddd#",
+ "#ddddddddd#",
+ "#ddddddddd#",
+ "#ddddddddd#",
+ "#ddddddddd#",
+ ".#ddddddd#.",
+ "..#ddddd#..",
+ "...#####...",
+ "...........",
+ "...........",
+ "..........."};
+ static QPixmap pixmap( breakpoint_wh_xpm );
+ return &pixmap;
+}
+
+
+const QPixmap* CodeEditor::executionPointPixmap()
+{
+ const char*exec_xpm[]={
+ "11 16 4 1",
+ "a c #00ff00",
+ "b c #000000",
+ ". c None",
+ "# c #00c000",
+ "...........",
+ "...........",
+ "...........",
+ "#a.........",
+ "#aaa.......",
+ "#aaaaa.....",
+ "#aaaaaaa...",
+ "#aaaaaaaaa.",
+ "#aaaaaaa#b.",
+ "#aaaaa#b...",
+ "#aaa#b.....",
+ "#a#b.......",
+ "#b.........",
+ "...........",
+ "...........",
+ "..........."};
+ static QPixmap pixmap( exec_xpm );
+ return &pixmap;
+}
+
+
+
+
+#include "codeeditor.moc"
diff --git a/src/codeeditor.h b/src/codeeditor.h
new file mode 100755
index 0000000..a3a57ce
--- /dev/null
+++ b/src/codeeditor.h
@@ -0,0 +1,98 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+#ifndef CODEEDITOR_H
+#define CODEEDITOR_H
+
+#include <qwidget.h>
+#include <kate/view.h>
+#include <kate/document.h>
+#include <kstatusbar.h>
+
+class CodeEditor : public QWidget
+{
+ Q_OBJECT
+ public:
+ CodeEditor(QWidget *parent = 0, const char *name = 0);
+ ~CodeEditor();
+
+ void clearExecutionMarker() ;
+ void setExecutionMarker( unsigned int line ) ;
+
+ QString getFilename() ;
+ bool isBreakpoint( unsigned int line ) ;
+ void setCursor( unsigned int line ) ;
+
+ void open( QString filename ) ;
+ bool close() ;
+ bool save() ;
+
+ protected:
+ Kate::View * m_view ;
+ Kate::Document * m_doc ;
+
+ KStatusBar *m_statusBar ;
+
+ unsigned int m_exeLine ;
+ QString m_filename ;
+ bool m_bFilename ;
+ void setHighlightMode() ;
+ bool askSave() ;
+
+ enum MarkType {
+ Bookmark = KTextEditor::MarkInterface::markType01,
+ Breakpoint = KTextEditor::MarkInterface::markType02,
+ ActiveBreakpoint = KTextEditor::MarkInterface::markType03,
+ ReachedBreakpoint = KTextEditor::MarkInterface::markType04,
+ DisabledBreakpoint = KTextEditor::MarkInterface::markType05,
+ ExecutionPoint = KTextEditor::MarkInterface::markType06
+ };
+
+
+ static const QPixmap* inactiveBreakpointPixmap();
+ static const QPixmap* activeBreakpointPixmap();
+ static const QPixmap* reachedBreakpointPixmap();
+ static const QPixmap* disabledBreakpointPixmap();
+ static const QPixmap* executionPointPixmap();
+
+
+ public slots:
+ void slotToggleBreakpoint() ; // set breakpoint at current position
+ void slotSave() ;
+ void slotSaveAs() ;
+ void slotOpen() ;
+ void slotShowConfig() ;
+ void slotFind() ;
+ void slotFindNext() ;
+ void slotNewFile() ;
+ void slotPrint() ;
+
+ void slotCut() ;
+ void slotCopy() ;
+ void slotPaste() ;
+
+ void slotUndo() ;
+ void slotRedo() ;
+ void slotSelectAll() ;
+
+ void slotCursorPositionChanged() ;
+
+};
+
+#endif
diff --git a/src/cpicoblaze.cpp b/src/cpicoblaze.cpp
new file mode 100755
index 0000000..4b85b7e
--- /dev/null
+++ b/src/cpicoblaze.cpp
@@ -0,0 +1,436 @@
+#include "cpicoblaze.h"
+
+#include <iostream>
+
+using namespace std ;
+
+CProgramCounter::CProgramCounter()
+{
+ pc = 0 ;
+}
+
+CProgramCounter::~CProgramCounter()
+{
+
+}
+
+void CProgramCounter::Next()
+{
+ pc = ( pc + 1 ) % (MAX_ADDRESS);
+}
+
+void CProgramCounter::Set( uint16_t address )
+{
+ pc = address % (MAX_ADDRESS) ;
+}
+
+uint16_t CProgramCounter::Get()
+{
+ return pc ;
+}
+
+CScratchPad::CScratchPad()
+{
+ int i ;
+ for ( i = 0 ; i < sizeof( ram ) ; i++ )
+ ram[ i ] = 0 ;
+}
+
+CScratchPad::~CScratchPad()
+{
+}
+
+CStack::CStack()
+{
+ int i ;
+ for ( i = 0 ; i < STACK_DEPTH ; i++ )
+ stack[ i ] = 0 ;
+ ptr = 0 ;
+}
+
+CStack::~CStack()
+{
+}
+
+void CStack::Push( uint16_t data )
+{
+ data &= 0x3FF ;
+ if ( ptr == STACK_DEPTH - 1 )
+ cout << ">>>>Stack overflow!<<<<\r\n" ;
+
+ stack[ ptr ] = data ;
+ ptr = ( ptr + 1 ) % STACK_DEPTH ;
+}
+
+uint16_t CStack::Pop()
+{
+ if ( ptr == 0 )
+ cout << ">>>>Stack underflow!<<<<\r\n" ;
+
+ ptr = ( ptr - 1 ) % STACK_DEPTH ;
+ return stack[ ptr ] ;
+}
+
+void CStack::Reset()
+{
+ ptr = 0 ;
+}
+
+uint8_t CScratchPad::Get( uint8_t address )
+{
+ return ram[ address % sizeof( ram ) ] ;
+}
+
+void CScratchPad::Set( uint8_t address, uint8_t data )
+{
+ ram[ address % sizeof( ram ) ] = data ;
+}
+
+CPort::CPort()
+{
+}
+
+
+CPort::~CPort()
+{
+}
+
+void CPort::addPort( CIOPort * port )
+{
+ portList.push_back( port ) ;
+}
+
+void CPort::deletePort( CIOPort * port )
+{
+ portList.remove( port ) ;
+}
+
+uint8_t CPort::PortIn()
+{
+ // find appropiate port
+ list<CIOPort*>::iterator i ;
+
+ for ( i = portList.begin() ; i != portList.end() ; i++ )
+ if ( (*i)->getID() == portid && (*i)->isReadable() )
+ return (*i)->In() ;
+
+
+ // Nothing found return zero
+ return 0 ;
+}
+
+void CPort::PortOut( uint8_t data )
+{
+ // find appropiate port
+ list<CIOPort*>::iterator i ;
+
+ for ( i = portList.begin() ; i != portList.end() ; i++ )
+ if ( (*i)->getID() == portid && (*i)->isWriteable() )
+ (*i)->Out( data ) ;
+}
+
+
+CCode::CCode( CPicoBlaze *cpu )
+{
+ m_cpu = cpu ;
+
+ int i ;
+ for ( i = 0 ; i < MAX_ADDRESS ; i++ )
+ CodeMap[ i ] = NULL ;
+}
+
+CCode::~CCode()
+{
+ ClearCode() ;
+}
+
+void CCode::ClearCode() {
+ int i ;
+ for ( i = 0 ; i < MAX_ADDRESS ; i++ )
+ if ( CodeMap[ i ] != NULL ) {
+ delete CodeMap[ i ] ;
+ CodeMap[ i ] = NULL ;
+ }
+}
+
+CInstruction * CCode::Disassemble( uint32_t code )
+{
+ uint32_t code_17_0 = (code & 0x3ffff) ;
+ uint32_t code_17_12 = (code & 0x3f000) ;
+ uint32_t code_17_10 = (code & 0x3fC00) ;
+ uint32_t code_7_0 = (code & 0x000ff) ;
+
+ /* The picoBlaze-3 instruction set */
+ if ( code_17_0 == instrRETURN ) return new RETURN( m_cpu, code ) ;
+ if ( code_17_0 == instrRETURNC ) return new RETURNC( m_cpu, code ) ;
+ if ( code_17_0 == instrRETURNNC ) return new RETURNNC( m_cpu, code ) ;
+ if ( code_17_0 == instrRETURNNZ ) return new RETURNNZ( m_cpu, code ) ;
+ if ( code_17_0 == instrRETURNZ ) return new RETURNZ( m_cpu, code ) ;
+ if ( code_17_0 == instrRETURNI_DISABLE ) return new RETURNI_DISABLE( m_cpu, code ) ;
+ if ( code_17_0 == instrRETURNI_ENABLE ) return new RETURNI_ENABLE( m_cpu, code ) ;
+ if ( code_17_0 == instrDISABLE_INTERRUPT ) return new DISABLE_INTERRUPT( m_cpu, code ) ;
+ if ( code_17_0 == instrENABLE_INTERRUPT ) return new ENABLE_INTERRUPT( m_cpu, code ) ;
+ if ( code_17_10 == instrCALL ) return new CALL( m_cpu, code ) ;
+ if ( code_17_10 == instrCALLC ) return new CALLC( m_cpu, code ) ;
+ if ( code_17_10 == instrCALLNC ) return new CALLNC( m_cpu, code ) ;
+ if ( code_17_10 == instrCALLNZ ) return new CALLNZ( m_cpu, code ) ;
+ if ( code_17_10 == instrCALLZ ) return new CALLZ( m_cpu, code ) ;
+ if ( code_17_10 == instrJUMP ) return new JUMP( m_cpu, code ) ;
+ if ( code_17_10 == instrJUMPC ) return new JUMPC( m_cpu, code ) ;
+ if ( code_17_10 == instrJUMPNC ) return new JUMPNC( m_cpu, code ) ;
+ if ( code_17_10 == instrJUMPNZ ) return new JUMPNZ( m_cpu, code ) ;
+ if ( code_17_10 == instrJUMPZ ) return new JUMPZ( m_cpu, code ) ;
+ if ( code_17_12 == instrADD_SX_KK ) return new ADD_SX_KK( m_cpu, code ) ;
+ if ( code_17_12 == instrADD_SX_SY ) return new ADD_SX_SY( m_cpu, code ) ;
+ if ( code_17_12 == instrADDCY_SX_KK ) return new ADDCY_SX_KK( m_cpu, code ) ;
+ if ( code_17_12 == instrADDCY_SX_SY ) return new ADDCY_SX_SY( m_cpu, code ) ;
+ if ( code_17_12 == instrAND_SX_KK ) return new AND_SX_KK( m_cpu, code ) ;
+ if ( code_17_12 == instrAND_SX_SY) return new AND_SX_SY( m_cpu, code ) ;
+ if ( code_17_12 == instrCOMPARE_SX_KK ) return new COMPARE_SX_KK( m_cpu, code ) ;
+ if ( code_17_12 == instrCOMPARE_SX_SY ) return new COMPARE_SX_SY( m_cpu, code ) ;
+ if ( code_17_12 == instrFETCH_SX_SS ) return new FETCH_SX_SS( m_cpu, code ) ;
+ if ( code_17_12 == instrFETCH_SX_SY ) return new FETCH_SX_SY( m_cpu, code ) ;
+ if ( code_17_12 == instrINPUT_SX_SY ) return new INPUT_SX_SY( m_cpu, code ) ;
+ if ( code_17_12 == instrINPUT_SX_PP ) return new INPUT_SX_PP( m_cpu, code ) ;
+ if ( code_17_12 == instrLOAD_SX_KK ) return new LOAD_SX_KK( m_cpu, code ) ;
+ if ( code_17_12 == instrLOAD_SX_SY ) return new LOAD_SX_SY( m_cpu, code ) ;
+ if ( code_17_12 == instrOR_SX_KK ) return new OR_SX_KK( m_cpu, code ) ;
+ if ( code_17_12 == instrOR_SX_SY ) return new OR_SX_SY( m_cpu, code ) ;
+ if ( code_17_12 == instrOUTPUT_SX_SY ) return new OUTPUT_SX_SY( m_cpu, code ) ;
+ if ( code_17_12 == instrOUTPUT_SX_PP ) return new OUTPUT_SX_PP( m_cpu, code ) ;
+ if ( code_17_12 == instrSTORE_SX_SS ) return new STORE_SX_SS( m_cpu, code ) ;
+ if ( code_17_12 == instrSTORE_SX_SY ) return new STORE_SX_SY( m_cpu, code ) ;
+ if ( code_17_12 == instrSUB_SX_KK ) return new SUB_SX_KK( m_cpu, code ) ;
+ if ( code_17_12 == instrSUB_SX_SY ) return new SUB_SX_SY( m_cpu, code ) ;
+ if ( code_17_12 == instrSUBCY_SX_KK ) return new SUBCY_SX_KK( m_cpu, code ) ;
+ if ( code_17_12 == instrSUBCY_SX_SY ) return new SUBCY_SX_SY( m_cpu, code ) ;
+ if ( code_17_12 == instrTEST_SX_KK ) return new TEST_SX_KK( m_cpu, code ) ;
+ if ( code_17_12 == instrTEST_SX_SY ) return new TEST_SX_SY( m_cpu, code ) ;
+ if ( code_17_12 == instrXOR_SX_KK ) return new XOR_SX_KK( m_cpu, code ) ;
+ if ( code_17_12 == instrXOR_SX_SY ) return new XOR_SX_SY( m_cpu, code ) ;
+ if ( code_7_0 == instrRL_SX ) return new RL_SX( m_cpu, code ) ;
+ if ( code_7_0 == instrRR_SX ) return new RR_SX( m_cpu, code ) ;
+ if ( code_7_0 == instrSL0_SX ) return new SL0_SX( m_cpu, code ) ;
+ if ( code_7_0 == instrSL1_SX ) return new SL1_SX( m_cpu, code ) ;
+ if ( code_7_0 == instrSLA_SX ) return new SLA_SX( m_cpu, code ) ;
+ if ( code_7_0 == instrSLX_SX ) return new SLX_SX( m_cpu, code ) ;
+ if ( code_7_0 == instrSR0_SX ) return new SR0_SX( m_cpu, code ) ;
+ if ( code_7_0 == instrSR1_SX ) return new SR1_SX( m_cpu, code ) ;
+ if ( code_7_0 == instrSRA_SX ) return new SRA_SX( m_cpu, code ) ;
+ if ( code_7_0 == instrSRX_SX ) return new SRX_SX( m_cpu, code ) ;
+/* switch( code_17_0 ) {
+ case instrRETURN : return new RETURN( m_cpu, code ) ;
+ case instrRETURNC : return new RETURNC( m_cpu, code ) ;
+ case instrRETURNNC : return new RETURNNC( m_cpu, code ) ;
+ case instrRETURNNZ : return new RETURNNZ( m_cpu, code ) ;
+ case instrRETURNZ : return new RETURNZ( m_cpu, code ) ;
+ case instrRETURNI_DISABLE : return new RETURNI_DISABLE( m_cpu, code ) ;
+ case instrRETURNI_ENABLE : return new RETURNI_ENABLE( m_cpu, code ) ;
+ case instrDISABLE_INTERRUPT : return new DISABLE_INTERRUPT( m_cpu, code ) ;
+ case instrENABLE_INTERRUPT : return new ENABLE_INTERRUPT( m_cpu, code ) ;
+ default:
+ switch( code_17_10 ) {
+ case instrCALL : return new CALL( m_cpu, code ) ;
+ case instrCALLC : return new CALLC( m_cpu, code ) ;
+ case instrCALLNC : return new CALLNC( m_cpu, code ) ;
+ case instrCALLNZ : return new CALLNZ( m_cpu, code ) ;
+ case instrCALLZ : return new CALLZ( m_cpu, code ) ;
+ case instrJUMP : return new JUMP( m_cpu, code ) ;
+ case instrJUMPC : return new JUMPC( m_cpu, code ) ;
+ case instrJUMPNC : return new JUMPNC( m_cpu, code ) ;
+ case instrJUMPNZ : return new JUMPNZ( m_cpu, code ) ;
+ case instrJUMPZ : return new JUMPZ( m_cpu, code ) ;
+ default:
+ switch ( code_17_12 ) {
+ case instrADD_SX_KK : return new ADD_SX_KK( m_cpu, code ) ;
+ case instrADD_SX_SY : return new ADD_SX_SY( m_cpu, code ) ;
+ case instrADDCY_SX_KK : return new ADDCY_SX_KK( m_cpu, code ) ;
+ case instrADDCY_SX_SY : return new ADDCY_SX_SY( m_cpu, code ) ;
+ case instrAND_SX_KK : return new AND_SX_KK( m_cpu, code ) ;
+ case instrAND_SX_SY : return new AND_SX_SY( m_cpu, code ) ;
+ case instrCOMPARE_SX_KK : return new COMPARE_SX_KK( m_cpu, code ) ;
+ case instrCOMPARE_SX_SY : return new COMPARE_SX_SY( m_cpu, code ) ;
+ case instrFETCH_SX_SS : return new FETCH_SX_SS( m_cpu, code ) ;
+ case instrFETCH_SX_SY : return new FETCH_SX_SY( m_cpu, code ) ;
+ case instrINPUT_SX_SY : return new INPUT_SX_SY( m_cpu, code ) ;
+ case instrINPUT_SX_PP : return new INPUT_SX_PP( m_cpu, code ) ;
+ case instrLOAD_SX_KK : return new LOAD_SX_KK( m_cpu, code ) ;
+ case instrLOAD_SX_SY : return new LOAD_SX_SY( m_cpu, code ) ;
+ case instrOR_SX_KK : return new OR_SX_KK( m_cpu, code ) ;
+ case instrOR_SX_SY : return new OR_SX_SY( m_cpu, code ) ;
+ case instrOUTPUT_SX_SY : return new OUTPUT_SX_SY( m_cpu, code ) ;
+ case instrOUTPUT_SX_PP : return new OUTPUT_SX_PP( m_cpu, code ) ;
+ case instrSTORE_SX_SS : return new STORE_SX_SS( m_cpu, code ) ;
+ case instrSTORE_SX_SY : return new STORE_SX_SY( m_cpu, code ) ;
+ case instrSUB_SX_KK : return new SUB_SX_KK( m_cpu, code ) ;
+ case instrSUB_SX_SY : return new SUB_SX_SY( m_cpu, code ) ;
+ case instrSUBCY_SX_KK : return new SUBCY_SX_KK( m_cpu, code ) ;
+ case instrSUBCY_SX_SY : return new SUBCY_SX_SY( m_cpu, code ) ;
+ case instrTEST_SX_KK : return new TEST_SX_KK( m_cpu, code ) ;
+ case instrTEST_SX_SY : return new TEST_SX_SY( m_cpu, code ) ;
+ case instrXOR_SX_KK : return new XOR_SX_KK( m_cpu, code ) ;
+ case instrXOR_SX_SY : return new XOR_SX_SY( m_cpu, code ) ;
+
+ case instrROTATE:
+ switch( code_7_0 ) {
+ case instrRL_SX : return new RL_SX( m_cpu, code ) ;
+ case instrRR_SX : return new RR_SX( m_cpu, code ) ;
+ case instrSL0_SX : return new SL0_SX( m_cpu, code ) ;
+ case instrSL1_SX : return new SL1_SX( m_cpu, code ) ;
+ case instrSLA_SX : return new SLA_SX( m_cpu, code ) ;
+ case instrSLX_SX : return new SLX_SX( m_cpu, code ) ;
+ case instrSR0_SX : return new SR0_SX( m_cpu, code ) ;
+ case instrSR1_SX : return new SR1_SX( m_cpu, code ) ;
+ case instrSRA_SX : return new SRA_SX( m_cpu, code ) ;
+ case instrSRX_SX : return new SRX_SX( m_cpu, code ) ;
+ }
+ }
+ }
+ }
+*/
+ cout << "Invalid code (" << code << ")\r\n" ;
+
+ return NULL ;
+}
+
+bool CCode::setInstruction( uint16_t address, uint32_t code, unsigned int sourceLine )
+{
+ CInstruction *instr = Disassemble( code ) ;
+ if ( instr == NULL ) {
+ cout << ">>>>Unknown code at address " << address << "<<<<\r\n" ;
+ return FALSE ;
+ }
+
+ if ( address >= MAX_ADDRESS ) {
+ cout << ">>>>Invalid address" << address << "<<<<\r\n" ;
+ delete instr ;
+ return FALSE ;
+ }
+
+
+ if ( CodeMap[ address ] != NULL ) {
+ cout << ">>>>Code is placed at same address (" << address << ")<<<<\r\n" ;
+ delete instr ;
+ return FALSE ;
+ }
+
+ instr->setSourceLine( sourceLine ) ;
+ CodeMap[ address ] = instr ;
+
+ return TRUE ;
+}
+
+CInstruction * CCode::getInstruction( uint16_t address )
+{
+ if ( address >= MAX_ADDRESS )
+ return NULL ;
+ else
+ return CodeMap[ address ] ;
+}
+
+void CCode::Print()
+{
+ int i ;
+
+ cout << "----listing----\r\n" ;
+ for ( i = 0 ; i < MAX_ADDRESS ; i++ ) {
+ if ( CodeMap[ i ] != NULL ) {
+ cout << i << " : " ;
+ CodeMap[ i ]->Print() ;
+ cout << "\r\n" ;
+ }
+ }
+ cout << "----end listing----\r\n" ;
+
+}
+
+CPicoBlaze::CPicoBlaze()
+{
+ flags.zero = false ;
+ flags.carry = false ;
+ flags.interrupt_enable = false ;
+
+ scratch = new CScratchPad ;
+ pc = new CProgramCounter ;
+ stack = new CStack ;
+ port = new CPort ;
+ code = new CCode( this ) ;
+}
+
+CPicoBlaze::~CPicoBlaze()
+{
+ delete scratch ;
+ delete pc ;
+ delete stack ;
+ delete port ;
+ delete code ;
+}
+
+void CPicoBlaze::Reset()
+{
+ RESET_EVENT resetEvent( this, 0 ) ;
+
+ resetEvent.Print() ; cout << "\r\n" ;
+ resetEvent.Execute() ;
+}
+
+void CPicoBlaze::Interrupt()
+{
+ INTERRUPT_EVENT interruptEvent( this, 0 ) ;
+
+// interruptEvent.Print() ; cout << "\r\n" ;
+ interruptEvent.Execute() ;
+}
+
+void CPicoBlaze::Print()
+{
+ int i ;
+
+ cout << "----CPU----\r\n" ;
+ cout << "regs|" ;
+ for ( i = 0 ; i < 15 ; i++ )
+ cout << "s" << i << "=" << (int) s[ i ] << "|" ;
+ cout << "\r\n" ;
+
+ cout << "flags|";
+ cout << "c=" << flags.carry ;
+ cout << "|z=" << flags.zero ;
+ cout << "|ie=" << flags.interrupt_enable << "|\r\n" ;
+ cout << "----end CPU----\r\n" ;
+}
+
+unsigned int CPicoBlaze::GetNextSourceLine()
+{
+ CInstruction *instr = code->getInstruction( pc->Get() ) ;
+ if ( instr == NULL ) {
+ cout << ">>>>Error in simulation (No code found at " << pc->Get() << ")<<<<\r\n" ;
+ return FALSE ;
+ }
+
+ return instr->getSourceLine() ;
+}
+
+bool CPicoBlaze::Next()
+{
+ CInstruction *instr = code->getInstruction( pc->Get() ) ;
+ if ( instr == NULL ) {
+ cout << ">>>>Error in simulation (No code found at " << pc->Get() << ")<<<<\r\n" ;
+ return FALSE ;
+ }
+
+ instr->Execute() ;
+
+ return TRUE ;
+}
+
+void CPicoBlaze::addPort( CIOPort * ioport )
+{
+ port->addPort( ioport ) ;
+}
+
+void CPicoBlaze::deletePort( CIOPort * ioport )
+{
+ port->deletePort( ioport ) ;
+}
+
+
diff --git a/src/cpicoblaze.h b/src/cpicoblaze.h
new file mode 100755
index 0000000..f792f23
--- /dev/null
+++ b/src/cpicoblaze.h
@@ -0,0 +1,154 @@
+
+#ifndef CPICOBLAZE
+#define CPICOBLAZE
+
+#include <iostream>
+#include <list>
+
+using namespace std ;
+
+class CPicoBlaze ;
+class CInstruction ;
+
+#include "types.h"
+#include "cinstruction.h"
+#include "hexcodes.h"
+
+#define MAX_ADDRESS 0x400
+#define STACK_DEPTH 31
+#define SCRATCHPAD_SIZE 64
+
+#define PortReadable 1
+#define PortWriteable 2
+class CIOPort
+{
+ public:
+
+ CIOPort( uint8_t id ) { m_id = id ; m_mode = 0 ; }
+
+ virtual void Out( uint8_t val ) = 0 ;
+ virtual uint8_t In() = 0 ;
+
+ uint8_t getID() { return m_id ; }
+ void setID( uint8_t id ) { m_id = id ; }
+ void setMode( int mode ) { m_mode = mode ; }
+ int getMode() { return m_mode ; }
+ bool isReadable() { return (m_mode & PortReadable) != 0 ; }
+ bool isWriteable() { return (m_mode & PortWriteable) != 0 ; }
+
+ private:
+ uint8_t m_id ;
+ int m_mode ;
+} ;
+
+class CProgramCounter {
+ public:
+ CProgramCounter() ;
+ ~CProgramCounter() ;
+
+ void Next() ;
+ void Set( uint16_t address ) ;
+ uint16_t Get() ;
+
+ protected:
+ uint16_t pc ;
+} ;
+
+class CScratchPad {
+ public:
+ CScratchPad() ;
+ ~CScratchPad() ;
+
+ uint8_t Get( uint8_t address ) ;
+ void Set( uint8_t address, uint8_t data ) ;
+
+ protected:
+ uint8_t ram[ SCRATCHPAD_SIZE ] ;
+} ;
+
+class CStack {
+ public:
+ CStack() ;
+ ~CStack() ;
+
+ void Push( uint16_t value ) ;
+ uint16_t Pop() ;
+ void Reset() ;
+
+ protected:
+ uint16_t stack[ STACK_DEPTH ] ;
+ uint8_t ptr ;
+} ;
+
+class CPort {
+ public:
+ CPort() ;
+ ~CPort() ;
+
+ void PortID( uint8_t id ) { portid = id ; } ;
+ uint8_t PortIn() ;
+ void PortOut( uint8_t data ) ;
+
+ void addPort( CIOPort * port ) ;
+ void deletePort( CIOPort * port ) ;
+
+ protected:
+ uint16_t portid ;
+
+ list<CIOPort*> portList ;
+
+} ;
+
+class CCode {
+ public:
+ CCode( CPicoBlaze *cpu ) ;
+ ~CCode() ;
+
+ bool setInstruction( uint16_t address, uint32_t code, unsigned int sourceLine ) ;
+ CInstruction *getInstruction( uint16_t address ) ;
+
+ void ClearCode() ;
+ void Print() ;
+
+ CInstruction * Disassemble( uint32_t code ) ;
+
+ protected:
+ CPicoBlaze *m_cpu ;
+
+ CInstruction * CodeMap[ MAX_ADDRESS ] ;
+} ;
+
+class CPicoBlaze {
+
+ public:
+ CPicoBlaze() ;
+ ~CPicoBlaze() ;
+
+ unsigned int GetNextSourceLine() ;
+ bool Next() ;
+ void Reset() ;
+ void Interrupt() ;
+ void Print() ;
+
+ void addPort( CIOPort * ioport ) ;
+ void deletePort( CIOPort * ioport ) ;
+
+ uint8_t s[ 16 ] ;
+ struct _flags {
+ bool zero ;
+ bool carry ;
+ bool interrupt_enable ;
+
+ bool preserved_zero ;
+ bool preserved_carry ;
+ } flags ;
+
+ CProgramCounter *pc ;
+ CScratchPad *scratch ;
+ CStack *stack ;
+ CPort *port ;
+ CCode *code ;
+} ;
+
+#endif
+
diff --git a/src/hexcodes.h b/src/hexcodes.h
new file mode 100755
index 0000000..ab326fc
--- /dev/null
+++ b/src/hexcodes.h
@@ -0,0 +1,64 @@
+#ifndef HEXCODES
+#define HEXCODES
+
+#define instrADD_SX_KK 0x18000
+#define instrADD_SX_SY 0x19000
+#define instrADDCY_SX_KK 0x1A000
+#define instrADDCY_SX_SY 0x1B000
+#define instrAND_SX_KK 0x0A000
+#define instrAND_SX_SY 0x0B000
+#define instrCALL 0x30000
+#define instrCALLC 0x31800
+#define instrCALLNC 0x31C00
+#define instrCALLNZ 0x31400
+#define instrCALLZ 0x31000
+#define instrCOMPARE_SX_KK 0x14000
+#define instrCOMPARE_SX_SY 0x15000
+#define instrDISABLE_INTERRUPT 0x3C000
+#define instrENABLE_INTERRUPT 0x3C001
+#define instrFETCH_SX_SS 0x06000
+#define instrFETCH_SX_SY 0x07000
+#define instrINPUT_SX_SY 0x05000
+#define instrINPUT_SX_PP 0x04000
+#define instrJUMP 0x34000
+#define instrJUMPC 0x35800
+#define instrJUMPNC 0x35C00
+#define instrJUMPNZ 0x35400
+#define instrJUMPZ 0x35000
+#define instrLOAD_SX_KK 0x00000
+#define instrLOAD_SX_SY 0x01000
+#define instrOR_SX_KK 0x0C000
+#define instrOR_SX_SY 0x0D000
+#define instrOUTPUT_SX_SY 0x2D000
+#define instrOUTPUT_SX_PP 0x2C000
+#define instrRETURN 0x2A000
+#define instrRETURNC 0x2B800
+#define instrRETURNNC 0x2BC00
+#define instrRETURNNZ 0x2B400
+#define instrRETURNZ 0x2B000
+#define instrRETURNI_DISABLE 0x38000
+#define instrRETURNI_ENABLE 0x38001
+#define instrROTATE 0x20000
+#define instrRL_SX 0x00002
+#define instrRR_SX 0x0000C
+#define instrSL0_SX 0x00006
+#define instrSL1_SX 0x00007
+#define instrSLA_SX 0x00000
+#define instrSLX_SX 0x00004
+#define instrSR0_SX 0x0000E
+#define instrSR1_SX 0x0000F
+#define instrSRA_SX 0x00008
+#define instrSRX_SX 0x0000A
+#define instrSTORE_SX_SS 0x2E000
+#define instrSTORE_SX_SY 0x2F000
+#define instrSUB_SX_KK 0x1C000
+#define instrSUB_SX_SY 0x1D000
+#define instrSUBCY_SX_KK 0x1E000
+#define instrSUBCY_SX_SY 0x1F000
+#define instrTEST_SX_KK 0x12000
+#define instrTEST_SX_SY 0x13000
+#define instrXOR_SX_KK 0x0E000
+#define instrXOR_SX_SY 0x0F000
+
+#endif
+
diff --git a/src/hi16-app-kpicosim.png b/src/hi16-app-kpicosim.png
new file mode 100755
index 0000000..74b759f
--- /dev/null
+++ b/src/hi16-app-kpicosim.png
Binary files differ
diff --git a/src/hi32-app-kpicosim.png b/src/hi32-app-kpicosim.png
new file mode 100755
index 0000000..3f0c83f
--- /dev/null
+++ b/src/hi32-app-kpicosim.png
Binary files differ
diff --git a/src/jtag.cpp b/src/jtag.cpp
new file mode 100644
index 0000000..461b511
--- /dev/null
+++ b/src/jtag.cpp
@@ -0,0 +1,326 @@
+#include "jtag.h"
+#include <errno.h>
+#include <string.h>
+#include <iostream>
+#include <linux/lp.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <linux/ppdev.h>
+#include <linux/parport.h>
+
+using namespace std ;
+
+
+#define JTAG_TDO PARPORT_STATUS_SELECT
+#define JTAG_TDI ( 1 << 0 )
+#define JTAG_CLK ( 1 << 1 )
+#define JTAG_TMS ( 1 << 2 )
+#define XILINX_PROG ( 1 << 4 )
+
+const char *jtag_states[] = {
+ "UNDEFINED", "TEST_LOGIC_RESET", "RUN_TEST_IDLE", "SELECT_DR_SCAN", "CAPTURE_DR", "SHIFT_DR", "EXIT_DR", "PAUSE_DR",
+ "EXIT2_DR", "UPDATE_DR", "SELECT_IR_SCAN", "CAPTURE_IR", "SHIFT_IR", "EXIT_IR", "PAUSE_IR", "EXIT2_IR", "UPDATE_IR"
+} ;
+
+CJTAG::CJTAG()
+{
+ m_state = ST_UNDEFINED ;
+ m_fd = -1 ;
+ m_open = false ;
+ m_verbose = false ;
+
+}
+
+CJTAG::~CJTAG()
+{
+ if ( m_open )
+ close() ;
+}
+
+void CJTAG::error( char *str )
+{
+ cout << "JTAG ERROR: " << str << "\r\n" ;
+}
+
+bool CJTAG::open( char *dev )
+{
+ if ( m_open )
+ close() ;
+
+// m_fd = ::open( dev, O_WRONLY | O_NONBLOCK ) ;
+
+ m_fd = ::open( dev, O_RDWR ) ;
+ if ( m_fd < 0 ) {
+ cerr << "Please check if you have read/write right to device '" << dev << "'" << endl ;
+ error( strerror( errno ) ) ;
+ return false ;
+ }
+
+// cout << "Successfully opened \"" << dev << "\"\r\n" ;
+
+ if ( ioctl( m_fd, PPCLAIM ) )
+ cout << "Unable to claim parallel port" << endl ;
+
+// if ( ioctl( m_fd, LPRESET, 0 ) )
+// cout << "reset returned non-zero" << endl ;
+
+ int i ;
+ for ( i = 0 ; i < 10 ; i++ )
+ execute( 1, 0 ) ;
+
+ m_state = ST_TEST_LOGIC_RESET ;
+
+ execute( 0, 0 ) ;
+
+ m_open = true ;
+
+ return true ;
+}
+
+bool CJTAG::isOpen()
+{
+ return m_open ;
+}
+
+void CJTAG::close()
+{
+ if ( m_open && m_fd >= 0 ) {
+ char c = 0 ;
+ ioctl( m_fd, PPWDATA, &c ) ;
+ ioctl( m_fd, PPRELEASE ) ;
+ ::close( m_fd ) ;
+ m_open = false ;
+ }
+}
+
+void CJTAG::selectIR()
+{
+ if ( m_state == ST_TEST_LOGIC_RESET )
+ execute( 0, 0 ) ;
+
+ while ( m_state != ST_SELECT_IR_SCAN )
+ execute( 1, 0 ) ;
+
+ // capture ir
+ execute( 0, 0 ) ;
+
+ // shift ir
+ execute( 0, 0 ) ;
+}
+
+void CJTAG::setIR( bool *instruction, int len )
+{
+ while ( len-- )
+ execute( 0, *instruction++ ) ;
+
+}
+
+void CJTAG::exitIR( bool b )
+{
+ // exit ir
+ execute( 1, b ) ;
+
+ // update ir
+ execute( 1, 0 ) ;
+}
+
+void CJTAG::selectRunTestIdle()
+{
+ if ( m_state != ST_RUN_TEST_IDLE ) {
+ if ( m_state == ST_SELECT_IR_SCAN || m_state == ST_SELECT_DR_SCAN )
+ execute( 0, 0 ) ;
+ while ( m_state != ST_UPDATE_DR && m_state != ST_UPDATE_IR )
+ execute( 1, 0 ) ;
+ execute( 0, 0 ) ;
+ }
+}
+
+void CJTAG::selectTestLogicReset()
+{
+ while ( m_state != ST_TEST_LOGIC_RESET )
+ execute( 1, 0 ) ;
+}
+
+void CJTAG::selectDR()
+{
+ if ( m_state == ST_TEST_LOGIC_RESET )
+ execute( 0, 0 ) ;
+
+ while ( m_state != ST_SELECT_DR_SCAN )
+ execute( 1, 0 ) ;
+
+ // capture dr
+ execute( 0, 0 ) ;
+
+ // shift dr
+ execute( 0, 0 ) ;
+}
+
+void CJTAG::setDR( bool *data, bool *out, int len )
+{
+ // shift dr in, and get data
+ if ( m_verbose ) {
+ while ( len-- ) {
+ cout << (*data ? "1" : "0") ;
+ *out++ = execute( 0, *data++ ) ;
+ }
+ cout << endl ;
+ } else {
+ while ( len-- )
+ *out++ = execute( 0, *data++ ) ;
+ }
+}
+
+void CJTAG::setVerbose( bool verbose )
+{
+ m_verbose = verbose ;
+}
+
+bool CJTAG::exitDR( bool data )
+{
+ // exit dr
+ return execute( 1, data ) ;
+}
+
+
+inline bool CJTAG::step( bool TMS, bool TDI )
+{
+ uint8_t c ;
+ int status ;
+
+ c = XILINX_PROG ; // output enable
+ if ( TMS ) c |= JTAG_TMS ;
+ if ( TDI ) c |= JTAG_TDI ;
+
+ c |= JTAG_CLK ;
+ ioctl( m_fd, PPWDATA, &c ) ;
+ c &= ~JTAG_CLK ;
+ ioctl( m_fd, PPWDATA, &c ) ;
+
+ // read TDO
+ ioctl( m_fd, PPRSTATUS, &status ) ;
+
+ c |= JTAG_CLK ;
+ ioctl( m_fd, PPWDATA, &c ) ;
+
+ return (status & JTAG_TDO) != 0 ;
+}
+
+bool CJTAG::execute( bool TMS, bool TDI )
+{
+ bool TDO ;
+
+ TDO = step( TMS , TDI ) ;
+
+ switch ( m_state ) {
+ case ST_TEST_LOGIC_RESET:
+ if ( TMS )
+ m_state = ST_TEST_LOGIC_RESET ;
+ else
+ m_state = ST_RUN_TEST_IDLE ;
+ break ;
+ case ST_RUN_TEST_IDLE:
+ if ( TMS )
+ m_state = ST_SELECT_DR_SCAN ;
+ else
+ m_state = ST_RUN_TEST_IDLE ;
+ break ;
+ case ST_SELECT_DR_SCAN:
+ if ( TMS )
+ m_state = ST_SELECT_IR_SCAN ;
+ else
+ m_state = ST_CAPTURE_DR ;
+ break ;
+ case ST_CAPTURE_DR:
+ if ( TMS )
+ m_state = ST_EXIT_DR ;
+ else
+ m_state = ST_SHIFT_DR ;
+ break ;
+ case ST_SHIFT_DR:
+ if ( TMS )
+ m_state = ST_EXIT_DR ;
+ else
+ m_state = ST_SHIFT_DR ;
+ break ;
+ case ST_EXIT_DR:
+ if ( TMS )
+ m_state = ST_UPDATE_DR ;
+ else
+ m_state = ST_PAUSE_DR ;
+ break ;
+ case ST_PAUSE_DR:
+ if ( TMS )
+ m_state = ST_EXIT2_DR ;
+ else
+ m_state = ST_PAUSE_DR ;
+ break ;
+ case ST_EXIT2_DR:
+ if ( TMS )
+ m_state = ST_UPDATE_DR ;
+ else
+ m_state = ST_SHIFT_DR ;
+ break ;
+ case ST_UPDATE_DR:
+ if ( TMS )
+ m_state = ST_SELECT_DR_SCAN ;
+ else
+ m_state = ST_RUN_TEST_IDLE ;
+ break ;
+ case ST_SELECT_IR_SCAN:
+ if ( TMS )
+ m_state = ST_TEST_LOGIC_RESET ;
+ else
+ m_state = ST_CAPTURE_IR ;
+ break ;
+ case ST_CAPTURE_IR:
+ if ( TMS )
+ m_state = ST_EXIT_IR ;
+ else
+ m_state = ST_SHIFT_IR ;
+ break ;
+ case ST_SHIFT_IR:
+ if ( TMS )
+ m_state = ST_EXIT_IR ;
+ else
+ m_state = ST_SHIFT_IR ;
+ break ;
+ case ST_EXIT_IR:
+ if ( TMS )
+ m_state = ST_UPDATE_IR ;
+ else
+ m_state = ST_PAUSE_IR ;
+ break ;
+ case ST_PAUSE_IR:
+ if ( TMS )
+ m_state = ST_EXIT2_IR ;
+ else
+ m_state = ST_PAUSE_IR ;
+ break ;
+ case ST_EXIT2_IR:
+ if ( TMS )
+ m_state = ST_UPDATE_IR ;
+ else
+ m_state = ST_SHIFT_IR ;
+ break ;
+ case ST_UPDATE_IR:
+ if ( TMS )
+ m_state = ST_SELECT_DR_SCAN ;
+ else
+ m_state = ST_RUN_TEST_IDLE ;
+ break ;
+ default:
+ break ;
+ }
+
+// cout << "state( " << (TMS != 0) << ", " << (TDI != 0) << "): " << jtag_states[ m_state ] << "\r\n" ;
+
+ return TDO ;
+}
+
+void CJTAG::printState()
+{
+ cout << "State = " << jtag_states[ m_state ] << endl ;
+}
diff --git a/src/jtag.h b/src/jtag.h
new file mode 100644
index 0000000..2bdb322
--- /dev/null
+++ b/src/jtag.h
@@ -0,0 +1,63 @@
+#include <stdint.h>
+#include <fcntl.h>
+
+
+class CJTAG {
+ public:
+ enum JTAG_STATE {
+ ST_UNDEFINED,
+ ST_TEST_LOGIC_RESET,
+ ST_RUN_TEST_IDLE,
+ ST_SELECT_DR_SCAN,
+ ST_CAPTURE_DR,
+ ST_SHIFT_DR,
+ ST_EXIT_DR,
+ ST_PAUSE_DR,
+ ST_EXIT2_DR,
+ ST_UPDATE_DR,
+ ST_SELECT_IR_SCAN,
+ ST_CAPTURE_IR,
+ ST_SHIFT_IR,
+ ST_EXIT_IR,
+ ST_PAUSE_IR,
+ ST_EXIT2_IR,
+ ST_UPDATE_IR
+ } ;
+ CJTAG() ;
+ ~CJTAG() ;
+
+ bool open( char *dev ) ;
+ void close() ;
+
+ void selectIR() ;
+ void setIR( bool *instruction, int len ) ;
+ void exitIR( bool b ) ;
+
+ void selectDR() ;
+ void setDR( bool *data, bool *out, int len ) ; // 'data' is replaced by data that is read.
+ bool exitDR( bool data ) ;
+
+
+ void selectRunTestIdle() ;
+ void selectTestLogicReset() ;
+
+ bool execute( bool TMS, bool TDI ) ;
+
+ void setVerbose( bool verbose ) ;
+
+ void printState() ;
+
+ bool isOpen() ;
+ private:
+ void error( char *str ) ;
+ bool step( bool TMS, bool TDI ) ;
+
+ int m_fd ;
+ bool m_open ;
+ enum JTAG_STATE m_state ;
+
+ bool m_verbose ;
+
+} ;
+
+
diff --git a/src/jtagdevice.cpp b/src/jtagdevice.cpp
new file mode 100644
index 0000000..22dd43d
--- /dev/null
+++ b/src/jtagdevice.cpp
@@ -0,0 +1,31 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+#include "jtagdevice.h"
+
+JTAGDevice::JTAGDevice()
+{
+}
+
+
+JTAGDevice::~JTAGDevice()
+{
+}
+
+
diff --git a/src/jtagdevice.h b/src/jtagdevice.h
new file mode 100644
index 0000000..6701acc
--- /dev/null
+++ b/src/jtagdevice.h
@@ -0,0 +1,40 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+#ifndef JTAGDEVICE_H
+#define JTAGDEVICE_H
+
+/* JTAG IDCODE's for Spartan-3 Devices */
+#define XC3S50 0x0140C093
+#define XC3S200 0x01414093
+#define XC3S400 0x0141C093
+#define XC3S1000 0x01428093
+#define XC3S1500 0x01434093
+#define XC3S2000 0x01440093
+#define XC3S4000 0x01448093
+#define XC3S5000 0x01450093
+
+
+class JTAGDevice{
+ public:
+ JTAGDevice();
+ ~JTAGDevice();
+};
+
+#endif
diff --git a/src/jtagprogrammer.cpp b/src/jtagprogrammer.cpp
new file mode 100644
index 0000000..f825fd7
--- /dev/null
+++ b/src/jtagprogrammer.cpp
@@ -0,0 +1,233 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+
+/* FIXME
+ *
+ * This source is still a mess.
+ * I will clean it in the (near?) future.
+ *
+ */
+
+#include "jtagprogrammer.h"
+#include <iostream>
+#include <qapplication.h>
+#include <qeventloop.h>
+
+bool IDCODE_PROM[] = { 0, 1, 1, 1, 1, 1, 1, 1 } ;
+bool BYPASS_PROM[] = { 1, 1, 1, 1, 1, 1, 1, 1 } ;
+bool IDCODE[] = { 1, 0, 0, 1, 0, 0 } ;
+bool CFG_IN[] = { 1, 0, 1, 0, 0, 0 } ;
+bool JSTART[] = { 0, 0, 1, 1, 0, 0 } ;
+bool JPROGRAM[] = { 1, 1, 0, 1, 0, 0 } ;
+bool JSHUTDOWN[] = { 1, 0, 1, 1, 0, 0 } ;
+bool USER1[] = { 0, 1, 0, 0, 0, 0 } ;
+bool USER2[] = { 1, 1, 0, 0, 0, 0 } ;
+
+#define XCF02S 0x05045093
+#define XC3S50 0x0140C093
+#define XC3S200 0x01414093
+#define XC3S400 0x0141C093
+#define XC3S1000 0x01428093
+#define XC3S1500 0x01434093
+#define XC3S2000 0x01440093
+#define XC3S4000 0x01448093
+#define XC3S5000 0x01450093
+
+#define ID_LEN 32
+
+const char *id_string[] =
+{
+ "XS3S50", "XS3S200", "XS3S400", "XS3S1000", "XS3S1500", "XS3S2000", "XS3S4000", "XS3S5000",
+ "XCF02S"
+} ;
+
+const unsigned int id_code[] =
+{
+ XC3S50, XC3S200, XC3S400, XC3S1000, XC3S1500, XC3S2000, XC3S4000, XC3S5000,
+ XCF02S
+} ;
+
+#define MAX_IDS ( sizeof( id_code ) / sizeof( int ) )
+
+JTAGProgrammer::JTAGProgrammer( QObject *parent )
+{
+ m_parent = parent ;
+ m_bitFilename = "" ;
+
+ m_dev = new CJTAG ;
+}
+
+
+JTAGProgrammer::~JTAGProgrammer()
+{
+ m_dev->close() ;
+ delete m_dev ;
+}
+
+int JTAGProgrammer::getDevice( bool *id ) {
+ unsigned int j, dev_id ;
+
+ for ( j = 0, dev_id = 0 ; j < ID_LEN ; j++ ) {
+ dev_id |= id[ j ] << j ;
+ }
+
+ for ( j = 0 ; j < MAX_IDS ; j++ ) {
+ if ( id_code[j] == dev_id ) {
+ std::string s ;
+ s = std::string( "Found Device : ") + id_string[j] + std::string( "\n" );
+ emit message( s.c_str() ) ;
+ return dev_id ;
+ }
+ }
+
+ std::cout << "Unknown ID: " << std::hex << dev_id << "\n" ;
+
+ return 0 ;
+}
+
+void JTAGProgrammer::program()
+{
+ if ( m_bitFilename == "" ) {
+ emit message( "No filename given\n" ) ;
+ return ;
+ }
+
+ bool id[ ID_LEN], ones[ ID_LEN ], dummy[ 32 ] ;
+ int device0, device1 ;
+ bool prom_present = true ;
+
+ for ( int i = 0 ; i < ID_LEN ; i++ )
+ ones[i] = 1 ;
+
+ if ( m_dev->isOpen() )
+ return ;
+
+ if ( !m_dev->open( (char*) "/dev/parport0" ) ) {
+ emit message( "/dev/parport0 could not be opened; check permissions\n" ) ;
+ return ;
+ }
+/* ...Get device(s)... */
+ m_dev->selectIR() ;
+ m_dev->setIR( IDCODE_PROM, 8 ) ;
+ m_dev->setIR( IDCODE, 5 ) ;
+ m_dev->exitIR( IDCODE[5] ) ;
+
+ m_dev->selectDR() ;
+ m_dev->setDR( ones, id, ID_LEN ) ;
+
+ device0 = getDevice( id ) ;
+
+ if ( !device0 ) {
+ emit message( "Unknown device in JTAG chain\n" ) ;
+ goto exit ;
+ }
+ m_dev->setDR( ones, id, ID_LEN-1 ) ;
+ id[ 31 ] = m_dev->exitDR( 1 ) ;
+
+ device1 = getDevice( id ) ;
+ if ( !device1 ) {
+ emit message( "Second device is unknown (I will try to continue)\n" ) ;
+ prom_present = false ;
+ }
+
+/* ....Setup for configuration..... */
+ m_dev->selectIR() ;
+ m_dev->setIR( JPROGRAM, 5 ) ; /* Clear configuration memory */
+ m_dev->exitIR( JPROGRAM[5] ) ; /* Although this is not documented?? */
+
+ m_dev->selectIR();
+ if ( prom_present ) m_dev->setIR( BYPASS_PROM, 8 ) ;
+ m_dev->setIR( JSHUTDOWN, 5 ) ;
+ m_dev->exitIR( JSHUTDOWN[5] ) ;
+
+ m_dev->selectRunTestIdle() ;
+ for ( int i = 0 ; i < 20 ; i++ ) /* Shutdown sequence */
+ m_dev->execute( 0, 0 ) ;
+
+ m_dev->selectIR() ;
+ if ( prom_present ) m_dev->setIR( BYPASS_PROM, 8 ) ;
+ m_dev->setIR( CFG_IN, 5 ) ;
+ m_dev->exitIR( CFG_IN[5] ) ;
+
+/* ....Send bit file.....*/
+ FILE *bit_file ;
+ bit_file = fopen( m_bitFilename.c_str(), "r" ) ;
+ if ( bit_file == NULL ) {
+ emit message( "Could not read bit file\n" ) ;
+ goto exit ;
+ }
+
+ int size ;
+ bool frame[ 8 ] ;
+ unsigned int cur, next ;
+ size = 0 ;
+
+ m_dev->selectDR() ;
+ fread( &cur, 1, 1, bit_file ) ;
+
+ int prog, prev_prog, total ;
+ fseek( bit_file, 0, SEEK_END ) ;
+ total = ftell( bit_file ) ;
+ rewind( bit_file ) ;
+
+ emit message( "Programming..." ) ;
+ for (prog=prev_prog=0;;) {
+ for ( int i = 0 ; i < 8; i++, cur <<= 1 )
+ frame[i] = (cur & 0x80 ) != 0 ;
+
+ size += 1;
+
+ emit progress( size*100/total ) ;
+
+ if ( fread( &next, 1, 1, bit_file ) == 0 )
+ break ;
+ m_dev->setDR( frame, dummy, 8 ) ;
+ cur = next ;
+
+ QApplication::eventLoop()->processEvents( QEventLoop::AllEvents ) ;
+ }
+ std::cout << std::endl ;
+
+ m_dev->setDR( frame, dummy, 7 ) ;
+ m_dev->exitDR( frame[7] ) ;
+ fclose( bit_file ) ;
+
+/*....Start FPGA.....*/
+ m_dev->selectTestLogicReset() ;
+
+ m_dev->selectIR() ;
+ if ( prom_present ) m_dev->setIR( BYPASS_PROM, 8 ) ;
+ m_dev->setIR( JSTART, 5 ) ;
+ m_dev->exitIR( JSTART[5] ) ;
+
+ m_dev->selectRunTestIdle() ;
+ for ( int i = 0 ; i < 20 ; i++ ) /* Start up sequence */
+ m_dev->execute( 0, 0 ) ;
+
+ emit message( "done.\n" ) ;
+exit:
+ m_dev->close() ;
+}
+
+void JTAGProgrammer::setBitFile( std::string filename )
+{
+ m_bitFilename = filename ;
+}
+
diff --git a/src/jtagprogrammer.h b/src/jtagprogrammer.h
new file mode 100644
index 0000000..becb368
--- /dev/null
+++ b/src/jtagprogrammer.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+#ifndef JTAGPROGRAMMER_H
+#define JTAGPROGRAMMER_H
+
+#include <qobject.h>
+#include <string.h>
+#include "jtag.h"
+class JTAGProgrammer : public QObject
+{
+ Q_OBJECT
+
+ public:
+ JTAGProgrammer( QObject *parent );
+ ~JTAGProgrammer();
+
+ void setBitFile( std::string filename ) ;
+
+ void program() ;
+
+ signals:
+ void progress( int percent ) ;
+ void message( const char *msg ) ;
+
+
+ protected:
+ int getDevice( bool *id ) ;
+
+ std::string m_bitFilename ;
+
+ CJTAG *m_dev ;
+ QObject *m_parent ;
+
+};
+
+#endif
diff --git a/src/kexportdialog.cpp b/src/kexportdialog.cpp
new file mode 100755
index 0000000..ae5a444
--- /dev/null
+++ b/src/kexportdialog.cpp
@@ -0,0 +1,158 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+#include "kexportdialog.h"
+#include <kfiledialog.h>
+
+KExportDialog::KExportDialog( QWidget *parent, const char *name ) : QDialog(parent, name)
+{
+ m_templateFile = "" ;
+ m_outputDir = "" ;
+
+ QLabel *label = new QLabel( this ) ;
+ label->setText( "Template file" ) ;
+ label->move( 10, 10 ) ;
+
+ label = new QLabel( this ) ;
+ label->setText( "Output directory" ) ;
+ label->move( 10, 35 ) ;
+
+ label = new QLabel( this ) ;
+ label->setText( "Entity name" ) ;
+ label->move( 10, 60 ) ;
+
+ m_lineTemplateFile = new KLineEdit( this ) ;
+ m_lineTemplateFile->setText( "" ) ;
+ m_lineTemplateFile->setFixedSize( 150, 20 ) ;
+ m_lineTemplateFile->move( 110, 10 ) ;
+
+ m_lineOutputDir = new KLineEdit( this ) ;
+ m_lineOutputDir->setText( "" ) ;
+ m_lineOutputDir->setFixedSize( 150, 20 ) ;
+ m_lineOutputDir->move( 110, 35 ) ;
+
+ m_lineEntityName = new KLineEdit( this ) ;
+ m_lineEntityName->setText( "" ) ;
+ m_lineEntityName->setFixedSize( 150, 20 ) ;
+ m_lineEntityName->move( 110, 60 ) ;
+
+ QPushButton *button = new QPushButton( this ) ;
+ button->setText( "OK" ) ;
+ button->setFixedSize( 60, 25 ) ;
+ button->move( 100, 90 ) ;
+ connect( button, SIGNAL( clicked() ), this, SLOT( btnOKClicked() ) ) ;
+
+ button = new QPushButton( this ) ;
+ button->setText( "Cancel" ) ;
+ button->setFixedSize( 60, 25 ) ;
+ button->move( 200, 90 ) ;
+ connect( button, SIGNAL( clicked() ), this, SLOT( btnCancelClicked() ) ) ;
+
+ button = new QPushButton( this ) ;
+ button->setText( "..." ) ;
+ button->setFixedSize( 25, 20 ) ;
+ button->move( 270, 10 ) ;
+ connect( button, SIGNAL( clicked() ), this, SLOT( showFileDialog() ) ) ;
+
+ button = new QPushButton( this ) ;
+ button->setText( "..." ) ;
+ button->setFixedSize( 25, 20 ) ;
+ button->move( 270, 35 ) ;
+ connect( button, SIGNAL( clicked() ), this, SLOT( showDirDialog() ) ) ;
+
+ setFixedSize( 340, 130 ) ;
+ setCaption( "Export to VHDL" ) ;
+ m_bCanceled = true ;
+}
+
+KExportDialog::~KExportDialog()
+{
+}
+
+void KExportDialog::modal()
+{
+ exec() ;
+}
+
+void KExportDialog::showFileDialog()
+{
+ KFileDialog dlg( QString::null, "*.vhd|vhdl template file", this, "template dlg", true ) ;
+ dlg.exec() ;
+
+ if ( dlg.selectedFile() != "" )
+ m_lineTemplateFile->setText( dlg.selectedFile() ) ;
+}
+
+void KExportDialog::showDirDialog()
+{
+ QString dir = KFileDialog::getExistingDirectory ( QString::null, this, "Export directory" ) ;
+ if ( dir != "" )
+ m_lineOutputDir->setText( dir ) ;
+}
+
+void KExportDialog::btnOKClicked()
+{
+ m_templateFile = m_lineTemplateFile->text() ;
+ m_outputDir = m_lineOutputDir->text() ;
+ m_entityName = m_lineEntityName->text() ;
+ m_bCanceled = false ;
+ close() ;
+}
+
+void KExportDialog::btnCancelClicked()
+{
+ m_outputDir = "" ;
+ m_templateFile = "" ;
+ m_entityName = "" ;
+
+ close() ;
+}
+
+void KExportDialog::setTemplateFile( QString file )
+{
+ m_lineTemplateFile->setText( file ) ;
+}
+
+void KExportDialog::setOutputDir( QString dir )
+{
+ m_lineOutputDir->setText( dir ) ;
+}
+
+void KExportDialog::setEntityName( QString name )
+{
+ m_lineEntityName->setText( name ) ;
+}
+
+QString KExportDialog::getTemplateFile()
+{
+ return m_templateFile ;
+}
+
+QString KExportDialog::getOutputDir()
+{
+ return m_outputDir ;
+}
+
+QString KExportDialog::getEntityName()
+{
+ return m_entityName ;
+}
+
+
+#include "kexportdialog.moc"
diff --git a/src/kexportdialog.h b/src/kexportdialog.h
new file mode 100755
index 0000000..2069ae8
--- /dev/null
+++ b/src/kexportdialog.h
@@ -0,0 +1,63 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+#ifndef KEXPORTDIALOG_H
+#define KEXPORTDIALOG_H
+
+#include <qobject.h>
+#include <klineedit.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qstring.h>
+#include <qdialog.h>
+
+class KExportDialog : public QDialog
+{
+ Q_OBJECT
+ public:
+ KExportDialog(QWidget *parent = 0, const char *name = 0 );
+ ~KExportDialog();
+
+ void setOutputDir( QString dir ) ;
+ void setTemplateFile( QString file ) ;
+ void setEntityName( QString name ) ;
+
+ QString getTemplateFile() ;
+ QString getOutputDir() ;
+ QString getEntityName() ;
+
+ void modal() ;
+
+ bool isCanceled() { return m_bCanceled ; }
+ protected:
+ QString m_outputDir ;
+ QString m_templateFile ;
+ QString m_entityName ;
+
+ KLineEdit * m_lineTemplateFile, * m_lineOutputDir, *m_lineEntityName ;
+ bool m_bCanceled ;
+
+ public slots:
+ void btnOKClicked() ;
+ void btnCancelClicked() ;
+ void showFileDialog() ;
+ void showDirDialog() ;
+};
+
+#endif
diff --git a/src/kjtagdialog.cpp b/src/kjtagdialog.cpp
new file mode 100644
index 0000000..a8d445e
--- /dev/null
+++ b/src/kjtagdialog.cpp
@@ -0,0 +1,117 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+#include "kjtagdialog.h"
+#include <qmessagebox.h>
+#include <kfiledialog.h>
+#include <kiconloader.h>
+
+KJTAGDialog::KJTAGDialog( QWidget *parent )
+ : QDialog( parent )
+{
+
+ setFixedSize( 330, 300 ) ;
+ m_groupConfigure = new QGroupBox( "Configure", this ) ;
+ m_groupConfigure->setFixedSize( 310, 45 ) ;
+ m_groupConfigure->move( 10, 10 ) ;
+
+ m_selectFileBtn = new QPushButton( m_groupConfigure ) ;
+ m_selectFileBtn->setFixedSize( 30, 25 ) ;
+ m_selectFileBtn->move( 205, 15 ) ;
+ m_selectFileBtn->setPixmap( KGlobal::iconLoader()->loadIcon( "fileopen", KIcon::Small ) ) ;
+ connect( m_selectFileBtn, SIGNAL( clicked() ), this, SLOT( selectFileName() ) ) ;
+
+ m_configureBtn = new QPushButton( "Configure", m_groupConfigure ) ;
+ m_configureBtn->setFixedSize( 60, 25 ) ;
+ m_configureBtn->move( 240, 15 ) ;
+
+ connect( m_configureBtn, SIGNAL( clicked() ), this, SLOT( configure() ) ) ;
+
+ m_bitFileLabel = new QLabel( "Bit file", m_groupConfigure ) ;
+ m_bitFileLabel->setFixedSize( 50, 25 ) ;
+ m_bitFileLabel->move( 10, 15 ) ;
+
+ m_bitFileEdit = new KLineEdit( m_groupConfigure ) ;
+ m_bitFileEdit->setFixedSize( 150, 25 ) ;
+ m_bitFileEdit->move( 50, 15 ) ;
+
+ m_progress = new KProgress( this ) ;
+ m_progress->setFixedSize( width(), 20 ) ;
+ m_progress->move( 0, 280 ) ;
+ m_progress->setTotalSteps( 100 ) ;
+
+ m_debug = new KTextEdit( this ) ;
+ m_debug->setFixedSize( 310, 200 ) ;
+ m_debug->move( 10, 60 ) ;
+
+ m_programmer = new JTAGProgrammer( this ) ;
+ connect( m_programmer, SIGNAL( progress(int) ), this, SLOT( progress(int) ) ) ;
+ connect( m_programmer, SIGNAL( message(const char*) ), this, SLOT( addMessage(const char*) ) ) ;
+
+ m_debug->insert( "This option is still very experimental!!\n"
+ "The code is tested with the Spartan-3 Development Board.\n"
+ "Assuming the following setup:\n"
+ " TDI--->[XC3SXXX]--->[XCF]--->TDO\n"
+ "========================================================\n" ) ;
+}
+
+KJTAGDialog::~KJTAGDialog()
+{
+ delete m_programmer ;
+}
+
+void KJTAGDialog::configure()
+{
+ m_debug->clear() ;
+ m_programmer->setBitFile( m_bitFileEdit->text() ) ;
+ m_programmer->program() ;
+ m_progress->setProgress( 0 ) ;
+}
+
+void KJTAGDialog::progress( int percent )
+{
+ m_progress->setProgress( percent ) ;
+}
+
+void KJTAGDialog::setFilename( QString filename )
+{
+ m_bitFileEdit->setText( filename ) ;
+}
+
+QString KJTAGDialog::getFilename()
+{
+ return m_bitFileEdit->text() ;
+}
+
+void KJTAGDialog::selectFileName()
+{
+ QString filename = KFileDialog::getOpenFileName( QString::null,
+ "*.bit|bit files\n*|All files",
+ this,
+ "Select configuration file" ) ;
+ if ( filename != "" )
+ m_bitFileEdit->setText( filename ) ;
+}
+
+void KJTAGDialog::addMessage( const char *msg )
+{
+ m_debug->insert( msg ) ;
+}
+
+
diff --git a/src/kjtagdialog.h b/src/kjtagdialog.h
new file mode 100644
index 0000000..7bc25a5
--- /dev/null
+++ b/src/kjtagdialog.h
@@ -0,0 +1,63 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+#ifndef KJTAGDIALOG_H
+#define KJTAGDIALOG_H
+
+#include <qdialog.h>
+#include <qpushbutton.h>
+#include <klineedit.h>
+#include <kprogress.h>
+#include <qlabel.h>
+#include <qgroupbox.h>
+#include <ktextedit.h>
+
+#include "jtagprogrammer.h"
+
+
+
+
+class KJTAGDialog : public QDialog
+{
+ Q_OBJECT
+ public:
+ KJTAGDialog(QWidget *parent);
+ ~KJTAGDialog();
+
+ void setFilename( QString filename ) ;
+ QString getFilename() ;
+
+ public slots:
+ void configure() ;
+ void progress( int progress ) ;
+ void selectFileName() ;
+ void addMessage( const char *msg ) ;
+
+ protected:
+ QPushButton *m_configureBtn, *m_selectFileBtn ;
+ KLineEdit *m_bitFileEdit ;
+ KProgress *m_progress ;
+ QLabel *m_bitFileLabel ;
+ QGroupBox *m_groupConfigure ;
+ KTextEdit *m_debug ;
+
+ JTAGProgrammer *m_programmer ;
+};
+
+#endif
diff --git a/src/kpicosim.cpp b/src/kpicosim.cpp
new file mode 100755
index 0000000..cf3eb13
--- /dev/null
+++ b/src/kpicosim.cpp
@@ -0,0 +1,631 @@
+/***************************************************************************
+ * 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 <qlabel.h>
+
+#include <kmainwindow.h>
+#include <klocale.h>
+
+#include <kmenubar.h>
+#include <qlayout.h>
+#include <qkeysequence.h>
+#include <knuminput.h>
+#include <qnamespace.h>
+#include <kportview.h>
+#include <qdockwindow.h>
+#include <kstatusbar.h>
+#include <kiconloader.h>
+#include "kexportdialog.h"
+#include "kjtagdialog.h"
+#include <kfiledialog.h>
+#include <kmessagebox.h>
+#include <qlayout.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 QSplitter( this ) ;
+ m_tabWidget = new QTabWidget( m_splitter ) ;
+ m_editor = new CodeEditor( m_tabWidget ) ;
+ m_messages = new KListView( m_splitter, "messages" ) ;
+ m_simulator = new KSimulator( this ) ;
+ m_processorView = new KProcessorView( this ) ;
+
+ m_tabWidget->addTab( m_editor, "Source" ) ;
+ addDockWindow( m_processorView, DockLeft ) ;
+
+ m_splitter->setOrientation( QSplitter::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, SIGNAL( clicked() ), m_editor, SLOT( slotNewFile() ), true, "New" ) ;
+ toolbar->insertButton( "fileopen", -1, SIGNAL( clicked() ), m_editor, SLOT( slotOpen() ), true, "Open" ) ;
+ toolbar->insertButton( "filesave", -1, SIGNAL( clicked() ), m_editor, SLOT( slotSave() ), true, "Save" ) ;
+ toolbar->insertButton( "filesaveas", -1, SIGNAL( clicked() ), m_editor, SLOT( slotSaveAs() ), true, "Save As" ) ;
+
+ m_debugBar = new KToolBar( this ) ;
+ addDockWindow( m_debugBar ) ;
+ m_debugBar->insertButton( UserIcon( "rebuild" ), COMPILE_ID, SIGNAL( clicked() ), this, SLOT( compile() ), true, "Compile" ) ;
+ m_debugBar->insertButton( "run", START_SIM_ID, SIGNAL( clicked() ), this, SLOT( startSim() ), true, "Start/Stop Debug" ) ;
+ m_debugBar->insertSeparator() ;
+ m_debugBar->insertButton( UserIcon( "continue" ), RUN_ID, SIGNAL( clicked() ), this, SLOT( startStop() ), false, "Continue" ) ;
+
+ m_debugBar->insertButton( UserIcon( "next" ), NEXT_ID, SIGNAL( clicked() ), m_simulator, SLOT( next() ), false, "Next" ) ;
+ m_debugBar->insertButton( UserIcon( "interrupt" ), INTERRUPT_ID, SIGNAL( clicked() ), m_simulator, SLOT( interrupt() ), false, "Interrupt" ) ;
+ m_debugBar->insertButton( UserIcon( "reset" ), RESET_ID, SIGNAL( clicked() ), m_simulator, SLOT( reset() ), false, "Reset" ) ;
+
+ connect( this, SIGNAL( run() ), m_simulator, SLOT( run() ) );
+ connect( this, SIGNAL( stop() ), m_simulator, SLOT( stop() ) ) ;
+ connect( m_simulator, SIGNAL( stepped( unsigned int ) ), this, SLOT( stepped( unsigned int ) ) ) ;
+ connect( m_processorView, SIGNAL( processorRegsChanged() ), this, SLOT( updateProcessorRegs() ) ) ;
+ connect( m_processorView, SIGNAL( processorFlagsChanged() ), this, SLOT( updateProcessorFlags() ) ) ;
+ connect( m_messages, SIGNAL( clicked( QListViewItem * ) ), this, SLOT( messageListClicked( QListViewItem * ) ) ) ;
+
+ 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( QString( "Mode: Edit" ), 0 ) ;
+ statusBar()->insertItem( QString( "Status: Stopped" ), 1 ) ;
+ statusBar()->insertItem( QString( "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", this, SLOT( fileExportVHDL() ) ) ;
+// exportMenu->insertItem( "COE", this, SLOT( fileExportCOE() ) ) ;
+ exportMenu->insertItem( "MEM", this, SLOT( fileExportMEM() ) ) ;
+ exportMenu->insertItem( "HEX", this, SLOT( fileExportHEX() ) ) ;
+
+ m_fileMenu = new KPopupMenu( this ) ;
+ m_fileMenu->insertItem( ldr->loadIcon( "filenew", KIcon::Small ), "New", this, SLOT( slotFileNew() ) ) ;
+ m_fileMenu->insertItem( ldr->loadIcon( "fileopen", KIcon::Small ), "Open", m_editor, SLOT( slotOpen() ) ) ;
+ m_fileMenu->insertSeparator() ;
+ m_fileMenu->insertItem( ldr->loadIcon( "filesave", KIcon::Small ), "Save", m_editor, SLOT( slotSave() ), QKeySequence::QKeySequence( "CTRL+S" ) ) ;
+ m_fileMenu->insertItem( ldr->loadIcon( "filesaveas", KIcon::Small ), "Save As...", m_editor, SLOT( slotSaveAs() ) ) ;
+ m_fileMenu->insertSeparator() ;
+ m_fileMenu->insertItem( ldr->loadIcon( "fileprint", KIcon::Small ), "Print...", m_editor, SLOT( slotPrint() ), QKeySequence::QKeySequence( "CTRL+P" ) ) ;
+ m_fileMenu->insertSeparator() ;
+ m_fileMenu->insertItem( "Export", exportMenu ) ;
+ m_fileMenu->insertSeparator() ;
+ m_fileMenu->insertItem( ldr->loadIcon( "fileclose", KIcon::Small ), "Quit", this, SLOT( slotClose() ) ) ;
+
+ m_editMenu = new KPopupMenu( this ) ;
+ m_editMenu->insertItem( ldr->loadIcon( "undo", KIcon::Small ), "Undo", m_editor, SLOT( slotUndo() ),QKeySequence::QKeySequence( "CTRL+Z" ) ) ;
+ m_editMenu->insertItem( ldr->loadIcon( "redo", KIcon::Small ), "Redo", m_editor, SLOT( slotRedo() ),QKeySequence::QKeySequence( "CTRL+SHIFT+Z" ) ) ;
+ m_editMenu->insertSeparator() ;
+ m_editMenu->insertItem( "Select All", m_editor, SLOT( slotSelectAll() ),QKeySequence::QKeySequence( "CTRL+A" ) ) ;
+ m_editMenu->insertSeparator() ;
+ m_editMenu->insertItem( ldr->loadIcon( "editcut", KIcon::Small ), "Cut", m_editor, SLOT( slotCut() ),QKeySequence::QKeySequence( "CTRL+X" ) ) ;
+ m_editMenu->insertItem( ldr->loadIcon( "editcopy", KIcon::Small ), "Copy", m_editor, SLOT( slotCopy() ),QKeySequence::QKeySequence( "CTRL+C" ) ) ;
+ m_editMenu->insertItem( ldr->loadIcon( "editpaste", KIcon::Small ), "Paste", m_editor, SLOT( slotPaste() ),QKeySequence::QKeySequence( "CTRL+V" ) ) ;
+ m_editMenu->insertSeparator() ;
+ m_editMenu->insertItem( ldr->loadIcon( "find", KIcon::Small ), "Find...", m_editor, SLOT( slotFind() ), QKeySequence::QKeySequence( "CTRL+F" ) ) ;
+ m_editMenu->insertItem( "Find Next", m_editor, SLOT( slotFindNext() ), QKeySequence::QKeySequence( "F3" ) ) ;
+
+
+ m_debugMenu = new KPopupMenu( this ) ;
+ m_debugMenu->insertSeparator() ;
+ m_debugMenu->insertItem( ldr->loadIcon( "rebuild", KIcon::Small ), "Compile", this, SLOT( compile() ), QKeySequence::QKeySequence( "SHIFT+F9" ) ) ;
+ m_debugMenu->insertItem( ldr->loadIcon( "run", KIcon::Small ), "Start Debug", this, SLOT( startSim() ), QKeySequence::QKeySequence( "F9" ) , START_SIM_ID ) ;
+
+ m_debugMenu->insertSeparator() ;
+ m_debugMenu->insertItem( "Continue", this, SLOT( startStop() ), QKeySequence::QKeySequence( "F10" ) , RUN_ID ) ;
+ m_debugMenu->insertItem( "Next", m_simulator, SLOT( next() ), QKeySequence::QKeySequence( "F5" ) , NEXT_ID ) ;
+ m_debugMenu->insertItem( "Interrupt", m_simulator, SLOT( interrupt() ), QKeySequence::QKeySequence( "F4" ) , INTERRUPT_ID ) ;
+ m_debugMenu->insertItem( "Reset", m_simulator, SLOT( reset() ), QKeySequence::QKeySequence( "F11" ) , RESET_ID ) ;
+
+ m_debugMenu->insertSeparator() ;
+ m_debugMenu->insertItem( "Toggle Breakpoint", m_editor, SLOT( slotToggleBreakpoint() ), QKeySequence::QKeySequence( "F8" ) ) ;
+
+ m_settingsMenu = new KPopupMenu( this ) ;
+ m_settingsMenu->insertItem( "Configure Editor...", m_editor, SLOT( slotShowConfig() ) ) ;
+
+ m_peripheralMenu = new KPopupMenu( this ) ;
+ m_peripheralMenu->insertItem( "I/O Port", this, SLOT( newIOPort() ) ) ;
+ m_peripheralMenu->insertItem( "Scratchpad", this, SLOT( showScratchpad() ), 0, VIEW_SCRATCHPAD_ID ) ;
+ m_peripheralMenu->insertItem( "Serial port", this, SLOT( showSerialPort() ), 0, VIEW_SERIAL_ID ) ;
+
+ m_jtagMenu = new KPopupMenu( this ) ;
+ m_jtagMenu->insertItem( "Download", this, 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()
+{
+
+ QString filename = KFileDialog::getSaveFileName( QString::null,
+ "*.hex|HEX files\n*|All files",
+ this,
+ "Export HEX" ) ;
+ if ( filename != "" && compile() ) {
+ m_simulator->exportHEX( filename, FALSE ) ;
+ }
+}
+
+void KPicoSim::fileExportMEM()
+{
+
+ QString filename = KFileDialog::getSaveFileName( QString::null,
+ "*.mem|MEM files\n*|All files",
+ this,
+ "Export MEM" ) ;
+ if ( filename != "" && compile() ) {
+ m_simulator->exportHEX( filename, 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, m_outputDir, m_entityName ) ) {
+ 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( QCloseEvent * 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, SIGNAL( closing( KPortView* ) ), this, 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( QString( "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( QString( "Status: Stopped" ), 1 ) ;
+ QString str ;
+ str.sprintf( "Instructions: %u", m_nrInstructions ) ;
+ statusBar()->changeItem( str, 2 ) ;
+ m_debugBar->setButton( RUN_ID, false ) ;
+ }
+ }
+}
+
+void KPicoSim::messageListClicked( QListViewItem *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() ;
+
+ QString 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( QString str )
+{
+ QListViewItem *item = new QListViewItem( 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() ) ;
+
+ 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( QString( "Mode: Debug" ), 0 ) ;
+ } else {
+ statusBar()->changeItem( QString( "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++ ) {
+ QString 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", QVariant::Bool ).toBool() )
+ showSerialPort() ;
+ if ( config.readPropertyEntry( "scratchpad", QVariant::Bool ).toBool() )
+ showScratchpad() ;
+ m_editor->open( config.readEntry( "filename" ) ) ;
+ m_bitfile = config.readEntry( "bitfile" ) ;
+
+/*
+ int nports = config.readPropertyEntry( "numIOPorts", QVariant::Int ).toInt() ;
+
+ for ( int i = 0 ; i < nports ; i++ ) {
+ QString 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, SIGNAL( closing( KPortView* ) ), this, SLOT( removeIOPort( KPortView* ) ) ) ;
+ }
+*/
+}
+
+#include "kpicosim.moc"
diff --git a/src/kpicosim.desktop b/src/kpicosim.desktop
new file mode 100755
index 0000000..0547660
--- /dev/null
+++ b/src/kpicosim.desktop
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Encoding=UTF-8
+Name=KPicosim
+Exec=kpicosim
+Icon=kpicosim
+Type=Application
+Comment=PicoBlaze IDE
+Comment[nl]=PicoBlaze Ontwikkelomgeving
diff --git a/src/kpicosim.h b/src/kpicosim.h
new file mode 100755
index 0000000..5ed9893
--- /dev/null
+++ b/src/kpicosim.h
@@ -0,0 +1,119 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+
+
+#ifndef _KPICOSIM_H_
+#define _KPICOSIM_H_
+
+#include "codeeditor.h"
+#include "ksimulator.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <kmainwindow.h>
+#include <klistview.h>
+#include <qsplitter.h>
+#include <kpopupmenu.h>
+#include <ktoolbar.h>
+#include <qtabwidget.h>
+#include "kprocessorview.h"
+#include "kserialview.h"
+#include "kscratchpadview.h"
+#include "kportview.h"
+
+class KPicoSim : public KMainWindow
+{
+ Q_OBJECT
+ public:
+ KPicoSim();
+ virtual ~KPicoSim();
+
+ protected:
+ CodeEditor * m_editor ;
+ KListView * m_messages ;
+ QSplitter * m_splitter ;
+ KProcessorView * m_processorView ;
+ KSerialView *m_serialView ;
+ KScratchpadView *m_scratchpadView ;
+ QTabWidget *m_tabWidget ;
+
+ KPopupMenu * m_fileMenu, * m_debugMenu, * m_settingsMenu, * m_editMenu, * m_peripheralMenu, *m_jtagMenu, *m_helpMenu ;
+
+ KSimulator * m_simulator ;
+
+ // Export to VHDL
+ QString m_templateFile, m_outputDir, m_entityName ;
+
+ bool m_simulationMode ;
+ unsigned int m_nrInstructions ;
+
+ void appendMessage( QString str ) ;
+ void updateViews() ;
+ void updateScratchpadView() ;
+
+ virtual void closeEvent( QCloseEvent *e ) ;
+
+ void buildMenu() ;
+
+ void openGUI() ;
+ void closeGUI() ;
+
+// QPtrList<KPortView> m_ioList ;
+ QString m_bitfile ;
+
+ QPixmap m_runPxp, m_stopPxp ;
+ KToolBar *m_debugBar ;
+
+ signals:
+ void run() ;
+ void stop() ;
+
+ public slots:
+ void startSim() ;
+ void startStop() ;
+ void stepped( unsigned int line ) ;
+ void messageListClicked( QListViewItem * item ) ;
+
+ void updateProcessorRegs() ;
+ void updateProcessorFlags() ;
+
+ void newIOPort() ;
+ void showSerialPort() ;
+ void showScratchpad() ;
+ void slotClose() ;
+
+ /* The export functions */
+ void fileExportVHDL() ;
+ void fileExportCOE() ;
+ void fileExportMEM() ;
+ void fileExportHEX() ;
+
+ bool compile() ;
+ void slotFileNew() ;
+
+// void removeIOPort( KPortView* ioport ) ;
+
+ /* JTAG */
+ void jtagDownload() ;
+};
+
+#endif // _KPICOSIM_H_
diff --git a/src/kpicosimconfig.h b/src/kpicosimconfig.h
new file mode 100755
index 0000000..13b9d6a
--- /dev/null
+++ b/src/kpicosimconfig.h
@@ -0,0 +1,37 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+#ifndef KPICOSIMCONFIG_H
+#define KPICOSIMCONFIG_H
+
+#include <kconfigskeleton.h>
+
+/**
+@author Mark Six
+*/
+class kpicosimconfig : public KConfigSkeleton
+{
+public:
+ kpicosimconfig();
+
+ ~kpicosimconfig();
+
+};
+
+#endif
diff --git a/src/kpicosimui.rc b/src/kpicosimui.rc
new file mode 100755
index 0000000..39df4cb
--- /dev/null
+++ b/src/kpicosimui.rc
@@ -0,0 +1,8 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="kpicosim" version="1">
+<MenuBar>
+ <Menu name="custom"><text>C&amp;ustom</text>
+ <Action name="custom_action" />
+ </Menu>
+</MenuBar>
+</kpartgui>
diff --git a/src/kport.cpp b/src/kport.cpp
new file mode 100755
index 0000000..d158cfd
--- /dev/null
+++ b/src/kport.cpp
@@ -0,0 +1,48 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+#include "kport.h"
+
+unsigned char KPort::In() { // Called by Picoblaze
+ emit read() ;
+ return m_readValue ;
+}
+
+void KPort::Out( unsigned char value ) { // Called by Picoblaze
+ m_writeValue = value ;
+ emit write( value ) ;
+}
+
+unsigned char KPort::getWriteValue() {
+ return m_writeValue ;
+}
+
+unsigned char KPort::getReadValue() {
+ return m_readValue ;
+}
+
+void KPort::setWriteValue( uint8_t value ) {
+ m_writeValue = value ;
+}
+
+void KPort::setReadValue( uint8_t value ) {
+ m_readValue = value ;
+}
+
+
diff --git a/src/kport.h b/src/kport.h
new file mode 100755
index 0000000..6038826
--- /dev/null
+++ b/src/kport.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+#ifndef KPORT_H
+#define KPORT_H
+
+#include <qobject.h>
+#include "cpicoblaze.h"
+
+class KPort : public QObject, public CIOPort
+{
+ Q_OBJECT
+ public:
+ KPort( unsigned char portID ) : CIOPort( portID ) {}
+ virtual ~KPort() {} ;
+
+ unsigned char In() ; // Called by Picoblaze
+ void Out( unsigned char value ) ; // Called by Picoblaze
+
+ unsigned char getWriteValue() ;
+ unsigned char getReadValue() ;
+
+ void setWriteValue( uint8_t value ) ;
+ void setReadValue( uint8_t value ) ;
+
+ signals:
+ void write( unsigned char value ) ;
+ void read() ;
+
+ private:
+ unsigned char m_readValue, m_writeValue ;
+} ;
+
+
+#endif
diff --git a/src/kportview.cpp b/src/kportview.cpp
new file mode 100755
index 0000000..7bf410e
--- /dev/null
+++ b/src/kportview.cpp
@@ -0,0 +1,185 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+#include "kportview.h"
+#include <qlayout.h>
+#include <qlabel.h>
+
+KPortView::KPortView( CPicoBlaze *cpu, QWidget *parent, const char *name)
+ : KToolBar(parent, name)
+{
+ m_cpu = cpu ;
+
+ QWidget *widget = new QWidget( this ) ;
+ widget->setMinimumSize( 200, 65 ) ;
+
+ QLabel *label = new QLabel( "ID", widget ) ;
+ label->move( 3, 0 ) ;
+
+ label = new QLabel( "b7", widget ) ;
+ label->move( 32, 0 ) ;
+
+ label = new QLabel( "b0", widget ) ;
+ label->move( 137, 0 ) ;
+
+ label = new QLabel( "I", widget ) ;
+ label->move( 160, 0 ) ;
+
+ label = new QLabel( "O", widget ) ;
+ label->move( 175, 0 ) ;
+
+ m_editID = new KLineEdit( widget ) ;
+ m_editID->setText( "0" ) ;
+ m_editID->setFixedSize( 30, 20 ) ;
+ m_editID->move( 2, 22 );
+ connect( m_editID, SIGNAL( textChanged( const QString &) ), this, SLOT( setID( const QString &) ) ) ;
+
+ int i ;
+ for ( i = 0 ; i < 8 ; i++ ) {
+ m_bits[ i ] = new QCheckBox( widget ) ;
+ m_bits[ i ]->move( 35 + i * 15, 22 ) ;
+ }
+
+ m_readable = new QCheckBox( widget ) ;
+ m_readable->move( 160, 22 ) ;
+
+ m_writeable = new QCheckBox( widget ) ;
+ m_writeable->move( 175, 22 ) ;
+
+ m_port = new KPort( 0 ) ;
+ m_cpu->addPort( m_port ) ;
+
+ connect( m_port, SIGNAL( read() ), this, SLOT( read() ) ) ;
+ connect( m_port, SIGNAL( write(unsigned char) ), this, SLOT( write(unsigned char) ) ) ;
+ connect( m_readable, SIGNAL( toggled(bool) ), this, SLOT( readableToggled(bool) ) ) ;
+ connect( m_writeable, SIGNAL( toggled(bool) ), this, SLOT( writeableToggled(bool) ) ) ;
+
+ setWidget( widget ) ;
+ setCloseMode( Always ) ;
+
+ m_writeable->setChecked( true ) ;
+ writeableToggled( true ) ;
+ m_readable->setChecked( true ) ;
+ readableToggled( true ) ;
+
+ setResizeEnabled( true ) ;
+
+ m_backgroundColor = m_editID->backgroundColor() ;
+}
+
+KPortView::~KPortView()
+{
+ m_cpu->deletePort( m_port ) ;
+}
+/*
+void KPortView::closeEvent ( QCloseEvent * e )
+{
+ emit closing( this ) ;
+}
+*/
+void KPortView::setID( const QString &newID )
+{
+ QString str ;
+ bool ok ;
+ int id ;
+
+ id = newID.toInt( &ok ) ;
+
+ if ( ok && id >= 0 && id <= 255 ) {
+ m_port->setID( id ) ; // change it back to the old id
+ m_editID->setText( newID ) ;
+ m_editID->setBackgroundColor( m_backgroundColor ) ;
+ } else {
+ m_editID->setBackgroundColor( QColor( 255, 128, 128 ) ) ;
+ }
+
+
+ /*else {
+ str.sprintf( "%d", m_port->getID() ) ;
+ m_editID->setText( str ) ;
+ }*/
+}
+
+QString KPortView::id()
+{
+ return m_editID->text() ;
+}
+
+void KPortView::read()
+{
+ unsigned char value = 0 ;
+ int i ;
+
+ for ( i = 0 ; i < 8 ; i++ )
+ if ( m_bits[ i ]->isChecked() )
+ value |= ( 0x80 >> i ) ;
+
+ m_port->setReadValue( value ) ;
+}
+
+void KPortView::write( unsigned char value )
+{
+ int i;
+ for ( i = 0 ; i < 8 ; i++ )
+ if ( value & ( 0x80 >> i ) )
+ m_bits[ i ]->setChecked( true ) ;
+ else
+ m_bits[ i ]->setChecked( false ) ;
+}
+
+void KPortView::readableToggled( bool on )
+{
+ int mode = m_port->getMode() ;
+ if ( on ) mode |= PortReadable ;
+ else mode &= ~PortReadable ;
+ m_port->setMode( mode ) ;
+}
+
+void KPortView::writeableToggled( bool on )
+{
+ int mode = m_port->getMode() ;
+ if ( on ) mode |= PortWriteable ;
+ else mode &= ~PortWriteable ;
+ m_port->setMode( mode ) ;
+}
+
+void KPortView::readConfig( KSimpleConfig &config, QString group )
+{
+ config.setGroup( group ) ;
+
+ int mode = config.readPropertyEntry( "Mode", QVariant::Int ).toInt() ;
+ m_port->setMode( mode ) ;
+ m_readable->setChecked( (mode & PortReadable) != 0 ) ;
+ m_writeable->setChecked( (mode & PortWriteable ) != 0 ) ;
+
+ QString id = config.readEntry( "Id" ) ;
+ setID( id ) ;
+}
+
+void KPortView::writeConfig( KSimpleConfig &config, QString group )
+{
+ config.setGroup( group ) ;
+
+ config.writeEntry( "Mode", m_port->getMode() ) ;
+ config.writeEntry( "Id", m_port->getID() ) ;
+}
+
+
+
+#include "kportview.moc"
diff --git a/src/kportview.h b/src/kportview.h
new file mode 100755
index 0000000..b4f2f0c
--- /dev/null
+++ b/src/kportview.h
@@ -0,0 +1,66 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+#ifndef KPORTVIEW_H
+#define KPORTVIEW_H
+
+#include <ktoolbar.h>
+#include <qcheckbox.h>
+#include <klineedit.h>
+#include "kport.h"
+#include <ksimpleconfig.h>
+
+class KPortView : public KToolBar
+{
+ Q_OBJECT
+ public:
+ KPortView( CPicoBlaze *cpu, QWidget *parent = 0, const char *name = 0);
+ ~KPortView();
+
+ KPort * m_port ;
+
+ public slots:
+ void read() ;
+ void write( unsigned char value ) ;
+
+ void writeableToggled( bool on ) ;
+ void readableToggled( bool on ) ;
+
+ void setID( const QString & newID ) ;
+ QString id() ;
+
+ void readConfig( KSimpleConfig &config, QString group ) ;
+ void writeConfig( KSimpleConfig &config, QString group ) ;
+
+ signals:
+// void closing( KPortView *ioport ) ;
+
+ protected:
+// virtual void closeEvent ( QCloseEvent * e ) ;
+
+ QCheckBox * m_bits[ 8 ], * m_readable, * m_writeable ;
+ KLineEdit * m_editID ;
+
+ CPicoBlaze * m_cpu ;
+
+ QColor m_backgroundColor ;
+
+};
+
+#endif
diff --git a/src/kprocessorview.cpp b/src/kprocessorview.cpp
new file mode 100755
index 0000000..f54469a
--- /dev/null
+++ b/src/kprocessorview.cpp
@@ -0,0 +1,208 @@
+#include "kprocessorview.h"
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qscrollview.h>
+#include <qsize.h>
+#include <qmessagebox.h>
+#include <qpopupmenu.h>
+#include <qcursor.h>
+
+MyListView::MyListView(QWidget *parent) : KListView(parent)
+{
+ connect( this, SIGNAL( contextMenu( KListView *, QListViewItem *, const QPoint & ) ),
+ SLOT( slotContextMenu( KListView *, QListViewItem *, const QPoint & ) ) );
+}
+
+MyListView::~MyListView()
+{
+}
+
+void MyListView::slotContextMenu( KListView *, QListViewItem *, const QPoint & )
+{
+// mousePressEvent( NULL ) ;
+ emit showPopupMenu() ;
+}
+/*
+void MyListView::mousePressEvent( QMouseEvent * event )
+{
+ //QMessageBox::information( this, "information", "mouse pressed" ) ;
+
+// if ( event->button() == RightButton )
+ emit showPopupMenu() ;
+// else
+// KListView::mousePressEvent( event ) ;
+}
+*/
+
+KProcessorView::KProcessorView(QWidget *parent, const char *name)
+ : KToolBar(parent)
+{
+ name = name ; // avoid compiler warning
+
+ view = new MyListView( this ) ;
+
+ connect( view, SIGNAL( itemRenamed( QListViewItem*) ), this, SLOT( slotItemRenamed(QListViewItem*) ) ) ;
+ connect( view, SIGNAL( showPopupMenu() ), this, SLOT( showPopupMenu() ) ) ;
+
+ view->addColumn( "Register" ) ;
+ view->addColumn( "Value" ) ;
+ view->setRootIsDecorated( true ) ;
+ view->setRenameable( 1, true ) ; // Column 1 is renameable
+ view->setRenameable( 0, false ) ; // Column 1 is renameable
+ view->setItemsRenameable( true ) ;
+ setWidget( view ) ;
+ setResizeEnabled( true ) ;
+
+ int i ;
+ char str[ 128 ] ;
+
+ QListViewItem *cpu = new QListViewItem( view ) ;
+ cpu->setText( 0, "CPU" ) ;
+
+ QListViewItem *flags = new QListViewItem( cpu ) ;
+ flags->setText( 0, "Flags" ) ;
+
+ zeroFlag = new QListViewItem( flags ) ;
+ zeroFlag->setText( 0, "Zero" ) ;
+ zeroFlag->setText( 1, "0" ) ;
+
+ carryFlag = new QListViewItem( flags ) ;
+ carryFlag->setText( 0, "Carry" ) ;
+ carryFlag->setText( 1, "0" ) ;
+
+ ieFlag = new QListViewItem( flags ) ;
+ ieFlag->setText( 0, "IE" ) ;
+ ieFlag->setText( 1, "0" ) ;
+
+ QListViewItem *reg = new QListViewItem( cpu ) ;
+ reg->setText( 0, "Registers" ) ;
+
+ for ( i = 0 ; i < 16 ; i++ ) {
+ regs[ i ] = new QListViewItem( reg ) ;
+ sprintf( str, "s%X", i ) ;
+ regs[ i ]->setText( 0, str ) ;
+ regs[ i ]->setText( 1, "0" ) ;
+ }
+
+ view->setOpen( cpu, true ) ;
+ view->setOpen( flags, true ) ;
+ view->setOpen( reg, true ) ;
+
+ m_bHexMode = false ;
+}
+
+void KProcessorView::slotHexMode()
+{
+ unsigned char regs[ 16 ] ;
+
+ getRegisterValues(regs) ;
+ m_bHexMode = !m_bHexMode ;
+ setRegisterValues(regs) ;
+}
+
+void KProcessorView::showPopupMenu()
+{
+ QPopupMenu *menu = new QPopupMenu( this ) ;
+ menu->insertItem( "Hexadecimal", this, SLOT( slotHexMode() ), 0, 1 ) ;
+ menu->setItemChecked( 1, m_bHexMode ) ;
+ menu->exec( QCursor::pos() );
+}
+
+void KProcessorView::slotItemRenamed( QListViewItem * item )
+{
+ int i, value, base ;
+ bool ok ;
+
+ if ( m_bHexMode ) base = 16 ;
+ else base = 10 ;
+
+ if ( !item )
+ return ;
+
+ for ( i = 0 ; i < 16 ; i++ ) {
+ if ( item == regs[ i ] ) {
+ value = item->text(1).toInt( &ok, base ) ;
+
+ if ( !ok || value < 0 || value > 255 ) {
+ QMessageBox::warning( parentWidget(), "Modify register", "Value should be between 0-255" ) ;
+ view->rename( item, 1 ) ;
+ } else {
+ emit processorRegsChanged() ;
+ }
+ return ;
+ }
+ }
+
+ if ( zeroFlag == item || carryFlag == item || ieFlag == item ) {
+ value = item->text(1).toInt( &ok ) ;
+ if ( !ok || value < 0 || value > 1 ) {
+ QMessageBox::warning( parentWidget(), "Modify flag", "Value should be between 0-1" ) ;
+ } else
+ emit processorFlagsChanged() ;
+ }
+}
+
+void KProcessorView::resizeEvent( QResizeEvent *event )
+{
+ event = event ;
+// view->resize( width() - 10, height() - 10 ) ;
+}
+
+void KProcessorView::getRegisterValues( unsigned char *values )
+{
+ int i, base ;
+ bool ok ;
+
+ if ( m_bHexMode ) base = 16 ;
+ else base = 10 ;
+
+ for ( i = 0 ; i < 16 ; i++ ) {
+ values[ i ] = regs[ i ]->text(1).toInt( &ok, base ) ;
+ }
+}
+
+void KProcessorView::setRegisterValues( unsigned char *values )
+{
+ int i, base ;
+
+ if ( m_bHexMode ) base = 16 ;
+ else base = 10 ;
+
+ QString str;
+ for ( i = 0 ; i < 16 ; i++ ) {
+ str.setNum( values[ i ], base ) ;
+ regs[ i ]->setText( 1, str ) ;
+ }
+}
+
+void KProcessorView::setFlags( unsigned char flags )
+{
+ if ( flags & 0x01 ) zeroFlag->setText( 1, "1" ) ;
+ else zeroFlag->setText( 1, "0" ) ;
+
+ if ( flags & 0x02 ) carryFlag->setText( 1, "1" ) ;
+ else carryFlag->setText( 1, "0" ) ;
+
+ if ( flags & 0x04 ) ieFlag->setText( 1, "1" ) ;
+ else ieFlag->setText( 1, "0" ) ;
+}
+
+unsigned char KProcessorView::getFlags()
+{
+ unsigned char flags = 0 ;
+
+ if ( zeroFlag->text(1).toInt() == 1 ) flags |= 0x01 ;
+ if ( carryFlag->text(1).toInt() == 1 ) flags |= 0x02 ;
+ if ( ieFlag->text(1).toInt() == 1 ) flags |= 0x04 ;
+
+ return flags ;
+}
+
+KProcessorView::~KProcessorView()
+{
+ delete view ;
+}
+
+
+
diff --git a/src/kprocessorview.h b/src/kprocessorview.h
new file mode 100755
index 0000000..ae4b6fc
--- /dev/null
+++ b/src/kprocessorview.h
@@ -0,0 +1,61 @@
+#ifndef KPROCESSORVIEW_H
+#define KPROCESSORVIEW_H
+
+
+#include <ktoolbar.h>
+#include <knuminput.h>
+#include <qcheckbox.h>
+#include <klistview.h>
+
+class MyListView : public KListView
+{
+ Q_OBJECT
+ public:
+ MyListView(QWidget *parent) ;
+ ~MyListView() ;
+
+ protected:
+// virtual void mousePressEvent( QMouseEvent *event ) ;
+
+
+ public slots:
+ void slotContextMenu( KListView *, QListViewItem *, const QPoint & ) ;
+
+ signals:
+ void showPopupMenu() ;
+} ;
+
+
+class KProcessorView : public KToolBar
+{
+ Q_OBJECT
+ public:
+ KProcessorView(QWidget *parent = 0, const char *name = 0);
+ ~KProcessorView();
+
+ void setRegisterValues( unsigned char *values ) ;
+ void getRegisterValues( unsigned char *values ) ;
+
+ void setFlags( unsigned char flags );
+ unsigned char getFlags() ;
+
+ public slots:
+ void slotItemRenamed( QListViewItem * item ) ;
+ void slotHexMode() ;
+ void showPopupMenu() ;
+
+ signals:
+ void processorRegsChanged() ;
+ void processorFlagsChanged() ;
+
+ private:
+ virtual void resizeEvent( QResizeEvent *event ) ;
+
+ protected:
+ MyListView *view ;
+ QListViewItem * regs[ 16 ] ;
+ QListViewItem * zeroFlag, * carryFlag, * ieFlag ;
+ bool m_bHexMode ;
+};
+
+#endif
diff --git a/src/kscratchpadview.cpp b/src/kscratchpadview.cpp
new file mode 100755
index 0000000..fffe989
--- /dev/null
+++ b/src/kscratchpadview.cpp
@@ -0,0 +1,59 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+#include "kscratchpadview.h"
+
+KScratchpadView::KScratchpadView( QWidget *parent, const char *name)
+ : KToolBar(parent, name)
+{
+ view = new KTextEdit( this ) ;
+ view->setFont( QFont( "Courier", view->font().pointSize() ) ) ;
+ view->setReadOnly( true ) ;
+
+ setWidget( view ) ;
+ setResizeEnabled( true ) ;
+}
+
+KScratchpadView::~KScratchpadView()
+{
+ delete view ;
+}
+
+void KScratchpadView::setContent( unsigned char *values, unsigned int len )
+{
+ unsigned int i, val ;
+
+ QString text, str ;
+
+ text = "Scratchpad" ;
+ for ( i = 0 ; i < len ; i++ ) {
+ if ( (i % 8) == 0 ) { // Show address
+ str.sprintf( "\n%02X:", i ) ;
+ text += str ;
+ }
+ val = values[ i ] ;
+ str.sprintf( " %02X", val ) ; // values
+ text += str ;
+ }
+
+ view->setText( text ) ;
+}
+
+
+#include "kscratchpadview.moc"
diff --git a/src/kscratchpadview.h b/src/kscratchpadview.h
new file mode 100755
index 0000000..eebc00c
--- /dev/null
+++ b/src/kscratchpadview.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+#ifndef KSCRATCHPADVIEW_H
+#define KSCRATCHPADVIEW_H
+
+#include <ktoolbar.h>
+#include <ktextedit.h>
+
+class KScratchpadView : public KToolBar
+{
+ Q_OBJECT
+ public:
+ KScratchpadView(QWidget *parent = 0, const char *name = 0);
+ ~KScratchpadView();
+
+ void setContent( unsigned char *values, unsigned int len ) ;
+
+ protected:
+ KTextEdit * view ;
+};
+
+#endif
diff --git a/src/kserialview.cpp b/src/kserialview.cpp
new file mode 100755
index 0000000..6ce0457
--- /dev/null
+++ b/src/kserialview.cpp
@@ -0,0 +1,321 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+#include "kserialview.h"
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qgroupbox.h>
+#include <qframe.h>
+
+KSerialView::KSerialView( CPicoBlaze *cpu, QWidget * parent ) : QWidget( parent )
+{
+ m_cpu = cpu ;
+
+ txPort = new KPort( 1 ) ;
+ txPort->setMode( PortWriteable ) ;
+
+ rxPort = new KPort( 1 ) ;
+ rxPort->setMode( PortReadable ) ;
+
+ statusPort = new KPort( 0 ) ;
+ statusPort->setMode( PortReadable ) ;
+
+ view = new KSerialWindow( this ) ;
+ QWidget *settings = new QWidget( this ) ;
+ settings->setMinimumSize( 90, 90 ) ;
+
+ QVBoxLayout *layout = new QVBoxLayout( this ) ;
+ layout->addWidget( view ) ;
+ layout->addWidget( settings ) ;
+
+ QGroupBox *groupBox = new QGroupBox( "Serial Settings", settings ) ;
+ groupBox->setFixedSize( 200, 80 ) ;
+ groupBox->move( 10, 0 ) ;
+
+ QLabel *label = new QLabel( groupBox ) ;
+ label->setText( "Transmit" ) ;
+ label->move( 5, 15 ) ;
+ label->setFixedSize( 55, 18 ) ;
+
+ label = new QLabel( groupBox ) ;
+ label->setText( "Receive" ) ;
+ label->move( 5, 35 ) ;
+ label->setFixedSize( 55, 18 ) ;
+
+ label = new QLabel( groupBox ) ;
+ label->setText( "Status" ) ;
+ label->move( 5, 55 ) ;
+ label->setFixedSize( 55, 18 ) ;
+
+ txPortID = new KLineEdit( groupBox ) ;
+ txPortID->move( 65, 15 ) ;
+ txPortID->setFixedSize( 40, 18 ) ;
+ txPortID->setText( "1" ) ;
+
+ rxPortID = new KLineEdit( groupBox ) ;
+ rxPortID->move( 65, 35 ) ;
+ rxPortID->setText( "1" ) ;
+ rxPortID->setFixedSize( 40, 18 ) ;
+
+ statusPortID = new KLineEdit( groupBox );
+ statusPortID->move( 65, 55 ) ;
+ statusPortID->setText( "0" ) ;
+ statusPortID->setFixedSize( 40, 18 ) ;
+
+ statusPort->setReadValue( 0 ) ; // Buffers are empty, nothing received.
+ connect( txPort, SIGNAL( write( unsigned char ) ), this, SLOT( transmit( unsigned char ) ) ) ;
+ connect( rxPort, SIGNAL( read() ), this, SLOT( receive() ) ) ;
+ connect( view, SIGNAL( keyPressed( int ) ), this, SLOT( keyPressed( int ) ) ) ;
+
+ connect( txPortID, SIGNAL( textChanged( const QString & ) ), this, SLOT( updateTxId( const QString & ) ) ) ;
+ connect( rxPortID, SIGNAL( textChanged( const QString & ) ), this, SLOT( updateRxId( const QString & ) ) ) ;
+ connect( statusPortID, SIGNAL( textChanged( const QString & ) ), this, SLOT( updateStatusId( const QString & ) ) ) ;
+
+ groupBox = new QGroupBox( "Status Register", settings ) ;
+ groupBox->setFixedSize( 200, 80 ) ;
+ groupBox->move( 250, 0 ) ;
+
+ label = new QLabel( groupBox ) ;
+ label->setText( "RX" ) ;
+ label->move( 106, 15 ) ;
+ label->setFixedSize( 20, 20 ) ;
+
+ label = new QLabel( groupBox ) ;
+ label->setText( "TX" ) ;
+ label->move( 168, 15 ) ;
+ label->setFixedSize( 20, 20 ) ;
+
+ label = new QLabel( groupBox ) ;
+ label->setText( "DR" ) ;
+ label->move( 80, 30 ) ;
+ label->setFixedSize( 20, 20 ) ;
+
+ label = new QLabel( groupBox ) ;
+ label->setText( "F" ) ;
+ label->move( 110, 30 ) ;
+ label->setFixedSize( 20, 20 ) ;
+
+ label = new QLabel( groupBox ) ;
+ label->setText( "HF" ) ;
+ label->move( 130, 30 ) ;
+ label->setFixedSize( 20, 20 ) ;
+
+ label = new QLabel( groupBox ) ;
+ label->setText( "F" ) ;
+ label->move( 160, 30 ) ;
+ label->setFixedSize( 20, 20 ) ;
+
+ label = new QLabel( groupBox ) ;
+ label->setText( "HF" ) ;
+ label->move( 179, 30 ) ;
+ label->setFixedSize( 20, 20 ) ;
+
+ int i ;
+ for ( i = 0 ; i < 8 ; i++ ) {
+ m_statusBits[ i ] = new QCheckBox( groupBox ) ;
+ m_statusBits[ i ]->move( 5 + i * 25, 50 ) ;
+ m_statusBits[ i ]->setFixedSize( 15, 20 ) ;
+ }
+
+ for ( i = 0 ; i < 6 ; i++ ) {
+ m_statusBits[ i ]->setEnabled( false ) ;
+ }
+
+ QFrame *frame = new QFrame( groupBox ) ;
+ frame->setFrameRect( QRect( 0, 0, 1, 50 ) ) ;
+ frame->setFrameShape( QFrame::VLine ) ;
+ frame->move( 73, 20 ) ;
+ frame->setFixedSize( 1, 50 ) ;
+
+ frame = new QFrame( groupBox ) ;
+ frame->setFrameRect( QRect( 0, 0, 1, 50 ) ) ;
+ frame->setFrameShape( QFrame::VLine ) ;
+ frame->move( 149, 20 ) ;
+ frame->setFixedSize( 1, 50 ) ;
+
+ connect( m_statusBits[ 6 ], SIGNAL( toggled( bool ) ), this, SLOT( txFlagsChanged( bool ) ) ) ;
+ connect( m_statusBits[ 7 ], SIGNAL( toggled( bool ) ), this, SLOT( txFlagsChanged( bool ) ) ) ;
+
+ fifoPtr = 0 ;
+
+ m_cpu->addPort( txPort ) ;
+ m_cpu->addPort( rxPort ) ;
+ m_cpu->addPort( statusPort ) ;
+
+ m_backgroundColor = rxPortID->backgroundColor() ;
+}
+
+
+KSerialView::~KSerialView()
+{
+ m_cpu->deletePort( txPort ) ;
+ m_cpu->deletePort( rxPort ) ;
+ m_cpu->deletePort( statusPort ) ;
+
+ delete txPort ;
+ delete rxPort ;
+ delete statusPort ;
+ delete view ;
+}
+
+void KSerialView::updateTxId( const QString & str )
+{
+ bool ok ;
+ int val ;
+ QString s ;
+
+ val = str.toInt( &ok ) ;
+ if ( ok && val >= 0 && val <= 255 ) {
+ txPortID->setBackgroundColor( m_backgroundColor ) ;
+ txPort->setID( val ) ;
+ } else {
+ txPortID->setBackgroundColor( QColor( 255, 128, 128 ) ) ;
+ }
+
+
+ /*else {
+ s.sprintf( "%u", txPort->getID() ) ;
+ txPortID->setText( s ) ;
+ }
+ */
+}
+
+void KSerialView::updateRxId( const QString & str )
+{
+ bool ok ;
+ int val ;
+ QString s ;
+
+ val = str.toInt( &ok ) ;
+ if ( ok && val >= 0 && val <= 255 ) {
+ rxPortID->setBackgroundColor( m_backgroundColor ) ;
+ rxPort->setID( val ) ;
+ } else {
+ rxPortID->setBackgroundColor( QColor( 255, 128, 128 ) ) ;
+ }
+
+ /*else {
+ s.sprintf( "%u", rxPort->getID() ) ;
+ rxPortID->setText( s ) ;
+ }
+ */
+}
+
+void KSerialView::updateStatusId( const QString & str )
+{
+ bool ok ;
+ int val ;
+ QString s ;
+
+ val = str.toInt( &ok ) ;
+ if ( ok && val >= 0 && val <= 255 ) {
+ statusPort->setID( val ) ;
+ statusPortID->setBackgroundColor( m_backgroundColor ) ;
+ } else {
+ statusPortID->setBackgroundColor( QColor( 255, 128, 128 ) ) ;
+ }
+ /*else {
+ s.sprintf( "%u", statusPort->getID() ) ;
+ statusPortID->setText( s ) ;
+ }
+*/
+}
+
+void KSerialView::transmit( unsigned char b )
+{
+ if ( b == '\r' )
+ b = '\n' ;
+
+ if ( b == 0x08 ) { // Backspace
+ view->doKeyboardAction( QTextEdit::ActionBackspace ) ;
+ } else {
+ QString str ;
+ view->insert( (str+=b) ) ;
+ }
+}
+
+unsigned char KSerialView::getReceiveFlags()
+{
+ unsigned char flags = 0 ;
+ if ( fifoPtr != 0 ) flags |= 0x10 ; // Receive
+ else flags &= ~0x10 ;
+
+ if ( fifoPtr > 7 ) flags |= 0x04 ; // Halffull Marker
+ else flags &= ~0x04 ;
+
+ if ( fifoPtr == 15 ) flags |= 0x08 ; // Full Marker
+ else flags &= ~0x08 ;
+
+ return flags ;
+}
+
+unsigned char KSerialView::getTransmitFlags()
+{
+ unsigned char flags = 0 ;
+ if ( m_statusBits[ 6 ]->isChecked() )
+ flags |= 0x02 ;
+ if ( m_statusBits[ 7 ]->isChecked() )
+ flags |= 0x01 ;
+
+ return flags ;
+}
+
+void KSerialView::receive()
+{
+ int i ;
+
+ if ( fifoPtr == 0 ) { // Fifo empty
+ statusPort->setReadValue( 0x00 ) ;
+ return ;
+ }
+
+ rxPort->setReadValue( rxFifo[ 0 ] ) ;
+ for ( i = 1 ; i < 16 ; i++ )
+ rxFifo[ i - 1 ] = rxFifo[ i ] ;
+ fifoPtr -= 1 ;
+
+ statusPort->setReadValue( getReceiveFlags() | getTransmitFlags() ) ;
+ setStatusBits( getReceiveFlags() ) ;
+}
+
+void KSerialView::keyPressed( int key )
+{
+ if ( key == '\n' || key == 0 )
+ return ;
+
+ rxFifo[ fifoPtr ] = key ;
+ if ( fifoPtr != 15 )
+ fifoPtr += 1 ;
+
+ statusPort->setReadValue( getReceiveFlags() | getTransmitFlags() ) ;
+ setStatusBits( getReceiveFlags() ) ;
+}
+
+void KSerialView::txFlagsChanged( bool en )
+{
+ en = en ;
+ statusPort->setReadValue( getReceiveFlags() | getTransmitFlags() ) ;
+}
+
+void KSerialView::setStatusBits( unsigned char value )
+{
+ m_statusBits[ 3 ]->setChecked( (value & 0x10) != 0 ) ;
+ m_statusBits[ 4 ]->setChecked( (value & 0x08) != 0 ) ;
+ m_statusBits[ 5 ]->setChecked( (value & 0x04) != 0 ) ;
+}
diff --git a/src/kserialview.h b/src/kserialview.h
new file mode 100755
index 0000000..1a21dbc
--- /dev/null
+++ b/src/kserialview.h
@@ -0,0 +1,110 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+#ifndef KSERIALVIEW_H
+#define KSERIALVIEW_H
+
+#include <ktoolbar.h>
+#include <ktextedit.h>
+#include <klineedit.h>
+#include <qcheckbox.h>
+#include <qpushbutton.h>
+#include <qfont.h>
+#include <qpopupmenu.h>
+
+#include "kport.h"
+
+class KSerialWindow : public KTextEdit
+{
+ Q_OBJECT
+
+ public:
+ KSerialWindow( QWidget *parent ) : KTextEdit( parent ) {
+ setWrapColumnOrWidth( 80 ) ; // Serial window is a terminal
+ setWrapPolicy( QTextEdit::Anywhere ) ;
+ setWordWrap( QTextEdit::FixedColumnWidth ) ;
+ setFont( KGlobalSettings::fixedFont() ) ; // Use default fixed font
+ }
+ virtual ~KSerialWindow() {} ;
+
+ protected:
+ virtual void keyPressEvent( QKeyEvent *e )
+ {
+ emit keyPressed( e->ascii() ) ;
+ }
+
+ virtual void mousePressEvent( QMouseEvent *e ) {
+ }
+ virtual void mouseReleaseEvent( QMouseEvent *e ) {}
+ virtual QPopupMenu *createPopupMenu( const QPoint &pos )
+ {
+ QPopupMenu *menu = new QPopupMenu( this ) ;
+ menu->insertItem( "clear view", this, SLOT( clearView() ) ) ;
+ return menu ;
+ }
+ public slots:
+ void clearView() {
+ clear() ;
+ }
+
+ signals:
+ void keyPressed( int key ) ;
+
+} ;
+
+class KSerialView : public QWidget
+{
+ Q_OBJECT
+ public:
+ KSerialView( CPicoBlaze *cpu, QWidget *parent );
+ ~KSerialView();
+
+ KPort * rxPort, * txPort, * statusPort ;
+
+ public slots:
+ void transmit( unsigned char ) ;
+ void receive() ;
+ void keyPressed( int key ) ;
+
+ protected:
+ KSerialWindow *view ;
+
+ unsigned char rxFifo[ 16 ] ;
+ unsigned char fifoPtr ;
+
+ unsigned char getReceiveFlags() ;
+ unsigned char getTransmitFlags() ;
+ void setStatusBits( unsigned char ) ;
+
+ CPicoBlaze * m_cpu ;
+
+ KLineEdit *txPortID, *rxPortID, *statusPortID ;
+ QCheckBox *m_statusBits[ 8 ] ;
+
+ QColor m_backgroundColor ;
+ QPushButton *m_clearButton ;
+
+ public slots:
+ void updateTxId( const QString & ) ;
+ void updateRxId( const QString & ) ;
+ void updateStatusId( const QString & ) ;
+ void txFlagsChanged( bool en ) ;
+};
+
+#endif
diff --git a/src/ksimulator.cpp b/src/ksimulator.cpp
new file mode 100755
index 0000000..57b2f43
--- /dev/null
+++ b/src/ksimulator.cpp
@@ -0,0 +1,151 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+#include "ksimulator.h"
+
+KSimulator::KSimulator(QObject *parent, const char *name )
+ : QObject(parent, name)
+{
+ m_picoBlaze = new CPicoBlaze() ;
+ m_assembler = new CAssembler() ;
+
+ m_assembler->setCode( m_picoBlaze->code ) ;
+ m_timer = new QTimer( this ) ;
+ m_bInterrupt = FALSE ;
+
+ m_timer->stop() ;
+ m_run = false ;
+ connect( m_timer, SIGNAL( timeout() ), this, SLOT( next() ) ) ;
+}
+
+KSimulator::~KSimulator()
+{
+
+ delete m_picoBlaze ;
+ delete m_assembler ;
+}
+
+void KSimulator::setMessageList( KListView *messageList )
+{
+ m_assembler->setMessageList( messageList ) ;
+}
+
+void KSimulator::reset()
+{
+ m_picoBlaze->Reset() ;
+ emit stepped( m_picoBlaze->GetNextSourceLine() ) ;
+}
+
+void KSimulator::clear()
+{
+ m_picoBlaze->code->ClearCode() ;
+ m_assembler->clear() ;
+}
+
+void KSimulator::interrupt()
+{
+ m_bInterrupt = TRUE ;
+}
+
+unsigned int KSimulator::getNextSourceLine()
+{
+ return m_picoBlaze->GetNextSourceLine() ;
+}
+
+void KSimulator::next()
+{
+ if ( m_bInterrupt ) {
+ m_bInterrupt = FALSE ;
+ m_picoBlaze->Interrupt() ;
+ } else
+ m_picoBlaze->Next() ;
+ emit stepped( m_picoBlaze->GetNextSourceLine() ) ;
+}
+
+CPicoBlaze * KSimulator::getCpu()
+{
+ return m_picoBlaze ;
+}
+
+unsigned char KSimulator::getFlags()
+{
+ unsigned char flags = 0 ;
+
+ if ( m_picoBlaze->flags.carry )
+ flags |= CARRY_FLAG ;
+ if ( m_picoBlaze->flags.zero )
+ flags |= ZERO_FLAG ;
+ if ( m_picoBlaze->flags.interrupt_enable )
+ flags |= INTERRUPT_FLAG ;
+
+ return flags ;
+}
+
+void KSimulator::setFlags( unsigned char flags )
+{
+ m_picoBlaze->flags.carry = flags & CARRY_FLAG ? TRUE : FALSE ;
+ m_picoBlaze->flags.zero = flags & ZERO_FLAG ? TRUE : FALSE ;
+ m_picoBlaze->flags.interrupt_enable = flags & INTERRUPT_FLAG ? TRUE : FALSE ;
+}
+
+void KSimulator::run()
+{
+ m_timer->start( 1 ) ;
+ m_run = true ;
+}
+
+void KSimulator::stop()
+{
+ m_timer->stop() ;
+ m_run = false ;
+}
+
+bool KSimulator::isRunning()
+{
+ return m_run ;
+}
+
+void KSimulator::getRegisterValues( unsigned char *values )
+{
+ int i ;
+
+ for ( i = 0 ; i < 16 ; i++ ) {
+ values[ i ] = m_picoBlaze->s[ i ] ;
+ }
+
+}
+
+void KSimulator::setRegisterValues( unsigned char *values )
+{
+ int i ;
+
+ for ( i = 0 ; i < 16 ; i++ ) {
+ m_picoBlaze->s[ i ] = values[ i ] ;
+ }
+}
+
+void KSimulator::getScratchpad( unsigned char * values )
+{
+ int i ;
+
+ for ( i = 0 ; i < SCRATCHPAD_SIZE ; i++ )
+ values[ i ] = m_picoBlaze->scratch->Get( i ) ;
+}
+
+#include "ksimulator.moc"
diff --git a/src/ksimulator.h b/src/ksimulator.h
new file mode 100755
index 0000000..f54f5be
--- /dev/null
+++ b/src/ksimulator.h
@@ -0,0 +1,91 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+#ifndef KSIMULATOR_H
+#define KSIMULATOR_H
+
+#include <qobject.h>
+#include "cpicoblaze.h"
+#include "cassembler.h"
+
+#include <string>
+#include <qtimer.h>
+#include <klistview.h>
+
+#include "kprocessorview.h"
+
+#define ZERO_FLAG 0x01
+#define CARRY_FLAG 0x02
+#define INTERRUPT_FLAG 0x04
+
+class KSimulator : public QObject
+{
+ Q_OBJECT
+ public:
+ KSimulator(QObject *parent = 0, const char *name = 0);
+ ~KSimulator();
+
+ void setFilename( string filename ) { m_assembler->setFilename( filename ) ; }
+ bool compile() { return m_assembler->assemble() ; }
+ bool exportVHDL( string templateFile, string outputDir, string entityName )
+ {
+ return m_assembler->exportVHDL( templateFile, outputDir, entityName ) ;
+ }
+
+ bool exportHEX( string filename, bool mem )
+ {
+ return m_assembler->exportHEX( filename, mem ) ;
+ }
+
+ void setRegisterValues( unsigned char *values ) ;
+ void getRegisterValues( unsigned char *values ) ;
+ unsigned char getFlags() ;
+ void setFlags( unsigned char flags ) ;
+ void getScratchpad( unsigned char * values ) ;
+
+ unsigned int getNextSourceLine() ;
+
+ void assemblerError( unsigned int line, const char * str ) ;
+ void setMessageList( KListView *messageList ) ;
+
+ bool isRunning() ;
+
+ CPicoBlaze * getCpu() ;
+
+ signals:
+ void stepped( unsigned int currentSourceLine ) ;
+
+ public slots:
+ void run() ;
+ void stop() ;
+ void next() ;
+ void interrupt() ;
+ void reset() ;
+ void clear() ;
+
+ private:
+ CPicoBlaze * m_picoBlaze ;
+ CAssembler * m_assembler ;
+ QTimer * m_timer ;
+ bool m_bInterrupt ;
+ KListView *m_messageList ;
+ bool m_run ;
+};
+
+#endif
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100755
index 0000000..2ab2fce
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,70 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+
+
+#include "kpicosim.h"
+#include <kapplication.h>
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <klocale.h>
+
+static const char description[] =
+ I18N_NOOP("A KDE KPart Application");
+
+static const char version[] = "0.1";
+
+static KCmdLineOptions options[] =
+{
+// { "+[URL]", I18N_NOOP( "Document to open" ), 0 },
+ KCmdLineLastOption
+};
+
+int main(int argc, char **argv)
+{
+ KAboutData about("kpicosim", I18N_NOOP("KPicoSim"), version, description,
+ KAboutData::License_GPL, "(C) %{YEAR} Mark Six", 0, 0, "m6@xs4all.nl");
+ about.addAuthor( "Mark Six", 0, "m6@xs4all.nl" );
+ KCmdLineArgs::init(argc, argv, &about);
+ KCmdLineArgs::addCmdLineOptions( options );
+ KApplication app;
+ KPicoSim *mainWin = 0;
+
+ if (app.isRestored())
+ {
+ RESTORE(KPicoSim);
+ }
+ else
+ {
+ // no session.. just start up normally
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ /// @todo do something with the command line args here
+
+ mainWin = new KPicoSim();
+ app.setMainWidget( mainWin );
+ mainWin->show();
+
+ args->clear();
+ }
+
+ // mainWin has WDestructiveClose flag by default, so it will delete itself.
+ return app.exec();
+}
+
diff --git a/src/pics/Makefile.am b/src/pics/Makefile.am
new file mode 100644
index 0000000..e726b97
--- /dev/null
+++ b/src/pics/Makefile.am
@@ -0,0 +1,5 @@
+INCLUDES = $(all_includes)
+METASOURCES = AUTO
+mypicsdir = $(kde_datadir)/kpicosim/pics
+
+mypics_DATA = continue.png interrupt.png next.png rebuild.png reset.png
diff --git a/src/pics/continue.png b/src/pics/continue.png
new file mode 100644
index 0000000..0d4232b
--- /dev/null
+++ b/src/pics/continue.png
Binary files differ
diff --git a/src/pics/interrupt.png b/src/pics/interrupt.png
new file mode 100644
index 0000000..69dfb9e
--- /dev/null
+++ b/src/pics/interrupt.png
Binary files differ
diff --git a/src/pics/next.png b/src/pics/next.png
new file mode 100644
index 0000000..561d70a
--- /dev/null
+++ b/src/pics/next.png
Binary files differ
diff --git a/src/pics/rebuild.png b/src/pics/rebuild.png
new file mode 100644
index 0000000..bd3c870
--- /dev/null
+++ b/src/pics/rebuild.png
Binary files differ
diff --git a/src/pics/reset.png b/src/pics/reset.png
new file mode 100644
index 0000000..a8dad33
--- /dev/null
+++ b/src/pics/reset.png
Binary files differ
diff --git a/src/psm.xml b/src/psm.xml
new file mode 100644
index 0000000..83e4386
--- /dev/null
+++ b/src/psm.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE language SYSTEM "language.dtd">
+<!--
+This program, including associated files, is free software. You may
+distribute 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
+
+-->
+
+<language name="pblazeASM" version="1.02" kateversion="2.1" section="Assembler" extensions="*.psm" mimetype="text/x-psm" author="Mark Six" license="GPL">
+ <highlighting>
+ <list name="instructions">
+ <item> ADD </item>
+ <item> ADDCY </item>
+ <item> AND </item>
+ <item> CALL </item>
+ <item> COMPARE </item>
+ <item> FETCH </item>
+ <item> INPUT </item>
+ <item> JUMP </item>
+ <item> LOAD </item>
+ <item> OR </item>
+ <item> OUTPUT </item>
+ <item> RETURN </item>
+ <item> RETURNI </item>
+ <item> ROTATE </item>
+ <item> RL </item>
+ <item> RR </item>
+ <item> SL0 </item>
+ <item> SL1 </item>
+ <item> SLA </item>
+ <item> SLX </item>
+ <item> SR0 </item>
+ <item> SR1 </item>
+ <item> SRA </item>
+ <item> SRX </item>
+ <item> STORE </item>
+ <item> SUB </item>
+ <item> SUBCY </item>
+ <item> TEST </item>
+ <item> XOR </item>
+ <item> DISABLE </item>
+ <item> ENABLE </item>
+ </list>
+
+ <list name="instruction_attr">
+ <item> NZ </item>
+ <item> Z </item>
+ <item> C </item>
+ <item> NC </item>
+ <item> INTERRUPT </item>
+ <item> DISABLE </item>
+ <item> ENABLE </item>
+ <item> s0 </item>
+ <item> s1 </item>
+ <item> s2 </item>
+ <item> s3 </item>
+ <item> s4 </item>
+ <item> s5 </item>
+ <item> s6 </item>
+ <item> s7 </item>
+ <item> s8 </item>
+ <item> s9 </item>
+ <item> sA </item>
+ <item> sB </item>
+ <item> sC </item>
+ <item> sD </item>
+ <item> sE </item>
+ <item> sF </item>
+ </list>
+
+ <list name="directives">
+ <item> constant </item>
+ <item> namereg </item>
+ <item> address </item>
+ </list>
+
+
+ <contexts>
+ <!-- The main context -->
+ <context name="Normal" attribute="Normal Text" lineEndContext="#stay">
+ <keyword attribute="Instructions" context="Opcode" String="instructions"/>
+ <keyword attribute="Directives" context="Opcode" String="directives"/>
+ <DetectChar attribute="Comment" context="Comment" char=";" />
+ </context>
+
+ <context name="Comment" attribute="Comment" lineEndContext="#pop" />
+
+ <context name="Opcode" attribute="Opcode" lineEndContext="#pop">
+ <keyword attribute="InstructionAttr" context="#stay" String="instruction_attr"/>
+ <DetectChar attribute="Comment" context="Comment" char=";" />
+ </context>
+ </contexts>
+
+ <itemDatas>
+ <itemData name="Normal Text" defStyleNum="dsNormal"/>
+ <itemData name="Directives" defStyleNum="dsOthers"/>
+ <itemData name="Instructions" defStyleNum="dsKeyword"/>
+ <itemData name="InstructionAttr" defStyleNum="dsNormal" color="#000080" selColor="#000080" bold="0" italic="1"/>
+ <itemData name="Comment" defStyleNum="dsComment" />
+ </itemDatas>
+ </highlighting>
+
+ <general>
+ <comments>
+ <comment name="singleLine" start=";" />
+ </comments>
+ <keywords casesensitive="0" weakDeliminator="_.$" />
+ </general>
+</language>
diff --git a/src/types.h b/src/types.h
new file mode 100755
index 0000000..f3d440c
--- /dev/null
+++ b/src/types.h
@@ -0,0 +1,9 @@
+
+
+typedef unsigned char uint8_t ;
+typedef unsigned short uint16_t ;
+typedef unsigned int uint32_t ;
+
+#define TRUE 1
+#define FALSE 0
+