/* Copyright (C) 2000 T. Scott Dattalo This file is part of gpsim. gpsim 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, or (at your option) any later version. gpsim 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 gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Logic.cc This is an example module library for interfacing with gpsim. In here you'll find some simple logic devices: AND2Gate - A 2-input AND gate OR2Gate - A 2-input OR gate */ /* IN_MODULE should be defined for modules */ #define IN_MODULE #include "../config.h" // get the definition for HAVE_GUI #ifdef HAVE_GUI /* XPM */ static char * and2_pixmap[] = { "32 32 3 1", " c black", ". c None", "X c white", " ............", " ........", " XXXXXXXXXXXXXXXXXX ........", " XXXXXXXXXXXXXXXXXXXXXX ......", " XXXXXXXXXXXXXXXXXXXXXX ......", " XXXXXXXXXXXXXXXXXXXXXXXX ....", " XXXXXXXXXXXXXXXXXXXXXXXX ...", " XXXXXXXXXXXXXXXXXXXXXXXXX ...", " XXXXXXXXXXXXXXXXXXXXXXXXXXX .", " XXXXXXXXXXXXXXXXXXXXXXXXXXX .", " XXXXXXXXXXXXXXXXXXXXXXXXXXX .", " XXXXXX XXX XXX X XXXXXXX .", " XXXXX X XX XX XX XX XXXXXX .", " XXXX XXX X XX XX XX XXXXXXX ", " XXXX XXX X X X XX XX XXXXXXX ", " XXXX XXX X X X XX XX XXXXXXX ", " XXXX X XX XX XX XXXXXXX ", " XXXX XXX X XX XX XX XXXXXXX ", " XXXX XXX X XXX XX XX XXXXXXX ", " XXXX XXX X XXX X XXXXXXX .", " XXXXXXXXXXXXXXXXXXXXXXXXXXX .", " XXXXXXXXXXXXXXXXXXXXXXXXXXX .", " XXXXXXXXXXXXXXXXXXXXXXXXXXX .", " XXXXXXXXXXXXXXXXXXXXXXXXXXX .", " XXXXXXXXXXXXXXXXXXXXXXXXX ...", " XXXXXXXXXXXXXXXXXXXXXXXX ...", " XXXXXXXXXXXXXXXXXXXXXXXX ....", " XXXXXXXXXXXXXXXXXXXXXX ......", " XXXXXXXXXXXXXXXXXXXXXX ......", " XXXXXXXXXXXXXXXXXX ........", " ........", " ............"}; /* XPM */ static char * or2_pixmap[] = { "32 32 3 1", " c black", ". c None", "X c white", " ............", " ........", " XXXXXXXXXXXXXXXXXX ........", " XXXXXXXXXXXXXXXXXXXXXX ......", " XXXXXXXXXXXXXXXXXXXXXX ......", ". XXXXXXXXXXXXXXXXXXXXXXX ....", ". XXXXXXXXXXXXXXXXXXXXXXX ...", ". XXXXXXXXXXXXXXXXXXXXXXXX ...", ".. XXXXXXXXXXXXXXXXXXXXXXXXX .", ".. XXXXXXXXXXXXXXXXXXXXXXXXX .", ".. XXXXXXXXXXXXXXXXXXXXXXXXX .", ".. XXXXXXX XX XXXXXXXXX .", "... XXXXX XXX X XXX XXXXXXXX .", "... XXXXX XXX X XXX XXXXXXXXX ", "... XXXXX XXX X XXX XXXXXXXXX ", "... XXXXX XXX X XXXXXXXXXX ", "... XXXXX XXX X X XXXXXXXXXXX ", "... XXXXX XXX X XX XXXXXXXXXX ", "... XXXXX XXX X XXX XXXXXXXXX ", "... XXXXXX XX XXX XXXXXXXX .", ".. XXXXXXXXXXXXXXXXXXXXXXXXX .", ".. XXXXXXXXXXXXXXXXXXXXXXXXX .", ".. XXXXXXXXXXXXXXXXXXXXXXXXX .", ".. XXXXXXXXXXXXXXXXXXXXXXXXX .", ". XXXXXXXXXXXXXXXXXXXXXXXX ...", ". XXXXXXXXXXXXXXXXXXXXXXX ...", ". XXXXXXXXXXXXXXXXXXXXXXX ....", " XXXXXXXXXXXXXXXXXXXXXX ......", " XXXXXXXXXXXXXXXXXXXXXX ......", " XXXXXXXXXXXXXXXXXX ........", " ........", " ............"}; static char * xor2_pixmap[] = { "40 32 3 1", " c None", ". c black", "X c white", " .................... ", " .. .................... ", " .... ........................ ", " ... ..XXXXXXXXXXXXXXXXXX.... ", " ... ..XXXXXXXXXXXXXXXXXXXXXX.. ", " ... ..XXXXXXXXXXXXXXXXXXXXXX.. ", " .... ..XXXXXXXXXXXXXXXXXXXXXXX.. ", " ... ..XXXXXXXXXXXXXXXXXXXXXXX... ", " ... ..XXXXXXXXXXXXXXXXXXXXXXXX.. ", " ... ..XXXXXXXXXXXXXXXXXXXXXXXXX.. ", " .... ..XXXXXXXXXXXXXXXXXXXXXXXXX.. ", " ... ..XXXXXXXXXXXXXXXXXXXXXXXXX.. ", " ... ..XXXX.XXX.XX...XX....XXXXX.. ", " .. ..XXX.XXX.X.XXX.X.XXX.XXXX.. ", " .. ..XXXX.X.XX.XXX.X.XXX.XXXXX..", " .. ..XXXX.X.XX.XXX.X.XXX.XXXXX..", " ... ..XXXXX.XXX.XXX.X....XXXXXX..", " ... ..XXXX.X.XX.XXX.X.X.XXXXXXX..", " ... ..XXXX.X.XX.XXX.X.XX.XXXXXX..", " ... ..XXX.XXX.X.XXX.X.XXX.XXXXX..", " ... ..XXX.XXX.XX...XX.XXX.XXXX.. ", " ... ..XXXXXXXXXXXXXXXXXXXXXXXXX.. ", " .. ..XXXXXXXXXXXXXXXXXXXXXXXXX.. ", " ... ..XXXXXXXXXXXXXXXXXXXXXXXXX.. ", " ... ..XXXXXXXXXXXXXXXXXXXXXXXXX.. ", " ... ..XXXXXXXXXXXXXXXXXXXXXXXX.. ", " ... ..XXXXXXXXXXXXXXXXXXXXXXX... ", " ... ..XXXXXXXXXXXXXXXXXXXXXXX.. ", " .... ..XXXXXXXXXXXXXXXXXXXXXX.. ", " ..... ..XXXXXXXXXXXXXXXXXXXXXX.. ", " .... ..XXXXXXXXXXXXXXXXXX.... ", " .. ........................ "}; static char * not_pixmap[] = { "32 32 3 1", " c black", ". c None", "X c white", " ...............................", " .............................", " ...........................", " X ..........................", " XXX ........................", " XXXX ......................", " XXXXXX ....................", " XXXXXXXX ...................", " XXXXXXXXXX .................", " XXXXXXXXXXX ...............", " XXXXXXXXXXXXX ..............", " XXXXXXXXXXXXXXX ............", " XXXXXXXXXXXXXXXX ..... ..", " XXXXXXXXXXXXXXXXXX .. XXX .", " XXXXXXXXXXXXXXXXXXXX XXXXX ", " XXXXXXXXXXXXXXXXXXXXXX XXXXX ", " XXXXXXXXXXXXXXXXXXXX XXXXX ", " XXXXXXXXXXXXXXXXXXX .. XXX .", " XXXXXXXXXXXXXXXXX ..... ..", " XXXXXXXXXXXXXXX ...........", " XXXXXXXXXXXXXX .............", " XXXXXXXXXXXX ...............", " XXXXXXXXXXX ................", " XXXXXXXXX ..................", " XXXXXXX ...................", " XXXXXX .....................", " XXXX .......................", " XXX ........................", " X ..........................", " ...........................", " .............................", " ..............................."}; #include #endif #include #include #include #include "logic.h" #include "../src/packages.h" #include "../src/gpsim_interface.h" #include "../src/attributes.h" //-------------------------------------------------------------- // Led_Input // This class is a minor extension of a normal IO_input. I may // remove it later, but for now it does serve a simple purpose. // Specifically, this derivation will intercept when a stimulus // is being changed. void Logic_Input::setDrivenState( bool new_state) { if(0) cout << name()<< " setDrivenState= " << (new_state ? "high" : "low") << endl; if(new_state != getDrivenState()) { bDrivingState = new_state; bDrivenState = new_state; if(LGParent) { LGParent->update_input_pin(m_iobit, new_state); LGParent->update_state(); } } } /************************************************************* * * LogicGate class */ LogicGate::LogicGate(void) { #ifdef HAVE_GUI pixmap=0; #endif } LogicGate::~LogicGate(void) { } //-------------------------------------------------------------- void LogicGate::update_input_pin(unsigned int pin, bool bValue) { unsigned int mask = 1<update_direction(1,true); // make the bidirectional an output // Position pin on middle right side of package package->set_pin_position(1,2.5); assign_pin(OUTPUT_BITPOSITION + 1, pOutputPin); Logic_Input *LIP; int j; pInputPins = (IOPIN **) new char[sizeof (IOPIN *) * (number_of_pins-1)]; string inname; for(i=j=INPUT_FIRST_BITPOSITION; iset_pin_position(i+1, 0.5); // Left side of package else package->set_pin_position(i+1, (float)((i-INPUT_FIRST_BITPOSITION)*0.9999)); // Left side of package assign_pin(i+1, LIP ); // Pin numbers begin at 1 } // Form the logic gate bit masks input_bit_mask = (1<< (number_of_pins-1)) - 1; initializeAttributes(); } #ifdef HAVE_GUI static gboolean expose(GtkWidget *widget, GdkEventExpose *event, LogicGate *lg) { if(lg->pixmap==0) { puts("LogicGate has no pixmap"); return 0; } gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], lg->pixmap, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); return 0; } GtkWidget *LogicGate::create_pixmap(char **pixmap_data) { GtkStyle *style; GdkBitmap *mask; GtkWidget *da; int width,height; style = gtk_style_new(); pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL, gdk_colormap_get_system(), &mask, &style->bg[GTK_STATE_NORMAL], pixmap_data); #if GTK_MAJOR_VERSION >= 2 gdk_drawable_get_size(pixmap,&width,&height); #else gdk_window_get_size(pixmap,&width,&height); #endif da = gtk_drawing_area_new(); gtk_drawing_area_size(GTK_DRAWING_AREA(da),width,height); gtk_signal_connect(GTK_OBJECT(da),"expose_event", (GtkSignalFunc) expose,this); return da; } #endif //-------------------------------------------------------------- // construct Module * AND2Gate::construct(const char *_new_name) { AND2Gate *a2gP = new AND2Gate ; a2gP->new_name(_new_name); a2gP->set_number_of_pins(3); a2gP->create_iopin_map(); return a2gP; } AND2Gate::AND2Gate(void) { #ifdef HAVE_GUI if(get_interface().bUsingGUI()) set_widget(create_pixmap(and2_pixmap)); #endif } AND2Gate::~AND2Gate(void) { } void ANDGate::update_state(void) { pOutputPin->putState((input_state & input_bit_mask) == input_bit_mask); if (pOutputPin->snode) pOutputPin->snode->update(); } //-------------------------------------------------------------- // construct OR2Gate::OR2Gate(void) { #ifdef HAVE_GUI if(get_interface().bUsingGUI()) set_widget(create_pixmap(or2_pixmap)); #endif } OR2Gate::~OR2Gate(void) { } Module * OR2Gate::construct(const char *_new_name) { OR2Gate *o2gP = new OR2Gate ; o2gP->new_name(_new_name); o2gP->set_number_of_pins(3); o2gP->create_iopin_map(); return o2gP; } void ORGate::update_state(void) { pOutputPin->putState((input_state & input_bit_mask) != 0); } //-------------------------------------------------------------- // construct NOT Module * NOTGate::construct(const char *_new_name) { NOTGate *a2gP = new NOTGate ; a2gP->new_name(_new_name); a2gP->set_number_of_pins(2); a2gP->create_iopin_map(); return a2gP; } NOTGate::NOTGate(void) { #ifdef HAVE_GUI if(get_interface().bUsingGUI()) set_widget(create_pixmap(not_pixmap)); #endif } NOTGate::~NOTGate(void) { } void NOTGate::update_state(void) { pOutputPin->putState((input_state & input_bit_mask) == 0); } //-------------------------------------------------------------- // construct XOR2Gate::XOR2Gate(void) { #ifdef HAVE_GUI if(get_interface().bUsingGUI()) set_widget(create_pixmap(xor2_pixmap)); #endif } XOR2Gate::~XOR2Gate(void) { } Module * XOR2Gate::construct(const char *_new_name) { XOR2Gate *o2gP = new XOR2Gate ; o2gP->new_name(_new_name); o2gP->set_number_of_pins(3); o2gP->create_iopin_map(); return o2gP; } void XORGate::update_state(void) { bool bNewOutputState=false; unsigned int mask=input_bit_mask; while(mask) { unsigned int lsb = (~mask + 1) & mask; mask ^= lsb; bNewOutputState ^= (lsb & input_state) ? true : false; } pOutputPin->putState(bNewOutputState); }