def parse_EQUALS(self, context, operands): if operands != None: expr = AddressExpression(context, operands) if expr.complete: if not context.reparse and context.passnum == 0: context.symtab.add(context.currentRecord.label, operands, expr.value, self.numwords, self.type) else: context.symtab.update(context.currentRecord.label, operands, expr.value, self.numwords, self.type) context.currentRecord.target = expr.value context.currentRecord.operandType = expr.refType context.currentRecord.complete = True else: if not context.reparse and context.passnum == 0: context.symtab.add(context.currentRecord.label, operands, None, self.numwords, self.type) else: if not context.reparse and context.passnum == 0: context.symtab.add(context.currentRecord.label, None, context.loc, self.numwords, self.type) else: context.symtab.update(context.currentRecord.label, None, context.loc, self.numwords, self.type) context.currentRecord.target = context.loc context.currentRecord.complete = True context.addSymbol = False
def parse_CHECKEquals(self, context, operands): if context.currentRecord.label != None: lhs = AddressExpression(context, [context.currentRecord.label]) rhs = AddressExpression(context, operands) if lhs.complete and rhs.complete: lpa = lhs.value rpa = rhs.value if lpa != rpa: context.error( "CHECK= test failed, \"%s\" (%06o) != \"%s\" (%06o)" % (context.currentRecord.label, lpa, ' '.join(operands), rpa)) context.currentRecord.target = lpa context.currentRecord.operandType = lhs.refType context.currentRecord.complete = True else: context.syntax("CHECK= directive must have a label") context.addSymbol = False
def parse_GENADR(self, context, operands): bank = None expr = AddressExpression(context, operands) if expr.complete: pa = expr.value bank = context.memmap.pseudoToBank(pa) if bank != None: context.currentRecord.code = [ context.memmap.pseudoToAddress(pa) ] context.currentRecord.operandType = expr.refType context.currentRecord.complete = True
def parse_ECADR(self, context, operands): pa = None expr = AddressExpression(context, operands) if expr.complete: pa = expr.value context.log( 3, "ECADR %s" % context.memmap.pseudoToSegmentedString(pa)) if context.memmap.isErasable(pa): context.currentRecord.code = [pa] context.currentRecord.operandType = expr.refType context.currentRecord.complete = True else: context.error("operand must be in erasable memory")
def parse_SETLOC(self, context, operands): expr = AddressExpression(context, operands) context.log(3, "SETLOC: \"%s\" (%06o)" % (operands, expr.value)) if expr.complete: pa = expr.value context.currentRecord.target = pa bank = context.memmap.pseudoToBank(pa) context.log(3, "SETLOC: bank=%02o" % bank) if context.memmap.isErasable(pa): context.switchEBank(bank) else: context.switchFBank(bank) context.setLoc(pa) context.currentRecord.operandType = expr.refType context.currentRecord.complete = True
def parse_FCADR(self, context, operands): pa = None expr = AddressExpression(context, operands) if expr.complete: pa = expr.value if context.memmap.isFixed(pa): (bank, offset) = context.memmap.pseudoToBankOffset(pa) if bank >= 040: bank -= 010 word = ((bank) << 10) | offset context.currentRecord.code = [word] context.currentRecord.target = pa context.currentRecord.operandType = expr.refType context.currentRecord.complete = True else: context.error("FCADR operand must be in fixed memory")
def parse_EBANKEquals(self, context, operands): pa = None expr = AddressExpression(context, operands) if expr.complete: pa = expr.value if context.memmap.isErasable(pa): context.log( 3, "EBANK= %s" % context.memmap.pseudoToSegmentedString(pa)) context.switchEBankPA(pa) context.currentRecord.target = pa context.currentRecord.operandType = expr.refType context.currentRecord.complete = True else: context.error("operand must be in erasable memory") context.currentRecord.update()
def parse(self, context, operands): if self.operandType == RecordType.NONE: if operands != None: context.error("instruction takes no operand") else: if operands == None: if not self.operandOptional: # FIXME: Remove this? if self.mnemonic == "MM" or self.mnemonic == "VN": # HACK: VN and MM are also used as labels in interpretive code. expr = AddressExpression(context, [self.mnemonic]) if expr.complete: context.currentRecord.code = [expr.value] context.currentRecord.complete = True context.incrLoc(self.numwords) return else: context.error("missing operand") try: method = self.__getattribute__("parse_" + self.methodName) except: method = None if method: method(context, operands) context.currentRecord.type = self.type context.incrLoc(self.numwords) if context.currentRecord.complete: if context.currentRecord.code: if len(context.currentRecord.code) == 1: context.log( 5, "directive: generated code %05o" % (context.currentRecord.code[0])) else: context.log( 5, "directive: generated code %05o %05o" % (context.currentRecord.code[0], context.currentRecord.code[1])) if self.numwords > 0 and context.interpArgs > 0: context.log( 5, "directive: incrementing interpArgCount: %d -> %d" % (context.interpArgCount, context.interpArgCount + 1)) context.interpArgCount += 1
def parse_SBANKEquals(self, context, operands): pa = None expr = AddressExpression(context, operands) if expr.complete: pa = expr.value if context.memmap.isFixed(pa): context.currentRecord.target = pa context.currentRecord.operandType = expr.refType context.currentRecord.complete = True bank = context.memmap.pseudoToBank(pa) if bank <= 037: context.super = 0 context.log(3, "SBANK=: setting superbit to 0") else: context.super = 1 context.log(3, "SBANK=: setting superbit to 1") else: context.error("operand must be in fixed memory")
def parse_EqualsMINUS(self, context, operands): expr = AddressExpression(context, operands) if expr.complete: # =MINUS is equivalent to EQUALS symbol - loc. It is used to generate the number of elements in a table. expr.value -= context.loc if not context.reparse and context.passnum == 0: context.symtab.add(context.currentRecord.label, operands, expr.value, self.numwords, self.type) else: context.symtab.update(context.currentRecord.label, operands, expr.value, self.numwords, self.type) context.currentRecord.target = expr.value context.currentRecord.operandType = expr.refType context.currentRecord.complete = True else: if not context.reparse and context.passnum == 0: context.symtab.add(context.currentRecord.label, operands, None, self.numwords, self.type) context.addSymbol = False
def parse_DNPTR(self, context, operands): expr = AddressExpression(context, operands) if expr.complete: pa = expr.value (bank, offset) = context.memmap.pseudoToSegmented(pa) if bank == None or offset == None: context.error("invalid address %06o" % pa) else: if (context.passnum > 0 and context.memmap.isSwitched(pa) and bank != context.fbank and bank != context.ebank): context.error( "bank (%02o) does not match current FB (%02o) or EB (%02o)" % (bank, context.fbank, context.ebank)) else: context.currentRecord.code = [ 030000 + context.memmap.pseudoToAddress(pa) ] context.currentRecord.target = pa context.currentRecord.operandType = expr.refType context.currentRecord.complete = True
def parse_BBCON(self, context, operands): bank = None expr = AddressExpression(context, operands) if expr.complete: if not context.memmap.isFixed(expr.value): context.error("BBCON operand must be in fixed memory") bank = context.memmap.getBankNumber(expr.value) bbval = 0 # Bits 14:10 of the generated word contain the bank number. Bit 15 is always zero. context.log( 3, "BBCON: bank=%o super=%d ebank=%o" % (bank, context.super, context.ebank)) if bank >= 040: bbval |= ((bank - 010) << 10) else: bbval |= (bank << 10) # Bits 9:7 are zero. # Bits 6:4: # FB < 030, SB=0: 011 # FB < 030, SB=1: 100 # 030 <= FB <= 037: 011 # FB > 037: 100 if bank < 030: if context.super == 1: bbval |= 0100 else: bbval |= 0060 elif 030 <= bank <= 037: bbval |= 0060 elif bank > 037: bbval |= 0100 # Bit 3 is zero. # Bits 2:0 equals the current EBANK= code. bbval |= (context.ebank & 07) context.currentRecord.code = [bbval] context.currentRecord.target = expr.value context.currentRecord.operandType = expr.refType context.currentRecord.complete = True
def parse_DNADR(self, context, operands): pa = None if self.mnemonic.startswith('-'): opnum = int(self.mnemonic[1]) else: opnum = int(self.mnemonic[0]) dnadrConstants = { 1: 000000, 2: 004000, 3: 010000, 4: 014000, 5: 020000, 6: 024000 } expr = AddressExpression(context, operands) if expr.complete: pa = expr.value if context.memmap.isErasable(pa): context.currentRecord.code = [pa + dnadrConstants[opnum]] context.currentRecord.operandType = expr.refType context.currentRecord.complete = True else: context.error("operand must be in erasable memory")
def parse_2CADR(self, context, operands): word1 = word2 = None expr = AddressExpression(context, operands) if expr.complete: pa = expr.value word1 = context.memmap.pseudoToAddress(pa) if context.memmap.isFixed(pa): bank = context.memmap.getBankNumber(pa) word2 = 0 # Bits 14:10 of the generated word contain the bank number. if bank >= 040: word2 |= ((bank - 010) << 10) else: word2 |= (bank << 10) # Bits 6:4: # FB < 030, SB=0: 011 # FB < 030, SB=1: 100 # 030 <= FB <= 037: 011 # FB > 037: 100 if bank < 030: if context.super == 1: word2 |= 0100 else: word2 |= 0060 elif 030 <= bank <= 037: word2 |= 0060 elif bank > 037: word2 |= 0100 # Bit 3 is zero. # Bits 2:0 equals the current EBANK= code. word2 |= (context.ebank & 07) else: word2 = context.memmap.getBankNumber(pa) context.currentRecord.code = [word1, word2] context.currentRecord.target = expr.value context.currentRecord.operandType = expr.refType context.currentRecord.complete = True
def parse(self, context, operands): if context.mode == OpcodeType.EXTENDED and self.mnemonic not in context.opcodes[ OpcodeType.EXTENDED]: context.error("missing EXTEND before extended instruction") return if self.operandType == OperandType.NONE: if operands != None: context.error("instruction takes no operand") else: context.currentRecord.code = [self.opcode] context.currentRecord.operandType = RecordType.NONE context.currentRecord.complete = True else: if operands == None: if self.operandOptional: context.currentRecord.code = [self.opcode] context.currentRecord.operandType = RecordType.NONE context.currentRecord.complete = True else: context.error("missing operand") else: if operands: expr = AddressExpression(context, operands) if expr.complete: pa = expr.value if pa < 0: # Negative, relative address. if self.mnemonic == "TC": pa -= 1 context.currentRecord.code = [ (self.opcode + pa) & 077777 ] else: if context.debug: context.currentRecord.target = expr.value address = context.memmap.pseudoToAddress(pa) if self.addressType == AddressType.FIXED_9: if context.memmap.isFixed( expr.value ) or context.previousWasIndex == True: address &= 0777 else: context.error( "Address must be in fixed memory") elif self.addressType == AddressType.FIXED_12: if context.memmap.isFixed( expr.value ) or context.previousWasIndex == True: address &= 07777 else: context.error( "Address must be in fixed memory") elif self.addressType == AddressType.ERASABLE_10: if context.memmap.isErasable( expr.value ) or context.previousWasIndex == True: address &= 01777 else: context.error( "Address must be in erasable memory") elif self.addressType == AddressType.ERASABLE_12: if context.memmap.isErasable( expr.value ) or context.previousWasIndex == True: address &= 07777 else: context.error( "Address must be in erasable memory") elif self.addressType == AddressType.GENERAL_12: address &= 07777 elif self.addressType == AddressType.CHANNEL: address &= 0777 else: context.error("Invalid address type") context.currentRecord.code = [ (self.opcode + address) & 077777 ] context.currentRecord.operandType = expr.refType context.currentRecord.complete = True else: context.error("missing operand") try: method = self.__getattribute__("parse_" + self.methodName) except: method = None if method: method(context, operands) context.currentRecord.type = self.type context.incrLoc(self.numwords) if context.mode == OpcodeType.EXTENDED: if self.mnemonic != "EXTEND" and self.mnemonic != "INDEX": context.mode = OpcodeType.BASIC if self.mnemonic != "INDEX" and context.previousWasIndex: context.previousWasIndex = False if context.currentRecord.complete: if self.numwords == 1: context.log( 5, "generated code %05o" % (context.currentRecord.code[0])) else: context.log( 5, "generated code %05o %05o" % (context.currentRecord.code[0], context.currentRecord.code[1]))