Пример #1
0
 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
Пример #2
0
 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
Пример #3
0
 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
Пример #4
0
 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")
Пример #5
0
 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
Пример #6
0
 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")
Пример #7
0
 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()
Пример #8
0
    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
Пример #9
0
 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")
Пример #10
0
 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
Пример #11
0
 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
Пример #12
0
    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
Пример #13
0
 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")
Пример #14
0
 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
Пример #15
0
    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]))