class CPU: # vectors ResetTo = 0xfffc IrqTo = 0xfffe NMITo = 0xfffa # processor flags NEGATIVE = 128 OVERFLOW = 64 BREAK = 16 DECIMAL = 8 INTERRUPT = 4 ZERO = 2 CARRY = 1 def __init__(self): # config self.debug = False self.externalLoop = True self.stopOnIterrupt = True # vm status self.breakFlag = False self.excycles = 0 self.addcycles = False self.processorCycles = 0; self.internalCycleDelay=0; # init self.clearMemory() self.reset() def __repr__(self): out = '<6502: A=%02x, X=%02x, Y=%02x, Flags=%02x, SP=%02x, PC=%04x>' return out % (self.a, self.x, self.y, self.flags, self.sp, self.pc) def step(self): breakFlag = False instructCode = self.ImmediateByte() self.pc +=1 self.pc &=0xffff self.excycles = 0 self.addcycles = self.extracycles[instructCode] self.instruct[instructCode](self) self.processorCycles += self.cycletime[instructCode]+self.excycles self.pc &=0xffff return self def reset(self): self.pc=0 self.sp=255 self.a=self.x=self.y=0 self.flags=32 self.breakFlag=False self.processorCycles=0 def clearMemory(self, start=0x0000, end=0xFFFF): self.memory = self.RAM = [] for addr in range(start, end + 1): self.memory.insert(addr, 0x00) def ByteAt(self, addr): return self.memory[addr] def WordAt(self, addr): return self.ByteAt(addr) + self.ByteAt(0xffff&(addr+1))*256 def ImmediateByte(self): return self.ByteAt(self.pc) def ZeroPageAddr(self): return self.ByteAt(self.pc) def ZeroPageXAddr(self): return 255 & (self.x + self.ByteAt(self.pc)) def ZeroPageYAddr(self): return 255 & (self.y + self.ByteAt(self.pc)) def IndirectXAddr(self): return self.WordAt( 255 & (self.ByteAt(self.pc) + self.x)) def IndirectYAddr(self): if self.addcycles: a1 = self.WordAt(self.ByteAt(self.pc)) a2 = (a1+self.y)&0xffff if ((a1&0xff00) != (a2&0xff00)): self.extracyles += 1 return a2 else: return (self.WordAt(self.ByteAt(self.pc))+self.y)&0xffff def AbsoluteAddr(self): return self.WordAt(self.pc) def AbsoluteXAddr(self): if self.addcycles: a1 = self.WordAt(self.pc) a2 = (a1+self.x)&0xffff if ((a1&0xff00)!=(a2&0xff00)): self.extracyles += 1; return a2 else: return (self.WordAt(self.pc)+self.x)&0xffff def AbsoluteYAddr(self): if self.addcycles: a1 = self.WordAt(self.pc) a2=(a1+self.y)&0xffff if ((a1&0xff00)!=(a2&0xff00)): self.extracyles += 1; return a2 else: return (self.WordAt(self.pc)+self.y)&0xffff def BranchRelAddr(self): self.excycles += 1 addr = self.ImmediateByte() self.pc += 1 if addr & 128: addr = self.pc - (addr ^ 0xFF) + 1 else: addr = self.pc + addr if (self.pc & 0xff00) != (addr & 0xff00): self.excycles += 1 self.pc = addr & 0xffff # stack def stPush(self,z): self.RAM[self.sp+256] = z&255; self.sp -= 1; self.sp &= 255 def stPop(self): self.sp += 1 self.sp &= 255 return self.ByteAt(self.sp+256) def stPushWord(self, z): self.stPush((z>>8)&255) self.stPush(z&255) def stPopWord(self): z = self.stPop() z += 256*self.stPop() return z # operations def FlagsNZ(self, z): self.flags &= ~(self.ZERO + self.NEGATIVE) if z == 0: self.flags |= self.ZERO else: self.flags |= z & 128 def opORA(self, x): self.a |= self.ByteAt(x()) self.FlagsNZ(self.a) def opASL(self, x): addr = x() tbyte = self.ByteAt(addr); self.flags &= ~(self.CARRY + self.NEGATIVE + self.ZERO) if (tbyte&128): self.flags |= self.CARRY tbyte = (tbyte << 1) & 0xFF if (tbyte): self.flags |= tbyte & 128 else: self.flags |= self.ZERO self.RAM[addr] = tbyte def opLSR(self, x): addr = x() tbyte = self.ByteAt(addr) self.flags &=~(self.CARRY+self.NEGATIVE+self.ZERO) self.flags |=tbyte&1 tbyte=tbyte>>1 if (tbyte): pass # {} else: self.flags |= self.ZERO self.RAM[addr]=tbyte def opBCL(self, x): if self.flags & x: self.pc += 1 else: self.BranchRelAddr() def opBST(self, x): if (self.flags&x): self.BranchRelAddr() else: self.pc+=1 def opCLR(self, x): self.flags &=~x def opSET(self, x): self.flags |= x def opAND(self, x): self.a &= self.ByteAt(x()) self.FlagsNZ(self.a) def opBIT(self, x): tbyte = self.ByteAt(x()) self.flags &=~(self.ZERO+self.NEGATIVE+self.OVERFLOW) if ((self.a&tbyte)==0): self.flags |=self.ZERO; self.flags |=tbyte&(128+64) def opROL(self, x): addr = x(); tbyte = self.ByteAt(addr) if self.flags & self.CARRY: if tbyte & 128: pass else: self.flags &= ~self.CARRY tbyte = (tbyte << 1) | 1 else: if tbyte & 128: self.flags |= self.CARRY tbyte = tbyte << 1 self.FlagsNZ(tbyte) self.RAM[addr] = tbyte & 0xFF def opEOR(self, x): self.a^=self.ByteAt(x()) self.FlagsNZ(a) def opADC(self, x): data=self.ByteAt(x()) if (self.flags&self.DECIMAL): if (self.flags&self.CARRY): tmp = 1 else: tmp = 0 data = self.bcd2dec[data]+self.bcd2dec[self.a]+tmp self.flags &= ~(self.CARRY+self.OVERFLOW+self.NEGATIVE+self.ZERO) if (data>99): self.flags|=self.CARRY+self.OVERFLOW; data -=100 if (data==0): self.flags|=self.ZERO else: self.flags |=data&128 self.a=self.dec2bcd[data] else: if self.flags & self.CARRY: tmp = 1 else: tmp = 0 data += self.a + tmp; self.flags &= ~(self.CARRY+self.OVERFLOW+self.NEGATIVE+self.ZERO) if data > 255: self.flags|=self.OVERFLOW+self.CARRY data &=255 if data == 0: self.flags |= self.ZERO else: self.flags |= data&128; self.a = data def opROR(self, x): addr=x() tbyte=self.ByteAt(addr) if (self.flags&self.CARRY): if (tbyte&1): pass # {} else: self.flags &=~ self.CARRY tbyte=(tbyte>>1)|128 else: if (tbyte&1): self.flags |= self.CARRY tbyte=tbyte>>1 self.FlagsNZ(tbyte) self.RAM[addr]=tbyte def opSTA(self, x): self.RAM[x()] = self.a def opSTY(self, x): self.RAM[x()] = self.y def opSTX(self, y): self.RAM[y()] = self.x def opCPY(self, x): tbyte=self.ByteAt(x()); self.flags &=~(self.CARRY+self.ZERO+self.NEGATIVE) if (self.y==tbyte): self.flags |= self.CARRY + self.ZERO elif (self.y>tbyte): self.flags |= self.CARRY else: self.flags |= self.NEGATIVE; def opCPX(self, y): tbyte=self.ByteAt(y()) self.flags &=~(self.CARRY+self.ZERO+self.NEGATIVE) if (self.x==tbyte): self.flags |= self.CARRY + self.ZERO elif (self.x>tbyte): self.flags |= self.CARRY else: self.flags |= self.NEGATIVE def opCMP(self, x): tbyte = self.ByteAt(x()) self.flags &=~(self.CARRY+self.ZERO+self.NEGATIVE) if (self.a==tbyte): self.flags |= self.CARRY + self.ZERO elif (self.a>tbyte): self.flags |= self.CARRY else: self.flags |= self.NEGATIVE def opSBC(self, x): data = self.ByteAt(x()) if (self.flags & self.DECIMAL): if (self.flags & self.CARRY): tmp = 0 else: tmp = 1 data = self.bcd2dec[a] - self.bcd2dec[data] - tmp self.flags &= ~(self.CARRY + self.ZERO + self.NEGATIVE + self.OVERFLOW) if (data==0): self.flags |= self.ZERO + self.CARRY elif (data>0): self.flags |= self.CARRY else: self.flags |= self.NEGATIVE data +=100 self.a = self.dec2bcd[data] else: if (self.flags & self.CARRY): tmp = 0 else: tmp = 1 data = self.a - data - tmp self.flags &=~(self.CARRY + self.ZERO + self.OVERFLOW + self.NEGATIVE) if (data==0): self.flags |= self.ZERO + self.CARRY elif (data>0): self.flags |= self.CARRY else: self.flags |= self.OVERFLOW self.flags |= data&128 self.a = data&255 def opDECR(self, x): addr=x(); tbyte = self.ByteAt(addr) self.flags &=~(self.ZERO+self.NEGATIVE) tbyte -= 1 if tbyte: self.flags |= self.tbyte&128 else: self.flags |= self.ZERO; self.RAM[addr] = tbyte def opINCR(self, x): addr=x(); tbyte = self.ByteAt(addr) self.flags &=~(self.ZERO + self.NEGATIVE) tbyte += 1 if (tbyte): self.flags |= tbyte&128 else: self.flags |= fZER; self.RAM[addr]=tbyte def opLDA(self, x): self.a = self.ByteAt(x()) self.FlagsNZ(self.a) def opLDY(self, x): self.y = self.ByteAt(x()) self.FlagsNZ(self.y) def opLDX(self, y): self.x = self.ByteAt(y()) self.FlagsNZ(self.x) # instructions def i00(self): pc = (self.pc + 2) & 0xFFFF self.stPushWord(pc) self.flags |= self.BREAK self.stPush(self.flags) self.flags |= self.INTERRUPT self.pc = self.WordAt(self.IrqTo) self.breakFlag = True def i01(self): self.opORA(self.IndirectXAddr) self.pc += 1 def i05(self): self.opORA(self.ZeroPageAddr) self.pc += 1 def i06(self): self.opASL(self.ZeroPageAddr) self.pc += 1 def i08(self): self.stPush(self.flags) def i09(self): self.a |= self.ImmediateByte() self.FlagsNZ(self.a) self.pc += 1 def i0a(self): if (self.a&128): self.flags |= self.CARRY else: self.flags &= ~self.CARRY; self.a = self.a << 1; self.FlagsNZ(self.a); self.a &= 255 def i0d(self): self.opORA(self.AbsoluteAddr) self.pc += 2 def i0e(self): self.opASL(self.AbsoluteAddr) self.pc += 2 def i10(self): self.opBCL(self.NEGATIVE) def i11(self): self.opORA(self.IndirectYAddr) self.pc += 1 def i15(self): self.opORA(self.ZeroPageXAddr) self.pc += 1 def i16(self): self.opASL(self.ZeroPageXAddr) self.pc += 1 def i18(self): self.opCLR(self.CARRY) def i19(self): self.opORA(self.AbsoluteYAddr) self.pc += 2 def i1d(self): self.opORA(self.AbsoluteXAddr) self.pc += 2 def i1e(self): self.opASL(self.AbsoluteXAddr) self.pc += 2 def i20(self): self.stPushWord((self.pc+1)&0xffff) self.pc=self.WordAt(self.pc) def i21(self): self.opAND(self.IndirectXAddr) self.pc += 1 def i24(self): self.opBIT(self.ZeroPageAddr) self.pc += 1 def i25(self): self.opAND(self.ZeroPageAddr) self.pc += 1 def i26(self): self.opROL(self.ZeroPageAddr) self.pc += 1 def i28(self): self.flags = self.stPop() def i29(self): self.a &= self.ImmediateByte() self.FlagsNZ(self.a) self.pc += 1 def i2a(self): if (self.flags & self.CARRY): if ((self.a & 128)==0): self.flags &=~self.CARRY; self.a=(self.a<<1)|1 else: if (self.a&128): self.flags|=self.CARRY; self.a=self.a<<1 self.FlagsNZ(self.a); self.a&=255 def i2c(self): self.opBIT(self.AbsoluteAddr) self.pc+=2 def i2d(self): self.opAND(self.AbsoluteAddr) self.pc+=2 def i2e(self): self.opROL(self.AbsoluteAddr) self.pc += 2 def i30(self): self.opBST(self.NEGATIVE) def i31(self): self.opAND(self.IndirectYAddr) self.pc += 1 def i35(self): self.opAND(self.ZeroPageXAddr) self.pc += 1 def i36(self): self.opROL(self.ZeroPageXAddr) self.pc += 1 def i38(self): self.opSET(self.CARRY) def i39(self): self.opAND(self.AbsoluteYAddr) self.pc+=2 def i3d(self): self.opAND(self.AbsoluteXAddr) self.pc += 2 def i3e(self): self.opROL(self.AbsoluteXAddr) self.pc+=2 def i40(self): self.flags = self.stPop() self.pc = self.stPopWord() def i41(self): self.opEOR(self.IndirectXAddr) self.pc+=1 def i45(self): self.opEOR(self.ZeroPageAddr) self.pc+=1 def i46(self): self.opLSR(self.ZeroPageAddr) self.pc+=1 def i48(self): self.stPush(self.a) def i49(self): self.a ^= self.ImmediateByte() self.FlagsNZ(self.a) self.pc+=1 def i4a(self): self.flags &=~(self.CARRY+self.NEGATIVE+self.ZERO); if (self.a&1): self.flags |= self.CARRY self.a=self.a>>1 if (self.a): pass # {} else: self.flags |= self.ZERO self.a&=255 def i4c(self): self.pc=self.WordAt(self.pc) def i4d(self): self.opEOR(self.AbsoluteAddr) self.pc+=2 def i4e(self): self.opLSR(self.AbsoluteAddr) self.pc += 2 def i50(self): self.opBCL(self.OVERFLOW) def i51(self): self.opEOR(self.IndirectYAddr) self.pc+=1 def i55(self): self.opEOR(self.ZeroPageXAddr) self.pc+=1 def i56(self): self.opLSR(self.ZeroPageXAddr) self.pc+=1 def i58(self): self.opCLR(self.INTERRUPT) def i59(self): self.opEOR(self.AbsoluteYAddr) self.pc +=2 def i5d(self): self.opEOR(self.AbsoluteXAddr) self.pc+=2 def i5e(self): self.opLSR(self.AbsoluteXAddr) self.pc+=2 def i60(self): self.pc=self.stPopWord() self.pc+=1 def i61(self): self.opADC(self.IndirectXAddr) self.pc+=1 def i65(self): self.opADC(self.ZeroPageAddr) self.pc+=1 def i66(self): self.opROR(self.ZeroPageAddr) self.pc+=1 def i68(self): self.a = self.stPop() self.FlagsNZ(self.a) def i69(self): data = self.ImmediateByte() if (self.flags & self.CARRY): tmp = 1 else: tmp = 0 if (self.flags & self.DECIMAL): data = self.bcd2dec[data] + self.bcd2dec[a] + tmp self.flags &= ~(self.CARRY+self.OVERFLOW+self.NEGATIVE+self.ZERO) if (data>99): self.flags|=self.CARRY+self.OVERFLOW data -=100 if (data==0): self.flags |= self.ZERO else: self.flags |= self.data&128 self.a = self.dec2bcd[data] else: if (self.flags & self.CARRY): tmp = 1 else: tmp = 0 data += self.a + tmp self.flags &= ~(self.CARRY+self.OVERFLOW+self.NEGATIVE+self.ZERO) if (data>255): self.flags |= self.OVERFLOW + self.CARRY data &=255 if (data==0): self.flags |= self.ZERO else: self.flags |= data&128 self.a=data self.pc += 1 def i6a(self): if self.flags & self.CARRY: if (self.a & 1) == 0: self.flags &= ~self.CARRY self.a = (self.a >> 1) | 128 else: if self.a & 1: self.flags |= self.CARRY self.a = self.a >> 1 self.FlagsNZ(self.a) self.a &= 255 def i6c(self): ta = self.WordAt(self.pc) self.pc = self.WordAt(ta) def i6d(self): self.opADC(self.AbsoluteAddr) self.pc +=2 def i6e(self): self.opROR(self.AbsoluteAddr) self.pc+=2 def i70(self): self.opBST(self.OVERFLOW) def i71(self): self.opADC(self.IndirectYAddr) self.pc+=1 def i75(self): self.opADC(self.ZeroPageXAddr) self.pc+=1 def i76(self): self.opROR(self.ZeroPageXAddr) self.pc+=1 def i78(self): self.opSET(self.INTERRUPT) def i79(self): self.opADC(self.AbsoluteYAddr) self.pc+=2 def i7d(self): self.opADC(self.AbsoluteXAddr) self.pc+=2 def i7e(self): self.opROR(self.AbsoluteXAddr) self.pc+=2 def i81(self): self.opSTA(self.IndirectXAddr) self.pc+=1 def i84(self): self.opSTY(self.ZeroPageAddr) self.pc+=1 def i85(self): self.opSTA(self.ZeroPageAddr) self.pc+=1 def i86(self): self.opSTX(self.ZeroPageAddr) self.pc+=1 def i88(self): self.y -= 1 self.y&=255 self.FlagsNZ(self.y) def i8a(self): self.a=self.x self.FlagsNZ(self.a) def i8c(self): self.opSTY(self.AbsoluteAddr) self.pc+=2 def i8d(self): self.opSTA(self.AbsoluteAddr) self.pc+=2 def i8e(self): self.opSTX(self.AbsoluteAddr) self.pc+=2 def i90(self): self.opBCL(self.CARRY) def i91(self): self.opSTA(self.IndirectYAddr) self.pc+=1 def i94(self): self.opSTY(self.ZeroPageXAddr) self.pc+=1 def i95(self): self.opSTA(self.ZeroPageXAddr) self.pc+=1 def i96(self): self.opSTX(self.ZeroPageYAddr) self.pc+=1 def i98(self): self.a = self.y self.FlagsNZ(self.a) def i99(self): self.opSTA(self.AbsoluteYAddr) self.pc+=2 def i9a(self): self.sp=self.x def i9d(self): self.opSTA(self.AbsoluteXAddr) self.pc+=2 def ia0(self): self.y=self.ImmediateByte() self.FlagsNZ(self.y) self.pc+=1 def ia1(self): self.opLDA(self.IndirectXAddr) self.pc+=1 def ia2(self): self.x=self.ImmediateByte() self.FlagsNZ(self.x) self.pc+=1 def ia4(self): self.opLDY(self.ZeroPageAddr) self.pc+=1 def ia5(self): self.opLDA(self.ZeroPageAddr) self.pc+=1 def ia6(self): self.opLDX(self.ZeroPageAddr) self.pc+=1 def ia8(self): self.y = self.a self.FlagsNZ(self.y) def ia9(self): self.a = self.ImmediateByte() self.FlagsNZ(self.a) self.pc += 1 def iaa(self): self.x = self.a self.FlagsNZ(self.x) def iac(self): self.opLDY(self.AbsoluteAddr) self.pc += 2 def iad(self): self.opLDA(self.AbsoluteAddr) self.pc += 2 def iae(self): self.opLDX(self.AbsoluteAddr) self.pc += 2 def ib0(self): self.opBST(self.CARRY) def ib1(self): self.opLDA(self.IndirectYAddr) self.pc+=1 def ib4(self): self.opLDY(self.ZeroPageXAddr) self.pc+=1 def ib5(self): self.opLDA(self.ZeroPageXAddr) self.pc+=1 def ib6(self): self.opLDX(self.ZeroPageYAddr) self.pc+=1 def ib8(self): self.opCLR(self.OVERFLOW) def ib9(self): self.opLDA(self.AbsoluteYAddr) self.pc+=2 def iba(self): self.x = self.sp self.FlagsNZ(self.x) def ibc(self): self.opLDY(self.AbsoluteXAddr) self.pc+=2 def ibd(self): self.opLDA(self.AbsoluteXAddr) self.pc+=2 def ibe(self): self.opLDX(self.AbsoluteYAddr) self.pc+=2 def ic0(self): tbyte = self.ImmediateByte() self.flags &=~(self.CARRY+self.ZERO+self.NEGATIVE); if (y==tbyte): self.flags |= self.CARRY+self.ZERO elif (y>tbyte): self.flags |= self.CARRY else: self.flags |= self.NEGATIVE; self.pc += 1 def ic1(self): self.opCMP(self.IndirectXAddr) self.pc+=1 def ic4(self): self.opCPY(self.ZeroPageAddr) self.pc += 1 def ic5(self): self.opCMP(self.ZeroPageAddr) self.pc += 1 def ic6(self): self.opDECR(self.ZeroPageAddr) self.pc += 1 def ic8(self): self.y += 1 self.y &= 255 self.FlagsNZ(self.y) def ic9(self): tbyte = self.ImmediateByte() self.flags &=~(self.CARRY+self.ZERO+self.NEGATIVE) if (self.a==tbyte): self.flags |= self.CARRY + self.ZERO elif (a>tbyte): self.flags |= self.CARRY else: self.flags |= self.NEGATIVE self.pc +=1 def ica(self): self.x -= 1 self.x &= 255 self.FlagsNZ(self.x) def icc(self): self.opCPY(self.AbsoluteAddr) self.pc += 2 def icd(self): self.opCMP(self.AbsoluteAddr) self.pc += 2 def ice(self): self.opDECR(self.AbsoluteAddr) self.pc += 2 def id0(self): self.opBCL(self.ZERO) def id1(self): self.opCMP(self.IndirectYAddr) self.pc+=1 def id5(self): self.opCMP(self.ZeroPageXAddr) self.pc+=1 def id6(self): self.opDECR(self.ZeroPageXAddr) self.pc+=1 def id8(self): self.opCLR(self.DECIMAL) def id9(self): self.opCMP(self.AbsoluteYAddr) self.pc+=2 def idd(self): self.opCMP(self.AbsoluteXAddr) self.pc+=2 def ide(self): self.opDECR(AbsoluteXAddr) self.pc+=2 def ie0(self): tbyte = self.ImmediateByte() self.flags &=~(self.CARRY+self.ZERO+self.NEGATIVE) if (self.x==tbyte): self.flags |= self.CARRY + self.ZERO elif (self.x>tbyte): self.flags |= self.CARRY else: self.flags |= self.NEGATIVE; self.pc += 1 def ie1(self): self.opSBC(self.IndirectXAddr) self.pc+=1 def ie4(self): self.opCPX(self.ZeroPageAddr) self.pc+=1 def ie5(self): self.opSBC(self.ZeroPageAddr) self.pc+=1 def ie6(self): self.opINCR(ZeroPageAddr) self.pc+=1 def ie8(self): self.x+=1 self.x&=255 self.FlagsNZ(self.x) def ie9(self): data=self.ImmediateByte() if (self.flags & self.DECIMAL): if (self.flags & self.CARRY): tmp = 0 else: tmp = 1 data = self.bcd2dec[a] - self.bcd2dec[data] - tmp self.flags &= ~(self.CARRY+self.ZERO+self.NEGATIVE+self.OVERFLOW) if (data==0): self.flags |= self.ZERO + self.CARRY elif (data>0): self.flags |= self.CARRY else: self.flags |= self.NEGATIVE; data +=100 self.a = self.dec2bcd[data] else: if (self.flags & self.CARRY): tmp = 0 else: tmp = 1 data = self.a - data - tmp self.flags &=~(self.CARRY+self.ZERO+self.OVERFLOW+self.NEGATIVE) if (data==0): self.flags |= self.ZERO + self.CARRY elif (data>0): self.flags |= self.CARRY else: self.flags |= self.OVERFLOW data &= 255; self.flags |= data&128; self.a=data self.pc+=1 def iea(self): pass def iec(self): self.opCPX(self.AbsoluteAddr) self.pc+=2 def ied(self): self.opSBC(self.AbsoluteAddr) self.pc+=2 def iee(self): self.opINCR(self.AbsoluteAddr) self.pc+=2 def if0(self): self.opBST(self.ZERO) def if1(self): self.opSBC(self.IndirectYAddr) self.pc+=1 def if5(self): self.opSBC(self.ZeroPageXAddr) self.pc+=1 def if6(self): self.opINCR(self.ZeroPageXAddr) self.pc+=1 def if8(self): self.opSET(self.DECIMAL) def if9(self): self.opSBC(self.AbsoluteYAddr) self.pc+=2 def ifd(self): self.opSBC(self.AbsoluteXAddr) self.pc+=2 def ife(self): self.opINCR(self.AbsoluteXAddr) self.pc+=2 def ini(self): if self.debug: raise NotImplementedError self.pc+=1 # code pages instruct = [ i00, i01, ini, ini, ini, i05, i06, ini, i08, i09, i0a, ini, ini, i0d, i0e, ini, i10, i11, ini, ini, ini, i15, i16, ini, i18, i19, ini, ini, ini, i1d, i1e, ini, i20, i21, ini, ini, i24, i25, i26, ini, i28, i29, i2a, ini, i2c, i2d, i2e, ini, i30, i31, ini, ini, ini, i35, i36, ini, i38, i39, ini, ini, ini, i3d, i3e, ini, i40, i41, ini, ini, ini, i45, i46, ini, i48, i49, i4a, ini, i4c, i4d, i4e, ini, i50, i51, ini, ini, ini, i55, i56, ini, i58, i59, ini, ini, ini, i5d, i5e, ini, i60, i61, ini, ini, ini, i65, i66, ini, i68, i69, i6a, ini, i6c, i6d, i6e, ini, i70, i71, ini, ini, ini, i75, i76, ini, i78, i79, ini, ini, ini, i7d, i7e, ini, ini, i81, ini, ini, i84, i85, i86, ini, i88, ini, i8a, ini, i8c, i8d, i8e, ini, i90, i91, ini, ini, i94, i95, i96, ini, i98, i99, i9a, ini, ini, i9d, ini, ini, ia0, ia1, ia2, ini, ia4, ia5, ia6, ini, ia8, ia9, iaa, ini, iac, iad, iae, ini, ib0, ib1, ini, ini, ib4, ib5, ib6, ini, ib8, ib9, iba, ini, ibc, ibd, ibe, ini, ic0, ic1, ini, ini, ic4, ic5, ic6, ini, ic8, ic9, ica, ini, icc, icd, ice, ini, id0, id1, ini, ini, ini, id5, id6, ini, id8, id9, ini, ini, ini, idd, ide, ini, ie0, ie1, ini, ini, ie4, ie5, ie6, ini, ie8, ie9, iea, ini, iec, ied, iee, ini, if0, if1, ini, ini, ini, if5, if6, ini, if8, if9, ini, ini, ini, ifd, ife, ini ] cycletime = [ 7, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 0, 4, 6, 0, # 00 2, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0, # 10 6, 6, 0, 0, 3, 3, 5, 0, 4, 2, 2, 0, 4, 4, 6, 0, # 20 2, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0, # 30 6, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 3, 4, 6, 0, # 40 2, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0, # 50 6, 6, 0, 0, 0, 3, 5, 0, 4, 2, 2, 0, 5, 4, 6, 0, # 60 2, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0, # 70 0, 6, 0, 0, 3, 3, 3, 0, 2, 0, 2, 0, 4, 4, 4, 0, # 80 2, 6, 0, 0, 4, 4, 4, 0, 2, 5, 2, 0, 0, 5, 0, 0, # 90 2, 6, 2, 0, 3, 3, 3, 0, 2, 2, 2, 0, 4, 4, 4, 0, # A0 2, 5, 0, 0, 4, 4, 4, 0, 2, 4, 2, 0, 4, 4, 4, 0, # B0 2, 6, 0, 0, 3, 3, 5, 0, 2, 2, 2, 0, 4, 4, 3, 0, # C0 2, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0, # D0 2, 6, 0, 0, 3, 3, 5, 0, 2, 2, 2, 0, 4, 4, 6, 0, # E0 2, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0 # F0 ] extracycles= [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 00 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, # 10 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 20 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, # 30 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 40 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, # 50 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 60 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, # 70 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 80 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 90 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # A0 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, # B0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # C0 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, # D0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # E0 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 # F0 ] # lookup tables for opBCD math. bcd2dec = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, # 0x00 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, # 0x10 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, # 0x20 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, # 0x30 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, # 0x40 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, # 0x50 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, # 0x60 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, # 0x70 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, # 0x80 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105, # 0x90 100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115, # 0xA0 110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125, # 0xB0 120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135, # 0xC0 130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145, # 0xD0 140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155, # 0xE0 150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165 # 0xF0 ] dec2bcd= [ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29, 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39, 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49, 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59, 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69, 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79, 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89, 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99 ]