CODE |
# attempt to create a chip8 interpreter from random import uniform import msvcrt,StringIO def cpu8(instr,regs,I,PC): opcode=instr/4096 instr=instr-4096*opcode if opcode==0: PC=opcode0(instr,PC) elif opcode==1: print "%X: jump %X"%(PC,instr) PC=instr elif opcode==2: stack.append(PC) print "%X: jsr %X"%(PC,instr) PC=instr elif opcode==3: register=int(instr/256) value=instr-256*register print "%X: skeq V%X,%X"%(PC,register,value) if regs[register]==value: PC+=4 else: PC+=2 elif opcode==4: register=int(instr/256) value=instr-256*register print "%X: skne v%X,%X"%(PC,register,value) if regs[register]==value: PC+=2 else: PC+=4 elif opcode==5: register1=int(instr/256) register2=int((instr-256*register1)/16) print "%X: skeq V%X,V%X"%(PC,register1,register2) if regs[register1]==regs[register2]: PC+=4 else: PC+=2 elif opcode==6: register=int(instr/256) value=instr-256*register regs[register]=value print "%X: mov V%X,%X"%(PC,register,value) PC+=2 elif opcode==7: register=int(instr/256) value=instr-256*register regs[register]+=value print "%X: add V%X,%X"%(PC,register,value) PC+=2 elif opcode==8: register1=int(instr/256) register2=int((instr-256*register1)/16) value=instr-256*register1-16*register2 opcode8(register1,register2,value,PC) PC+=2 elif opcode==9: register1=int(instr/256) register2=int((instr-256*register1)/16) print "%X: skne V%X,V%X"%(PC,register1,register2) if regs[register1]==regs[register2]: PC+=2 else: PC+=4 elif opcode==0xA: I=instr print "%X: mvi %X"%(PC,instr) PC+=2 elif opcode==0xB: print "%X: jmi %X"%(PC,instr) PC=instr+regs[0] elif opcode==0xC: register=int(instr/256) seed=instr-256*register regs[register]=int(uniform(0,seed+1)) print "%X: rand V%X,%X"%(PC,register,seed) PC+=2 elif opcode==0xD: register1=int(instr/256) register2=int((instr-256*register1)/16) height=instr-256*register1-16*register2 print "%X: sprite V%X,V%X,%X"%(PC,register1,register2,height) # sprite(register1,register2,height,I) PC+=2 elif opcode==0xE: register=int(instr/256) value=instr-register*256 PC=opcodeE(register,value,PC) PC+=2 elif opcode==0xF: register=int(instr/256) value=instr-register*256 I=opcodeF(register,value,PC,I) PC+=2 return PC,I def opcode0(value,PC): if value==0xE0: print "%X: cls"%(PC) PC+=2 elif value==0xEE: print "%X: rts"%(PC) PC=stack.pop()+2 else: print "NoOp" PC=0 return PC def opcode8(register1,register2,value,PC): if value==1: regs[register1]=regs[register2] print "%X: mov V%X,V%X"%(PC,register1,register2) elif value==2: regs[register1]=regs[register1]|regs[register2] print "%X: or V%X,V%X"%(PC,register1,register2) elif value==3: regs[register1]=regs[register1]®s[register2] print "%X: and V%X,V%X"%(PC,register1,register2) elif value==4: regs[register1]=regs[register1]^regs[register2] print "%X xor V%X,V%X"%(PC,register1,register2) elif value==5: regs[register1]+=regs[register2] if regs[register1]>0xFF: regs[0xF]=1 regs[register1]=regs[register1]%0xFF print "%X add V%X,V%X"%(PC,register1,register2) elif value==7: regs[register1]-=regs[register2] if regs[register1]<0: regs[register1]+=0xFF regs[0xF]=1 print "%X sub V%X,V%X"%(PC,register1,register2) elif value==6: regs[0xF]=regs[register1]&1 regs[register1]=regs[register1]>>1 print "%X: shr V%X"%(PC,register1) elif value==0xE: regs[0xF]=regs[register1]&128 regs[register1]=regs[register1]<<1 print "%X: shl V%X"%(PC,register1) def opcodeE(register,value,PC): if value==0x9E: if msvcrt.kbhit()==1: a=msvcrt.getch() if ord(a)==value: PC+=2 print "%X: skpr V%X"%(PC,register) elif value==0xa1: if msvcrt.kbhit()==1: a=msvcrt.getch() if ord(a)<>value: PC+=2 print "%X: skup V%X"%(PC,register) return PC def opcodeF(register,value,PC,I): if value==0x07: regs[register]=delay[0] print "%X: gdelay V%X"%(PC,register) elif value==0x0A: key=msvcrt.getch() regs[register]=key print "%X: key V%X"%(PC,register) elif value==0x15: delay[0]=regs[register] print "%X: sdelay V%X"%(PC,register) elif value==0x18: delay[1]=regs[register] print "%X: ssound V%X"%(PC,register) elif value==0x1e: I+=regs[register] print "%X: adi V%X"%(PC,register) elif value==0x29: i=regs[register]*5 print "%X: font V%X"%(PC,register) elif value==0x33: print "%X: bcd V%X"%(PC,register) #need info about binary coded decimal elif value==0x55: fil=StringIO(memory) fil.seek(I) for a in range(register): fil.write(chr(regs[a])) I+=1 print "%X: str V0-V%X"%(PC,register) elif value==0x65: for a in range(register): regs[a]=ord(memory[I]) I+=1 print "%X: ldr V0-V%X"%(PC,register) return I def gdelay(): #refresh should be 60Hz if delay[0]!=0 or delay[1]!=0: if delay[0]==0: delay[1]-=1 else: delay[0]-=1 regs=[0]*16 stack=[] screen=" "*32*64 delay=[0]*2 PC=0x200 I=0 memory="" # load a 4x5 font file=open("rom.bin","rb") memory+=file.read() file.close() memory+=" "*(0x200-len(memory)) #load a program file=open("pong","rb") memory+=file.read() file.close() print memory while PC<>0: intr=ord(memory[PC])*256+ord(memory[PC+1]) PC,I=cpu8(intr,regs,I,PC) gdelay() print "registers:", regs print "stack:",stack print "I: 0x%X"%I |
bon si quelqu'un sait comment faire en sorte que les delay[0] et delay[1] decompte à 60 Hz, qu'il n'hésite pas
( rq : je devrais tout de même commencer à m'attaquer à la partie "graphique" histoire de voir si toutes mes instructions marchent au poil ... )