def Conditional(): """ Conditional instructions reg,dest con,dest """ global Asm if MissingOperand(): return val = assem.EvalExpr()[0] if not assem.MoreParameters(): errors.DoError('missoper', False) return dest = assem.EvalExpr()[0] if dec.Asm.Pass == 2: if (val < 0 or val > 15): # Range error errors.DoError('range', False) # !!!! isz on last 2 locations of page causes jump to next page. Strange but # true according to page 3-42 target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1] + (val & 15)) target.CodeByte(dest) dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2] NoMore()
def BitInst(): global Asm if MissingOperand(): return opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1] bitno = assem.EvalExpr()[0] if dec.Asm.Pass == 2 and (bitno > 7 or bitno < 0): assem.DoError('range', False) bitno = bitno & 7 if not assem.MoreParameters(): errors.DoError('missoper', False) return datareg = GetReg() if datareg[0] > 5: assem.DoError('badoper', False) datareg = datareg[1] target.CodeByte(opcode + BitSwap(bitno)) target.CodeByte(datareg) dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2] NoMore()
def Branch(): """ Branching is simply done by copying the second byte of the instruction to PCL. Therefore the destination is always on the same page as the second byte of the branch instruction. """ global Asm if MissingOperand(): return value = assem.EvalExpr()[0] if dec.Asm.Instructions[dec.Asm.Mnemonic][1] > 0xFF: # It's a 2 byte instruction target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1] >> 8) offset = 2 else: offset = 1 if dec.Asm.Pass == 2: # Don't check range in pass 1 as label may be forward referenced page = (dec.Asm.BOL_Address + offset) >> 8 destpage = value >> 8 if page != destpage: # Destination not on the same page errors.DoError('range', False) target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1]) target.CodeByte(value) dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2] NoMore()
def Immediate(): """ Immediate operand. May be prefixed by one of the immediate prefixes. """ global Asm if MissingOperand(): return prefix = '#' if assem.NowChar() in '#/=\\': prefix = assem.NowChar(True) value = assem.EvalExpr()[0] if prefix == '#': val = value & 255 elif prefix == '/': val = (value >> 8) & 255 elif prefix == '=': val = (value >> 16) & 255 else: val = (value >> 24) & 255 if dec.Asm.Instructions[dec.Asm.Mnemonic][1] > 0xFF: # It's a 2 byte instruction target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1] >> 8) target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1]) target.CodeByte(val) dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2] NoMore()
def BranchBit(): """ Handle the bit test branch instructions. """ global Asm if MissingOperand(): # We need operands return dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2] par1 = GetBit() if not assem.MoreParameters(): # Oops only one operand given errors.DoError('missoper', False) return value = assem.EvalExpr() offset = value[0] - dec.Asm.BOL_Address - 3 if dec.Asm.Pass == 2 and (offset < -128 or offset > 127): # Out of range errors.DoError('range', False) target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1]) target.CodeByte(par1) target.CodeByte(offset) NoMore()
def LBranch(): """ Handle long branch instructions. Displacement is destinaiton - current address - 3 in case 3 byte long instruction Displacement is destinaiton - current address - 4 in case 4 byte long instruction """ global Asm if MissingOperand(): return opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1] value = assem.EvalExpr() offset = value[0] - dec.Asm.BOL_Address - 3 if opcode > 255: # It's a 2 byte opcode offset = offset - 1 target.CodeByte(opcode >> 8) target.CodeByte(opcode) target.CodeWord(offset) dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2] NoMore()
def Bits(): """ Handle Bit instructions Both bit set/clr as well as branch bit set/clr instructions are handled by this routine. """ global Asm if MissingOperand(): return bitno = assem.EvalExpr()[0] opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1] + ((bitno & 7)) dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2] if not assem.MoreParameters(): # We expected more parameters errors.DoError('missoper', False) return param = dec.Asm.Parse_Line[dec.Asm.Parse_Pointer:dec.Asm.Parse_Pointer+2]\ .upper() if param in ('A,', 'X,', 'Y,', 'A ', 'X ', 'Y '): assem.NowChar(True) if param[0] == 'A': mem = 255 elif param[0] == 'X': mem = 128 else: mem = 129 else: mem = assem.EvalExpr()[0] if dec.Asm.Mnemonic[1] == 'R': # It's a branch instruction if not assem.MoreParameters(): # We expected more parameters errors.DoError('missoper', False) return dest = assem.EvalExpr()[0] offset = dest - dec.Asm.BOL_Address - 3 target.CodeByte(opcode) target.CodeByte(mem) target.CodeByte(offset) if dec.Asm.Pass == 2 and (offset < -128 or offset > +127): errors.DoError('range', False) else: # It wasn't a branch instruction target.CodeByte(opcode) target.CodeByte(mem) if dec.Asm.Pass == 2: if (bitno < 0 or bitno > 7) or (mem < 0 or mem > 255): errors.DoError('range', False) NoMore()
def Branch(index): """ Handle branch instructions. Displacement is destinaiton - current address - 2 """ global Asm dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][index] if dec.Asm.Timing == 0: errros.DoError('badopco', False) return if MissingOperand(): return value = assem.EvalExpr() offset = value[0] - dec.Asm.BOL_Address - 2 if dec.Asm.Pass == 2 and (offset < -128 or offset > 127): errors.DoError('range', False) target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1]) target.CodeByte(offset) NoMore()
def Math(): global Asm if MissingOperand(): return opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1] timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2] if assem.GetWord().upper() != 'A': errors.DoError('badoper', False) return if not assem.MoreParameters(): errors.DoError('missoper', False) return value = GetReg() for i in range(0, len(opcode[value[0]]), 2): byte = opcode[value[0]][i:i + 2] if byte == 'XX': target.CodeByte(value[1]) else: target.CodeByte(int(byte, 16)) dec.Asm.Timing = timing[value[0]] NoMore()
def SingleW(): global Asm if MissingOperand(): return reg1 = GetReg() if dec.Flags.ErrorInLine: # An error was found in parameter 1, no need to continue return if reg1[0] == 'rr' or reg1[0] == 'R' or reg1[0] == 'r': # Operand is register pair target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1][0]) target.CodeByte(reg1[1]) dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][0] if dec.Asm.Pass == 2 and (reg1[1] & 1) != 0: errors.DoError('range', False) elif reg1[0] == '@r' or reg1[0] == '@R': # Operand is indirect register pair target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1][1]) target.CodeByte(reg1[1]) dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][1] else: errors.DoError('badoper', False) NoMore()
def Implied(): """ Handle implied addressing mode. Simply save the opcode and we're done with it. """ global Asm opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1] if (opcode >> 24) != 0: # Save 4 bytes of opcode target.CodeByte(opcode >> 24) target.CodeByte(opcode >> 16) target.CodeByte(opcode >> 8) target.CodeByte(opcode) elif (opcode >> 16) != 0: # Save 3 bytes of opcode target.CodeByte(opcode >> 16) target.CodeByte(opcode >> 8) target.CodeByte(opcode) elif (opcode >> 8) != 0: # Save 2 bytes of opcode target.CodeByte(opcode >> 8) target.CodeByte(opcode) else: # Save 1 byte of opcode target.CodeByte(opcode) dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2]
def Restart(): global Asm if MissingOperand(): return value = assem.EvalExpr() if dec.Flags.ErrorInLine: # Save dummy bute to keep passes in sync target.CodeByte(0) else: # No errors were found vector = value[0] if value[1] and dec.Asm.Pass == 1: # Don't bother about range in case of forward referenced in pass 1 vector = 0 if vector > 8: if vector not in (16, 24, 32, 40, 48, 56): errors.DoError('range', False) vector = 0 if vector > 7: vector = vector >> 3 target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1] + (vector << 3)) NoMore()
def Single(): global Asm if MissingOperand(): return opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1] timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2] value = GetReg() if len(opcode[value[0]]) == 0: errors.DoError('badoper', False) return for i in range(0, len(opcode[value[0]]), 2): byte = opcode[value[0]][i:i + 2] if byte == 'XX': target.CodeByte(value[1]) else: target.CodeByte(int(byte, 16)) dec.Asm.Timing = timing[value[0]] NoMore()
def Immediate(): global Asm if MissingOperand(): return prefix = assem.NowChar() if prefix in '#/=\\': prefix = assem.NowChar(True) else: prefix = '#' value = assem.EvalExpr() if prefix == '#': byte = value[0] elif prefix == '/': byte = value[0] >> 8 elif prefix == '=': byte = value[0] >> 16 else: byte = value[0] >> 24 target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1]) target.CodeByte(byte) NoMore()
def Branch(): global Asm if MissingOperand(): return operand = GetOperand() if operand[0] == 1 or operand[0] == 2: # Branch relative offset = operand[1] - dec.Asm.BOL_Address - 2 if dec.Asm.Pass == 2 and (offset < -128 or offset > 127): errors.DoError('range', False) target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1][0]) target.CodeByte(offset) dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][0] elif operand[0] == 9: # Branch [indirect] target.CodeWord(dec.Asm.Instructions[dec.Asm.Mnemonic][1][1]) target.CodeByte(operand[1]) dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][1] else: errors.DoError('badoper', False) return NoMore()
def Jumps(): global Asm if MissingOperand(): return if assem.NowChar() == '@': # It is an indirect jump reg1 = GetReg() if reg1[0] == '@rr' or reg1[0] == '@R': target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1][1]) target.CodeByte(reg1[1]) dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][1] if reg1[1] & 1 != 0: errors.DoError('range', False) else: errors.DoError('badoper', False) else: # It's not an indirect jump if dec.Asm.Mnemonic == 'CALL': # It's a CALL instruction opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1][0] dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][0] else: # It's JP instruction conditions = {'F': 0x00, 'C': 0x70, 'NC': 0xF0, 'Z': 0x60, 'NZ': 0xE0, 'PL': 0xD0, 'MI': 0x50, 'OV': 0x40, 'NOV': 0xC0, 'EQ': 0x60, 'NE': 0xE0, 'GE': 0x90, 'LT': 0x10, 'GT': 0xA0, 'LE': 0x20, 'UGE': 0xF0, 'ULT': 0x70, 'UGT': 0xB0, 'ULE': 0x30} pointer = dec.Asm.Parse_Pointer cond = assem.GetWord().upper() if cond in conditions and assem.NowChar() == ',': # A legal condition code was given opcode = conditions[cond] + 13 dec.Asm.Timing = '10+' if not assem.MoreParameters(): errors.DoError('missoper', False) return else: # No condition was given dec.Asm.Parse_Pointer = pointer dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2][0] opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1][0] dest = assem.EvalExpr() target.CodeByte(opcode) target.CodeWord(dest[0]) if dec.Asm.Pass == 2 and (dest[0] >> 16) != 0: errors.DoError('range', False) NoMore()
def Load(): global Asm if MissingOperand(): return reg1 = GetReg() if dec.Flags.ErrorInLine: # An error was found in parameter 1, no need to continue return if not assem.MoreParameters(): errors.DoError('missoper', False) return reg2 = GetReg() firstpar = 'LD.' + reg1[0] if firstpar in dec.Asm.Instructions: secpar = dec.Asm.Instructions[firstpar][0] opcode = dec.Asm.Instructions[firstpar][1] timing = dec.Asm.Instructions[firstpar][2] extra = dec.Asm.Instructions[firstpar][3] index = 0 for t in secpar: if t == reg2[0]: # Found 2nd parameter, now let's save it to the target file opc = opcode[index] Code(opc) dec.Asm.Timing = timing[index] if extra[index] == 1: # save one extra byte from operand 2 target.CodeByte(reg2[1]) elif extra[index] == 2: # save two extra bytes from operand 2 target.CodeWord(reg2[1]) elif extra[index] == 3: # save one extra byte from operand 1 target.CodeByte(reg1[1]) elif extra[index] == 4: # save one extra byte from operand 1 and one from operand 2 target.CodeByte(reg1[1]) target.CodeByte(reg2[1]) elif extra[index] == 5: # save two extra bytes from operand 1 target.CodeWord(reg1[1]) NoMore() return index = index + 1 # This type of parameter was not allowed as second parameter errors.DoError('badoper', False) else: # This type of parameter was not allowed as first parameter errors.DoError('badoper', False)
def Code(opcode): """ Write an opcode to the target file. If the opcode > 255 then a pre-byte must be saved first """ if opcode > 255: target.CodeByte(opcode >> 8) target.CodeByte(opcode)
def Implied(): global Asm if dec.Asm.Instructions[dec.Asm.Mnemonic][1] > 0xFF: # It's a two byte instruction target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1] >> 8) target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1] & 0xFF) dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2]
def MovXInst(): """ MOVX A,@DPTR MOV A,@Ri MOV @DPTR,A MOV @Ri,A """ global Asm if MissingOperand(): # We need some operands return par1 = GetReg() if not assem.MoreParameters(): # Only one operand given errors.DoError('missoper', False) return par2 = GetReg() dec.Asm.Timing = '2' if par1[1] == 1: # Can be either A,@DPTR or A,@Ri if par2[1] == 7: # It's A,@DPTR for sure target.CodeByte(0xE0) elif par2[1] == 3: # It's A,@Ri target.CodeByte(0xE2 + par2[0]) else: # None of the above errors.DoError('badoper', False) return elif par1[1] == 7: # It's @DPTR,A mode if par2[1] != 1: # Second parameter is not A errors.DoError('badoper', False) return target.CodeByte(0xF0) elif par1[1] == 3: # It's @Ri,A mode if par2[1] != 1: # Second parameter is not A errors.DoError('badoper', False) return target.CodeByte(0xF2 + par1[0]) else: # 1st parameter is wrong errors.DoError('badoper', False) return NoMore()
def PointerData(): """ Pointer pair with data instructions pointer,data """ global Asm MissingOperand() parsepointer = dec.Asm.Parse_Pointer pointer = -1 pntr = assem.GetWord().upper() if len(pntr) == 2 and pntr[1] == "P": # It might as well be a poiner pair if pntr[0] >= '0' and pntr[0] <= '7': # It sure is pointer = int(pntr[0]) * 2 if pointer == -1: # It wasn't a pointer, so it must be an expression now dec.Asm.Parse_Pointer = parsepointer pointer = assem.EvalExpr()[0] if not assem.MoreParameters(): errors.DoError('missoper', False) return prefix = '#' if assem.NowChar() in '#/=\\': prefix = assem.NowChar(True) value = assem.EvalExpr() if prefix == '#': val = value[0] & 255 elif prefix == '/': val = (value[0] >> 8) & 255 elif prefix == '=': val = (value[0] >> 16) & 255 else: val = (value[0] >> 24) & 255 if dec.Asm.Pass == 2: # Range check only in pass 2 if pointer < 0 or pointer > 15 or pointer % 2 == 1: # Range error errors.DoError('range', False) target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1] + pointer) target.CodeByte(val) dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2] NoMore()
def Djnz(): """ Handle DJNZ. DJNZ has two opcodes in the instruction table. The first one is for DJNZ Rx,dest. The second entry is for DJNZ @Rn,dest. If indirect mode doesn't exist the opcode for it should be 00. """ global Asm if MissingOperand(): return registers = ('R0', 'R1', 'R2', 'R3', 'R4', 'R5', 'R6', 'R7', '@R0', '@R1') regname = assem.GetWord().upper() if regname in registers: index = 0 for t in registers: if t == regname: break index = index + 1 if index < 8: # direct addressing mode opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1][0] + index else: # indirect addressing mode opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1][1] if opcode == 0: errors.DoError('badoper', False) return opcode = opcode + (index & 1) else: errors.DoError('badoper', False) return if not assem.MoreParameters(): errors.DoError('missoper', False) return value = assem.EvalExpr() if dec.Asm.Pass == 2: temp = (dec.Asm.BOL_Address + 1) >> 8 dest = value[0] >> 8 if temp != dest: # Destination is not in the same memory page errors.DoError('range', False) target.CodeByte(opcode) target.CodeByte(value[0]) dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2] NoMore()
def Pairs(): """ Handle paired operand instructions. """ global Asm if MissingOperand(): return reg1 = assem.GetWord().upper() if not assem.MoreParameters(): errors.DoError('missoper', False) return if assem.NowChar() == ' ': errors.DoError('missoper', False) return if assem.NowChar() in '#/=\\': reg2 = '#' else: reg2 = assem.GetWord().upper() operand = reg1 + ',' + reg2 operands = dec.Asm.Instructions[dec.Asm.Mnemonic][1] opcodes = dec.Asm.Instructions[dec.Asm.Mnemonic][2] times = dec.Asm.Instructions[dec.Asm.Mnemonic][3] if operand in operands: index = 0 for t in operands: if t == operand: break index = index + 1 target.CodeByte(opcodes[index]) dec.Asm.Timing = times[index] if reg2 == '#': prefix = assem.NowChar(True) value = assem.EvalExpr() if prefix == '#': target.CodeByte(value[0]) elif prefix == '/': target.CodeByte(value[0] >> 8) elif prefix == '=': target.CodeByte(value[0] >> 16) else: target.CodeByte(value[0] >> 24) else: errors.DoError('badoper', False) NoMore()
def MovBit(): """ See if first or second operand is a C. If it is it is a bit MOV. If it is not return False and parse normal MOV. """ global Asm # Save the begin pointer in case're on a dead track pntr = dec.Asm.Parse_Pointer par1 = assem.GetWord().upper() if not assem.MoreParameters(): # We need 2 paarameters errors.DoError('missoper', False) return if par1 == 'C': # First parameter is a C bitreg = GetBit() target.CodeByte(0xA2) target.CodeByte(bitreg) dec.Asm.Timing = '1' NoMore() return True par2 = assem.GetWord().upper() if par2 == 'C': # Second parameter is a C endpntr = dec.Asm.Parse_Pointer dec.Asm.Parse_Pointer = pntr bitreg = GetBit() dec.Asm.Parse_Pointer = endpntr target.CodeByte(0x92) target.CodeByte(bitreg) dec.Asm.Timing = '2' NoMore() return True # Nope, it's not MOV C, restore pointer and try again dec.Asm.Parse_Pointer = pntr return False
def Immediate(): global Asm if MissingOperand(): return opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1] timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2] dest = GetReg() if dest[0] > 5: errors.DoError('badoper', False) return if len(opcode[dest[0]]) == 0: errors.DoError('badoper', False) return if not assem.MoreParameters(): errors.DoError('missoper', False) return if assem.NowChar() in '#/=\\': prefix = assem.NowChar(True) else: prefix = '#' value = assem.EvalExpr() for i in range(0, len(opcode[dest[0]]), 2): byte = opcode[dest[0]][i:i + 2] if byte == 'XX': target.CodeByte(dest[1]) else: target.CodeByte(int(byte, 16)) if prefix == '#': data = value[0] elif prefix == '/': data = value[0] >> 8 elif prefix == '=': data = value[0] >> 16 else: data = value[0] >> 24 target.CodeByte(data) dec.Asm.Timing = timing[dest[0]] NoMore()
def Exchange(): """ Handle EXG and TFR directives. Both directives take 2 operands of either 8-bit size or 16-bit size. Sizes of the registers may not be mixed. """ global Asm if MissingOperand(): return reg1 = assem.GetWord().upper() if not assem.MoreParameters(): errors.DoError('missoper', False) return reg2 = assem.GetWord().upper() words = { 'A:B': 0, 'D': 0, 'X': 1, 'Y': 2, 'US': 3, 'U': 3, 'SP': 4, 'S': 4, 'PC': 5 } bytes = {'A': 8, 'B': 9, 'CC': 10, 'CCR': 10, 'DP': 11, 'DPR': 11} if reg1 in words: if reg2 in words: target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1]) target.CodeByte((words[reg1] << 4) + words[reg2]) dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2] else: errors.DoError('badoper', False) elif reg1 in bytes: if reg2 in bytes: target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1]) target.CodeByte((bytes[reg1] << 4) + bytes[reg2]) dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2] else: errors.DoError('badoper', False) else: errors.DoError('badoper', False) NoMore()
def Move(): global Asm if MissingOperand(): return param = dec.Asm.Parse_Line[dec.Asm.Parse_Pointer:dec.Asm.Parse_Pointer+2]\ .upper() if param in ('A,', 'X,', 'Y,'): assem.NowChar(True) if param == 'A,': dest = 255 elif param == 'X,': dest = 128 else: dest = 129 else: dest = assem.EvalExpr()[0] if not assem.MoreParameters(): # We expected more parameters errors.DoError('missoper', False) return prefix = assem.NowChar(True) if prefix not in '#/=\\': errors.DoError('badoper', False) return value = assem.EvalExpr()[0] if prefix == '/': value = value >> 8 elif prefix == '=': value = value >> 16 elif prefix == '\\': value = value >> 24 Code(dec.Asm.Instructions[dec.Asm.Mnemonic][1]) target.CodeByte(dest) target.CodeByte(value) dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2] if dest < 0 or dest > 255: errors.DoError('range', False) NoMore()
def MviInst(): global Asm if MissingOperand(): return registers = 'ABCDEHLM' reg1 = registers.find(assem.NowChar(True).upper()) if reg1 < 0: errors.DoError('badoper', False) return if reg1 == 7: # timing is different if first operand is M dec.Asm.Timing = '9' if not assem.MoreParameters(): errors.DoError('missoper', False) return if assem.NowChar() == ' ': errors.DoError('missoper', False) return prefix = assem.NowChar() if prefix in '#/=\\': prefix = assem.NowChar(True) else: prefix = '#' value = assem.EvalExpr() if prefix == '#': byte = value[0] elif prefix == '/': byte = value[0] >> 8 elif prefix == '=': byte = value[0] >> 16 else: byte = value[0] >> 24 NoMore() opcode = dec.Asm.Instructions[dec.Asm.Mnemonic][1] + (reg1 << 3) target.CodeByte(opcode) target.CodeByte(byte)
def Immediate2(): """ RLDI instruction with immediate operand. First operand is the register to be loaded. Second operand is the immediate 16 bit data. May be prefixed by one of the immediate prefixes. """ global Asm if MissingOperand(): return # Get register register = assem.EvalExpr()[0] if dec.Asm.Pass == 2: # Don't check range in pass 1 as label may be forward referenced if register < 0 or register > 15: register = 0 if not assem.MoreParameters(): errors.DoError('missoper', False) return prefix = '#' if assem.NowChar() in '#/=\\': prefix = assem.NowChar(True) value = assem.EvalExpr()[0] if prefix == '#': val = value & 0xFFFF elif prefix == '/': val = (value >> 8) & 0xFFFF elif prefix == '=': val = (value >> 16) & 0xFFFF else: val = (value >> 24) & 0xFFFF target.CodeByte(dec.Asm.Instructions[dec.Asm.Mnemonic][1] >> 8) target.CodeByte((dec.Asm.Instructions[dec.Asm.Mnemonic][1] & 0xFF) + register) target.CodeByte(val >> 8) target.CodeByte(val & 0xFF) dec.Asm.Timing = dec.Asm.Instructions[dec.Asm.Mnemonic][2] NoMore()
def SaveAll(prebyte, opcode, operand): if opcode == 0: errors.DoError('badoper', False) return if prebyte != 0: target.CodeByte(prebyte) target.CodeByte(opcode) if operand[0] in (0, 1, 4, 7, 9, 10, 11, 12, 13, 14): target.CodeByte(operand[1]) elif operand[0] in (2, 5, 8): target.CodeWord(operand[1]) NoMore()