class CoreRopeSim(QFrame): def __init__(self, parent, usbif): super().__init__(parent) self._usbif = usbif self._bank_switches = [] self._updating_switches = False self._setup_ui() self._rope_loader = MemoryLoad(usbif, um.WriteSimFixed, 0o100, 1024, self._bank_switches, self._aux_switch) self._rope_loader.finished.connect(self._load_complete) self._rope_dumper = MemoryDump(usbif, um.ReadFixed, um.Fixed, 0o100, 1024, self._bank_switches, self._aux_switch) self._rope_loader.finished.connect(self._dump_complete) def _setup_ui(self): self.setFrameStyle(QFrame.StyledPanel | QFrame.Raised) # Set up our basic layout layout = QGridLayout(self) self.setLayout(layout) layout.setSpacing(1) layout.setMargin(1) for bank in range(0o44): col = bank % 18 row = int(bank / 18) * 2 sw = self._create_bank_switch('%o' % bank, layout, row, col, 1) sw.stateChanged.connect( lambda state, bank=bank: self._update_crs_bank(bank)) self._bank_switches.append(sw) self._aux_switch = self._create_bank_switch('44-77', layout, 5, 0, 2) label = QLabel('CRS', self) font = label.font() font.setPointSize(12) font.setBold(True) label.setFont(font) label.setAlignment(Qt.AlignCenter) layout.addWidget(label, 5, 16, 2, 2, Qt.AlignCenter) b = self._create_button('ALL', layout, 5, 1, 3) b.pressed.connect(lambda: self._set_all(True)) b = self._create_button('NONE', layout, 5, 3, 2) b.pressed.connect(lambda: self._set_all(False)) self._crs_sel = QRadioButton('CRS', self) self._crs_sel.setLayoutDirection(Qt.RightToLeft) layout.addWidget(self._crs_sel, 5, 6, 2, 3) layout.setAlignment(self._crs_sel, Qt.AlignRight) self._agc_sel = QRadioButton('AGC', self) self._agc_sel.setChecked(True) layout.addWidget(self._agc_sel, 5, 8, 2, 3) layout.setAlignment(self._agc_sel, Qt.AlignCenter) font.setPointSize(7) self._crs_sel.setFont(font) self._agc_sel.setFont(font) b = self._create_button('LOAD', layout, 5, 12, 3) b.pressed.connect(self._load_rope) b = self._create_button('DUMP', layout, 5, 14, 2) b.pressed.connect(self._dump_rope) def _update_crs_bank(self, bank): if self._updating_switches: return group = int(bank / 16) first_bank = group * 16 enables = [False] * 16 for i in range(16): bank = first_bank + i if bank < 0o44: sw = self._bank_switches[bank] else: sw = self._aux_switch enables[i] = sw.isChecked() write_crs_enables = getattr(um, 'WriteControlCRSBankEnable%u' % group) self._usbif.send(write_crs_enables(*enables)) def _update_all_banks(self): for bank in [0, 0o20, 0o40, 0o60]: self._update_crs_bank(bank) def _set_all(self, state): self._updating_switches = True for sw in self._bank_switches: sw.setChecked(state) self._updating_switches = False self._update_all_banks() def _create_button(self, name, layout, row, col, width): label = QLabel(name, self) label.setAlignment(Qt.AlignCenter) font = label.font() font.setPointSize(7) font.setBold(True) label.setFont(font) label.setMinimumWidth(30) layout.addWidget(label, row, col, 1, width) layout.setAlignment(label, Qt.AlignCenter) b = QPushButton(self) b.setFixedSize(20, 20) layout.addWidget(b, row + 1, col, 1, width) layout.setAlignment(b, Qt.AlignCenter) return b def _create_bank_switch(self, name, layout, row, col, width): label = QLabel(name, self) label.setAlignment(Qt.AlignBottom | (Qt.AlignLeft if width == 2 else Qt.AlignCenter)) font = label.font() font.setPointSize(7) font.setBold(True) label.setFont(font) layout.addWidget(label, row, col, 1, width) check = QCheckBox(self) check.setFixedSize(20, 20) check.setStyleSheet( 'QCheckBox::indicator{subcontrol-position:center;}') layout.addWidget(check, row + 1, col, 1, 1) layout.setAlignment(check, Qt.AlignCenter) return check def _load_rope(self): filename, group = QFileDialog.getOpenFileName(self, 'Load AGC Rope', 'roms', 'AGC ROMs (*.bin)') if group == '': return self._updating_switches = True self._rope_loader.load_memory(filename) def _load_complete(self): self._updating_switches = False def _dump_complete(self): self._updating_switches = False self._update_all_banks() def _dump_rope(self): filename, group = QFileDialog.getSaveFileName(self, 'Save AGC Rope', 'roms', 'AGC ROMs (*.bin)') if group == '': return self._updating_switches = True if self._agc_sel.isChecked(): z = [False] * 16 for m in [ um.WriteControlCRSBankEnable0, um.WriteControlCRSBankEnable1, um.WriteControlCRSBankEnable2, um.WriteControlCRSBankEnable3 ]: self._usbif.send(m(*z)) self._rope_dumper.dump_memory(filename)
class WriteW(QWidget): def __init__(self, parent, usbif): super().__init__(parent) self._usbif = usbif self._time_switches = {} self._pulse_switches = {} self._mode = WRITE_W_POSITIONS['ALL'] self._setup_ui() usbif.send(um.WriteControlWriteW(mode=um.WriteWMode.ALL, s1_s2=0)) z = (0, ) * len(TIME_SWITCHES) usbif.send(um.WriteControlTimeSwitches(*z)) z = (0, ) * len(PULSE_SWITCHES) usbif.send(um.WriteControlPulseSwitches(*z)) def _update_mode(self, mode): self._mode = mode self._send_mode(self._s2.isChecked()) def _send_mode(self, s1_s2): self._usbif.send(um.WriteControlWriteW(mode=self._mode, s1_s2=s1_s2)) def _send_times(self, state): time_states = { s: self._time_switches[s].isChecked() for s in self._time_switches.keys() } self._usbif.send(um.WriteControlTimeSwitches(**time_states)) def _send_pulses(self, state): pulse_states = { s: self._pulse_switches[s].isChecked() for s in self._pulse_switches.keys() } self._usbif.send(um.WriteControlPulseSwitches(**pulse_states)) def _setup_ui(self): layout = QVBoxLayout(self) self.setLayout(layout) layout.setMargin(1) layout.setSpacing(1) s1_s2 = QWidget(self) s1_s2_layout = QHBoxLayout(s1_s2) s1_s2.setLayout(s1_s2_layout) s1_s2_layout.setMargin(1) s1_s2_layout.setSpacing(0) self._s1 = QRadioButton('S1', s1_s2) font = self._s1.font() font.setPointSize(7) font.setBold(True) self._s1.setFont(font) self._s1.setLayoutDirection(Qt.RightToLeft) self._s1.setChecked(True) self._s2 = QRadioButton('S2', s1_s2) self._s2.setFont(font) self._s2.toggled.connect(lambda s: self._send_mode(s)) s1_s2_layout.addWidget(self._s1) s1_s2_layout.setAlignment(self._s1, Qt.AlignLeft) s1_s2_layout.addWidget(self._s2) s1_s2_layout.setAlignment(self._s2, Qt.AlignLeft) layout.addWidget(s1_s2) layout.setAlignment(s1_s2, Qt.AlignRight) write_w_box = QGroupBox('WRITE W', self) write_w_layout = QGridLayout(write_w_box) write_w_box.setLayout(write_w_layout) write_w_layout.setMargin(1) write_w_layout.setSpacing(1) row = 0 col = 0 for label, mode in WRITE_W_POSITIONS.items(): pos = QRadioButton(label, write_w_box) pos.setFont(font) if label == 'ALL': pos.setChecked(True) pos.pressed.connect(lambda m=mode: self._update_mode(m)) write_w_layout.addWidget(pos, row, col) col += 1 if row == 0 or col >= 3: col = 0 row += 1 layout.addWidget(write_w_box) switch_frame = QFrame(self) switch_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised) switch_layout = QGridLayout(switch_frame) switch_layout.setMargin(1) switch_layout.setSpacing(1) switch_frame.setLayout(switch_layout) layout.addWidget(switch_frame) row = self._add_switches(switch_frame, switch_layout, TIME_SWITCHES, self._time_switches, self._send_times, row) sep = QFrame(switch_frame) sep.setFrameStyle(QFrame.HLine | QFrame.Raised) switch_layout.addWidget(sep, row, 0, 1, 6) row += 1 self._add_switches(switch_frame, switch_layout, PULSE_SWITCHES, self._pulse_switches, self._send_pulses, row) def _add_switches(self, switch_frame, switch_layout, switches, switch_dict, switch_fn, row): col = 0 for v, l in switches.items(): check = QCheckBox(switch_frame) check.setFixedSize(20, 20) check.setStyleSheet( 'QCheckBox::indicator{subcontrol-position:center;}') check.stateChanged.connect(switch_fn) switch_dict[v] = check switch_layout.addWidget(check, row, col) switch_layout.setAlignment(check, Qt.AlignCenter) label = QLabel(l, switch_frame) font = label.font() font.setPointSize(7) font.setBold(True) label.setFont(font) switch_layout.addWidget(label, row + 1, col) switch_layout.setAlignment(label, Qt.AlignCenter) col += 1 if col >= 6: col = 0 row += 2 return row
class ErasableMemSim(QFrame): def __init__(self, parent, usbif): super().__init__(parent) self._usbif = usbif self._bank_switches = [] self._updating_switches = False self._setup_ui() self._core_loader = MemoryLoad(usbif, um.WriteSimErasable, 0o10, 256, self._bank_switches, None) self._core_loader.finished.connect(self._load_complete) self._core_dumper = MemoryDump(usbif, um.ReadErasable, um.Erasable, 0o10, 256, self._bank_switches, None) self._core_loader.finished.connect(self._dump_complete) def _setup_ui(self): self.setFrameStyle(QFrame.StyledPanel | QFrame.Raised) # Set up our basic layout layout = QGridLayout(self) self.setLayout(layout) layout.setSpacing(1) layout.setMargin(1) for bank in range(0o10): sw = self._create_bank_switch('E%o' % bank, layout, 0, bank, 1) sw.stateChanged.connect(self._update_ems_banks) self._bank_switches.append(sw) for col in range(0o10, 0o22): s = QSpacerItem(20, 20) layout.addItem(s, 1, col) label = QLabel('EMS', self) font = label.font() font.setPointSize(12) font.setBold(True) label.setFont(font) label.setAlignment(Qt.AlignCenter) layout.addWidget(label, 5, 16, 2, 2, Qt.AlignCenter) b = self._create_button('ALL', layout, 5, 1, 3) b.pressed.connect(lambda: self._set_all(True)) b = self._create_button('NONE', layout, 5, 3, 2) b.pressed.connect(lambda: self._set_all(False)) self._ems_sel = QRadioButton('EMS', self) self._ems_sel.setLayoutDirection(Qt.RightToLeft) layout.addWidget(self._ems_sel, 5, 6, 2, 3) layout.setAlignment(self._ems_sel, Qt.AlignRight) self._agc_sel = QRadioButton('AGC', self) self._agc_sel.setChecked(True) layout.addWidget(self._agc_sel, 5, 8, 2, 3) layout.setAlignment(self._agc_sel, Qt.AlignCenter) font.setPointSize(7) self._ems_sel.setFont(font) self._agc_sel.setFont(font) b = self._create_button('PAD', layout, 5, 11, 2) b.pressed.connect(self._load_pad) b = self._create_button('LOAD', layout, 5, 12, 3) b.pressed.connect(self._load_core) b = self._create_button('DUMP', layout, 5, 14, 2) b.pressed.connect(self._dump_core) def _update_ems_banks(self): if self._updating_switches: return enables = [False] * 8 for i, sw in enumerate(self._bank_switches): enables[i] = sw.isChecked() self._usbif.send(um.WriteControlEMSBankEnable(*enables)) def _set_all(self, state): self._updating_switches = True for sw in self._bank_switches: sw.setChecked(state) self._updating_switches = False self._update_ems_banks() def _create_button(self, name, layout, row, col, width): label = QLabel(name, self) label.setAlignment(Qt.AlignCenter) font = label.font() font.setPointSize(7) font.setBold(True) label.setFont(font) label.setMinimumWidth(30) layout.addWidget(label, row, col, 1, width) layout.setAlignment(label, Qt.AlignCenter) b = QPushButton(self) b.setFixedSize(20, 20) layout.addWidget(b, row + 1, col, 1, width) layout.setAlignment(b, Qt.AlignCenter) return b def _create_bank_switch(self, name, layout, row, col, width): label = QLabel(name, self) label.setAlignment(Qt.AlignBottom | (Qt.AlignLeft if width == 2 else Qt.AlignCenter)) font = label.font() font.setPointSize(7) font.setBold(True) label.setFont(font) layout.addWidget(label, row, col, 1, width) check = QCheckBox(self) check.setFixedSize(20, 20) check.setStyleSheet( 'QCheckBox::indicator{subcontrol-position:center;}') layout.addWidget(check, row + 1, col, 1, 1) layout.setAlignment(check, Qt.AlignCenter) return check def _load_pad(self): filename, group = QFileDialog.getOpenFileName( self, 'Load AGC Pad Load', 'pads', 'AGC Pad Load Files (*.pad)') if group == '': return load_data = [] with open(filename, 'r') as f: for l in f.readlines(): parts = l.split() addr_idx = 0 if len(parts) == 3: if parts[0] in ('CMPAD', 'LMPAD'): addr_idx = 1 else: raise RuntimeError('Invalid pad load line "%s"' % l) elif len(parts) != 2: raise RuntimeError('Invalid pad load line "%s"' % l) addr = int(parts[addr_idx], 8) val = int(parts[addr_idx + 1], 8) load_data.append((addr, val)) msg_type = um.WriteErasable if self._agc_sel.isChecked( ) else um.WriteSimErasable for addr, val in load_data: print('%04o %o' % (addr, val)) self._usbif.send(msg_type(addr=addr, data=val, parity=0)) def _load_core(self): filename, group = QFileDialog.getOpenFileName( self, 'Load AGC Core File', 'cores', 'AGC Core Files (*.bin)') if group == '': return self._updating_switches = True self._core_loader.load_memory( filename, um.WriteErasable if self._agc_sel.isChecked() else um.WriteSimErasable) def _load_complete(self): self._updating_switches = False def _dump_complete(self): self._updating_switches = False self._update_ems_banks() def _dump_core(self): filename, group = QFileDialog.getSaveFileName( self, 'Save AGC Core Dump', 'cores', 'AGC Core Files (*.bin)') if group == '': return self._updating_switches = True if self._agc_sel.isChecked(): z = [False] * 8 self._usbif.send(um.WriteControlEMSBankEnable(*z)) self._core_dumper.dump_memory(filename)
class CompStop(QFrame): def __init__(self, parent, usbif): super().__init__(parent) self._usbif = usbif self._stop_switches = {} self._stop_inds = {} self._setup_ui() usbif.poll(um.ReadControlStopCause()) usbif.listen(self) z = (0, ) * (len(STOP_CONDS) + 1) usbif.send(um.WriteControlStop(*z)) def handle_msg(self, msg): if isinstance(msg, um.ControlStopCause): for v in STOP_CONDS.values(): self._stop_inds[v].set_on(getattr(msg, v)) def _set_stop_conds(self, on): settings = { s: self._stop_switches[s].isChecked() for s in STOP_CONDS.values() } settings['s1_s2'] = self._s2.isChecked() self._usbif.send(um.WriteControlStop(**settings)) def _setup_ui(self): self.setFrameStyle(QFrame.StyledPanel | QFrame.Raised) layout = QGridLayout(self) self.setLayout(layout) layout.setMargin(1) layout.setSpacing(1) # Construct the stop indicators and switches col = 0 for l, n in STOP_CONDS.items(): self._create_stop_cond(l, n, layout, col) col += 1 label = QLabel('COMP STOP', self) font = label.font() font.setPointSize(12) font.setBold(True) label.setFont(font) label.setAlignment(Qt.AlignCenter) layout.addWidget(label, 3, 0, 1, 4, Qt.AlignRight) self._s1 = QRadioButton('S1', self) self._s1.setLayoutDirection(Qt.RightToLeft) layout.addWidget(self._s1, 3, 5, 1, 2) layout.setAlignment(self._s1, Qt.AlignRight) self._s1.setChecked(True) self._s1.toggled.connect(self._set_stop_conds) self._s2 = QRadioButton('S2', self) layout.addWidget(self._s2, 3, 6, 1, 2) layout.setAlignment(self._s2, Qt.AlignRight) font.setPointSize(7) self._s1.setFont(font) self._s2.setFont(font) def _create_stop_cond(self, label_text, name, layout, col): # Create an indicator to show stop status ind = Indicator(self, QColor(255, 0, 0)) ind.setFixedSize(25, 20) layout.addWidget(ind, 0, col) layout.setAlignment(ind, Qt.AlignCenter) self._stop_inds[name] = ind # Add a switch to control the stop control state check = QCheckBox(self) check.setFixedSize(20, 20) check.setStyleSheet( 'QCheckBox::indicator{subcontrol-position:center;}') layout.addWidget(check, 1, col) layout.setAlignment(check, Qt.AlignCenter) check.stateChanged.connect(self._set_stop_conds) self._stop_switches[name] = check # Create a label for the inhibit switch label = QLabel(label_text, self) label.setAlignment(Qt.AlignCenter) font = label.font() font.setPointSize(7) font.setBold(True) label.setFont(font) label_height = 2 if '\n' in label_text else 1 layout.addWidget(label, 2, col, label_height, 1) layout.setAlignment(label, Qt.AlignCenter | Qt.AlignTop)