1
0
mirror of https://github.com/mnaberez/py65.git synced 2024-07-27 21:29:00 +00:00
py65/mpu.py
2008-07-01 16:47:47 +00:00

1235 lines
27 KiB
Python

class MPU:
# 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
]