bones_machine.py 4.29 KB
#!/usr/bin/env python

import sys, os, time

# if len(sys.argv) == 1 :
#     rom = [line.strip() for line in sys.stdin]
# elif sys.argv[1] == "--fork" :
#     if os.fork() != 0 :
#         os._exit(0)
#     rom = [line.strip() for line in sys.stdin]
# elif sys.argv[1] == "--tmpfile" :
#     rom = [line.strip() for line in open(sys.argv[2])]
#     os.remove(sys.argv[2])
# else :
#     sys.stderr.write("bones: invalid command line\n")
#     sys.exit(1)

import warnings
import gtk, gobject
import bones.gui.control, bones.view.machine, bones.machine
from bones.view.events import EventError, NoMoreEvent

class Bones :
    def __init__ (self, rom) :
        self.rom = rom
        self.gui = bones.gui.control.BonesWindow(self.rom)
        self.view = bones.view.machine.MachineView(self.gui)
        self.machine = bones.machine.Machine(self.view, self.rom)
        self.gui.main.irq.assign("0", "boot")
        self.gui.main.irq.assign("1", "device error")
        self.gui.main.irq.assign("2", "clock")
        self.gui.cpu.control.reset.connect("clicked", self.reset)
        self.gui.cpu.control.clock.connect("clicked", self.clock)
        self.gui.control.next.connect("clicked", self.next)
        self.gui.control.cycle.connect("clicked", self.cycle)
        self._can_do = False
        self._autorun = False
        self._id = None
        gobject.timeout_add(100, self.update)
        self.gui.control.run.connect("clicked", self.start_run)
        self.gui.control.stop.connect("clicked", self.stop_run)
    def reset (self, *args) :
        self.gui.cpu.control.reset.set_sensitive(gtk.FALSE)
        self.machine.cpu.reset()
    def clock (self, *args) :
        self.machine.cpu.clock()
    def control_set_sensitive (self, sensitive=gtk.TRUE) :
        for button in [self.gui.control.next,
                       self.gui.control.cycle,
                       self.gui.control.run] :
            button.set_sensitive(sensitive)
    def update (self, *args) :
        time.sleep(0.01)
        if self.view is None :
            return gtk.FALSE
        elif self.view.queue.can_do() and not self._autorun :
            self.control_set_sensitive(gtk.TRUE)
        else :
            self.control_set_sensitive(gtk.FALSE)
        return gtk.TRUE
    def start_run (self, *args) :
        self._autorun = True
        self.control_set_sensitive(gtk.FALSE)
        self.gui.control.stop.set_sensitive(gtk.TRUE)
        self.gui.control.run.set_sensitive(gtk.FALSE)
        self.do_run()
    def _remove_id (self) :
        try :
            gobject.source_remove(self._id)
        except :
            pass
    def do_run (self, *args) :
        if self.gui is None :
            return gtk.FALSE
        try :
            self.do()
            speed = (101 - int(self.gui.control.speed.get_value())) * 10
            self._id = gobject.timeout_add(speed, self.do_run)
        except NoMoreEvent :
            self._remove_id()
        return gtk.FALSE
    def stop_run (self, *args) :
        self._autorun = False
        self.gui.control.stop.set_sensitive(gtk.FALSE)
        self.gui.control.run.set_sensitive(gtk.TRUE)
        self._remove_id()
        self.update()
    def do (self, cycle=False) :
        while self.view is not None :
            try :
                if cycle == self.view.queue.do(self.gui.cursor) :
                    break
            except EventError :
                time.sleep(0.01)
            except NoMoreEvent :
                self.gui.main.set_sensitive(gtk.FALSE)
                self.gui.control.disable()
                if self._autorun :
                    raise
                else :
                    return
    def next (self, *args) :
        self.do()
        self.update()
    def cycle (self, *args) :
        self.gui.cursor.wait()
        self.do(cycle=True)
        self.gui.cursor.normal()
        self.update()
    def start (self) :
        self.machine.start()
        self.gui.show_all()
        self.update()
        self.gui.run(self)
    def quit (self) :
        self.machine.quit()
        try :
            self.gui.destroy()
        except :
            pass
        self.gui = self.view = None

if __name__ == "__main__" :
    warnings.filterwarnings("ignore", category=DeprecationWarning)
    bones = Bones(rom)
    bones.view.queue.debug = True
    print "=" * 29, "starting", "=" * 29
    bones.start()