diff --git a/src/apu/SndAlleg.c b/src/apu/SndAlleg.c index 5753d96..fdc9115 100755 --- a/src/apu/SndAlleg.c +++ b/src/apu/SndAlleg.c @@ -1,16 +1,17 @@ -/** EMULib Emulation Library *********************************/ -/** **/ -/** SndUnix.c **/ -/** **/ -/** This file contains standard sound generation routines **/ -/** for Unix using /dev/dsp and /dev/audio. **/ -/** **/ -/** Copyright (C) Marat Fayzullin 1996-2002 **/ -/** You are not allowed to distribute this software **/ -/** commercially. Please, notify me, if you make any **/ -/** changes to this file. **/ -/*************************************************************/ -#include "Sound.h" +/* + * Allegro Sound Driver for EMULib Sound system - The TI-NESulator Project + * SndAlleg.C + * + * Created by Manoël Trapier + * Copyright 2003-2008 986 Corp. All rights reserved. + * + * $LastChangedDate: 2007-03-28 15:50:50 +0200 (mer, 28 mar 2007) $ + * $Author: mtrapier $ + * $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/types.h $ + * $Revision: 25 $ + * + */ +#include #include @@ -27,7 +28,6 @@ AUDIOSTREAM *stream; static pthread_t ThreadID; -static int SoundFD; static int SoundRate = 0; static int MasterVolume = 64; static int MasterSwitch = (1<=SoundRate/3) break; @@ -262,7 +263,7 @@ static void *DSPLoop(void *Arg) for(I=0;I=SND_CHANNELS)||(Length<=0)) return; diff --git a/src/corecpu/Codes.h b/src/corecpu/Codes.h index 861d6c6..759b599 100755 --- a/src/corecpu/Codes.h +++ b/src/corecpu/Codes.h @@ -1,837 +1,838 @@ - /** M6502: portable 6502 emulator ****************************/ - /** **/ - /** Codes.h **/ - /** **/ - /** This file contains implementation for the main table of **/ - /** 6502 commands. It is included from 6502.c. **/ - /** **/ - /** Copyright (C) Marat Fayzullin 1996-2002 **/ - /** Alex Krasivsky 1996 **/ - /** You are not allowed to distribute this software **/ - /** commercially. Please, notify me, if you make any **/ - /** changes to this file. **/ - /*************************************************************/ -/* - * $LastChangedDate: 2007-05-31 18:01:41 +0200 (jeu, 31 mai 2007) $ - * $Author: mtrapier $ - * $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/Codes.h $ - * $Revision: 57 $ - */ - -case 0x10: -if (R->P & N_FLAG) - R->PC.W++; -else -{ - M_JR; -} break; /* BPL * REL */ - -case 0x30: -if (R->P & N_FLAG) -{ - M_JR; -} -else - R->PC.W++; -break; /* BMI * REL */ - -case 0xD0: -if (R->P & Z_FLAG) - R->PC.W++; -else -{ - M_JR; -} break; /* BNE * REL */ - -case 0xF0: -if (R->P & Z_FLAG) -{ - M_JR; -} -else - R->PC.W++; -break; /* BEQ * REL */ - -case 0x90: -if (R->P & C_FLAG) - R->PC.W++; -else -{ - M_JR; -} break; /* BCC * REL */ - -case 0xB0: -if (R->P & C_FLAG) -{ - M_JR; -} -else - R->PC.W++; -break; /* BCS * REL */ - -case 0x50: -if (R->P & V_FLAG) - R->PC.W++; -else -{ - M_JR; -} break; /* BVC * REL */ - -case 0x70: -if (R->P & V_FLAG) -{ - M_JR; -} -else - R->PC.W++; -break; /* BVS * REL */ - - - /* RTI */ -case 0x40: - -M_POP(R->P); -R->P |= R_FLAG; -M_POP(R->PC.B.l); -M_POP(R->PC.B.h); - -break; - - - /* RTS */ -case 0x60: - -M_POP(R->PC.B.l); -M_POP(R->PC.B.h); -R->PC.W++; -break; - - - /* JSR $ssss ABS */ -case 0x20: - -K.B.l = Op6502(R->PC.W++); - -K.B.h = Op6502(R->PC.W); - -M_PUSH(R->PC.B.h); - -M_PUSH(R->PC.B.l); - -R->PC = K; -break; - - - /* JMP $ssss ABS */ -case 0x4C: -M_LDWORD(K); -R->PC = K; -break; - - - /* JMP ($ssss) ABDINDIR */ -case 0x6C: - -M_LDWORD(K); - -R->PC.B.l = Rd6502(K.W); - -K.B.l++; - -R->PC.B.h = Rd6502(K.W); - -break; - - - /* BRK */ -case 0x00: - -R->PC.W++; - -M_PUSH(R->PC.B.h); -M_PUSH(R->PC.B.l); - -M_PUSH(R->P | B_FLAG); - -R->P = (R->P | I_FLAG) & ~D_FLAG; - -R->PC.B.l = Rd6502(0xFFFE); - -R->PC.B.h = Rd6502(0xFFFF); - -break; - - - /* CLI */ -case 0x58: - -if ((R->IRequest != INT_NONE) && (R->P & I_FLAG)) - -{ - - R->AfterCLI = 1; - - R->IBackup = R->ICount; - - R->ICount = 1; - -} -R->P &= ~I_FLAG; - -break; - - - /* PLP */ -case 0x28: - -M_POP(I); - -if ((R->IRequest != INT_NONE) && ((I ^ R->P) & ~I & I_FLAG)) - -{ - - R->AfterCLI = 1; - - R->IBackup = R->ICount; - - R->ICount = 1; - -} -R->P = I | R_FLAG | B_FLAG; - -break; - - -case 0x08: -M_PUSH(R->P); -break; /* PHP */ - -case 0x18: -R->P &= ~C_FLAG; -break; /* CLC */ - -case 0xB8: -R->P &= ~V_FLAG; -break; /* CLV */ - -case 0xD8: -R->P &= ~D_FLAG; -break; /* CLD */ - -case 0x38: -R->P |= C_FLAG; -break; /* SEC */ - -case 0xF8: -R->P |= D_FLAG; -break; /* SED */ - -case 0x78: -R->P |= I_FLAG; -break; /* SEI */ - -case 0x48: -M_PUSH(R->A); -break; /* PHA */ - -case 0x68: -M_POP(R->A); -M_FL(R->A); -break; /* PLA */ - -case 0x98: -R->A = R->Y; -M_FL(R->A); -break; /* TYA */ - -case 0xA8: -R->Y = R->A; -M_FL(R->Y); -break; /* TAY */ - -case 0xC8: -R->Y++; -M_FL(R->Y); -break; /* INY */ - -case 0x88: -R->Y--; -M_FL(R->Y); -break; /* DEY */ - -case 0x8A: -R->A = R->X; -M_FL(R->A); -break; /* TXA */ - -case 0xAA: -R->X = R->A; -M_FL(R->X); -break; /* TAX */ - -case 0xE8: -R->X++; -M_FL(R->X); -break; /* INX */ - -case 0xCA: -R->X--; -M_FL(R->X); -break; /* DEX */ + /** M6502: portable 6502 emulator ****************************/ + /** **/ + /** Codes.h **/ + /** **/ + /** This file contains implementation for the main table of **/ + /** 6502 commands. It is included from 6502.c. **/ + /** **/ + /** Copyright (C) Marat Fayzullin 1996-2002 **/ + /** Alex Krasivsky 1996 **/ + /** You are not allowed to distribute this software **/ + /** commercially. Please, notify me, if you make any **/ + /** changes to this file. **/ + /*************************************************************/ +/* + * $LastChangedDate: 2007-05-31 18:01:41 +0200 (jeu, 31 mai 2007) $ + * $Author: mtrapier $ + * $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/Codes.h $ + * $Revision: 57 $ + */ + +case 0x10: +if (R->P & N_FLAG) + R->PC.W++; +else +{ + M_JR; +} break; /* BPL * REL */ + +case 0x30: +if (R->P & N_FLAG) +{ + M_JR; +} +else + R->PC.W++; +break; /* BMI * REL */ + +case 0xD0: +if (R->P & Z_FLAG) + R->PC.W++; +else +{ + M_JR; +} break; /* BNE * REL */ + +case 0xF0: +if (R->P & Z_FLAG) +{ + M_JR; +} +else + R->PC.W++; +break; /* BEQ * REL */ + +case 0x90: +if (R->P & C_FLAG) + R->PC.W++; +else +{ + M_JR; +} break; /* BCC * REL */ + +case 0xB0: +if (R->P & C_FLAG) +{ + M_JR; +} +else + R->PC.W++; +break; /* BCS * REL */ + +case 0x50: +if (R->P & V_FLAG) + R->PC.W++; +else +{ + M_JR; +} break; /* BVC * REL */ + +case 0x70: +if (R->P & V_FLAG) +{ + M_JR; +} +else + R->PC.W++; +break; /* BVS * REL */ + + + /* RTI */ +case 0x40: + +M_POP(R->P); +R->P |= R_FLAG; +M_POP(R->PC.B.l); +M_POP(R->PC.B.h); + +break; + + + /* RTS */ +case 0x60: + +M_POP(R->PC.B.l); +M_POP(R->PC.B.h); +R->PC.W++; +break; + + + /* JSR $ssss ABS */ +case 0x20: + +K.B.l = Op6502(R->PC.W++); + +K.B.h = Op6502(R->PC.W); + +M_PUSH(R->PC.B.h); + +M_PUSH(R->PC.B.l); + +R->PC = K; +break; + + + /* JMP $ssss ABS */ +case 0x4C: +M_LDWORD(K); +R->PC = K; +break; + + + /* JMP ($ssss) ABDINDIR */ +case 0x6C: + +M_LDWORD(K); + +R->PC.B.l = Rd6502(K.W); + +K.B.l++; + +R->PC.B.h = Rd6502(K.W); + +break; + + + /* BRK */ +case 0x00: + +R->PC.W++; + +M_PUSH(R->PC.B.h); +M_PUSH(R->PC.B.l); + +M_PUSH(R->P | B_FLAG); + +R->P = (R->P | I_FLAG) & ~D_FLAG; + +R->PC.B.l = Rd6502(0xFFFE); + +R->PC.B.h = Rd6502(0xFFFF); + +break; + + + /* CLI */ +case 0x58: + +if ((R->IRequest != INT_NONE) && (R->P & I_FLAG)) + +{ + + R->AfterCLI = 1; + + R->IBackup = R->ICount; + + R->ICount = 1; + +} +R->P &= ~I_FLAG; + +break; + + + /* PLP */ +case 0x28: + +M_POP(I); + +if ((R->IRequest != INT_NONE) && ((I ^ R->P) & ~I & I_FLAG)) + +{ + + R->AfterCLI = 1; + + R->IBackup = R->ICount; + + R->ICount = 1; + +} +R->P = I | R_FLAG | B_FLAG; + +break; + + +case 0x08: +M_PUSH(R->P); +break; /* PHP */ + +case 0x18: +R->P &= ~C_FLAG; +break; /* CLC */ + +case 0xB8: +R->P &= ~V_FLAG; +break; /* CLV */ + +case 0xD8: +R->P &= ~D_FLAG; +break; /* CLD */ + +case 0x38: +R->P |= C_FLAG; +break; /* SEC */ + +case 0xF8: +R->P |= D_FLAG; +break; /* SED */ + +case 0x78: +R->P |= I_FLAG; +break; /* SEI */ + +case 0x48: +M_PUSH(R->A); +break; /* PHA */ + +case 0x68: +M_POP(R->A); +M_FL(R->A); +break; /* PLA */ + +case 0x98: +R->A = R->Y; +M_FL(R->A); +break; /* TYA */ + +case 0xA8: +R->Y = R->A; +M_FL(R->Y); +break; /* TAY */ + +case 0xC8: +R->Y++; +M_FL(R->Y); +break; /* INY */ + +case 0x88: +R->Y--; +M_FL(R->Y); +break; /* DEY */ + +case 0x8A: +R->A = R->X; +M_FL(R->A); +break; /* TXA */ + +case 0xAA: +R->X = R->A; +M_FL(R->X); +break; /* TAX */ + +case 0xE8: +R->X++; +M_FL(R->X); +break; /* INX */ + +case 0xCA: +R->X--; +M_FL(R->X); +break; /* DEX */ default: /* In CMOS version unrecognized instructions are concidered as - NOP */ -case 0xEA: -break; /* NOP */ - -case 0x9A: -R->S = R->X; -break; /* TXS */ - -case 0xBA: -R->X = R->S; -M_FL(R->X); -break; /* TSX */ - - -case 0x24: -MR_Zp(I); -M_BIT(I); -break; /* BIT $ss ZP */ - -case 0x2C: -MR_Ab(I); -M_BIT(I); -break; /* BIT $ssss ABS */ - - -case 0x05: -MR_Zp(I); -M_ORA(I); -break; /* ORA $ss ZP */ - -case 0x06: -MM_Zp(M_ASL); -break; /* ASL $ss ZP */ - -case 0x25: -MR_Zp(I); -M_AND(I); -break; /* AND $ss ZP */ - -case 0x26: -MM_Zp(M_ROL); -break; /* ROL $ss ZP */ - -case 0x45: -MR_Zp(I); -M_EOR(I); -break; /* EOR $ss ZP */ - -case 0x46: -MM_Zp(M_LSR); -break; /* LSR $ss ZP */ - -case 0x65: -MR_Zp(I); -M_ADC(I); -break; /* ADC $ss ZP */ - -case 0x66: -MM_Zp(M_ROR); -break; /* ROR $ss ZP */ - -case 0x84: -MW_Zp(R->Y); -break; /* STY $ss ZP */ - -case 0x85: -MW_Zp(R->A); -break; /* STA $ss ZP */ - -case 0x86: -MW_Zp(R->X); -break; /* STX $ss ZP */ - -case 0xA4: -MR_Zp(R->Y); -M_FL(R->Y); -break; /* LDY $ss ZP */ - -case 0xA5: -MR_Zp(R->A); -M_FL(R->A); -break; /* LDA $ss ZP */ - -case 0xA6: -MR_Zp(R->X); -M_FL(R->X); -break; /* LDX $ss ZP */ - -case 0xC4: -MR_Zp(I); -M_CMP(R->Y, I); -break; /* CPY $ss ZP */ - -case 0xC5: -MR_Zp(I); -M_CMP(R->A, I); -break; /* CMP $ss ZP */ - -case 0xC6: -MM_Zp(M_DEC); -break; /* DEC $ss ZP */ - -case 0xE4: -MR_Zp(I); -M_CMP(R->X, I); -break; /* CPX $ss ZP */ - -case 0xE5: -MR_Zp(I); -M_SBC(I); -break; /* SBC $ss ZP */ - -case 0xE6: -MM_Zp(M_INC); -break; /* INC $ss ZP */ - - -case 0x0D: -MR_Ab(I); -M_ORA(I); -break; /* ORA $ssss ABS */ - -case 0x0E: -MM_Ab(M_ASL); -break; /* ASL $ssss ABS */ - -case 0x2D: -MR_Ab(I); -M_AND(I); -break; /* AND $ssss ABS */ - -case 0x2E: -MM_Ab(M_ROL); -break; /* ROL $ssss ABS */ - -case 0x4D: -MR_Ab(I); -M_EOR(I); -break; /* EOR $ssss ABS */ - -case 0x4E: -MM_Ab(M_LSR); -break; /* LSR $ssss ABS */ - -case 0x6D: -MR_Ab(I); -M_ADC(I); -break; /* ADC $ssss ABS */ - -case 0x6E: -MM_Ab(M_ROR); -break; /* ROR $ssss ABS */ - -case 0x8C: -MW_Ab(R->Y); -break; /* STY $ssss ABS */ - -case 0x8D: -MW_Ab(R->A); -break; /* STA $ssss ABS */ - -case 0x8E: -MW_Ab(R->X); -break; /* STX $ssss ABS */ - -case 0xAC: -MR_Ab(R->Y); -M_FL(R->Y); -break; /* LDY $ssss ABS */ - -case 0xAD: -MR_Ab(R->A); -M_FL(R->A); -break; /* LDA $ssss ABS */ - -case 0xAE: -MR_Ab(R->X); -M_FL(R->X); -break; /* LDX $ssss ABS */ - -case 0xCC: -MR_Ab(I); -M_CMP(R->Y, I); -break; /* CPY $ssss ABS */ - -case 0xCD: -MR_Ab(I); -M_CMP(R->A, I); -break; /* CMP $ssss ABS */ - -case 0xCE: -MM_Ab(M_DEC); -break; /* DEC $ssss ABS */ - -case 0xEC: -MR_Ab(I); -M_CMP(R->X, I); -break; /* CPX $ssss ABS */ - -case 0xED: -MR_Ab(I); -M_SBC(I); -break; /* SBC $ssss ABS */ - -case 0xEE: -MM_Ab(M_INC); -break; /* INC $ssss ABS */ - - -case 0x09: -MR_Im(I); -M_ORA(I); -break; /* ORA #$ss IMM */ - -case 0x29: -MR_Im(I); -M_AND(I); -break; /* AND #$ss IMM */ - -case 0x49: -MR_Im(I); -M_EOR(I); -break; /* EOR #$ss IMM */ - -case 0x69: -MR_Im(I); -M_ADC(I); -break; /* ADC #$ss IMM */ - -case 0xA0: -MR_Im(R->Y); -M_FL(R->Y); -break; /* LDY #$ss IMM */ - -case 0xA2: -MR_Im(R->X); -M_FL(R->X); -break; /* LDX #$ss IMM */ - -case 0xA9: -MR_Im(R->A); -M_FL(R->A); -break; /* LDA #$ss IMM */ - -case 0xC0: -MR_Im(I); -M_CMP(R->Y, I); -break; /* CPY #$ss IMM */ - -case 0xC9: -MR_Im(I); -M_CMP(R->A, I); -break; /* CMP #$ss IMM */ - -case 0xE0: -MR_Im(I); -M_CMP(R->X, I); -break; /* CPX #$ss IMM */ - -case 0xE9: -MR_Im(I); -M_SBC(I); -break; /* SBC #$ss IMM */ - - -case 0x15: -MR_Zx(I); -M_ORA(I); -break; /* ORA $ss,x ZP,x */ - -case 0x16: -MM_Zx(M_ASL); -break; /* ASL $ss,x ZP,x */ - -case 0x35: -MR_Zx(I); -M_AND(I); -break; /* AND $ss,x ZP,x */ - -case 0x36: -MM_Zx(M_ROL); -break; /* ROL $ss,x ZP,x */ - -case 0x55: -MR_Zx(I); -M_EOR(I); -break; /* EOR $ss,x ZP,x */ - -case 0x56: -MM_Zx(M_LSR); -break; /* LSR $ss,x ZP,x */ - -case 0x75: -MR_Zx(I); -M_ADC(I); -break; /* ADC $ss,x ZP,x */ - -case 0x76: -MM_Zx(M_ROR); -break; /* ROR $ss,x ZP,x */ - -case 0x94: -MW_Zx(R->Y); -break; /* STY $ss,x ZP,x */ - -case 0x95: -MW_Zx(R->A); -break; /* STA $ss,x ZP,x */ - -case 0x96: -MW_Zy(R->X); -break; /* STX $ss,y ZP,y */ - -case 0xB4: -MR_Zx(R->Y); -M_FL(R->Y); -break; /* LDY $ss,x ZP,x */ - -case 0xB5: -MR_Zx(R->A); -M_FL(R->A); -break; /* LDA $ss,x ZP,x */ - -case 0xB6: -MR_Zy(R->X); -M_FL(R->X); -break; /* LDX $ss,y ZP,y */ - -case 0xD5: -MR_Zx(I); -M_CMP(R->A, I); -break; /* CMP $ss,x ZP,x */ - -case 0xD6: -MM_Zx(M_DEC); -break; /* DEC $ss,x ZP,x */ - -case 0xF5: -MR_Zx(I); -M_SBC(I); -break; /* SBC $ss,x ZP,x */ - -case 0xF6: -MM_Zx(M_INC); -break; /* INC $ss,x ZP,x */ - - -case 0x19: -MR_Ay(I); -M_ORA(I); -break; /* ORA $ssss,y ABS,y */ - -case 0x1D: -MR_Ax(I); -M_ORA(I); -break; /* ORA $ssss,x ABS,x */ - -case 0x1E: -MM_Ax(M_ASL); -break; /* ASL $ssss,x ABS,x */ - -case 0x39: -MR_Ay(I); -M_AND(I); -break; /* AND $ssss,y ABS,y */ - -case 0x3D: -MR_Ax(I); -M_AND(I); -break; /* AND $ssss,x ABS,x */ - -case 0x3E: -MM_Ax(M_ROL); -break; /* ROL $ssss,x ABS,x */ - -case 0x59: -MR_Ay(I); -M_EOR(I); -break; /* EOR $ssss,y ABS,y */ - -case 0x5D: -MR_Ax(I); -M_EOR(I); -break; /* EOR $ssss,x ABS,x */ - -case 0x5E: -MM_Ax(M_LSR); -break; /* LSR $ssss,x ABS,x */ - -case 0x79: -MR_Ay(I); -M_ADC(I); -break; /* ADC $ssss,y ABS,y */ - -case 0x7D: -MR_Ax(I); -M_ADC(I); -break; /* ADC $ssss,x ABS,x */ - -case 0x7E: -MM_Ax(M_ROR); -break; /* ROR $ssss,x ABS,x */ - -case 0x99: -MW_Ay(R->A); -break; /* STA $ssss,y ABS,y */ - -case 0x9D: -MW_Ax(R->A); -break; /* STA $ssss,x ABS,x */ - -case 0xB9: -MR_Ay(R->A); -M_FL(R->A); -break; /* LDA $ssss,y ABS,y */ - -case 0xBC: -MR_Ax(R->Y); -M_FL(R->Y); -break; /* LDY $ssss,x ABS,x */ - -case 0xBD: -MR_Ax(R->A); -M_FL(R->A); -break; /* LDA $ssss,x ABS,x */ - -case 0xBE: -MR_Ay(R->X); -M_FL(R->X); -break; /* LDX $ssss,y ABS,y */ - -case 0xD9: -MR_Ay(I); -M_CMP(R->A, I); -break; /* CMP $ssss,y ABS,y */ - -case 0xDD: -MR_Ax(I); -M_CMP(R->A, I); -break; /* CMP $ssss,x ABS,x */ - -case 0xDE: -MM_Ax(M_DEC); -break; /* DEC $ssss,x ABS,x */ - -case 0xF9: -MR_Ay(I); -M_SBC(I); -break; /* SBC $ssss,y ABS,y */ - -case 0xFD: -MR_Ax(I); -M_SBC(I); -break; /* SBC $ssss,x ABS,x */ - -case 0xFE: -MM_Ax(M_INC); -break; /* INC $ssss,x ABS,x */ - - -case 0x01: -MR_Ix(I); -M_ORA(I); -break; /* ORA ($ss,x) INDEXINDIR */ - -case 0x11: -MR_Iy(I); -M_ORA(I); -break; /* ORA ($ss),y INDIRINDEX */ - -case 0x21: -MR_Ix(I); -M_AND(I); -break; /* AND ($ss,x) INDEXINDIR */ - -case 0x31: -MR_Iy(I); -M_AND(I); -break; /* AND ($ss),y INDIRINDEX */ - -case 0x41: -MR_Ix(I); -M_EOR(I); -break; /* EOR ($ss,x) INDEXINDIR */ - -case 0x51: -MR_Iy(I); -M_EOR(I); -break; /* EOR ($ss),y INDIRINDEX */ - -case 0x61: -MR_Ix(I); -M_ADC(I); -break; /* ADC ($ss,x) INDEXINDIR */ - -case 0x71: -MR_Iy(I); -M_ADC(I); -break; /* ADC ($ss),y INDIRINDEX */ - -case 0x81: -MW_Ix(R->A); -break; /* STA ($ss,x) INDEXINDIR */ - -case 0x91: -MW_Iy(R->A); -break; /* STA ($ss),y INDIRINDEX */ - -case 0xA1: -MR_Ix(R->A); -M_FL(R->A); -break; /* LDA ($ss,x) INDEXINDIR */ - -case 0xB1: -MR_Iy(R->A); -M_FL(R->A); -break; /* LDA ($ss),y INDIRINDEX */ - -case 0xC1: -MR_Ix(I); -M_CMP(R->A, I); -break; /* CMP ($ss,x) INDEXINDIR */ - -case 0xD1: -MR_Iy(I); -M_CMP(R->A, I); -break; /* CMP ($ss),y INDIRINDEX */ - -case 0xE1: -MR_Ix(I); -M_SBC(I); -break; /* SBC ($ss,x) INDEXINDIR */ - -case 0xF1: -MR_Iy(I); -M_SBC(I); -break; /* SBC ($ss),y INDIRINDEX */ - - -case 0x0A: -M_ASL(R->A); -break; /* ASL a ACC */ - -case 0x2A: -M_ROL(R->A); -break; /* ROL a ACC */ - -case 0x4A: -M_LSR(R->A); -break; /* LSR a ACC */ - -case 0x6A: -M_ROR(R->A); -break; /* ROR a ACC */ - + NOP */ +case 0xEA: +break; /* NOP */ + +case 0x9A: +R->S = R->X; +break; /* TXS */ + +case 0xBA: +R->X = R->S; +M_FL(R->X); +break; /* TSX */ + + +case 0x24: +MR_Zp(I); +M_BIT(I); +break; /* BIT $ss ZP */ + +case 0x2C: +MR_Ab(I); +M_BIT(I); +break; /* BIT $ssss ABS */ + + +case 0x05: +MR_Zp(I); +M_ORA(I); +break; /* ORA $ss ZP */ + +case 0x06: +MM_Zp(M_ASL); +break; /* ASL $ss ZP */ + +case 0x25: +MR_Zp(I); +M_AND(I); +break; /* AND $ss ZP */ + +case 0x26: +MM_Zp(M_ROL); +break; /* ROL $ss ZP */ + +case 0x45: +MR_Zp(I); +M_EOR(I); +break; /* EOR $ss ZP */ + +case 0x46: +MM_Zp(M_LSR); +break; /* LSR $ss ZP */ + +case 0x65: +MR_Zp(I); +M_ADC(I); +break; /* ADC $ss ZP */ + +case 0x66: +MM_Zp(M_ROR); +break; /* ROR $ss ZP */ + +case 0x84: +MW_Zp(R->Y); +break; /* STY $ss ZP */ + +case 0x85: +MW_Zp(R->A); +break; /* STA $ss ZP */ + +case 0x86: +MW_Zp(R->X); +break; /* STX $ss ZP */ + +case 0xA4: +MR_Zp(R->Y); +M_FL(R->Y); +break; /* LDY $ss ZP */ + +case 0xA5: +MR_Zp(R->A); +M_FL(R->A); +break; /* LDA $ss ZP */ + +case 0xA6: +MR_Zp(R->X); +M_FL(R->X); +break; /* LDX $ss ZP */ + +case 0xC4: +MR_Zp(I); +M_CMP(R->Y, I); +break; /* CPY $ss ZP */ + +case 0xC5: +MR_Zp(I); +M_CMP(R->A, I); +break; /* CMP $ss ZP */ + +case 0xC6: +MM_Zp(M_DEC); +break; /* DEC $ss ZP */ + +case 0xE4: +MR_Zp(I); +M_CMP(R->X, I); +break; /* CPX $ss ZP */ + +case 0xE5: +MR_Zp(I); +M_SBC(I); +break; /* SBC $ss ZP */ + +case 0xE6: +MM_Zp(M_INC); +break; /* INC $ss ZP */ + + +case 0x0D: +MR_Ab(I); +M_ORA(I); +break; /* ORA $ssss ABS */ + +case 0x0E: +MM_Ab(M_ASL); +break; /* ASL $ssss ABS */ + +case 0x2D: +MR_Ab(I); +M_AND(I); +break; /* AND $ssss ABS */ + +case 0x2E: +MM_Ab(M_ROL); +break; /* ROL $ssss ABS */ + +case 0x4D: +MR_Ab(I); +M_EOR(I); +break; /* EOR $ssss ABS */ + +case 0x4E: +MM_Ab(M_LSR); +break; /* LSR $ssss ABS */ + +case 0x6D: +MR_Ab(I); +M_ADC(I); +break; /* ADC $ssss ABS */ + +case 0x6E: +MM_Ab(M_ROR); +break; /* ROR $ssss ABS */ + +case 0x8C: +MW_Ab(R->Y); +break; /* STY $ssss ABS */ + +case 0x8D: +MW_Ab(R->A); +break; /* STA $ssss ABS */ + +case 0x8E: +MW_Ab(R->X); +break; /* STX $ssss ABS */ + +case 0xAC: +MR_Ab(R->Y); +M_FL(R->Y); +break; /* LDY $ssss ABS */ + +case 0xAD: +MR_Ab(R->A); +M_FL(R->A); +break; /* LDA $ssss ABS */ + +case 0xAE: +MR_Ab(R->X); +M_FL(R->X); +break; /* LDX $ssss ABS */ + +case 0xCC: +MR_Ab(I); +M_CMP(R->Y, I); +break; /* CPY $ssss ABS */ + +case 0xCD: +MR_Ab(I); +M_CMP(R->A, I); +break; /* CMP $ssss ABS */ + +case 0xCE: +MM_Ab(M_DEC); +break; /* DEC $ssss ABS */ + +case 0xEC: +MR_Ab(I); +M_CMP(R->X, I); +break; /* CPX $ssss ABS */ + +case 0xED: +MR_Ab(I); +M_SBC(I); +break; /* SBC $ssss ABS */ + +case 0xEE: +MM_Ab(M_INC); +break; /* INC $ssss ABS */ + + +case 0x09: +MR_Im(I); +M_ORA(I); +break; /* ORA #$ss IMM */ + +case 0x29: +MR_Im(I); +M_AND(I); +break; /* AND #$ss IMM */ + +case 0x49: +MR_Im(I); +M_EOR(I); +break; /* EOR #$ss IMM */ + +case 0x69: +MR_Im(I); +M_ADC(I); +break; /* ADC #$ss IMM */ + +case 0xA0: +MR_Im(R->Y); +M_FL(R->Y); +break; /* LDY #$ss IMM */ + +case 0xA2: +MR_Im(R->X); +M_FL(R->X); +break; /* LDX #$ss IMM */ + +case 0xA9: +MR_Im(R->A); +M_FL(R->A); +break; /* LDA #$ss IMM */ + +case 0xC0: +MR_Im(I); +M_CMP(R->Y, I); +break; /* CPY #$ss IMM */ + +case 0xC9: +MR_Im(I); +M_CMP(R->A, I); +break; /* CMP #$ss IMM */ + +case 0xE0: +MR_Im(I); +M_CMP(R->X, I); +break; /* CPX #$ss IMM */ + +case 0xE9: +MR_Im(I); +M_SBC(I); +break; /* SBC #$ss IMM */ + + +case 0x15: +MR_Zx(I); +M_ORA(I); +break; /* ORA $ss,x ZP,x */ + +case 0x16: +MM_Zx(M_ASL); +break; /* ASL $ss,x ZP,x */ + +case 0x35: +MR_Zx(I); +M_AND(I); +break; /* AND $ss,x ZP,x */ + +case 0x36: +MM_Zx(M_ROL); +break; /* ROL $ss,x ZP,x */ + +case 0x55: +MR_Zx(I); +M_EOR(I); +break; /* EOR $ss,x ZP,x */ + +case 0x56: +MM_Zx(M_LSR); +break; /* LSR $ss,x ZP,x */ + +case 0x75: +MR_Zx(I); +M_ADC(I); +break; /* ADC $ss,x ZP,x */ + +case 0x76: +MM_Zx(M_ROR); +break; /* ROR $ss,x ZP,x */ + +case 0x94: +MW_Zx(R->Y); +break; /* STY $ss,x ZP,x */ + +case 0x95: +MW_Zx(R->A); +break; /* STA $ss,x ZP,x */ + +case 0x96: +MW_Zy(R->X); +break; /* STX $ss,y ZP,y */ + +case 0xB4: +MR_Zx(R->Y); +M_FL(R->Y); +break; /* LDY $ss,x ZP,x */ + +case 0xB5: +MR_Zx(R->A); +M_FL(R->A); +break; /* LDA $ss,x ZP,x */ + +case 0xB6: +MR_Zy(R->X); +M_FL(R->X); +break; /* LDX $ss,y ZP,y */ + +case 0xD5: +MR_Zx(I); +M_CMP(R->A, I); +break; /* CMP $ss,x ZP,x */ + +case 0xD6: +MM_Zx(M_DEC); +break; /* DEC $ss,x ZP,x */ + +case 0xF5: +MR_Zx(I); +M_SBC(I); +break; /* SBC $ss,x ZP,x */ + +case 0xF6: +MM_Zx(M_INC); +break; /* INC $ss,x ZP,x */ + + +case 0x19: +MR_Ay(I); +M_ORA(I); +break; /* ORA $ssss,y ABS,y */ + +case 0x1D: +MR_Ax(I); +M_ORA(I); +break; /* ORA $ssss,x ABS,x */ + +case 0x1E: +MM_Ax(M_ASL); +break; /* ASL $ssss,x ABS,x */ + +case 0x39: +MR_Ay(I); +M_AND(I); +break; /* AND $ssss,y ABS,y */ + +case 0x3D: +MR_Ax(I); +M_AND(I); +break; /* AND $ssss,x ABS,x */ + +case 0x3E: +MM_Ax(M_ROL); +break; /* ROL $ssss,x ABS,x */ + +case 0x59: +MR_Ay(I); +M_EOR(I); +break; /* EOR $ssss,y ABS,y */ + +case 0x5D: +MR_Ax(I); +M_EOR(I); +break; /* EOR $ssss,x ABS,x */ + +case 0x5E: +MM_Ax(M_LSR); +break; /* LSR $ssss,x ABS,x */ + +case 0x79: +MR_Ay(I); +M_ADC(I); +break; /* ADC $ssss,y ABS,y */ + +case 0x7D: +MR_Ax(I); +M_ADC(I); +break; /* ADC $ssss,x ABS,x */ + +case 0x7E: +MM_Ax(M_ROR); +break; /* ROR $ssss,x ABS,x */ + +case 0x99: +MW_Ay(R->A); +break; /* STA $ssss,y ABS,y */ + +case 0x9D: +MW_Ax(R->A); +break; /* STA $ssss,x ABS,x */ + +case 0xB9: +MR_Ay(R->A); +M_FL(R->A); +break; /* LDA $ssss,y ABS,y */ + +case 0xBC: +MR_Ax(R->Y); +M_FL(R->Y); +break; /* LDY $ssss,x ABS,x */ + +case 0xBD: +MR_Ax(R->A); +M_FL(R->A); +break; /* LDA $ssss,x ABS,x */ + +case 0xBE: +MR_Ay(R->X); +M_FL(R->X); +break; /* LDX $ssss,y ABS,y */ + +case 0xD9: +MR_Ay(I); +M_CMP(R->A, I); +break; /* CMP $ssss,y ABS,y */ + +case 0xDD: +MR_Ax(I); +M_CMP(R->A, I); +break; /* CMP $ssss,x ABS,x */ + +case 0xDE: +MM_Ax(M_DEC); +break; /* DEC $ssss,x ABS,x */ + +case 0xF9: +MR_Ay(I); +M_SBC(I); +break; /* SBC $ssss,y ABS,y */ + +case 0xFD: +MR_Ax(I); +M_SBC(I); +break; /* SBC $ssss,x ABS,x */ + +case 0xFE: +MM_Ax(M_INC); +break; /* INC $ssss,x ABS,x */ + + +case 0x01: +MR_Ix(I); +M_ORA(I); +break; /* ORA ($ss,x) INDEXINDIR */ + +case 0x11: +MR_Iy(I); +M_ORA(I); +break; /* ORA ($ss),y INDIRINDEX */ + +case 0x21: +MR_Ix(I); +M_AND(I); +break; /* AND ($ss,x) INDEXINDIR */ + +case 0x31: +MR_Iy(I); +M_AND(I); +break; /* AND ($ss),y INDIRINDEX */ + +case 0x41: +MR_Ix(I); +M_EOR(I); +break; /* EOR ($ss,x) INDEXINDIR */ + +case 0x51: +MR_Iy(I); +M_EOR(I); +break; /* EOR ($ss),y INDIRINDEX */ + +case 0x61: +MR_Ix(I); +M_ADC(I); +break; /* ADC ($ss,x) INDEXINDIR */ + +case 0x71: +MR_Iy(I); +M_ADC(I); +break; /* ADC ($ss),y INDIRINDEX */ + +case 0x81: +MW_Ix(R->A); +break; /* STA ($ss,x) INDEXINDIR */ + +case 0x91: +MW_Iy(R->A); +break; /* STA ($ss),y INDIRINDEX */ + +case 0xA1: +MR_Ix(R->A); +M_FL(R->A); +break; /* LDA ($ss,x) INDEXINDIR */ + +case 0xB1: +MR_Iy(R->A); +M_FL(R->A); +break; /* LDA ($ss),y INDIRINDEX */ + +case 0xC1: +MR_Ix(I); +M_CMP(R->A, I); +break; /* CMP ($ss,x) INDEXINDIR */ + +case 0xD1: +MR_Iy(I); +M_CMP(R->A, I); +break; /* CMP ($ss),y INDIRINDEX */ + +case 0xE1: +MR_Ix(I); +M_SBC(I); +break; /* SBC ($ss,x) INDEXINDIR */ + +case 0xF1: +MR_Iy(I); +M_SBC(I); +break; /* SBC ($ss),y INDIRINDEX */ + + +case 0x0A: +M_ASL(R->A); +break; /* ASL a ACC */ + +case 0x2A: +M_ROL(R->A); +break; /* ROL a ACC */ + +case 0x4A: +M_LSR(R->A); +break; /* LSR a ACC */ + +case 0x6A: +M_ROR(R->A); +break; /* ROR a ACC */ + + diff --git a/src/corecpu/Debug.c b/src/corecpu/Debug.c index ecede48..2d28a20 100755 --- a/src/corecpu/Debug.c +++ b/src/corecpu/Debug.c @@ -1,480 +1,482 @@ -/** M6502: portable 6502 emulator ****************************/ -/** **/ -/** Debug.c **/ -/** **/ -/** This file contains the built-in debugging routine for **/ -/** the 6502 emulator which is called on each 6502 step **/ -/** when Trap!=0. **/ -/** **/ -/** Copyright (C) Marat Fayzullin 1996-1997 **/ -/** Alex Krasivsky 1996 **/ -/** You are not allowed to distribute this software **/ -/** commercially. Please, notify me, if you make any **/ -/** changes to this file. **/ -/*************************************************************/ -/* - * $LastChangedDate: 2007-04-19 18:18:57 +0200 (jeu, 19 avr 2007) $ - * $Author: mtrapier $ - * $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/Debug.c $ - * $Revision: 43 $ - */ - -#include "M6502.h" -#ifdef DEBUG -#include -#include -#include -#include - -#include - -#include - -#define RDWORD(A) (Rd6502(A+1)*256+Rd6502(A)) - -extern unsigned char *Memory; - -void showlastop(); - -enum Addressing_Modes -{ - Ac = 0, Il, Im, Ab, Zp, Zx, Zy, Ax, Ay, Rl, Ix, Iy, In, No -}; - - - -static byte *mn[] = -{ - "adc ", "and ", "asl ", "bcc ", "bcs ", "beq ", "bit ", "bmi ", - "bne ", "bpl ", "brk", "bvc ", "bvs ", "clc", "cld", "cli", - "clv", "cmp ", "cpx ", "cpy ", "dec ", "dex", "dey", "inx", - "iny", "eor ", "inc ", "jmp ", "jsr ", "lda ", "nop ", "ldx ", - "ldy ", "lsr ", "ora ", "pha", "php", "pla", "plp", "rol ", - "ror ", "rti", "rts", "sbc ", "sta ", "stx ", "sty ", "sec ", - "sed", "sei", "tax", "tay", "txa", "tya", "tsx", "txs" -}; - - - -static byte ad[512] = -{ - 10, Il, 34, Ix, No, No, No, No, No, No, 34, Zp, 2, Zp, No, No, - 36, Il, 34, Im, 2, Ac, No, No, No, No, 34, Ab, 2, Ab, No, No, - 9, Rl, 34, Iy, No, No, No, No, No, No, 34, Zx, 2, Zx, No, No, - 13, Il, 34, Ay, No, No, No, No, No, No, 34, Ax, 2, Ax, No, No, - 28, Ab, 1, Ix, No, No, No, No, 6, Zp, 1, Zp, 39, Zp, No, No, - 38, Il, 1, Im, 39, Ac, No, No, 6, Ab, 1, Ab, 39, Ab, No, No, - 7, Rl, 1, Iy, No, No, No, No, No, No, 1, Zx, 39, Zx, No, No, - 47, Il, 1, Ay, No, No, No, No, No, No, 1, Ax, 39, Ax, No, No, - 41, Il, 25, Ix, No, No, No, No, No, No, 25, Zp, 33, Zp, No, No, - 35, Il, 25, Im, 33, Ac, No, No, 27, Ab, 25, Ab, 33, Ab, No, No, - 11, Rl, 25, Iy, No, No, No, No, No, No, 25, Zx, 33, Zx, No, No, - 15, Il, 25, Ay, No, No, No, No, No, No, 25, Ax, 33, Ax, No, No, - 42, Il, 0, Ix, No, No, No, No, No, No, 0, Zp, 40, Zp, No, No, - 37, Il, 0, Im, 40, Ac, No, No, 27, In, 0, Ab, 40, Ab, No, No, - 12, Rl, 0, Iy, No, No, No, No, No, No, 0, Zx, 40, Zx, No, No, - 49, Il, 0, Ay, No, No, No, No, No, No, 0, Ax, 40, Ax, No, No, - No, No, 44, Ix, No, No, No, No, 46, Zp, 44, Zp, 45, Zp, No, No, - 22, Il, No, No, 52, Il, No, No, 46, Ab, 44, Ab, 45, Ab, No, No, - 3, Rl, 44, Iy, No, No, No, No, 46, Zx, 44, Zx, 45, Zy, No, No, - 53, Il, 44, Ay, 55, Il, No, No, No, No, 44, Ax, No, No, No, No, - 32, Im, 29, Ix, 31, Im, No, No, 32, Zp, 29, Zp, 31, Zp, No, No, - 51, Il, 29, Im, 50, Il, No, No, 32, Ab, 29, Ab, 31, Ab, No, No, - 4, Rl, 29, Iy, No, No, No, No, 32, Zx, 29, Zx, 31, Zy, No, No, - 16, Il, 29, Ay, 54, Il, No, No, 32, Ax, 29, Ax, 31, Ay, No, No, - 19, Im, 17, Ix, No, No, No, No, 19, Zp, 17, Zp, 20, Zp, No, No, - 24, Il, 17, Im, 21, Il, No, No, 19, Ab, 17, Ab, 20, Ab, No, No, - 8, Rl, 17, Iy, No, No, No, No, No, No, 17, Zx, 20, Zx, No, No, - 14, Il, 17, Ay, No, No, No, No, No, No, 17, Ax, 20, Ax, No, No, - 18, Im, 43, Ix, No, No, No, No, 18, Zp, 43, Zp, 26, Zp, No, No, - 23, Il, 43, Im, 30, Il, No, No, 18, Ab, 43, Ab, 26, Ab, No, No, - 5, Rl, 43, Iy, No, No, No, No, No, No, 43, Zx, 26, Zx, No, No, - 48, Il, 43, Ay, No, No, No, No, No, No, 43, Ax, 26, Ax, No, No -}; - - - -/** DAsm() ****************************************************/ -/** This function will disassemble a single command and **/ -/** return the number of bytes disassembled. **/ -/**************************************************************/ -int DAsm(char *S, word A) -{ - - byte J; - - word B, OP, TO; - - - B = A; - OP = Rd6502(B++) * 2; - - - switch (ad[OP + 1]) - - { - - case Ac: - sprintf(S, "%s a", mn[ad[OP]]); - break; - - case Il: - sprintf(S, "%s", mn[ad[OP]]); - break; - - - case Rl: - J = Rd6502(B++); - TO = A + 2 + ((J < 0x80) ? J : (J - 256)); - - sprintf(S, "%s $%04X", mn[ad[OP]], TO); - break; - - - case Im: - sprintf(S, "%s #$%02X", mn[ad[OP]], Rd6502(B++)); - break; - - case Zp: - sprintf(S, "%s $%02X", mn[ad[OP]], Rd6502(B++)); - break; - - case Zx: - sprintf(S, "%s $%02X,x", mn[ad[OP]], Rd6502(B++)); - break; - - case Zy: - sprintf(S, "%s $%02X,y", mn[ad[OP]], Rd6502(B++)); - break; - - case Ix: - sprintf(S, "%s ($%02X,x)", mn[ad[OP]], Rd6502(B++)); - break; - - case Iy: - sprintf(S, "%s ($%02X),y", mn[ad[OP]], Rd6502(B++)); - break; - - - case Ab: - sprintf(S, "%s $%04X", mn[ad[OP]], RDWORD(B)); - B += 2; - break; - - case Ax: - sprintf(S, "%s $%04X,x", mn[ad[OP]], RDWORD(B)); - B += 2; - break; - - case Ay: - sprintf(S, "%s $%04X,y", mn[ad[OP]], RDWORD(B)); - B += 2; - break; - - case In: - sprintf(S, "%s ($%04X)", mn[ad[OP]], RDWORD(B)); - B += 2; - break; - - - default: - sprintf(S, ".db $%02X; ", OP / 2); - - } - return (B - A); - -} - - -/** Debug6502() **********************************************/ -/** This function should exist if DEBUG is #defined. When **/ -/** Trace!=0, it is called after each command executed by **/ -/** the CPU, and given the 6502 registers. Emulation exits **/ -/** if Debug6502() returns 0. **/ -/*************************************************************/ -byte Debug6502(M6502 * R) -{ - static char FA[8] = "NVRBDIZC"; - char S[128]; - byte F; - int J, I; - - DAsm(S, R->PC.W); - - printf - ( - "A:%02X P:%02X X:%02X Y:%02X S:%04X PC:%04X Flags:[", - R->A, R->P, R->X, R->Y, R->S + 0x0100, R->PC.W - ); - - - for (J = 0, F = R->P; J < 8; J++, F <<= 1) - - printf("%c", F & 0x80 ? FA[J] : '.'); - - puts("]"); - - - printf - ( - "AT PC: [%02X - %s] AT SP: [%02X %02X %02X]\n", - Rd6502(R->PC.W), S, - Rd6502(0x0100 + (byte) (R->S + 1)), - Rd6502(0x0100 + (byte) (R->S + 2)), - Rd6502(0x0100 + (byte) (R->S + 3)) - ); - - - sprintf(S, ""); - remove_keyboard(); - -#ifdef USE_SOUND - StopSound(); -#endif - - - while (1) - { - printf("\n[Command,'?']-> "); - - fflush(stdout); - fflush(stdin); - - - fgets(S, 50, stdin); - - for (J = 0; S[J] >= ' '; J++) - S[J] = toupper(S[J]); - - S[J] = '\0'; - - - switch (S[0]) - { - case 'H': - case '?': - puts("\n***** Built-in 6502 Debugger Commands *****"); - puts(" : Break at the next instruction"); - puts("= : Break at addr"); - puts("+ : Break at PC + offset"); - puts("t : Set PC to addr"); - puts("c : Continue without break"); - puts("j : Continue from addr"); - puts("m : Memory dump at addr"); - puts("d : Disassembly at addr"); - puts("v : Show ;interrupt vectors"); - puts("?,h : Show this help text"); - puts("r : Show Register Status"); - puts("q : Exit 6502 emulation"); - - puts("----- TI-NES Specific -----"); - puts("w : Dump Memory State"); - puts("o : Show PPU registers"); - puts("p : Dump PPU memory at addr"); - puts("a : Dump all memory to memory.log"); - puts("s : Dump sprite table to sprite.log"); - puts("n : Dump name table to nt.log"); - puts("z : Show lastest opcode executed"); - puts("i : SpriteTable Dump"); - puts("g : Get sprite info"); - break; - - case '\0': - return (1); - - case 'Z': - showlastop(); - break; - - case 'W': - DumpMemoryState(stdout); - break; - - - case 'A': - { - - FILE * fpDmpMem; - - if ((fpDmpMem = fopen("memory.log", "wb")) != NULL) - - { - - // fwrite(Memory, 1, 0x8000, fpDmpMem); - //fwrite(mLBank, 1, 0x4000, fpDmpMem); - //fwrite(mUBank, 1, 0x4000, fpDmpMem); - - fclose(fpDmpMem); - - } - } - break; - - - - - - case '=': - if (strlen(S) >= 2) - - { - sscanf(S + 1, "%hX", &(R->Trap)); - R->Trace = 0; - return (1); - } - break; - - case '+': - if (strlen(S) >= 2) - - { - - sscanf(S + 1, "%hX", &(R->Trap)); - - R->Trap += R->PC.W; - R->Trace = 0; - - return (1); - - } - break; - - case 'J': - if (strlen(S) >= 2) - - { - sscanf(S + 1, "%hX", &(R->PC.W)); - R->Trace = 0; - return (1); - } - break; - - case 'T': - if (strlen(S) >= 2) - - { - sscanf(S + 1, "%hX", &(R->PC.W)); - R->Trace = 1; - } - break; - - case 'C': - R->Trap = 0xFFFF; - R->Trace = 0; - install_keyboard(); - - //ResumeSound(); - - SetSound(0, SND_RECTANGLE); - SetSound(1, SND_RECTANGLE); - SetSound(2, SND_TRIANGLE); - SetSound(3, SND_NOISE); - - return (1); - - case 'Q': - return (0); - - - case 'V': - puts("\n6502 Interrupt Vectors:"); - printf("[$FFFC] INIT: $%04X\n", Rd6502(0xFFFC) + 256 * Rd6502(0xFFFD)); - printf("[$FFFE] IRQ: $%04X\n", Rd6502(0xFFFE) + 256 * Rd6502(0xFFFF)); - printf("[$FFFA] NMI: $%04X\n", Rd6502(0xFFFA) + 256 * Rd6502(0xFFFB)); - break; - - case 'M': - { - word Addr; - - if (strlen(S) > 1) - sscanf(S + 1, "%hX", &Addr); - else - Addr = R->PC.W; - puts(""); - for (J = 0; J < 16; J++) - { - printf("%04X: ", Addr); - for (I = 0; I < 16; I++, Addr++) - - printf("%02X ", Rd6502(Addr)); - - printf(" | "); - Addr -= 16; - - for (I = 0; I < 16; I++, Addr++) - - putchar(isprint(Rd6502(Addr)) ? Rd6502(Addr) : '.'); - - puts(""); - - } - } - break; - - case 'R': - - printf - ( - "A:%02X P:%02X X:%02X Y:%02X S:%04X PC:%04X Flags:[", - R->A, R->P, R->X, R->Y, R->S + 0x0100, R->PC.W - ); - - - for (J = 0, F = R->P; J < 8; J++, F <<= 1) - - printf("%c", F & 0x80 ? FA[J] : '.'); - - puts("]"); - - - printf - ( - "AT PC: [%02X - %s] AT SP: [%02X %02X %02X]\n", - Rd6502(R->PC.W), S, - Rd6502(0x0100 + (byte) (R->S + 1)), - Rd6502(0x0100 + (byte) (R->S + 2)), - Rd6502(0x0100 + (byte) (R->S + 3)) - ); - - break; - - - case 'D': - - { - - word Addr; - - - if (strlen(S) > 1) - sscanf(S + 1, "%hX", &Addr); - else - Addr = R->PC.W; - - puts(""); - - for (J = 0; J < 16; J++) - - { - - printf("%04X: ", Addr); - - Addr += DAsm(S, Addr); - - puts(S); - - } - } - break; - - } - } - - /* Continue with emulation */ - return (1); - -} - - -#endif /* DEBUG */ +/** M6502: portable 6502 emulator ****************************/ +/** **/ +/** Debug.c **/ +/** **/ +/** This file contains the built-in debugging routine for **/ +/** the 6502 emulator which is called on each 6502 step **/ +/** when Trap!=0. **/ +/** **/ +/** Copyright (C) Marat Fayzullin 1996-1997 **/ +/** Alex Krasivsky 1996 **/ +/** You are not allowed to distribute this software **/ +/** commercially. Please, notify me, if you make any **/ +/** changes to this file. **/ +/*************************************************************/ +/* + * $LastChangedDate: 2007-04-19 18:18:57 +0200 (jeu, 19 avr 2007) $ + * $Author: mtrapier $ + * $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/Debug.c $ + * $Revision: 43 $ + */ + +#include "M6502.h" +#ifdef DEBUG +#include +#include +#include +#include + +#include + +#include +#include +#include + +#define RDWORD(A) (Rd6502(A+1)*256+Rd6502(A)) + +extern unsigned char *Memory; + +void showlastop(); + +enum Addressing_Modes +{ + Ac = 0, Il, Im, Ab, Zp, Zx, Zy, Ax, Ay, Rl, Ix, Iy, In, No +}; + + + +static char *mn[] = +{ + "adc ", "and ", "asl ", "bcc ", "bcs ", "beq ", "bit ", "bmi ", + "bne ", "bpl ", "brk", "bvc ", "bvs ", "clc", "cld", "cli", + "clv", "cmp ", "cpx ", "cpy ", "dec ", "dex", "dey", "inx", + "iny", "eor ", "inc ", "jmp ", "jsr ", "lda ", "nop ", "ldx ", + "ldy ", "lsr ", "ora ", "pha", "php", "pla", "plp", "rol ", + "ror ", "rti", "rts", "sbc ", "sta ", "stx ", "sty ", "sec ", + "sed", "sei", "tax", "tay", "txa", "tya", "tsx", "txs" +}; + + + +static byte ad[512] = +{ + 10, Il, 34, Ix, No, No, No, No, No, No, 34, Zp, 2, Zp, No, No, + 36, Il, 34, Im, 2, Ac, No, No, No, No, 34, Ab, 2, Ab, No, No, + 9, Rl, 34, Iy, No, No, No, No, No, No, 34, Zx, 2, Zx, No, No, + 13, Il, 34, Ay, No, No, No, No, No, No, 34, Ax, 2, Ax, No, No, + 28, Ab, 1, Ix, No, No, No, No, 6, Zp, 1, Zp, 39, Zp, No, No, + 38, Il, 1, Im, 39, Ac, No, No, 6, Ab, 1, Ab, 39, Ab, No, No, + 7, Rl, 1, Iy, No, No, No, No, No, No, 1, Zx, 39, Zx, No, No, + 47, Il, 1, Ay, No, No, No, No, No, No, 1, Ax, 39, Ax, No, No, + 41, Il, 25, Ix, No, No, No, No, No, No, 25, Zp, 33, Zp, No, No, + 35, Il, 25, Im, 33, Ac, No, No, 27, Ab, 25, Ab, 33, Ab, No, No, + 11, Rl, 25, Iy, No, No, No, No, No, No, 25, Zx, 33, Zx, No, No, + 15, Il, 25, Ay, No, No, No, No, No, No, 25, Ax, 33, Ax, No, No, + 42, Il, 0, Ix, No, No, No, No, No, No, 0, Zp, 40, Zp, No, No, + 37, Il, 0, Im, 40, Ac, No, No, 27, In, 0, Ab, 40, Ab, No, No, + 12, Rl, 0, Iy, No, No, No, No, No, No, 0, Zx, 40, Zx, No, No, + 49, Il, 0, Ay, No, No, No, No, No, No, 0, Ax, 40, Ax, No, No, + No, No, 44, Ix, No, No, No, No, 46, Zp, 44, Zp, 45, Zp, No, No, + 22, Il, No, No, 52, Il, No, No, 46, Ab, 44, Ab, 45, Ab, No, No, + 3, Rl, 44, Iy, No, No, No, No, 46, Zx, 44, Zx, 45, Zy, No, No, + 53, Il, 44, Ay, 55, Il, No, No, No, No, 44, Ax, No, No, No, No, + 32, Im, 29, Ix, 31, Im, No, No, 32, Zp, 29, Zp, 31, Zp, No, No, + 51, Il, 29, Im, 50, Il, No, No, 32, Ab, 29, Ab, 31, Ab, No, No, + 4, Rl, 29, Iy, No, No, No, No, 32, Zx, 29, Zx, 31, Zy, No, No, + 16, Il, 29, Ay, 54, Il, No, No, 32, Ax, 29, Ax, 31, Ay, No, No, + 19, Im, 17, Ix, No, No, No, No, 19, Zp, 17, Zp, 20, Zp, No, No, + 24, Il, 17, Im, 21, Il, No, No, 19, Ab, 17, Ab, 20, Ab, No, No, + 8, Rl, 17, Iy, No, No, No, No, No, No, 17, Zx, 20, Zx, No, No, + 14, Il, 17, Ay, No, No, No, No, No, No, 17, Ax, 20, Ax, No, No, + 18, Im, 43, Ix, No, No, No, No, 18, Zp, 43, Zp, 26, Zp, No, No, + 23, Il, 43, Im, 30, Il, No, No, 18, Ab, 43, Ab, 26, Ab, No, No, + 5, Rl, 43, Iy, No, No, No, No, No, No, 43, Zx, 26, Zx, No, No, + 48, Il, 43, Ay, No, No, No, No, No, No, 43, Ax, 26, Ax, No, No +}; + + + +/** DAsm() ****************************************************/ +/** This function will disassemble a single command and **/ +/** return the number of bytes disassembled. **/ +/**************************************************************/ +int DAsm(char *S, word A) +{ + + byte J; + + word B, OP, TO; + + + B = A; + OP = Rd6502(B++) * 2; + + + switch (ad[OP + 1]) + + { + + case Ac: + sprintf(S, "%s a", mn[ad[OP]]); + break; + + case Il: + sprintf(S, "%s", mn[ad[OP]]); + break; + + + case Rl: + J = Rd6502(B++); + TO = A + 2 + ((J < 0x80) ? J : (J - 256)); + + sprintf(S, "%s $%04X", mn[ad[OP]], TO); + break; + + + case Im: + sprintf(S, "%s #$%02X", mn[ad[OP]], Rd6502(B++)); + break; + + case Zp: + sprintf(S, "%s $%02X", mn[ad[OP]], Rd6502(B++)); + break; + + case Zx: + sprintf(S, "%s $%02X,x", mn[ad[OP]], Rd6502(B++)); + break; + + case Zy: + sprintf(S, "%s $%02X,y", mn[ad[OP]], Rd6502(B++)); + break; + + case Ix: + sprintf(S, "%s ($%02X,x)", mn[ad[OP]], Rd6502(B++)); + break; + + case Iy: + sprintf(S, "%s ($%02X),y", mn[ad[OP]], Rd6502(B++)); + break; + + + case Ab: + sprintf(S, "%s $%04X", mn[ad[OP]], RDWORD(B)); + B += 2; + break; + + case Ax: + sprintf(S, "%s $%04X,x", mn[ad[OP]], RDWORD(B)); + B += 2; + break; + + case Ay: + sprintf(S, "%s $%04X,y", mn[ad[OP]], RDWORD(B)); + B += 2; + break; + + case In: + sprintf(S, "%s ($%04X)", mn[ad[OP]], RDWORD(B)); + B += 2; + break; + + + default: + sprintf(S, ".db $%02X; ", OP / 2); + + } + return (B - A); + +} + + +/** Debug6502() **********************************************/ +/** This function should exist if DEBUG is #defined. When **/ +/** Trace!=0, it is called after each command executed by **/ +/** the CPU, and given the 6502 registers. Emulation exits **/ +/** if Debug6502() returns 0. **/ +/*************************************************************/ +byte Debug6502(M6502 * R) +{ + static char FA[8] = "NVRBDIZC"; + char S[128]; + byte F; + int J, I; + + DAsm(S, R->PC.W); + + printf + ( + "A:%02X P:%02X X:%02X Y:%02X S:%04X PC:%04X Flags:[", + R->A, R->P, R->X, R->Y, R->S + 0x0100, R->PC.W + ); + + + for (J = 0, F = R->P; J < 8; J++, F <<= 1) + + printf("%c", F & 0x80 ? FA[J] : '.'); + + puts("]"); + + + printf + ( + "AT PC: [%02X - %s] AT SP: [%02X %02X %02X]\n", + Rd6502(R->PC.W), S, + Rd6502(0x0100 + (byte) (R->S + 1)), + Rd6502(0x0100 + (byte) (R->S + 2)), + Rd6502(0x0100 + (byte) (R->S + 3)) + ); + + + S[0] = 0; + remove_keyboard(); + +#ifdef USE_SOUND + StopSound(); +#endif + + + while (1) + { + printf("\n[Command,'?']-> "); + + fflush(stdout); + fflush(stdin); + + + fgets(S, 50, stdin); + + for (J = 0; S[J] >= ' '; J++) + S[J] = toupper(S[J]); + + S[J] = '\0'; + + + switch (S[0]) + { + case 'H': + case '?': + puts("\n***** Built-in 6502 Debugger Commands *****"); + puts(" : Break at the next instruction"); + puts("= : Break at addr"); + puts("+ : Break at PC + offset"); + puts("t : Set PC to addr"); + puts("c : Continue without break"); + puts("j : Continue from addr"); + puts("m : Memory dump at addr"); + puts("d : Disassembly at addr"); + puts("v : Show ;interrupt vectors"); + puts("?,h : Show this help text"); + puts("r : Show Register Status"); + puts("q : Exit 6502 emulation"); + + puts("----- TI-NES Specific -----"); + puts("w : Dump Memory State"); + puts("o : Show PPU registers"); + puts("p : Dump PPU memory at addr"); + puts("a : Dump all memory to memory.log"); + puts("s : Dump sprite table to sprite.log"); + puts("n : Dump name table to nt.log"); + puts("z : Dump mapper status"); + puts("i : SpriteTable Dump"); + puts("g : Get sprite info"); + break; + + case '\0': + return (1); + + case 'Z': + mapper_dump(stdout); + break; + + case 'W': + DumpMemoryState(stdout); + break; + + + case 'A': + { + + FILE * fpDmpMem; + + if ((fpDmpMem = fopen("memory.log", "wb")) != NULL) + + { + + // fwrite(Memory, 1, 0x8000, fpDmpMem); + //fwrite(mLBank, 1, 0x4000, fpDmpMem); + //fwrite(mUBank, 1, 0x4000, fpDmpMem); + + fclose(fpDmpMem); + + } + } + break; + + + + + + case '=': + if (strlen(S) >= 2) + + { + sscanf(S + 1, "%hX", &(R->Trap)); + R->Trace = 0; + return (1); + } + break; + + case '+': + if (strlen(S) >= 2) + + { + + sscanf(S + 1, "%hX", &(R->Trap)); + + R->Trap += R->PC.W; + R->Trace = 0; + + return (1); + + } + break; + + case 'J': + if (strlen(S) >= 2) + + { + sscanf(S + 1, "%hX", &(R->PC.W)); + R->Trace = 0; + return (1); + } + break; + + case 'T': + if (strlen(S) >= 2) + + { + sscanf(S + 1, "%hX", &(R->PC.W)); + R->Trace = 1; + } + break; + + case 'C': + R->Trap = 0xFFFF; + R->Trace = 0; + install_keyboard(); + + //ResumeSound(); + + SetSound(0, SND_RECTANGLE); + SetSound(1, SND_RECTANGLE); + SetSound(2, SND_TRIANGLE); + SetSound(3, SND_NOISE); + + return (1); + + case 'Q': + return (0); + + + case 'V': + puts("\n6502 Interrupt Vectors:"); + printf("[$FFFC] INIT: $%04X\n", Rd6502(0xFFFC) + 256 * Rd6502(0xFFFD)); + printf("[$FFFE] IRQ: $%04X\n", Rd6502(0xFFFE) + 256 * Rd6502(0xFFFF)); + printf("[$FFFA] NMI: $%04X\n", Rd6502(0xFFFA) + 256 * Rd6502(0xFFFB)); + break; + + case 'M': + { + word Addr; + + if (strlen(S) > 1) + sscanf(S + 1, "%hX", &Addr); + else + Addr = R->PC.W; + puts(""); + for (J = 0; J < 16; J++) + { + printf("%04X: ", Addr); + for (I = 0; I < 16; I++, Addr++) + + printf("%02X ", Rd6502(Addr)); + + printf(" | "); + Addr -= 16; + + for (I = 0; I < 16; I++, Addr++) + + putchar(isprint(Rd6502(Addr)) ? Rd6502(Addr) : '.'); + + puts(""); + + } + } + break; + + case 'R': + + printf + ( + "A:%02X P:%02X X:%02X Y:%02X S:%04X PC:%04X Flags:[", + R->A, R->P, R->X, R->Y, R->S + 0x0100, R->PC.W + ); + + + for (J = 0, F = R->P; J < 8; J++, F <<= 1) + + printf("%c", F & 0x80 ? FA[J] : '.'); + + puts("]"); + + + printf + ( + "AT PC: [%02X - %s] AT SP: [%02X %02X %02X]\n", + Rd6502(R->PC.W), S, + Rd6502(0x0100 + (byte) (R->S + 1)), + Rd6502(0x0100 + (byte) (R->S + 2)), + Rd6502(0x0100 + (byte) (R->S + 3)) + ); + + break; + + + case 'D': + + { + + word Addr; + + + if (strlen(S) > 1) + sscanf(S + 1, "%hX", &Addr); + else + Addr = R->PC.W; + + puts(""); + + for (J = 0; J < 16; J++) + + { + + printf("%04X: ", Addr); + + Addr += DAsm(S, Addr); + + puts(S); + + } + } + break; + + } + } + + /* Continue with emulation */ + return (1); + +} + + +#endif /* DEBUG */ diff --git a/src/corecpu/M6502.c b/src/corecpu/M6502.c index 989606b..54bfdb0 100755 --- a/src/corecpu/M6502.c +++ b/src/corecpu/M6502.c @@ -254,6 +254,155 @@ void Int6502(M6502 *R,byte Type) } } +#ifdef TRACE_EXECUTION + +enum Addressing_Modes +{ + Ac = 0, Il, Im, Ab, Zp, Zx, Zy, Ax, Ay, Rl, Ix, Iy, In, No +}; + +static char *mnCAP[] = +{ + "ADC", "AND", "ASL", "BCC", "BCS", "BEQ", "BIT", "BMI", + "BNE", "BPL", "BRK", "BVC", "BVS", "CLC", "CLD", "CLI", + "CLV", "CMP", "CPX", "CPY", "DEC", "DEX", "DEY", "INX", + "INY", "EOR", "INC", "JMP", "JSR", "LDA", "NOP", "LDX", + "LDY", "LSR", "ORA", "PHA", "PHP", "PLA", "PLP", "ROL", + "ROR", "RTI", "RTS", "SBC", "STA", "STX", "STY", "SEC", + "SED", "SEI", "TAX", "TAY", "TXA", "TYA", "TSX", "TXS" +}; + +#define DAsm DAsmCAP + +static byte ad[512] = +{ + 10, Il, 34, Ix, No, No, No, No, No, No, 34, Zp, 2, Zp, No, No, + 36, Il, 34, Im, 2, Ac, No, No, No, No, 34, Ab, 2, Ab, No, No, + 9, Rl, 34, Iy, No, No, No, No, No, No, 34, Zx, 2, Zx, No, No, + 13, Il, 34, Ay, No, No, No, No, No, No, 34, Ax, 2, Ax, No, No, + 28, Ab, 1, Ix, No, No, No, No, 6, Zp, 1, Zp, 39, Zp, No, No, + 38, Il, 1, Im, 39, Ac, No, No, 6, Ab, 1, Ab, 39, Ab, No, No, + 7, Rl, 1, Iy, No, No, No, No, No, No, 1, Zx, 39, Zx, No, No, + 47, Il, 1, Ay, No, No, No, No, No, No, 1, Ax, 39, Ax, No, No, + 41, Il, 25, Ix, No, No, No, No, No, No, 25, Zp, 33, Zp, No, No, + 35, Il, 25, Im, 33, Ac, No, No, 27, Ab, 25, Ab, 33, Ab, No, No, + 11, Rl, 25, Iy, No, No, No, No, No, No, 25, Zx, 33, Zx, No, No, + 15, Il, 25, Ay, No, No, No, No, No, No, 25, Ax, 33, Ax, No, No, + 42, Il, 0, Ix, No, No, No, No, No, No, 0, Zp, 40, Zp, No, No, + 37, Il, 0, Im, 40, Ac, No, No, 27, In, 0, Ab, 40, Ab, No, No, + 12, Rl, 0, Iy, No, No, No, No, No, No, 0, Zx, 40, Zx, No, No, + 49, Il, 0, Ay, No, No, No, No, No, No, 0, Ax, 40, Ax, No, No, + No, No, 44, Ix, No, No, No, No, 46, Zp, 44, Zp, 45, Zp, No, No, + 22, Il, No, No, 52, Il, No, No, 46, Ab, 44, Ab, 45, Ab, No, No, + 3, Rl, 44, Iy, No, No, No, No, 46, Zx, 44, Zx, 45, Zy, No, No, + 53, Il, 44, Ay, 55, Il, No, No, No, No, 44, Ax, No, No, No, No, + 32, Im, 29, Ix, 31, Im, No, No, 32, Zp, 29, Zp, 31, Zp, No, No, + 51, Il, 29, Im, 50, Il, No, No, 32, Ab, 29, Ab, 31, Ab, No, No, + 4, Rl, 29, Iy, No, No, No, No, 32, Zx, 29, Zx, 31, Zy, No, No, + 16, Il, 29, Ay, 54, Il, No, No, 32, Ax, 29, Ax, 31, Ay, No, No, + 19, Im, 17, Ix, No, No, No, No, 19, Zp, 17, Zp, 20, Zp, No, No, + 24, Il, 17, Im, 21, Il, No, No, 19, Ab, 17, Ab, 20, Ab, No, No, + 8, Rl, 17, Iy, No, No, No, No, No, No, 17, Zx, 20, Zx, No, No, + 14, Il, 17, Ay, No, No, No, No, No, No, 17, Ax, 20, Ax, No, No, + 18, Im, 43, Ix, No, No, No, No, 18, Zp, 43, Zp, 26, Zp, No, No, + 23, Il, 43, Im, 30, Il, No, No, 18, Ab, 43, Ab, 26, Ab, No, No, + 5, Rl, 43, Iy, No, No, No, No, No, No, 43, Zx, 26, Zx, No, No, + 48, Il, 43, Ay, No, No, No, No, No, No, 43, Ax, 26, Ax, No, No +}; + +#define RDWORD(A) (Rd6502(A+1)*256+Rd6502(A)) + +/** DAsm() ****************************************************/ +/** This function will disassemble a single command and **/ +/** return the number of bytes disassembled. **/ +/**************************************************************/ +int DAsmCAP(char *S, word A) +{ + + byte J; + + word B, OP, TO; + + + B = A; + OP = Rd6502(B++) * 2; + + + switch (ad[OP + 1]) + + { + + case Ac: + sprintf(S, "%s A", mnCAP[ad[OP]]); + break; + + case Il: + sprintf(S, "%s", mnCAP[ad[OP]]); + break; + + + case Rl: + J = Rd6502(B++); + TO = A + 2 + ((J < 0x80) ? J : (J - 256)); + + sprintf(S, "%s $%04x", mnCAP[ad[OP]], TO); + break; + + + case Im: + sprintf(S, "%s #$%02x", mnCAP[ad[OP]], Rd6502(B++)); + break; + + case Zp: + sprintf(S, "%s $%02x", mnCAP[ad[OP]], Rd6502(B++)); + break; + + case Zx: + sprintf(S, "%s $%02x,X", mnCAP[ad[OP]], Rd6502(B++)); + break; + + case Zy: + sprintf(S, "%s $%02x,Y", mnCAP[ad[OP]], Rd6502(B++)); + break; + + case Ix: + sprintf(S, "%s ($%02x,X)", mnCAP[ad[OP]], Rd6502(B++)); + break; + + case Iy: + sprintf(S, "%s ($%02x),Y", mnCAP[ad[OP]], Rd6502(B++)); + break; + + + case Ab: + sprintf(S, "%s $%04x", mnCAP[ad[OP]], RDWORD(B)); + B += 2; + break; + + case Ax: + sprintf(S, "%s $%04x,X", mnCAP[ad[OP]], RDWORD(B)); + B += 2; + break; + + case Ay: + sprintf(S, "%s $%04x,Y", mnCAP[ad[OP]], RDWORD(B)); + B += 2; + break; + + case In: + sprintf(S, "%s ($%04x)", mnCAP[ad[OP]], RDWORD(B)); + B += 2; + break; + + + default: + sprintf(S, ".db $%02x; ", OP / 2); + + } + return (B - A); + +} +#endif /** Run6502() ************************************************/ /** This function will run 6502 code until Loop6502() call **/ @@ -274,8 +423,29 @@ word Run6502(M6502 *R) if(R->Trace) if(!Debug6502(R)) return(R->PC.W); #endif + +#ifdef TRACE_EXECUTION + while(1) + { - I=Op6502(R->PC.W++); + static char FA[8] = "NV.BDIZC"; + char S[128]; + byte F; + int J, I; + + DAsm(S, R->PC.W); + + printf + ( + "AT PC: [%02x - %s]\n", + Rd6502(R->PC.W), S + ); + break; + } + +#endif + + I=Op6502(R->PC.W++); R->ICount-=Cycles[I]; //#ifdef DEBUG @@ -289,6 +459,34 @@ word Run6502(M6502 *R) #include "Codes.h" } +#ifdef TRACE_EXECUTION + while(1) + { + static char FA[8] = "NV.BDIZC"; + char S[128]; + byte F; + int J, I; + + printf + ( + "A:%02x X:%02x Y:%02x S:%04x, PC:%04x Flags:[", + R->A, R->X, R->Y, R->S + 0x0100, R->PC.W + ); + + + for (J = 0, F = R->P; J < 8; J++, F <<= 1) + + printf("%c", F & 0x80 ? FA[J] : '.'); + + printf("], Stack[%02x, %02x, %02x]\n", + Rd6502(0x0100 + (byte) (R->S + 1)), + Rd6502(0x0100 + (byte) (R->S + 2)), + Rd6502(0x0100 + (byte) (R->S + 3))); + + break; + } +#endif + /* If cycle counter expired... */ if(R->ICount<=0) { diff --git a/src/corecpu/Tables.h b/src/corecpu/Tables.h index e977670..b6c0059 100755 --- a/src/corecpu/Tables.h +++ b/src/corecpu/Tables.h @@ -18,24 +18,24 @@ * $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/Tables.h $ * $Revision: 52 $ */ - -static byte Cycles[256] = -{ - 7, 6, 2, 1, 5, 3, 5, 5, 3, 2, 2, 1, 6, 4, 6, 2, - 2, 5, 5, 1, 5, 4, 6, 5, 2, 4, 2, 1, 6, 4, 6, 2, - 6, 6, 2, 1, 3, 3, 5, 5, 4, 2, 2, 1, 4, 4, 6, 2, - 2, 5, 5, 1, 4, 4, 6, 5, 2, 4, 2, 1, 4, 4, 6, 2, - 6, 6, 2, 1, 3, 3, 5, 5, 3, 2, 2, 1, 3, 4, 6, 2, - 2, 5, 5, 1, 4, 4, 6, 5, 2, 4, 3, 1, 8, 4, 6, 2, - 6, 6, 2, 1, 3, 3, 5, 5, 4, 2, 2, 1, 6, 4, 6, 2, - 2, 5, 5, 1, 4, 4, 6, 5, 5, 4, 4, 1, 6, 4, 6, 2, - 3, 6, 2, 1, 3, 3, 3, 5, 2, 2, 2, 1, 4, 4, 4, 2, - 2, 6, 5, 1, 4, 4, 4, 5, 2, 5, 2, 1, 4, 5, 5, 2, - 2, 6, 2, 1, 3, 3, 3, 5, 2, 2, 2, 1, 4, 4, 4, 2, - 2, 5, 5, 1, 4, 4, 4, 5, 2, 4, 2, 1, 4, 4, 4, 2, - 2, 6, 2, 1, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 2, - 2, 5, 5, 1, 4, 4, 6, 5, 2, 4, 3, 2, 4, 4, 6, 2, - 2, 6, 2, 1, 3, 3, 5, 5, 2, 2, 2, 1, 4, 4, 6, 2, + +static byte Cycles[256] = +{ + 7, 6, 2, 1, 5, 3, 5, 5, 3, 2, 2, 1, 6, 4, 6, 2, + 2, 5, 5, 1, 5, 4, 6, 5, 2, 4, 2, 1, 6, 4, 6, 2, + 6, 6, 2, 1, 3, 3, 5, 5, 4, 2, 2, 1, 4, 4, 6, 2, + 2, 5, 5, 1, 4, 4, 6, 5, 2, 4, 2, 1, 4, 4, 6, 2, + 6, 6, 2, 1, 3, 3, 5, 5, 3, 2, 2, 1, 3, 4, 6, 2, + 2, 5, 5, 1, 4, 4, 6, 5, 2, 4, 3, 1, 8, 4, 6, 2, + 6, 6, 2, 1, 3, 3, 5, 5, 4, 2, 2, 1, 6, 4, 6, 2, + 2, 5, 5, 1, 4, 4, 6, 5, 5, 4, 4, 1, 6, 4, 6, 2, + 3, 6, 2, 1, 3, 3, 3, 5, 2, 2, 2, 1, 4, 4, 4, 2, + 2, 6, 5, 1, 4, 4, 4, 5, 2, 5, 2, 1, 4, 5, 5, 2, + 2, 6, 2, 1, 3, 3, 3, 5, 2, 2, 2, 1, 4, 4, 4, 2, + 2, 5, 5, 1, 4, 4, 4, 5, 2, 4, 2, 1, 4, 4, 4, 2, + 2, 6, 2, 1, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 2, + 2, 5, 5, 1, 4, 4, 6, 5, 2, 4, 3, 2, 4, 4, 6, 2, + 2, 6, 2, 1, 3, 3, 5, 5, 2, 2, 2, 1, 4, 4, 6, 2, 2, 5, 5, 1, 4, 4, 6, 5, 2, 4, 4, 1, 4, 4, 6, 2 }; diff --git a/src/include/Sound.h b/src/include/Sound.h index 5103012..cd60d83 100644 --- a/src/include/Sound.h +++ b/src/include/Sound.h @@ -137,7 +137,6 @@ void MIDITicks(int N); /** skip initialization and be silent. Pass Verbose!=0 to **/ /** see initialization messages. **/ /*************************************************************/ -#warning You Suck ! int InitSound(int Rate,int Verbose); /** StopSound() **********************************************/ diff --git a/src/include/mappers/manager.h b/src/include/mappers/manager.h index bf5475a..1a517d5 100755 --- a/src/include/mappers/manager.h +++ b/src/include/mappers/manager.h @@ -27,6 +27,9 @@ typedef void (*MapperDump) (); #ifdef __TINES_MAPPERS__ +#include +#include + extern NesCart *Cart; /* Available functions for mappers */ @@ -34,9 +37,6 @@ extern NesCart *Cart; #define GETLAST16KBANK(c) ((c->PROMSize>>14)-1) #define GETLAST32KBANK(c) ((c->PROMSize>>15)-1) -void map_sram(); /* Map SRAM */ -void unmap_sram(); /* Unmap SRAM */ - void set_vrom_bank_1k(unsigned short addr,int slot); void set_vrom_bank_2k(unsigned short addr,int slot); void set_vrom_bank_4k(unsigned short addr,int slot); @@ -57,4 +57,7 @@ extern void (*mapper_dump) (FILE *fp); #endif /* __TINES_MAPPERS__ */ +void map_sram(); /* Map SRAM */ +void unmap_sram(); /* Unmap SRAM */ + #endif diff --git a/src/main.c b/src/main.c index 49ae111..867155b 100755 --- a/src/main.c +++ b/src/main.c @@ -20,6 +20,7 @@ #include #include #include +#include #ifndef WIN32 @@ -41,7 +42,7 @@ int HBLANK_TIME = 140; double APU_BASEFREQ = 1.7734474; #elif !ISPAL && ISNTSC int VBLANK_TIME = 20; -int HBLANK_TIME = 119; +int HBLANK_TIME = 115; //119; double APU_BASEFREQ = 1.7897725; //#define VBLANK_TIME 20 //#define HBLANK_TIME 260 @@ -69,7 +70,7 @@ double APU_BASEFREQ = 1.7897725; #include #define V_MAJOR 0 -#define V_MINOR 29 +#define V_MINOR 30 #define VS_ID "$Id: main.c 58 2007-05-31 16:02:16Z mtrapier $" #define VS_REVISION "$Revision: 58 $" @@ -117,8 +118,6 @@ PALETTE pal; short IRQScanHit = -1; -NesCart *Cart; - /* palette */ unsigned long ColorPalette[ 8 * 63 ]; @@ -126,130 +125,130 @@ unsigned long ColorPalette[ 8 * 63 ]; void CloseHook(void) { - WantClosing = 1; + WantClosing = 1; } void ips_fps_counter(void) { - FPS = frame; - IPS = icount; - frame = 0; - icount = 0; + FPS = frame; + IPS = icount; + frame = 0; + icount = 0; } END_OF_FUNCTION(ips_fps_counter); void SaveSaveRam(char *name) { - FILE *fp; - int i; - char fname[512]; - //byte car; - strcpy(fname, name); - strcat(fname, ".svt"); - if ((fp = fopen(fname, "wb"))) - { - printf("Saving savestate '%s'\n", fname); - for( i = 0x60; i < 0x80; i++) - { - fwrite(get_page_ptr(i), 1, 0x100, fp); - } - - fclose(fp); - } + FILE *fp; + int i; + char fname[512]; + //byte car; + strcpy(fname, name); + strcat(fname, ".svt"); + if ((fp = fopen(fname, "wb"))) + { + printf("Saving savestate '%s'\n", fname); + for( i = 0x60; i < 0x80; i++) + { + fwrite(get_page_ptr(i), 1, 0x100, fp); + } + + fclose(fp); + } } void LoadSaveRam(char *name) { - FILE *fp; - int i; - char fname[512]; - - strcpy(fname, name); - strcat(fname, ".svt"); - if ((fp = fopen(fname, "rb"))) - { - printf("Loading savestate '%s'\n", fname); - for( i = 0x60; i < 0x80; i++) - { - fread(get_page_ptr(i), 1, 0x0100, fp); - } - fclose(fp); - - } + FILE *fp; + int i; + char fname[512]; + + strcpy(fname, name); + strcat(fname, ".svt"); + if ((fp = fopen(fname, "rb"))) + { + printf("Loading savestate '%s'\n", fname); + for( i = 0x60; i < 0x80; i++) + { + fread(get_page_ptr(i), 1, 0x0100, fp); + } + fclose(fp); + + } } void LoadPalette(char *filename, PALETTE pal) { - FILE *fp; - - unsigned char r, v, b, i; - printf("%s: try to load pallette file '%s'", __func__, filename); - if ((fp = fopen(filename, "rb")) != NULL) - { - - for (i = 0; i < 64; i++) - { - - fread(&r, 1, 1, fp); - fread(&v, 1, 1, fp); - fread(&b, 1, 1, fp); - - /* r = (r * 64) / 255; - v = (v * 64) / 255; - b = (b * 64) / 255;*/ - - + FILE *fp; + + unsigned char r, v, b, i; + printf("%s: try to load pallette file '%s'", __func__, filename); + if ((fp = fopen(filename, "rb")) != NULL) + { + + for (i = 0; i < 64; i++) + { + + fread(&r, 1, 1, fp); + fread(&v, 1, 1, fp); + fread(&b, 1, 1, fp); + +/* r = (r * 64) / 255; + v = (v * 64) / 255; + b = (b * 64) / 255;*/ + + #ifdef USE_24BITS - ColorPalette[i + (0 * 63)] = SET_RGB(r,v,b); - - /* Red emphase */ - ColorPalette[i + (1 * 63)] = SET_RGB(r + 10, v - 05, b - 05); - - /* Green emphase */ - ColorPalette[i + (2 * 63)] = SET_RGB(r - 05, v + 10, b - 05); - - /* Red + green emphase */ - ColorPalette[i + (3 * 63)] = SET_RGB(r + 05, v + 05, b - 10); - - /* Blue emphase */ - ColorPalette[i + (4 * 63)] = SET_RGB(r - 05, v - 05, b + 10); - - /* Red + blue emphase */ - ColorPalette[i + (5 * 63)] = SET_RGB(r + 05, v - 10, b + 05); - - /* Blue + green emphase */ - ColorPalette[i + (6 * 63)] = SET_RGB(r - 10, v + 05, b + 05); - - /* Red + Green + Blue emphase */ - ColorPalette[i + (7 * 63)] = SET_RGB(r + 00, v + 00, b + 00);*/ + ColorPalette[i + (0 * 63)] = SET_RGB(r,v,b); + + /* Red emphase */ + ColorPalette[i + (1 * 63)] = SET_RGB(r + 10, v - 05, b - 05); + + /* Green emphase */ + ColorPalette[i + (2 * 63)] = SET_RGB(r - 05, v + 10, b - 05); + + /* Red + green emphase */ + ColorPalette[i + (3 * 63)] = SET_RGB(r + 05, v + 05, b - 10); + + /* Blue emphase */ + ColorPalette[i + (4 * 63)] = SET_RGB(r - 05, v - 05, b + 10); + + /* Red + blue emphase */ + ColorPalette[i + (5 * 63)] = SET_RGB(r + 05, v - 10, b + 05); + + /* Blue + green emphase */ + ColorPalette[i + (6 * 63)] = SET_RGB(r - 10, v + 05, b + 05); + + /* Red + Green + Blue emphase */ + ColorPalette[i + (7 * 63)] = SET_RGB(r + 00, v + 00, b + 00);*/ #else /* Else Use 8Bits */ - pal[i].r = r; - pal[i].g = v; - pal[i].b = b; - - pal[i + 64].r = r; - pal[i + 64].g = v; - pal[i + 64].b = b; - - pal[i + 128].r = r; - pal[i + 128].g = v; - pal[i + 128].b = b; - - pal[i + 192].r = r; - pal[i + 192].g = v; - pal[i + 192].b = b; + pal[i].r = r; + pal[i].g = v; + pal[i].b = b; + + pal[i + 64].r = r; + pal[i + 64].g = v; + pal[i + 64].b = b; + + pal[i + 128].r = r; + pal[i + 128].g = v; + pal[i + 128].b = b; + + pal[i + 192].r = r; + pal[i + 192].g = v; + pal[i + 192].b = b; #endif - } - fclose(fp); - printf(" [ OK ]\n"); - } - else - { - printf("Error loading palette '%s'!\n", filename); - exit(-1); - } + } + fclose(fp); + printf(" [ OK ]\n"); + } + else + { + printf("Error loading palette '%s'!\n", filename); + exit(-1); + } } int DAsm(char *S, word A); @@ -258,371 +257,390 @@ int oppos = 0; void pushop(word op) { - latestop[oppos] = op; - // printf("%d\n", oppos); - oppos = (oppos+1)%42; + latestop[oppos] = op; + // printf("%d\n", oppos); + oppos = (oppos+1)%42; } void showlastop(FILE *fp) { #ifdef DEBUG - int i,j; - char S[256]; - i = oppos; - do - { - j=(DAsm(S,latestop[i])-1); - fprintf(fp, "0x%04X : %s\n", MainCPU.PC.W,S); - i = (i+1)%42; - } - while(i != oppos); + int i,j; + char S[256]; + i = oppos; + do + { + j=(DAsm(S,latestop[i])-1); + fprintf(fp, "0x%04X : %s\n", MainCPU.PC.W,S); + i = (i+1)%42; + } + while(i != oppos); #endif } +NesCart *Cart; + void *signalhandler(int sig) { - static int state=0; - M6502 *R = &MainCPU; - byte F; - int J, I; - static char FA[8] = "NVRBDIZC"; - char S[128]; - char name[512]; - static FILE *fp = NULL; - sprintf(name, "crashdump-%d.txt", time(NULL)); - if (state != 0) - { - fprintf(stderr, "\n\n\nCrashed within signal!\nEmergency exit\n"); - exit(42); - } - state = 1; - - if (fp == NULL) - fp = fopen(name, "wt"); - - state = 2; - - if (fp) fprintf(stderr, - "\n\n\n\n\n" - "#sick# TI-NESulator %d.%d #sick#\n" - "see %s for more information", - V_MAJOR, - V_MINOR, - name); - - if (!fp) fp = stderr; - - fprintf(fp,"\n\n\n\n\n" - "#sick# TI-NESulator %d.%d #sick# signal: ", - V_MAJOR, - V_MINOR); - switch(sig) - { - default: - case SIGABRT: fprintf(fp,"Abnormal termination"); break; - case SIGILL: fprintf(fp,"Illegal instruction"); break; - case SIGINT: fprintf(fp,"CTRL+C signal"); break; - case SIGSEGV: fprintf(fp,"Segmentation fault"); break; - case SIGTERM: fprintf(fp,"Termination request"); break; - } - fprintf(fp,"\nAn error occured during the excution.\n Crash report information :\n"); + static int state=0; + M6502 *R = &MainCPU; + byte F; + int J, I; + static char FA[8] = "NVRBDIZC"; + char S[128]; + char name[512]; + static FILE *fp = NULL; + sprintf(name, "crashdump-%d.txt", (int)time(NULL)); + if (state != 0) + { + fprintf(stderr, "\n\n\nCrashed within signal!\nEmergency exit\n"); + exit(42); + } + state = 1; + + if (fp == NULL) + fp = fopen(name, "wt"); + + state = 2; + + if (fp) fprintf(stderr, + "\n\n\n\n\n" + "#sick# TI-NESulator %d.%d #sick#\n" + "see %s for more information", + V_MAJOR, + V_MINOR, + name); + + if (!fp) fp = stderr; + + fprintf(fp,"\n\n\n\n\n" + "#sick# TI-NESulator %d.%d #sick# signal: ", + V_MAJOR, + V_MINOR); + switch(sig) + { + default: + case SIGABRT: fprintf(fp,"Abnormal termination"); break; + case SIGILL: fprintf(fp,"Illegal instruction"); break; + case SIGINT: fprintf(fp,"CTRL+C signal"); break; + case SIGSEGV: fprintf(fp,"Segmentation fault"); break; + case SIGTERM: fprintf(fp,"Termination request"); break; + } + fprintf(fp,"\nAn error occured during the excution.\n Crash report information :\n"); #ifdef DEBUG - DAsm(S, R->PC.W); + DAsm(S, R->PC.W); #endif - fprintf(fp, "CPU: A:%02X P:%02X X:%02X Y:%02X S:%04X PC:%04X Flags:[", - R->A, R->P, R->X, R->Y, R->S + 0x0100, R->PC.W); - for (J = 0, F = R->P; J < 8; J++, F <<= 1) - fprintf(fp, "%c", F & 0x80 ? FA[J] : '.'); - fprintf(fp, "]\nCPU: "); - fprintf(fp, "AT PC: [%02X - %s] AT SP: [%02X %02X %02X]\nLast execution :\n", + fprintf(fp, "CPU: A:%02X P:%02X X:%02X Y:%02X S:%04X PC:%04X Flags:[", + R->A, R->P, R->X, R->Y, R->S + 0x0100, R->PC.W); + for (J = 0, F = R->P; J < 8; J++, F <<= 1) + fprintf(fp, "%c", F & 0x80 ? FA[J] : '.'); + fprintf(fp, "]\nCPU: "); + fprintf(fp, "AT PC: [%02X - %s] AT SP: [%02X %02X %02X]\nLast execution :\n", Rd6502(R->PC.W), S, Rd6502(0x0100 + (byte) (R->S + 1)), Rd6502(0x0100 + (byte) (R->S + 2)), Rd6502(0x0100 + (byte) (R->S + 3))); - showlastop(fp); - // fprintf(fp, "PPU: CR1: 0x%02X (NT:%d AI:%d SP:%d BP:%d SS:%d NMI:%d)\n",ppu.ControlRegister1.b, ppu.ControlRegister1.s.NameTblAddr, ppu.ControlRegister1.s.AddrIncrmt, ppu.ControlRegister1.s.SptPattern, ppu.ControlRegister1.s.BgPattern, ppu.ControlRegister1.s.SpriteSize, ppu.ControlRegister1.s.VBlank_NMI); - // fprintf(fp, "PPU: CR2: 0x%02X (FBC/CI:%d SV:%d BV:%d SC:%d BC:%d DT:%d)\n",ppu.ControlRegister2.b,ppu.ControlRegister2.s.Colour,ppu.ControlRegister2.s.SpriteVisibility,ppu.ControlRegister2.s.BgVisibility,ppu.ControlRegister2.s.SpriteClipping,ppu.ControlRegister2.s.BgClipping,ppu.ControlRegister2.s.DisplayType); - // fprintf(fp, "PPU: SR: 0x%02X (VB:%d S0:%d SSC:%d VWF:%d)\n", ppu.StatusRegister.b,ppu.StatusRegister.s.VBlankOccur,ppu.StatusRegister.s.Sprite0Occur,ppu.StatusRegister.s.SprtCount,ppu.StatusRegister.s.VRAMProtect); - // fprintf(fp, "PPU: M:%d ST:%d VRAMPtr:0x%04X T:0x%04X\n",ppu.MirrorDir,ppu.ScreenType,ppu.VRAMAddrReg2.W,ppu.TmpVRamPtr); - - mapper_dump(fp); - - for(I = 0; I < 0xFFFF; I += 0x10) - fprintf(fp, "%04X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X | %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", - I, - Rd6502(I+0x00), Rd6502(I+0x01), Rd6502(I+0x02), Rd6502(I+0x03), - Rd6502(I+0x04), Rd6502(I+0x05), Rd6502(I+0x06), Rd6502(I+0x07), - Rd6502(I+0x08), Rd6502(I+0x09), Rd6502(I+0x0A), Rd6502(I+0x0B), - Rd6502(I+0x0C), Rd6502(I+0x0D), Rd6502(I+0x0E), Rd6502(I+0x0F), - // --- // - isprint(Rd6502(I+0x00))?Rd6502(I+0x00):'_', - isprint(Rd6502(I+0x01))?Rd6502(I+0x01):'_', - isprint(Rd6502(I+0x02))?Rd6502(I+0x02):'_', - isprint(Rd6502(I+0x03))?Rd6502(I+0x03):'_', - isprint(Rd6502(I+0x04))?Rd6502(I+0x04):'_', - isprint(Rd6502(I+0x05))?Rd6502(I+0x05):'_', - isprint(Rd6502(I+0x06))?Rd6502(I+0x06):'_', - isprint(Rd6502(I+0x07))?Rd6502(I+0x07):'_', - isprint(Rd6502(I+0x08))?Rd6502(I+0x08):'_', - isprint(Rd6502(I+0x09))?Rd6502(I+0x09):'_', - isprint(Rd6502(I+0x0A))?Rd6502(I+0x0A):'_', - isprint(Rd6502(I+0x0B))?Rd6502(I+0x0B):'_', - isprint(Rd6502(I+0x0C))?Rd6502(I+0x0C):'_', - isprint(Rd6502(I+0x0D))?Rd6502(I+0x0D):'_', - isprint(Rd6502(I+0x0E))?Rd6502(I+0x0E):'_', - isprint(Rd6502(I+0x0F))?Rd6502(I+0x0F):'_'); - - DumpMemoryState(fp); - - fprintf(stderr, "\nPlease join this informations when submiting crash report\n"); - if (fp != stderr) fclose(fp); - //getchar(); - exit(-42); + showlastop(fp); +// fprintf(fp, "PPU: CR1: 0x%02X (NT:%d AI:%d SP:%d BP:%d SS:%d NMI:%d)\n",ppu.ControlRegister1.b, ppu.ControlRegister1.s.NameTblAddr, ppu.ControlRegister1.s.AddrIncrmt, ppu.ControlRegister1.s.SptPattern, ppu.ControlRegister1.s.BgPattern, ppu.ControlRegister1.s.SpriteSize, ppu.ControlRegister1.s.VBlank_NMI); +// fprintf(fp, "PPU: CR2: 0x%02X (FBC/CI:%d SV:%d BV:%d SC:%d BC:%d DT:%d)\n",ppu.ControlRegister2.b,ppu.ControlRegister2.s.Colour,ppu.ControlRegister2.s.SpriteVisibility,ppu.ControlRegister2.s.BgVisibility,ppu.ControlRegister2.s.SpriteClipping,ppu.ControlRegister2.s.BgClipping,ppu.ControlRegister2.s.DisplayType); +// fprintf(fp, "PPU: SR: 0x%02X (VB:%d S0:%d SSC:%d VWF:%d)\n", ppu.StatusRegister.b,ppu.StatusRegister.s.VBlankOccur,ppu.StatusRegister.s.Sprite0Occur,ppu.StatusRegister.s.SprtCount,ppu.StatusRegister.s.VRAMProtect); +// fprintf(fp, "PPU: M:%d ST:%d VRAMPtr:0x%04X T:0x%04X\n",ppu.MirrorDir,ppu.ScreenType,ppu.VRAMAddrReg2.W,ppu.TmpVRamPtr); + + //MapperDump(fp); + + for(I = 0; I < 0xFFFF; I += 0x10) + fprintf(fp, "%04X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X | %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", + I, + Rd6502(I+0x00), Rd6502(I+0x01), Rd6502(I+0x02), Rd6502(I+0x03), + Rd6502(I+0x04), Rd6502(I+0x05), Rd6502(I+0x06), Rd6502(I+0x07), + Rd6502(I+0x08), Rd6502(I+0x09), Rd6502(I+0x0A), Rd6502(I+0x0B), + Rd6502(I+0x0C), Rd6502(I+0x0D), Rd6502(I+0x0E), Rd6502(I+0x0F), + // --- // + isprint(Rd6502(I+0x00))?Rd6502(I+0x00):'_', + isprint(Rd6502(I+0x01))?Rd6502(I+0x01):'_', + isprint(Rd6502(I+0x02))?Rd6502(I+0x02):'_', + isprint(Rd6502(I+0x03))?Rd6502(I+0x03):'_', + isprint(Rd6502(I+0x04))?Rd6502(I+0x04):'_', + isprint(Rd6502(I+0x05))?Rd6502(I+0x05):'_', + isprint(Rd6502(I+0x06))?Rd6502(I+0x06):'_', + isprint(Rd6502(I+0x07))?Rd6502(I+0x07):'_', + isprint(Rd6502(I+0x08))?Rd6502(I+0x08):'_', + isprint(Rd6502(I+0x09))?Rd6502(I+0x09):'_', + isprint(Rd6502(I+0x0A))?Rd6502(I+0x0A):'_', + isprint(Rd6502(I+0x0B))?Rd6502(I+0x0B):'_', + isprint(Rd6502(I+0x0C))?Rd6502(I+0x0C):'_', + isprint(Rd6502(I+0x0D))?Rd6502(I+0x0D):'_', + isprint(Rd6502(I+0x0E))?Rd6502(I+0x0E):'_', + isprint(Rd6502(I+0x0F))?Rd6502(I+0x0F):'_'); + + DumpMemoryState(fp); + + fprintf(stderr, "\nPlease join this informations when submiting crash report\n"); + if (fp != stderr) fclose(fp); + //getchar(); + exit(-42); } byte Page40[256]; void WrHook4000Multiplexer(byte addr, byte value) { - static byte SQ1V = 0; - static byte SQ2V = 0; - static byte TRIV = 0; - static byte NOIV = 0; - - static unsigned short SQ1P = 0; - static unsigned short SQ2P = 0; - static unsigned short TRIP = 0; - static unsigned short NOIP = 0; - - static byte Sq1_reg0 = 0; - static byte Sq1_reg1 = 0; - static byte Sq1_reg2 = 0; - static byte Sq1_reg3 = 0; - - static byte Sq2_reg0 = 0; - static byte Sq2_reg1 = 0; - static byte Sq2_reg2 = 0; - static byte Sq2_reg3 = 0; - - double SQ; - switch(addr) - { + static byte SQ1V = 0; + static byte SQ2V = 0; + static byte NOIV = 0; + + static unsigned short SQ1P = 0; + static unsigned short SQ2P = 0; + static unsigned short TRIP = 0; + static unsigned short NOIP = 0; + + static byte Sq1_reg0 = 0; + static byte Sq1_reg1 = 0; + static byte Sq1_reg2 = 0; + static byte Sq1_reg3 = 0; + + static byte Sq2_reg0 = 0; + static byte Sq2_reg1 = 0; + static byte Sq2_reg2 = 0; + static byte Sq2_reg3 = 0; + + double SQ = 0.0; + + switch(addr) + { #ifdef USE_SOUND - case 0x00: /* DDLE NNNN */ - Sq1_reg0 = value; - if (Sq1_reg0 & 0x10) - { + case 0x00: /* DDLE NNNN */ + Sq1_reg0 = value; + if (Sq1_reg0 & 0x10) + { SQ1V = 0x0F/*(0x04+(value&0x0F))& 0x0F*/; - } - else - { + } + else + { SQ1V = value&0x0F; - } - - break; - case 0x01: /* EPPP NSSS */ - Sq1_reg1 = value; - break; - case 0x02: - /*printf("Sq1 reg0: 0x%02X - duty:0x%X loop:0x%X env:0x%X vol:0x%X\n", - Sq1_reg0, - (Sq1_reg0&0xC0)>>6, - (Sq1_reg0&0x20)>>5, - (Sq1_reg0&0x10)>>4, - Sq1_reg0&0x0F); - printf("Sq1 reg1: 0x%02X - sweep:0x%X period:0x%X neg:0x%X shift:0x%X\n", - Sq1_reg1, - (Sq1_reg1&0x80)>>8, - (Sq1_reg1&0x70)>>4, - (Sq1_reg1&0x08)>>3, - Sq1_reg1&0x07); - printf("Sq1 reg2: 0x%02X\n", value); - printf("Sq1 reg3: 0x%02X\n", Sq1_reg3);*/ - SQ1P = value | ((Sq1_reg3&0x7) << 8); - SQ = APU_BASEFREQ * 1000 * 1000 / (SQ1P+1 /*+ - (Sq1_reg1&0x80)?0:( (Sq1_reg1&0x08)?(SQ1P>>(Sq1_reg1&0x07)):(SQ1P<<(Sq1_reg1&0x07)) )*/); - SetSound(0,SND_MELODIC); - - //printf("SQ1V = %d - SQ = %f - SQ1P = %d\n", SQ1V, SQ, SQ1P); - - - // { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 0, SQ1P, SQ1V); fclose(fp); } - - Sound(0, (int) SQ/22, (0xFF/0x0F) * SQ1V); - - // printf("40%02X: 0x%02X (SQ1P:%d SQ:%f (%d))\n", addr, value, SQ1P, SQ, (int) SQ); - Sq1_reg2 = value; - break; - - case 0x03: - Sq1_reg3 = value; - SQ1P = Sq1_reg2 | ((value&0x7) << 8); - SQ = APU_BASEFREQ * 1000 * 1000 / (SQ1P+1 /*+ - (Sq1_reg1&0x80)?0:( (Sq1_reg1&0x08)?(SQ1P>>(Sq1_reg1&0x07)):(SQ1P<<(Sq1_reg1&0x07)) )*/); - // { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 0, SQ1P, SQ1V); fclose(fp); } - Sound(0, (int) SQ/22, (0xFF/0x0F) * SQ1V); - break; - - - - case 0x04: - Sq2_reg0 = value; - if (Sq2_reg0 & 0x10) - { + } + + break; + case 0x01: /* EPPP NSSS */ + Sq1_reg1 = value; + break; + case 0x02: + /*printf("Sq1 reg0: 0x%02X - duty:0x%X loop:0x%X env:0x%X vol:0x%X\n", + Sq1_reg0, + (Sq1_reg0&0xC0)>>6, + (Sq1_reg0&0x20)>>5, + (Sq1_reg0&0x10)>>4, + Sq1_reg0&0x0F); + printf("Sq1 reg1: 0x%02X - sweep:0x%X period:0x%X neg:0x%X shift:0x%X\n", + Sq1_reg1, + (Sq1_reg1&0x80)>>8, + (Sq1_reg1&0x70)>>4, + (Sq1_reg1&0x08)>>3, + Sq1_reg1&0x07); + printf("Sq1 reg2: 0x%02X\n", value); + printf("Sq1 reg3: 0x%02X\n", Sq1_reg3);*/ + SQ1P = value | ((Sq1_reg3&0x7) << 8); + SQ = APU_BASEFREQ * 1000 * 1000 / (SQ1P+1 /*+ + (Sq1_reg1&0x80)?0:( (Sq1_reg1&0x08)?(SQ1P>>(Sq1_reg1&0x07)):(SQ1P<<(Sq1_reg1&0x07)) )*/); + SetSound(0,SND_MELODIC); + + //printf("SQ1V = %d - SQ = %f - SQ1P = %d\n", SQ1V, SQ, SQ1P); + +#ifdef SOUND_LOG + { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 0, SQ1P, SQ1V); fclose(fp); } +#endif + Sound(0, (int) SQ/22, (0xFF/0x0F) * SQ1V); + +// printf("40%02X: 0x%02X (SQ1P:%d SQ:%f (%d))\n", addr, value, SQ1P, SQ, (int) SQ); + Sq1_reg2 = value; + break; + + case 0x03: + Sq1_reg3 = value; + SQ1P = Sq1_reg2 | ((value&0x7) << 8); + SQ = APU_BASEFREQ * 1000 * 1000 / (SQ1P+1 /*+ + (Sq1_reg1&0x80)?0:( (Sq1_reg1&0x08)?(SQ1P>>(Sq1_reg1&0x07)):(SQ1P<<(Sq1_reg1&0x07)) )*/); +#ifdef SOUND_LOG + { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 0, SQ1P, SQ1V); fclose(fp); } +#endif + Sound(0, (int) SQ/22, (0xFF/0x0F) * SQ1V); + break; + + + + case 0x04: + Sq2_reg0 = value; + if (Sq2_reg0 & 0x10) + { SQ2V = 0x0F; //SQ2V = (0x04+(value&0x0F))& 0x0F; - } - else - { - SQ2V = value&0x0F; - } - - break; - case 0x05: - Sq2_reg1 = value; - break; - - case 0x06: - Sq2_reg2 = value; - - SQ2P = Sq2_reg2 | ((Sq2_reg3&0x7) << 8); - - SQ = APU_BASEFREQ * 1000 * 1000 / (SQ2P+1 /*+ - (Sq2_reg1&0x80)?0:( (Sq2_reg1&0x08)?(SQ2P>>(Sq2_reg1&0x07)):(SQ2P<<(Sq2_reg1&0x07)) )*/); - - /* printf("Sq2 reg0: 0x%02X - duty:0x%X loop:0x%X env:0x%X vol:0x%X\n", - Sq2_reg0, - (Sq2_reg0&0xC0)>>6, - (Sq2_reg0&0x20)>>5, - (Sq2_reg0&0x10)>>4, - Sq2_reg0&0x0F); - printf("Sq2 reg1: 0x%02X - sweep:0x%X period:0x%X neg:0x%X shift:0x%X\n", - Sq2_reg1, - (Sq2_reg1&0x80)>>8, - (Sq2_reg1&0x70)>>4, - (Sq2_reg1&0x08)>>3, - Sq2_reg1&0x07); - printf("Sq2 reg2: 0x%02X\n", value); - printf("Sq2 reg3: 0x%02X\n", Sq2_reg3); - printf("SQ2V = %d - SQ = %f - SQ2P = %d\n", SQ2V, SQ, SQ2P);*/ - - // { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 1, SQ2P, SQ2V); fclose(fp); } - Sound(1, (int) SQ/22, (0xFF/0x0F) * SQ2V); - break; - - case 0x07: - Sq2_reg3 = value; - - SQ2P = Sq2_reg2 | ((Sq2_reg3&0x7) << 8); - //SQ2P = (SQ2P & 0x00FF) | ((value&0x7) << 8); - SQ = APU_BASEFREQ * 1000 * 1000 / (SQ2P+1 /*+ - (Sq2_reg1&0x80)?0:( (Sq2_reg1&0x08)?(SQ2P>>(Sq2_reg1&0x07)):(SQ2P<<(Sq2_reg1&0x07)) )*/); - // { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 1, SQ2P, SQ2V); fclose(fp); } - Sound(1, (int) SQ/22, (0xFF/0x0F) * SQ2V); - break; - - case 0x0A: - TRIP = (TRIP & 0xFF00) | value; - SQ = APU_BASEFREQ * 1000 * 1000 / TRIP; - // { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 2, TRIP, 255); fclose(fp); } - Sound(2, (int) SQ/22, 127); - break; - - case 0x0B: - TRIP = (TRIP & 0x00FF) | ((value&0x7) << 8);; - SQ = APU_BASEFREQ * 1000 * 1000 / TRIP; - // { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 2, TRIP, 255); fclose(fp); } - - Sound(2, (int) SQ/22, 127); - break; - - /* case 0x0C: - NOIV = value & 0x0F; - break; - - case 0x0E: - NOIP = value & 0x0F; - SQ = APU_BASEFREQ * 1000 * 1000 / NOIP; - // { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 2, TRIP, 255); fclose(fp); } - SetSound(3, SND_NOISE); - Sound(3, (int) SQ/22, (0xFF/0x0F) * NOIV); - break; - case 0x0F: - - break;*/ - case 0x15: - /* DMC, Noise, Triangle, Sq 2, Sq 1 */ - //SetChannels(0, (value&0x01)?0x01:0); - /* printf("40%02X: 0x%02X [%c%c%c%c%c]\n", addr, value, - (value&0x10)?'d':'.', - (value&0x08)?'n':'.', - (value&0x04)?'t':'.', - (value&0x02)?'2':'.', - (value&0x01)?'1':'.');*/ - - break; -#endif - case 0x14: - ppu_fillSprRamDMA(value); - break; - - case 0x16: - WritePaddle(&P1, value); - //WritePaddle(&P2, value); - break; - - case 0x17: - // printf("40%02X: 0x%02X\n", addr, value); - - break; - // default: - //Page40[addr] = value; - // printf("40%02X: 0x%02X\n", addr, value); - // printf("pAPU: 0x%X @ 0x40%X\n", value, addr); - } + } + else + { + SQ2V = value&0x0F; + } + + break; + case 0x05: + Sq2_reg1 = value; + break; + + case 0x06: + Sq2_reg2 = value; + + SQ2P = Sq2_reg2 | ((Sq2_reg3&0x7) << 8); + + SQ = APU_BASEFREQ * 1000 * 1000 / (SQ2P+1 /*+ + (Sq2_reg1&0x80)?0:( (Sq2_reg1&0x08)?(SQ2P>>(Sq2_reg1&0x07)):(SQ2P<<(Sq2_reg1&0x07)) )*/); + + /* printf("Sq2 reg0: 0x%02X - duty:0x%X loop:0x%X env:0x%X vol:0x%X\n", + Sq2_reg0, + (Sq2_reg0&0xC0)>>6, + (Sq2_reg0&0x20)>>5, + (Sq2_reg0&0x10)>>4, + Sq2_reg0&0x0F); + printf("Sq2 reg1: 0x%02X - sweep:0x%X period:0x%X neg:0x%X shift:0x%X\n", + Sq2_reg1, + (Sq2_reg1&0x80)>>8, + (Sq2_reg1&0x70)>>4, + (Sq2_reg1&0x08)>>3, + Sq2_reg1&0x07); + printf("Sq2 reg2: 0x%02X\n", value); + printf("Sq2 reg3: 0x%02X\n", Sq2_reg3); + printf("SQ2V = %d - SQ = %f - SQ2P = %d\n", SQ2V, SQ, SQ2P);*/ +#ifdef SOUND_LOG + { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 1, SQ2P, SQ2V); fclose(fp); } +#endif + Sound(1, (int) SQ/22, (0xFF/0x0F) * SQ2V); + break; + + case 0x07: + Sq2_reg3 = value; + + SQ2P = Sq2_reg2 | ((Sq2_reg3&0x7) << 8); + //SQ2P = (SQ2P & 0x00FF) | ((value&0x7) << 8); + SQ = APU_BASEFREQ * 1000 * 1000 / (SQ2P+1 /*+ + (Sq2_reg1&0x80)?0:( (Sq2_reg1&0x08)?(SQ2P>>(Sq2_reg1&0x07)):(SQ2P<<(Sq2_reg1&0x07)) )*/); +#ifdef SOUND_LOG + { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 1, SQ2P, SQ2V); fclose(fp); } +#endif + Sound(1, (int) SQ/22, (0xFF/0x0F) * SQ2V); + break; + + case 0x0A: + TRIP = (TRIP & 0xFF00) | value; + SQ = APU_BASEFREQ * 1000 * 1000 / TRIP; +#ifdef SOUND_LOG + { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 2, TRIP, 127); fclose(fp); } +#endif + Sound(2, (int) SQ/22, 127); + break; + + case 0x0B: + TRIP = (TRIP & 0x00FF) | ((value&0x7) << 8);; + SQ = APU_BASEFREQ * 1000 * 1000 / TRIP; +#ifdef SOUND_LOG + { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 2, TRIP, 127); fclose(fp); } +#endif + Sound(2, (int) SQ/22, 127); + break; + case 0x0C: + NOIV = value & 0x0F; +#ifdef SOUND_LOG + { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 3, NOIP, NOIV); fclose(fp); } +#endif + SetSound(3, SND_NOISE); + Sound(3, (int) SQ/22, (0xFF/0x0F) * NOIV); + break; + + case 0x0E: + NOIP = value & 0x0F; + SQ = APU_BASEFREQ * 1000 * 1000 / NOIP; +#ifdef SOUND_LOG + { FILE *fp = fopen("sound.log", "at"); fprintf(fp, "%d %d %d\n", 3, NOIP, NOIV); fclose(fp); } +#endif + SetSound(3, SND_NOISE); + Sound(3, (int) SQ/22, NOIV); + break; + case 0x0F: + + break; + case 0x15: + /* DMC, Noise, Triangle, Sq 2, Sq 1 */ + //SetChannels(0, (value&0x01)?0x01:0); +/* printf("40%02X: 0x%02X [%c%c%c%c%c]\n", addr, value, + (value&0x10)?'d':'.', + (value&0x08)?'n':'.', + (value&0x04)?'t':'.', + (value&0x02)?'2':'.', + (value&0x01)?'1':'.');*/ + + break; + #endif + case 0x14: + ppu_fillSprRamDMA(value); + break; + + case 0x16: + WritePaddle(&P1, value); + //WritePaddle(&P2, value); + break; + + case 0x17: +// printf("40%02X: 0x%02X\n", addr, value); + if (value == 0x00) + Int6502(&MainCPU,INT_IRQ); + + break; +// default: + //Page40[addr] = value; + // printf("40%02X: 0x%02X\n", addr, value); +// printf("pAPU: 0x%X @ 0x40%X\n", value, addr); + } + } byte RdHook4000Multiplexer(byte addr) { - byte ret; - switch(addr) - { - case 0x16: - ret = ReadPaddle(&P1); - break; - - case 0x17: - ret = 0x40; - break; - - case 0x15: - ret = 0x1F; - default: - ret = 0x42; - } - return ret; + byte ret; + switch(addr) + { + case 0x16: + ret = ReadPaddle(&P1); + break; + + case 0x17: + ret = 0x40; + break; + + case 0x15: + ret = 0x1F; + default: + ret = 0x42; + } + return ret; } void printUsage(int argc, char *argv[]) { - printf("Usage : %s game.nes [-p number][-f][-b filename.pal][ filename.nes\n" - " -p: to add plugin 'number'\n" - " -f: to start in FDS mode\n" - " -d: to start directily into the debugguer\n" - " -b: to use palette file 'filename.pal'\n", - argv[0]); - exit(0); + printf("Usage : %s game.nes [-p number][-f][-b filename.pal][ filename.nes\n" + " -p: to add plugin 'number'\n" + " -f: to start in FDS mode\n" + " -d: to start directily into the debugguer\n" + " -b: to use palette file 'filename.pal'\n", + argv[0]); + exit(0); } int main(int argc, char *argv[]) { - int i; - unsigned char j, k; - unsigned char *MemoryPage; - - /* Here we will fill the memory */ - /* + int i; + unsigned char j, k; + unsigned char *MemoryPage; + + /* Here we will fill the memory */ + /* --------------------------------------- $10000 Upper Bank of Cartridge ROM --------------------------------------- $C000 @@ -637,8 +655,8 @@ int main(int argc, char *argv[]) 2kB Internal RAM, mirrored 4 times --------------------------------------- $0000 */ - - /* Print the banner */ + + /* Print the banner */ printf("--------------------------------------------------------------------------------\n" "Welcome to TI-NESulator v%d.%d - by Godzil\n" "Copyright 2003-2007 TRAPIER Manoel (godzil@godzil.net)\n" @@ -828,7 +846,7 @@ int main(int argc, char *argv[]) } printf("Reseting main RAM...\t\t"); - //Force the stack to be empty of zero + /* Force the stack to be full of zero */ for( i = 0x100 ; i < 0x200 ; i++ ) { Wr6502(i, 0x00); } @@ -904,7 +922,7 @@ int main(int argc, char *argv[]) if (ppu_init() != 0) fatal("PPU Initialisation error..\n"); - //DumpMemoryState(); + /* DumpMemoryState(); */ if (Cart->Flags & iNES_4SCREEN) { ppu_setScreenMode(PPU_SCMODE_FOURSC); @@ -996,25 +1014,6 @@ int main(int argc, char *argv[]) } - exit(0);*/ - - /* int K, L1, V = 127, L2, I; - - if(440>=48000/3) printf("Pwet\n"); - K=48000/440; - L1=0; - V<<=7; - for(I=0;I>8,Addr&0x00FF, Value); + WriteMemory((Addr&0xFF00)>>8,Addr&0x00FF, Value); } byte Rd6502(register word Addr) { /* Read memory for normal use */ - return ReadMemory((Addr&0xFF00)>>8,Addr&0x00FF); - + return ReadMemory((Addr&0xFF00)>>8,Addr&0x00FF); + } extern byte *memory_pages[0xFF]; byte Op6502(register word Addr) { /* Read OpCodes */ - byte *ptr; - return (ptr = memory_pages[(Addr&0xFF00)>>8])>1?ptr[Addr&0x00FF]:0; - - //return ReadMemory((Addr&0xFF00)>>8,Addr&0x00FF); + byte *ptr; + return ((ptr = memory_pages[(Addr&0xFF00)>>8])>(byte*)1)?ptr[Addr&0x00FF]:0; + + //return ReadMemory((Addr&0xFF00)>>8,Addr&0x00FF); } /** Loop6502() ***********************************************/ @@ -1082,7 +1080,6 @@ byte Loop6502(register M6502 * R) { byte ret; short skey; - printf("pouic\n"); long WaitTime; static long delta=0; @@ -1110,19 +1107,21 @@ byte Loop6502(register M6502 * R) if (ScanLine == 241) frame++; - //if (ScanLine >= (241 + VBLANK_TIME)) - if (ScanLine >= 262) + if (ScanLine >= 240 + VBLANK_TIME) { /* End of VBlank Time */ /* Sync at 60FPS */ /* Get current time in microseconds */ gettimeofday(&timeEnd, NULL); - /* Calculate the waiting time, 16666 is the time of one frame in microseconds at a 60Hz rate) */ WaitTime = (timeEnd.tv_sec) - (timeStart.tv_sec); WaitTime *= 1000000; WaitTime += (timeEnd.tv_usec - timeStart.tv_usec); +#if !ISPAL && ISNTSC + /* Calculate the waiting time, 16666 is the time of one frame in microseconds at a 60Hz rate) */ WaitTime = 16666 - WaitTime + delta; - +#elif ISPAL && !ISNTSC + WaitTime = 20000 - WaitTime + delta; +#endif /* If we press Page Up, we dont we to accelerate "time" */ if (!key[KEY_PGUP]) @@ -1227,6 +1226,6 @@ byte Loop6502(register M6502 * R) /************************************ TO BE WRITTEN BY USER **/ byte Patch6502(register byte Op, register M6502 * R) { - //printf("Invalid Opcode : 0x%X @ 0x%04X !\n", Op, R->PC.W); - return 1; + //printf("Invalid Opcode : 0x%X @ 0x%04X !\n", Op, R->PC.W); + return 1; } diff --git a/src/mappersmanager/manager.c b/src/mappersmanager/manager.c index 92996a3..622cd9b 100644 --- a/src/mappersmanager/manager.c +++ b/src/mappersmanager/manager.c @@ -19,7 +19,7 @@ MapperWriteHook mapper_hook; typedef struct Mapper_ { byte id; - byte *name; + char *name; MapperInit init; MapperIRQ irq; diff --git a/src/mappersmanager/mappers/temp/aorom.c b/src/mappersmanager/mappers/aorom.c similarity index 94% rename from src/mappersmanager/mappers/temp/aorom.c rename to src/mappersmanager/mappers/aorom.c index 3d80dff..d41eee2 100755 --- a/src/mappersmanager/mappers/temp/aorom.c +++ b/src/mappersmanager/mappers/aorom.c @@ -1,63 +1,65 @@ -/* - * AOROM Mapper - The TI-NESulator Project - * aorom.h - * - * Created by Manoel TRAPIER. - * Copyright (c) 2003-2007 986Corp. All rights reserved. - * - * $LastChangedDate: 2007-04-26 18:47:34 +0200 (jeu, 26 avr 2007) $ - * $Author: mtrapier $ - * $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/aorom.h $ - * $Revision: 46 $ - * - */ - -unsigned char aorom_load_bank; - -void aorom_MapperWriteHook(register byte Addr, register byte Value); - -extern byte *ppu_mem_nameTables; - -int aorom_InitMapper(NesCart * cart) -{ - int i; - - set_prom_bank_32k(0x8000,0); - - ppu_setScreenMode(PPU_SCMODE_SINGLE); - - aorom_load_bank = 0; - - /* Register the write hook */ - for (i = 0x80; i < 0x100; i++) - { - set_page_wr_hook(i, aorom_MapperWriteHook); - set_page_writeable(i, true); - } - - - return 0; - -} - -void aorom_MapperWriteHook(register byte Addr, register byte Value) -{ - int BankNb; - - if (Value & (1 << 4)) - ppu_setSingleScreen(PPU_SCREEN_000); - else - ppu_setSingleScreen(PPU_SCREEN_400); - - BankNb = Value & 0x0F; - - aorom_load_bank = BankNb; - - //printf("aorom: Asking bank %d (giving %d & %d) - mirror is %d\n",BankNb,BankNb,(Value<<1)+1,Value&0x0F); - set_prom_bank_32k(0x8000,BankNb); -} - -void aorom_MapperDump(FILE *fp) -{ - fprintf(fp,"aorom: bank:%d\n",aorom_load_bank); -} +/* + * AOROM Mapper - The TI-NESulator Project + * aorom.c + * + * Created by Manoel TRAPIER. + * Copyright (c) 2003-2007 986Corp. All rights reserved. + * + * $LastChangedDate: 2007-04-26 18:47:34 +0200 (jeu, 26 avr 2007) $ + * $Author: mtrapier $ + * $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/aorom.h $ + * $Revision: 46 $ + * + */ + +#include "aorom.h" + +unsigned char aorom_load_bank; + +void aorom_MapperWriteHook(register byte Addr, register byte Value); + +extern byte *ppu_mem_nameTables; + +int aorom_InitMapper(NesCart * cart) +{ + int i; + + set_prom_bank_32k(0x8000,0); + + ppu_setScreenMode(PPU_SCMODE_SINGLE); + + aorom_load_bank = 0; + + /* Register the write hook */ + for (i = 0x80; i < 0x100; i++) + { + set_page_wr_hook(i, aorom_MapperWriteHook); + set_page_writeable(i, true); + } + + + return 0; + +} + +void aorom_MapperWriteHook(register byte Addr, register byte Value) +{ + int BankNb; + + if (Value & (1 << 4)) + ppu_setSingleScreen(PPU_SCREEN_000); + else + ppu_setSingleScreen(PPU_SCREEN_400); + + BankNb = Value & 0x0F; + + aorom_load_bank = BankNb; + + //printf("aorom: Asking bank %d (giving %d & %d) - mirror is %d\n",BankNb,BankNb,(Value<<1)+1,Value&0x0F); + set_prom_bank_32k(0x8000,BankNb); +} + +void aorom_MapperDump(FILE *fp) +{ + fprintf(fp,"aorom: bank:%d\n",aorom_load_bank); +} diff --git a/src/mappersmanager/unused/aorom.h b/src/mappersmanager/mappers/aorom.h similarity index 100% rename from src/mappersmanager/unused/aorom.h rename to src/mappersmanager/mappers/aorom.h diff --git a/src/mappersmanager/mappers/temp/cnrom.c b/src/mappersmanager/mappers/cnrom.c similarity index 97% rename from src/mappersmanager/mappers/temp/cnrom.c rename to src/mappersmanager/mappers/cnrom.c index 72a40b7..cbc5a41 100755 --- a/src/mappersmanager/mappers/temp/cnrom.c +++ b/src/mappersmanager/mappers/cnrom.c @@ -1,6 +1,6 @@ /* * CNROM Mapper - The TI-NESulator Project - * cnrom.h + * cnrom.c * * Created by Manoel TRAPIER. * Copyright (c) 2003-2007 986Corp. All rights reserved. @@ -12,6 +12,8 @@ * */ +#include "cnrom.h" + unsigned char cnrom_load_bank; void cnrom_MapperWriteHook(register byte Addr, register byte Value); diff --git a/src/mappersmanager/unused/cnrom.h b/src/mappersmanager/mappers/cnrom.h similarity index 100% rename from src/mappersmanager/unused/cnrom.h rename to src/mappersmanager/mappers/cnrom.h diff --git a/src/mappersmanager/mappers/temp/genericmapper.c b/src/mappersmanager/mappers/genericmapper.c similarity index 100% rename from src/mappersmanager/mappers/temp/genericmapper.c rename to src/mappersmanager/mappers/genericmapper.c diff --git a/src/mappersmanager/mappers/temp/iremh3001.c b/src/mappersmanager/mappers/iremh3001.c similarity index 93% rename from src/mappersmanager/mappers/temp/iremh3001.c rename to src/mappersmanager/mappers/iremh3001.c index 517089b..8200a25 100755 --- a/src/mappersmanager/mappers/temp/iremh3001.c +++ b/src/mappersmanager/mappers/iremh3001.c @@ -1,125 +1,127 @@ -/* - * IREMH3001 Mapper - The TI-NESulator Project - * iremh3001.h - * - * Created by Manoel TRAPIER. - * Copyright (c) 2003-2007 986Corp. All rights reserved. - * - * $LastChangedDate: 2007-04-16 01:55:35 +0200 (lun, 16 avr 2007) $ - * $Author: godzil $ - * $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/iremh3001.h $ - * $Revision: 39 $ - * - */ - -unsigned short iremh3001_prom_slot[3]; - -unsigned short iremh3001_vrom_slot[8]; - -int iremh3001_InitMapper(NesCart * cart) -{ - - set_prom_bank_16k(0x8000, 0); - set_prom_bank_16k(0xC000, GETLAST16KBANK(cart)); - - iremh3001_prom_slot[0] = 0; - iremh3001_prom_slot[1] = 1; - iremh3001_prom_slot[2] = GETLAST16KBANK(cart); - - set_vrom_bank_8k(0x0000,4); - - iremh3001_vrom_slot[0] = 0; - iremh3001_vrom_slot[1] = 0; - iremh3001_vrom_slot[2] = 0; - iremh3001_vrom_slot[3] = 0; - iremh3001_vrom_slot[4] = 0; - iremh3001_vrom_slot[5] = 0; - iremh3001_vrom_slot[6] = 0; - iremh3001_vrom_slot[7] = 0; - - return 0; - -} - -int iremh3001_MapperWriteHook(register word Addr, register byte Value) -{ - - switch(Addr) - { - case 0x8000: /* Set 8k PROM @ 8000 */ - printf("iremh3001: %X: change PROM to %d[%X]\n", Addr, Value, Value); - set_prom_bank_8k(0x8000, Value); - iremh3001_prom_slot[0] = Value; - break; - - case 0x9003: /* Mirroring ??? */ - printf("iremh3001: Mirroring[0x%X:%d] ?\n", Value, Value); - break; - - case 0x9005: /* IRQ ??? */ - printf("iremh3001: IRQ[0x%X:%d] ?\n", Value, Value); - break; - - case 0x9006: /* IRQ ??? */ - printf("iremh3001: IRQ[0x%X:%d] ?\n", Value, Value); - break; - - case 0xA000: /* Set 8k PROM @ A000 */ - printf("iremh3001: %X: change PROM to %d[%X]\n", Addr, Value, Value); - set_prom_bank_8k(0xA000, Value); - iremh3001_prom_slot[1] = Value; - break; - - case 0xB000: /* Set 1k VROM @ 0000 */ - case 0xB001: /* Set 1k VROM @ 0400 */ - case 0xB002: /* Set 1k VROM @ 0800 */ - case 0xB003: /* Set 1k VROM @ 0C00 */ - case 0xB004: /* Set 1k VROM @ 1000 */ - case 0xB005: /* Set 1k VROM @ 1400 */ - case 0xB006: /* Set 1k VROM @ 1800 */ - case 0xB007: /* Set 1k VROM @ 1C00 */ - printf("iremh3001: %X: change VROM to %d[%X]\n", (Addr&0x0F)<<10, Value, Value); - set_vrom_bank_1k((Addr&0xF)<<10, Value); - iremh3001_vrom_slot[Addr&0x0F] = Value; - break; - - case 0xC000: /* Set 8k PROM @ C000 */ - printf("iremh3001: %X: change PROM to %d[%X]\n", Addr, Value, Value); - set_prom_bank_8k(0xC000, Value); - iremh3001_prom_slot[2] = Value; - break; - - default: - printf("@:%X -- V:%X", Addr, Value); - return 0; - - } - - return 1; -} - -void iremh3001_MapperDump(FILE *fp) -{ - fprintf(fp,"iremh3001: prom: $8000:%d $A000:%d $C000:%d\n", - iremh3001_prom_slot[0], - iremh3001_prom_slot[1], - iremh3001_prom_slot[2]); - - fprintf(fp,"iremh3001: vrom: $0000:%d $0400:%d $0800:%d $0C00:%d\n" \ - " $1000:%d $1400:%d $1800:%d $1C00:%d\n", - iremh3001_vrom_slot[0], - iremh3001_vrom_slot[1], - iremh3001_vrom_slot[2], - iremh3001_vrom_slot[3], - iremh3001_vrom_slot[4], - iremh3001_vrom_slot[5], - iremh3001_vrom_slot[6], - iremh3001_prom_slot[7]); -} - - -int iremh3001_MapperIRQ(int cycledone) -{ - - return 0; -} +/* + * IREMH3001 Mapper - The TI-NESulator Project + * iremh3001.c + * + * Created by Manoel TRAPIER. + * Copyright (c) 2003-2007 986Corp. All rights reserved. + * + * $LastChangedDate: 2007-04-16 01:55:35 +0200 (lun, 16 avr 2007) $ + * $Author: godzil $ + * $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/iremh3001.h $ + * $Revision: 39 $ + * + */ + +#include "iremh3001.h" + +unsigned short iremh3001_prom_slot[3]; + +unsigned short iremh3001_vrom_slot[8]; + +int iremh3001_InitMapper(NesCart * cart) +{ + + set_prom_bank_16k(0x8000, 0); + set_prom_bank_16k(0xC000, GETLAST16KBANK(cart)); + + iremh3001_prom_slot[0] = 0; + iremh3001_prom_slot[1] = 1; + iremh3001_prom_slot[2] = GETLAST16KBANK(cart); + + set_vrom_bank_8k(0x0000,4); + + iremh3001_vrom_slot[0] = 0; + iremh3001_vrom_slot[1] = 0; + iremh3001_vrom_slot[2] = 0; + iremh3001_vrom_slot[3] = 0; + iremh3001_vrom_slot[4] = 0; + iremh3001_vrom_slot[5] = 0; + iremh3001_vrom_slot[6] = 0; + iremh3001_vrom_slot[7] = 0; + + return 0; + +} + +int iremh3001_MapperWriteHook(register byte Addr, register byte Value) +{ + + switch(Addr) + { + case 0x8000: /* Set 8k PROM @ 8000 */ + printf("iremh3001: %X: change PROM to %d[%X]\n", Addr, Value, Value); + set_prom_bank_8k(0x8000, Value); + iremh3001_prom_slot[0] = Value; + break; + + case 0x9003: /* Mirroring ??? */ + printf("iremh3001: Mirroring[0x%X:%d] ?\n", Value, Value); + break; + + case 0x9005: /* IRQ ??? */ + printf("iremh3001: IRQ[0x%X:%d] ?\n", Value, Value); + break; + + case 0x9006: /* IRQ ??? */ + printf("iremh3001: IRQ[0x%X:%d] ?\n", Value, Value); + break; + + case 0xA000: /* Set 8k PROM @ A000 */ + printf("iremh3001: %X: change PROM to %d[%X]\n", Addr, Value, Value); + set_prom_bank_8k(0xA000, Value); + iremh3001_prom_slot[1] = Value; + break; + + case 0xB000: /* Set 1k VROM @ 0000 */ + case 0xB001: /* Set 1k VROM @ 0400 */ + case 0xB002: /* Set 1k VROM @ 0800 */ + case 0xB003: /* Set 1k VROM @ 0C00 */ + case 0xB004: /* Set 1k VROM @ 1000 */ + case 0xB005: /* Set 1k VROM @ 1400 */ + case 0xB006: /* Set 1k VROM @ 1800 */ + case 0xB007: /* Set 1k VROM @ 1C00 */ + printf("iremh3001: %X: change VROM to %d[%X]\n", (Addr&0x0F)<<10, Value, Value); + set_vrom_bank_1k((Addr&0xF)<<10, Value); + iremh3001_vrom_slot[Addr&0x0F] = Value; + break; + + case 0xC000: /* Set 8k PROM @ C000 */ + printf("iremh3001: %X: change PROM to %d[%X]\n", Addr, Value, Value); + set_prom_bank_8k(0xC000, Value); + iremh3001_prom_slot[2] = Value; + break; + + default: + printf("@:%X -- V:%X", Addr, Value); + return 0; + + } + + return 1; +} + +void iremh3001_MapperDump(FILE *fp) +{ + fprintf(fp,"iremh3001: prom: $8000:%d $A000:%d $C000:%d\n", + iremh3001_prom_slot[0], + iremh3001_prom_slot[1], + iremh3001_prom_slot[2]); + + fprintf(fp,"iremh3001: vrom: $0000:%d $0400:%d $0800:%d $0C00:%d\n" \ + " $1000:%d $1400:%d $1800:%d $1C00:%d\n", + iremh3001_vrom_slot[0], + iremh3001_vrom_slot[1], + iremh3001_vrom_slot[2], + iremh3001_vrom_slot[3], + iremh3001_vrom_slot[4], + iremh3001_vrom_slot[5], + iremh3001_vrom_slot[6], + iremh3001_prom_slot[7]); +} + + +int iremh3001_MapperIRQ(int cycledone) +{ + + return 0; +} diff --git a/src/mappersmanager/unused/iremh3001.h b/src/mappersmanager/mappers/iremh3001.h similarity index 88% rename from src/mappersmanager/unused/iremh3001.h rename to src/mappersmanager/mappers/iremh3001.h index e16f1d1..99e1011 100755 --- a/src/mappersmanager/unused/iremh3001.h +++ b/src/mappersmanager/mappers/iremh3001.h @@ -16,6 +16,5 @@ #include int iremh3001_InitMapper(NesCart * cart); -int iremh3001_MapperWriteHook(register word Addr, register byte Value); void iremh3001_MapperDump(FILE *fp); int iremh3001_MapperIRQ(int cycledone); \ No newline at end of file diff --git a/src/mappersmanager/mappers/mmc1.c b/src/mappersmanager/mappers/mmc1.c index cd963ed..2605c0a 100755 --- a/src/mappersmanager/mappers/mmc1.c +++ b/src/mappersmanager/mappers/mmc1.c @@ -14,9 +14,6 @@ #include "norom.h" -#include -#include - unsigned char MMC1_reg0; unsigned char MMC1_reg1; @@ -52,7 +49,6 @@ unsigned char mmc1_CurrentBank; #define MMC1_REG2_DEFAULT 0 #define MMC1_REG3_DEFAULT 0 - void mmc1_MapperWriteReg0(register byte Addr, register byte Value); void mmc1_MapperWriteReg1(register byte Addr, register byte Value); void mmc1_MapperWriteReg2(register byte Addr, register byte Value); diff --git a/src/mappersmanager/mappers/mmc1.h b/src/mappersmanager/mappers/mmc1.h index 1cd69f8..c8822c0 100644 --- a/src/mappersmanager/mappers/mmc1.h +++ b/src/mappersmanager/mappers/mmc1.h @@ -1,9 +1,14 @@ /* + * MMC1 Mapper - The TI-NESulator Project * mmc1.h - * TI-NESulator.X * - * Created by Manoël Trapier on 02/12/07. - * Copyright 2007 986 Corp. All rights reserved. + * Created by Manoel TRAPIER. + * Copyright (c) 2003-2007 986Corp. All rights reserved. + * + * $LastChangedDate: 2007-05-02 18:37:41 +0200 (mer, 02 mai 2007) $ + * $Author: mtrapier $ + * $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/mmc1.h $ + * $Revision: 50 $ * */ @@ -12,5 +17,4 @@ int mmc1_InitMapper (NesCart *cart); int mmc1_MapperIRQ (int cycledone); -void mmc1_MapperDump (); -void mmc1_MapperWriteHook(register byte Addr, register byte Value); \ No newline at end of file +void mmc1_MapperDump (); \ No newline at end of file diff --git a/src/mappersmanager/mappers/temp/mmc3.c b/src/mappersmanager/mappers/mmc3.c similarity index 99% rename from src/mappersmanager/mappers/temp/mmc3.c rename to src/mappersmanager/mappers/mmc3.c index ee07302..d9ecc3f 100755 --- a/src/mappersmanager/mappers/temp/mmc3.c +++ b/src/mappersmanager/mappers/mmc3.c @@ -12,6 +12,10 @@ * */ +#include "mmc3.h" + +extern unsigned short ScanLine; + unsigned short mmc3_command; unsigned char mmc3_irq_counter; @@ -43,8 +47,6 @@ void mmc3_MapperDump(FILE *fp) int mmc3_InitMapper(NesCart * cart) { - int i; - set_prom_bank_16k(0x8000, 0); set_prom_bank_16k(0xC000, GETLAST16KBANK(cart)); @@ -75,8 +77,6 @@ int mmc3_InitMapper(NesCart * cart) mmc3_first_prom_page = 0x8000; mmc3_second_prom_page = 0xA000; - //mmc3_first_prom_page = 0; // Set it to 0x8000 - /* Register mapper write hook */ set_page_wr_hook(0x80, mmc3_MapperWrite80Hook); @@ -92,7 +92,6 @@ int mmc3_InitMapper(NesCart * cart) set_page_writeable(0xE0, true); return 0; - } void mmc3_MapperWrite80Hook(byte addr, byte Value) @@ -250,8 +249,6 @@ void mmc3_MapperWriteA0Hook(byte addr, byte Value) } -extern unsigned short ScanLine; - void mmc3_MapperWriteC0Hook(byte addr, byte Value) { //printf("%s(0x%02X, 0x%02X)\n", __func__, addr, Value); diff --git a/src/mappersmanager/unused/mmc3.h b/src/mappersmanager/mappers/mmc3.h similarity index 100% rename from src/mappersmanager/unused/mmc3.h rename to src/mappersmanager/mappers/mmc3.h diff --git a/src/mappersmanager/mappers/temp/mmc4.c b/src/mappersmanager/mappers/mmc4.c similarity index 96% rename from src/mappersmanager/mappers/temp/mmc4.c rename to src/mappersmanager/mappers/mmc4.c index 54a885c..9dc4601 100644 --- a/src/mappersmanager/mappers/temp/mmc4.c +++ b/src/mappersmanager/mappers/mmc4.c @@ -1,23 +1,25 @@ -/* - * MMC4 Mapper - The TI-NESulator Project - * mmc4.h - * - * Created by Manoel TRAPIER. - * Copyright (c) 2007 986Corp. All rights reserved. - * - * $LastChangedDate: 2007-05-31 18:00:41 +0200 (jeu, 31 mai 2007) $ - * $Author: mtrapier $ - * $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/mmc4.h $ - * $Revision: 56 $ - * - */ +/* + * MMC4 Mapper - The TI-NESulator Project + * mmc4.h + * + * Created by Manoel TRAPIER. + * Copyright (c) 2007 986Corp. All rights reserved. + * + * $LastChangedDate: 2007-05-31 18:00:41 +0200 (jeu, 31 mai 2007) $ + * $Author: mtrapier $ + * $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/mmc4.h $ + * $Revision: 56 $ + * + */ + +#include "mmc4.h" byte mmc4_RegA; byte mmc4_RegB; byte mmc4_RegC; byte mmc4_RegD; byte mmc4_RegE; -byte mmc4_RegF; +byte mmc4_RegF; #ifdef DEBUG #define LOG @@ -25,8 +27,8 @@ byte mmc4_RegF; #else #define LOG #endif - - + + void mmc4_MapperWriteRegA(register byte Addr, register byte Value) { LOG("%s(%02X, %02X)\n", __func__, Addr, Value); @@ -75,51 +77,52 @@ void mmc4_MapperWriteRegF(register byte Addr, register byte Value) ppu_setMirroring(PPU_MIRROR_VERTICAL); } - -void mmc4_MapperDump(FILE *fp) -{ - -} - -int mmc4_InitMapper(NesCart * cart) + +void mmc4_MapperDump(FILE *fp) +{ + +} + +int mmc4_InitMapper(NesCart * cart) { int i; - - set_prom_bank_16k(0x8000,0); - set_prom_bank_16k(0xC000, GETLAST16KBANK(cart)); - - if (cart->VROMSize > 0) set_vrom_bank_8k(0x0000,0); - - /* Mapper should register itself for write hook */ - for (i = 0xA0; i < 0xB0 ; i++) - { - set_page_wr_hook(i, mmc4_MapperWriteRegA); - set_page_writeable(i, true); - } - for (i = 0xB0; i < 0xC0 ; i++) - { - set_page_wr_hook(i, mmc4_MapperWriteRegB); - set_page_writeable(i, true); + + set_prom_bank_16k(0x8000,0); + set_prom_bank_16k(0xC000, GETLAST16KBANK(cart)); + + if (cart->VROMSize > 0) + set_vrom_bank_8k(0x0000,0); + + /* Mapper should register itself for write hook */ + for (i = 0xA0; i < 0xB0 ; i++) + { + set_page_wr_hook(i, mmc4_MapperWriteRegA); + set_page_writeable(i, true); + } + for (i = 0xB0; i < 0xC0 ; i++) + { + set_page_wr_hook(i, mmc4_MapperWriteRegB); + set_page_writeable(i, true); } - for (i = 0xC0; i < 0xD0 ; i++) - { - set_page_wr_hook(i, mmc4_MapperWriteRegC); - set_page_writeable(i, true); - } - for (i = 0xD0; i < 0xE0 ; i++) - { - set_page_wr_hook(i, mmc4_MapperWriteRegD); - set_page_writeable(i, true); - } - for (i = 0xE0; i < 0xF0 ; i++) - { - set_page_wr_hook(i, mmc4_MapperWriteRegE); - set_page_writeable(i, true); - } - for (i = 0xF0; i < 0x100 ; i++) - { - set_page_wr_hook(i, mmc4_MapperWriteRegF); - set_page_writeable(i, true); + for (i = 0xC0; i < 0xD0 ; i++) + { + set_page_wr_hook(i, mmc4_MapperWriteRegC); + set_page_writeable(i, true); + } + for (i = 0xD0; i < 0xE0 ; i++) + { + set_page_wr_hook(i, mmc4_MapperWriteRegD); + set_page_writeable(i, true); + } + for (i = 0xE0; i < 0xF0 ; i++) + { + set_page_wr_hook(i, mmc4_MapperWriteRegE); + set_page_writeable(i, true); + } + for (i = 0xF0; i < 0x100 ; i++) + { + set_page_wr_hook(i, mmc4_MapperWriteRegF); + set_page_writeable(i, true); } for (i = 0x60; i < 0x80 ; i++) @@ -130,8 +133,8 @@ int mmc4_InitMapper(NesCart * cart) //ppu_setScreenMode(PPU_SCMODE_NORMAL); //ppu_setMirroring(PPU_MIRROR_HORIZTAL); - - return 0; - -} + + return 0; + +} diff --git a/src/mappersmanager/unused/mmc4.h b/src/mappersmanager/mappers/mmc4.h similarity index 100% rename from src/mappersmanager/unused/mmc4.h rename to src/mappersmanager/mappers/mmc4.h diff --git a/src/mappersmanager/mappers/norom.c b/src/mappersmanager/mappers/norom.c index 93b2ef0..e09bfff 100644 --- a/src/mappersmanager/mappers/norom.c +++ b/src/mappersmanager/mappers/norom.c @@ -1,9 +1,14 @@ /* + * NOROM Mapper - The TI-NESulator Project * norom.c - * TI-NESulator.X * - * Created by Manoël Trapier on 25/10/07. - * Copyright 2007 986 Corp. All rights reserved. + * Created by Manoel TRAPIER. + * Copyright (c) 2003-2007 986Corp. All rights reserved. + * + * $LastChangedDate: 2007-04-16 01:55:35 +0200 (lun, 16 avr 2007) $ + * $Author: godzil $ + * $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/unrom.h $ + * $Revision: 39 $ * */ @@ -11,8 +16,6 @@ int norom_InitMapper(NesCart *cart) { - int i; - set_page_ptr_16k(0x80, cart->PROMBanks); /* mUBank = 0xC000 */ diff --git a/src/mappersmanager/mappers/norom.h b/src/mappersmanager/mappers/norom.h index 6c095c4..7053b3f 100644 --- a/src/mappersmanager/mappers/norom.h +++ b/src/mappersmanager/mappers/norom.h @@ -1,9 +1,14 @@ /* - * norom.h - * TI-NESulator.X + * NOROM Mapper - The TI-NESulator Project + * norom.c * - * Created by Manoël Trapier on 25/10/07. - * Copyright 2007 986 Corp. All rights reserved. + * Created by Manoel TRAPIER. + * Copyright (c) 2003-2007 986Corp. All rights reserved. + * + * $LastChangedDate: 2007-04-16 01:55:35 +0200 (lun, 16 avr 2007) $ + * $Author: godzil $ + * $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/unrom.h $ + * $Revision: 39 $ * */ @@ -12,5 +17,4 @@ int norom_InitMapper (NesCart *cart); int norom_MapperIRQ (int cycledone); -void norom_MapperDump (); -void norom_MapperWriteHook(register byte Addr, register byte Value); \ No newline at end of file +void norom_MapperDump (); \ No newline at end of file diff --git a/src/mappersmanager/mappers/temp/unrom.c b/src/mappersmanager/mappers/unrom.c similarity index 87% rename from src/mappersmanager/mappers/temp/unrom.c rename to src/mappersmanager/mappers/unrom.c index be1cae0..7ebbb86 100755 --- a/src/mappersmanager/mappers/temp/unrom.c +++ b/src/mappersmanager/mappers/unrom.c @@ -11,10 +11,12 @@ * $Revision: 39 $ * */ - + +#include "unrom.h" + unsigned char unrom_load_vbank; -void unrom_MapperWriteHook(register byte Addr, register byte Value); +void unrom_MapperWriteHook(byte Addr, byte Value); int unrom_InitMapper(NesCart * cart) { @@ -39,7 +41,7 @@ int unrom_InitMapper(NesCart * cart) } -void unrom_MapperWriteHook(register byte Addr, register byte Value) +void unrom_MapperWriteHook(byte Addr, byte Value) { set_vrom_bank_8k(0x0000,Value); unrom_load_vbank = Value; diff --git a/src/mappersmanager/unused/unrom.h b/src/mappersmanager/mappers/unrom.h similarity index 100% rename from src/mappersmanager/unused/unrom.h rename to src/mappersmanager/mappers/unrom.h diff --git a/src/mappersmanager/mappers_list.h b/src/mappersmanager/mappers_list.h index e859049..5d9a795 100644 --- a/src/mappersmanager/mappers_list.h +++ b/src/mappersmanager/mappers_list.h @@ -9,12 +9,28 @@ /* This file could be generated from the mappers directory... */ #include "mappers/norom.h" +#include "mappers/aorom.h" +#include "mappers/unrom.h" +#include "mappers/cnrom.h" + +#include "mappers/iremh3001.h" + #include "mappers/mmc1.h" +#include "mappers/mmc3.h" +#include "mappers/mmc4.h" Mapper Mappers[] = { -{ 0, "No Mapper", norom_InitMapper, norom_MapperIRQ, norom_MapperDump }, -{ 1, "MMC1", mmc1_InitMapper, norom_MapperIRQ, mmc1_MapperDump }, +{ 0 , "No Mapper", norom_InitMapper, norom_MapperIRQ, norom_MapperDump }, +{ 7 , "AOROM", aorom_InitMapper, norom_MapperIRQ, aorom_MapperDump }, +{ 2 , "CNROM", cnrom_InitMapper, norom_MapperIRQ, cnrom_MapperDump }, +{ 3 , "UNROM", unrom_InitMapper, norom_MapperIRQ, unrom_MapperDump }, +{ 1 , "MMC1", mmc1_InitMapper, norom_MapperIRQ, mmc1_MapperDump }, +{ 4 , "MMC3", mmc3_InitMapper, mmc3_MapperIRQ, mmc3_MapperDump }, +{ 10, "MMC4", mmc3_InitMapper, norom_MapperIRQ, mmc4_MapperDump }, + +{ 65, "Irem H3001", iremh3001_InitMapper, iremh3001_MapperIRQ, iremh3001_MapperDump }, + /* EOL tag */ { 0, NULL, NULL, NULL, NULL } }; diff --git a/src/mappersmanager/utils.c b/src/mappersmanager/utils.c index f7b2104..ef28bf6 100755 --- a/src/mappersmanager/utils.c +++ b/src/mappersmanager/utils.c @@ -23,6 +23,10 @@ #include #include +#define __TINES_PPU_INTERNAL__ +#include +#undef __TINES_PPU_INTERNAL__ + extern NesCart *Cart; extern char MapperWantIRQ; diff --git a/src/pluginsmanager/manager.c b/src/pluginsmanager/manager.c index d3e44e6..6f1a85b 100644 --- a/src/pluginsmanager/manager.c +++ b/src/pluginsmanager/manager.c @@ -19,7 +19,7 @@ typedef struct Plugin_ { - byte *name; + char *name; PluginInit init; PluginDeinit deinit; @@ -55,9 +55,15 @@ void plugin_list() int plugin_load(int id) { Plugin *ptr = &(Plugins[0]); + int i = id; - for ( ; id == 0 && ptr != NULL; id -- ) - ptr ++; + printf("%s(%d)", __func__, id); + + for ( ; i > 1 && ptr->name != NULL; i -- ) + { + printf("%d - %s\n", i, ptr->name); + ptr ++; + } if (ptr == NULL) return -1; diff --git a/src/pluginsmanager/plugins/gamegenie.c b/src/pluginsmanager/plugins/gamegenie.c index a299c66..a62e0c2 100644 --- a/src/pluginsmanager/plugins/gamegenie.c +++ b/src/pluginsmanager/plugins/gamegenie.c @@ -4,6 +4,7 @@ #define __TINES_PLUGINS__ #include +#undef __TINES_PLUGINS_ #include #include @@ -53,7 +54,6 @@ byte gg_RdHookPatch##d(byte addr) \ } #define GG_MAX_PATCH 10 - /* Defines the rdhook patches */ GG_RDHOOKPATCH(0) GG_RDHOOKPATCH(1) @@ -68,7 +68,7 @@ GG_RDHOOKPATCH(9) void gg_SetPatch(int id, byte page, byte addr, byte value) { - func_rdhook *fptr; + func_rdhook fptr; if (id >= GG_MAX_PATCH) return; @@ -418,7 +418,7 @@ byte gg_SelectPatch() if (gg_PatchUsed[i] == 0x00) sprintf(tmp, "Patch %d: Not used", i); else - sprintf(tmp, "Patch %d: Put 0x%02X on address 0x%02X%02X (Code: %08X)", + sprintf(tmp, "Patch %d: Put 0x%02X on address 0x%02X%02X (Code: %08lX)", i, gg_PatchedValue[i], gg_PatchedPage[i], gg_PatchedAddr[i], gg_MakeCode((gg_PatchedPage[i]<<8) | gg_PatchedAddr[i], gg_PatchedValue[i])); diff --git a/src/ppu/debug/ppu.debug.c b/src/ppu/debug/ppu.debug.c index c9568d8..88a323f 100644 --- a/src/ppu/debug/ppu.debug.c +++ b/src/ppu/debug/ppu.debug.c @@ -218,7 +218,7 @@ void ppu_dumpOneNameTable(unsigned short nametable, int xd, int yd) void ppu_dumpOneAttributeTable(unsigned short nametable, int xd, int yd) { - int x, y, x1, y1, Color, AttrByte; + int x, x1, y1, Color, AttrByte; for (x = 0; x < 0x40; x++) { AttrByte = PPU_Rd(nametable + 0x23C0 + x); diff --git a/src/ppu/ppu.c b/src/ppu/ppu.c index 31b9399..c142721 100755 --- a/src/ppu/ppu.c +++ b/src/ppu/ppu.c @@ -1,9 +1,9 @@ /* * PPU emulation - The TI-NESulator Project * ppu.c - * + * * Define and emulate the PPU (Picture Processing Unit) of the real NES - * + * * Created by Manoel TRAPIER. * Copyright (c) 2003-2007 986Corp. All rights reserved. * @@ -23,6 +23,8 @@ #include #include +#include + #include #define __TINES_PLUGINS__ @@ -185,43 +187,45 @@ byte ppu_screenMode; int ppu_init() { int i; - + + /*byte defaultColors[] = { 0x09,0x01,0x00,0x01,0x00,0x02,0x02,0x0D,0x08,0x10,0x08,0x24,0x00,0x00,0x04,0x2C, + 0x09,0x01,0x34,0x03,0x00,0x04,0x00,0x14,0x08,0x3A,0x00,0x02,0x00,0x20,0x2C,0x08 };*/ + if (ppu_initMemory()) return -1; - + /* Set ppu memory parameters */ - + /* First: Allocate each memory zone */ ppu_mem_patternTables = (byte*) malloc(PPU_MEM_PATTERNTABLES_SIZE); if (!ppu_mem_patternTables) return -1; - + ppu_mem_nameTables = (byte*) malloc(PPU_MEM_NAMETABLE_SIZE); if (!ppu_mem_nameTables) return -1; - + ppu_mem_paletteValues = (byte*) malloc(PPU_MEM_PALETTEVALUES_SIZE); if (!ppu_mem_paletteValues) return -1; - + printf("ppu_mem_nameTables :%p\n" "ppu_mem_patternTables:%p\n" "ppu_mem_paletteValues:%p\n", ppu_mem_nameTables, ppu_mem_patternTables, ppu_mem_paletteValues); - + /* Second: make the ppu memory manager point on the memory zones */ ppu_setPagePtr8k(0x00, ppu_mem_patternTables); ppu_setPagePtr4k(0x20, ppu_mem_nameTables); - ppu_setPagePtr (0x3F, ppu_mem_paletteValues); - + ppu_setPagePtr (0x3F, ppu_mem_paletteValues); + for ( i = 0x00; i < 0x0F; i++ ) ppu_setPageGhost(0x30 + i, true, 0x20 + i); - + /* Third: set registers to defaults */ - - + /* Now test the memory ! */ /* Fille PPU memory with garbage */ @@ -230,9 +234,10 @@ int ppu_init() for (i = 0x0000; i < 0x1000 ; i++) ppu_mem_nameTables[i] = rand()%0xFF; for (i = 0x0000; i < 0x001F ; i++) - ppu_mem_paletteValues[i] = rand()%0xFF; + ppu_mem_paletteValues[i] = rand()%0xFF; + + //memcpy(ppu_mem_paletteValues, defaultColors, 32); - /* Dump PPU memory state */ //ppu_memoryDumpState(stdout); @@ -241,8 +246,8 @@ int ppu_init() ppu_addrIncrement = 1; ppu_spritePatternTable = 0; - ppu_spriteSize = 8; - ppu_execNMIonVBlank = 0; + ppu_spriteSize = 8; + ppu_execNMIonVBlank = 0; ppu_spriteVisibility = 0; ppu_backgroundVisibility = 0; @@ -254,29 +259,29 @@ int ppu_init() ppu_bgColor = 0; /* Set PPU registers on CPU side */ - set_page_rd_hook(0x20, ppu_readReg); + set_page_rd_hook(0x20, ppu_readReg); set_page_wr_hook(0x20, ppu_writeReg); - + set_page_readable(0x20, true); set_page_writeable(0x20, true); - - + + /* Set PPU Ghost Registers */ for(i = 0x21; i < 0x40; i++) set_page_ghost(i, true, 0x20); // plugin_install_keypressHandler('i', ppu_debugSprites); // plugin_install_keypressHandler('I', ppu_debugSprites); - + // plugin_install_keypressHandler('u', ppu_debugColor); // plugin_install_keypressHandler('U', ppu_debugColor); - + /* allocate the PPU Video memory */ VideoBuffer = create_bitmap(256, 240); - + if (VideoBuffer == NULL) return -1; - + return 0; } @@ -284,46 +289,45 @@ void ppu_updateSpriteScanlineTable() { int i, line, j, k; volatile int sprite_x, sprite_y, sprite_idx, sprite_attr; - + int curline; - + for (line = 0; line < 241; line ++) { PPU_NbSpriteByScanLine[line] = 0; PPU_NbSpriteByScanLineOverFlow[line] = 0; - + for (i = 0; i < 9; i++) PPU_SpriteByScanLine[line][i] = 0xFFFFFFFF; } - + for ( i = 0; i < 64; i ++) { /* Fill sprite_zzz variables */ - sprite_y = ppu_mem_spritesTable[(i*4) + 0]; + sprite_y = ppu_mem_spritesTable[(i*4) + 0] + 1; sprite_idx = ppu_mem_spritesTable[(i*4) + 1]; sprite_attr = ppu_mem_spritesTable[(i*4) + 2] | ((i==0)?0x04:0); /* Add a flag for the sprite #0 */ sprite_x = ppu_mem_spritesTable[(i*4) + 3]; - + /* For each line covered by the sprite */ for (line = 0; line < ppu_spriteSize; line ++) - { + { curline = line + sprite_y; - + if ((curline < 0) || (curline > 240)) continue; /* Don't go beyond, this sprite go beyond the borders */ - - if (PPU_NbSpriteByScanLine[curline] < 7) + + if (PPU_NbSpriteByScanLine[curline] < 8) PPU_NbSpriteByScanLine[curline] ++; else { PPU_NbSpriteByScanLineOverFlow[curline] = 1; - //printf("sprite of: %d - %d\n", curline, PPU_NbSpriteByScanLine[curline]); + //printf("sprite of: %u - %u\n", curline, PPU_NbSpriteByScanLine[curline]); continue; /* We have 8 sprite in this line, don't continue */ } - if (((sprite_x+8) < 0) && ((sprite_x-8) > 256)) continue; /* this sprite isn't either displayable */ - /* Now test if this sprite can be put in the sprite list */ + /* Now test if this sprite can be put in the sprite list */ for (j = 0; j <= PPU_NbSpriteByScanLine[curline]; j++) { /* sprite are ordered by their y value, so, the first time that @@ -334,21 +338,21 @@ void ppu_updateSpriteScanlineTable() if needed the rightest item. */ for (k = 7; k >= j; k--) PPU_SpriteByScanLine[curline][k] = PPU_SpriteByScanLine[curline][k-1]; - + PPU_SpriteByScanLine[curline][j] = 0; - + PPU_SCANLINESPRITE_SET_ATTRS (PPU_SpriteByScanLine[curline][j], sprite_attr); //printf("new sprite [%02X:%02X:%02X:%02X] at sl:%d : 0x%08X ", //sprite_attr, sprite_idx, curline - sprite_x, sprite_y, //curline, PPU_SpriteByScanLine[curline][j]); - + PPU_SCANLINESPRITE_SET_TILIDX(PPU_SpriteByScanLine[curline][j], sprite_idx); //printf("- 0x%08X ", PPU_SpriteByScanLine[curline][j]); - + PPU_SCANLINESPRITE_SET_RELY (PPU_SpriteByScanLine[curline][j], curline - sprite_y); //printf("- 0x%08X ", PPU_SpriteByScanLine[curline][j]); - - PPU_SCANLINESPRITE_SET_X (PPU_SpriteByScanLine[curline][j], sprite_x); + + PPU_SCANLINESPRITE_SET_X (PPU_SpriteByScanLine[curline][j], sprite_x); //printf("- 0x%08X\n", PPU_SpriteByScanLine[curline][j]); break; /* Stop the for, we don't need to go further in the line list */ @@ -371,7 +375,7 @@ void ppu_setMirroring(byte direction) default: direction = PPU_MIRROR_HORIZTAL; ppu_mirrorMode = direction; - + case PPU_MIRROR_HORIZTAL: /* Horizontal */ //printf("Set mirror to Hor\n"); ppu_setPagePtr1k(0x20, ppu_mem_nameTables + 0x000); @@ -396,13 +400,13 @@ void ppu_setSingleScreen(byte screen) return; if (ppu_singleScreenMode == screen) return; /* Same value, no need to change! */ - + switch(screen) { default: screen = PPU_SCREEN_000; ppu_singleScreenMode = screen; - + case PPU_SCREEN_000: /* 0x2000 */ //printf("Set screen to 0x000\n"); ppu_setPagePtr1k(0x20, ppu_mem_nameTables + 0x000); @@ -410,7 +414,7 @@ void ppu_setSingleScreen(byte screen) ppu_setPagePtr1k(0x28, ppu_mem_nameTables + 0x000); ppu_setPagePtr1k(0x2C, ppu_mem_nameTables + 0x000); break; - + case PPU_SCREEN_400: /* 0x2400 */ //printf("Set screen to 0x400\n"); ppu_setPagePtr1k(0x20, ppu_mem_nameTables + 0x400); @@ -418,7 +422,7 @@ void ppu_setSingleScreen(byte screen) ppu_setPagePtr1k(0x28, ppu_mem_nameTables + 0x400); ppu_setPagePtr1k(0x2C, ppu_mem_nameTables + 0x400); break; - + case PPU_SCREEN_800: /* 0x2800 */ //printf("Set screen to 0x800\n"); ppu_setPagePtr1k(0x20, ppu_mem_nameTables + 0x800); @@ -426,7 +430,7 @@ void ppu_setSingleScreen(byte screen) ppu_setPagePtr1k(0x28, ppu_mem_nameTables + 0x800); ppu_setPagePtr1k(0x2C, ppu_mem_nameTables + 0x800); break; - + case PPU_SCREEN_C00: /* 0x2C00 */ //printf("Set screen to 0xC00\n"); ppu_setPagePtr1k(0x20, ppu_mem_nameTables + 0xC00); @@ -458,7 +462,7 @@ void ppu_setScreenMode(byte mode) default: mode = PPU_SCMODE_NORMAL; - ppu_screenMode = mode; + ppu_screenMode = mode; case PPU_SCMODE_NORMAL: /* Normal screen (2 NT with mirroring) */ //printf("Set Normal Screen\n"); @@ -491,7 +495,7 @@ void ppu_updateCounters() | |+===++=++=++=====++=====+ | +---------------+-----------------------------------------------+ |2007 access | DC B A 98765 43210 | -+===============+===============================================+ ++===============+===============================================+ 8421 8421 8421 8421 ------------------- @@ -505,120 +509,218 @@ _AAA BCDD DDDE EEEE PPU_Reg_Counter |= PPU_Reg_H << 10; PPU_Reg_Counter |= PPU_Reg_VT << 5; PPU_Reg_Counter |= PPU_Reg_HT; - + IF_N_KEY printf("Counter update to %04X\n",PPU_Reg_Counter); } +extern M6502 MainCPU; + int ppu_hblank(int scanline) -{ +{ int i, j; byte pixelColor = 0x42; - byte Color = 0x42; + byte BgColor = 0x42; + byte SpriteColor = 0x42; unsigned short addr; byte value; unsigned short tmp_HHT = 0; - unsigned short tmp_VVTFV = 0; - + unsigned short tmp_VVTFV = 0; + unsigned long CurrentSprite; + byte SpriteVFlip; + /* If no plan activated, we have nothing to do ! */ - + if (scanline == 0) { ppu_bgColor = ppu_readMemory(0x3F,00); clear_to_color(VideoBuffer, ppu_bgColor); - + if ((ppu_spriteVisibility != 0) || (ppu_backgroundVisibility != 0)) ppu_updateCounters(); } if (scanline < 240) { - - /* For each PPU pixel of this scanline */ - for (i = 0; i < 256; i ++) - { - /* determine which from sprite bg, bg and sprite fg is in the front */ + /* For each PPU pixel of this scanline */ + for (i = 0; i < 256; i ++) + { + /* Set the current pixel color to the bg color */ pixelColor = ppu_readMemory(0x3F,00); - - /* is there sprite(s) on this line ? */ - - /* */ - /* Didn't display sprite for now, juste the BG */ - - /* Read NameTable */ + + /* Compute current pixel bg color if bg is visible */ if (ppu_backgroundVisibility == 1) { -/* -xxxx AABB BxxC CCxx -xxxx AA11 11BB BCCC -*/ -/* -s:32 i:235 cnt:089D addr:0BCF cba:0 addr:0000 - -0000 BBBB CCCC FFFF -0000 1100 1101 1111 - - AABB B C CC - - BA98 7654 3210 - -xxxx 1111 1100 1111 - FFFF CCCC FFFF - -*/ - addr = (PPU_Reg_Counter & 0x0C00); addr = addr | 0x03C0; addr |= (PPU_Reg_Counter >> 4 ) & 0x0038; - addr |= (PPU_Reg_Counter >> 2 ) & 0x0007; - + addr |= (PPU_Reg_Counter >> 2 ) & 0x0007; + PPU_Reg_AR = ppu_readMemory(0x20 | ((addr>>8) & 0x0F), addr& 0xFF); - PPU_Reg_AR = PPU_Reg_AR >> (((PPU_Reg_Counter >> 4 ) & 0x04)|((PPU_Reg_Counter ) & 0x02)); PPU_Reg_AR = (PPU_Reg_AR<<2) & 0x0C; - + PPU_Reg_PAR = ppu_readMemory(0x20 | ((PPU_Reg_Counter>>8) & 0x0F), PPU_Reg_Counter& 0xFF); - /* C BA98 7654 3210 */ - /* 1 8421 8421 8421 */ - + addr = PPU_Reg_S; addr |= ((PPU_Reg_PAR & 0xFF) << 4); addr |= ((PPU_Reg_Counter >> 12) & 0x07); - value = ppu_readMemory((addr >> 8) , addr ); - Color = (value & (1 << (7-(i + PPU_Reg_FH) % 8)))?0x01:0; - - value = ppu_readMemory((addr >> 8) , addr | 0x08 ); - Color |= (value & (1 << (7-(i + PPU_Reg_FH) % 8)))?0x02:0; - - if (Color > 0x00) - { - Color |= PPU_Reg_AR; - Color &= 0x0F; + value = ppu_readMemory((addr >> 8) , addr ); + BgColor = (value & (1 << (7-(i + PPU_Reg_FH) % 8)))?0x01:0; - pixelColor = ppu_readMemory(0x3F, Color); + value = ppu_readMemory((addr >> 8) , addr | 0x08 ); + BgColor |= (value & (1 << (7-(i + PPU_Reg_FH) % 8)))?0x02:0; + if (BgColor > 0x00) + { + BgColor |= PPU_Reg_AR; + BgColor &= 0x0F; + + pixelColor = ppu_readMemory(0x3F, BgColor); } if (((i + PPU_Reg_FH)%8) == 7) { - tmp_HHT = ((PPU_Reg_Counter >> 5) & 0x0020) | + tmp_HHT = ((PPU_Reg_Counter >> 5) & 0x0020) | (PPU_Reg_Counter & 0x001F); tmp_HHT = (tmp_HHT + 1) & 0x003F; - - /* Reassemble with HT & H */ - PPU_Reg_Counter = (PPU_Reg_Counter & 0xFBE0) | - ((tmp_HHT & 0x0020) << 5) | - (tmp_HHT & 0x001F); - } - + + /* Reassemble with HT & H */ + PPU_Reg_Counter = (PPU_Reg_Counter & 0xFBE0) | + ((tmp_HHT & 0x0020) << 5) | + (tmp_HHT & 0x001F); + } } - /* draw the pixel */ - _putpixel(VideoBuffer, i, scanline, pixelColor); + + /* Now calculate if there is a sprite here and sprite visibility is on */ + if ((ppu_spriteVisibility == 1) && + (PPU_NbSpriteByScanLine[scanline] != 0)) + { + /* scan each sprite on this line to find the one (or more) that is on this pixel */ + for (j = 0; j < PPU_NbSpriteByScanLine[scanline]; j++) + { + /* they are orderer by X, so if this one is too far on the right + it's not need to go further */ + CurrentSprite = PPU_SpriteByScanLine[scanline][j]; + + if (PPU_SCANLINESPRITE_GET_X(CurrentSprite) > i) + break; /* break the current for */ + + if ((PPU_SCANLINESPRITE_GET_X(CurrentSprite) + 8) < i) + continue; /* Not this one too (too far on the left) try next one*/ + + /* Ok if we arrive here, the current sprite is on the good position */ + /* Does the sprite is a BG or FG sprite ? */ + + /* Ok we could now get the sprite current pixel color */ + /* Read sprite scanline pattern */ + SpriteVFlip = PPU_SCANLINESPRITE_GET_ATTRS(CurrentSprite) & PPU_SPRITE_FLAGS_VFLIP; + + if (ppu_spriteSize == 8) + { + addr = (PPU_SCANLINESPRITE_GET_TILIDX(CurrentSprite) << 4) + ppu_spritePatternTable; + } + else + { + if (PPU_SCANLINESPRITE_GET_RELY(CurrentSprite) < 8) + addr = (((PPU_SCANLINESPRITE_GET_TILIDX(CurrentSprite)&0xFE) + (SpriteVFlip?1:0)) << 4) + ((PPU_SCANLINESPRITE_GET_TILIDX(CurrentSprite)&0x01)?0x1000:0x0000); + else + addr = (((PPU_SCANLINESPRITE_GET_TILIDX(CurrentSprite)&0xFE) + (SpriteVFlip?0:1)) << 4) + ((PPU_SCANLINESPRITE_GET_TILIDX(CurrentSprite)&0x01)?0x1000:0x0000); + } + //printf("sprite addr: %04X\n", addr); + if (SpriteVFlip) + { + addr += 7; + addr -= (PPU_SCANLINESPRITE_GET_RELY(CurrentSprite) % 8); + } + else + addr += (PPU_SCANLINESPRITE_GET_RELY(CurrentSprite) % 8); + + + if (PPU_SCANLINESPRITE_GET_ATTRS(CurrentSprite) & PPU_SPRITE_FLAGS_HFLIP) + { + value = ppu_readMemory((addr >> 8) , addr ); + SpriteColor = (value & (1 << (i-PPU_SCANLINESPRITE_GET_X(CurrentSprite))))?0x01:0; + + value = ppu_readMemory((addr >> 8) , addr | 0x08 ); + SpriteColor |= (value & (1 << (i-PPU_SCANLINESPRITE_GET_X(CurrentSprite))))?0x02:0; + } + else + { + value = ppu_readMemory((addr >> 8) , addr ); + SpriteColor = (value & (1 << (7-(i-PPU_SCANLINESPRITE_GET_X(CurrentSprite)))))?0x01:0; + + value = ppu_readMemory((addr >> 8) , addr | 0x08 ); + SpriteColor |= (value & (1 << (7-(i-PPU_SCANLINESPRITE_GET_X(CurrentSprite)))))?0x02:0; + } + + if (SpriteColor > 0x00) + { + SpriteColor |= ((PPU_SCANLINESPRITE_GET_ATTRS(CurrentSprite) & PPU_SPRITE_FLAGS_UPPERCOLOR) << 2); + SpriteColor &= 0x0F; + } + + if ((PPU_SCANLINESPRITE_GET_ATTRS(CurrentSprite) & 0x04) && + (SpriteColor != 0x00) && (BgColor != 0x00)) + { + ppu_spriteZeroHit = 1; + } + if ( ( (PPU_SCANLINESPRITE_GET_ATTRS(CurrentSprite) & PPU_SPRITE_FLAGS_BGPRIO) && (BgColor == 0x0000)) || + (!(PPU_SCANLINESPRITE_GET_ATTRS(CurrentSprite) & PPU_SPRITE_FLAGS_BGPRIO)) ) + { + if (SpriteColor != 0x00) pixelColor = ppu_readMemory(0x3F, (0x10 + SpriteColor)); + } + } + } + + + /* draw the pixel */ + /*if (ppu_displayType) + pixelColor &= 0x30;*/ + _putpixel(VideoBuffer, i, scanline, pixelColor); } + + if (ppu_backgroundVisibility || ppu_spriteVisibility) + if (PPU_NbSpriteByScanLineOverFlow[scanline] == 1) + ppu_scanlineSpriteOverflow = 1; + + //blit(VideoBuffer, screen, 0, scanline, 0, scanline, 256, 1); + + + if (ppu_backgroundVisibility == 1) + { + + tmp_VVTFV = ((PPU_Reg_Counter >> 3 ) & 0x0100) | /* V */ + ((PPU_Reg_Counter >> 2 ) & 0x00F8) | /* VT */ + ((PPU_Reg_Counter >> 12) & 0x0007); /* FV */ + //printf("counter:%04X vvtfv:%04X ", PPU_Reg_Counter, tmp_VVTFV); + + tmp_VVTFV++; + //printf("__ vvtfv:0x%04X == 0x%04X ? ", tmp_VVTFV, 30<<3); + if ((tmp_VVTFV&0x0F8) == 0xF0) + { + tmp_VVTFV &= ~0x0F8; + tmp_VVTFV ^= 0x100; + //printf("YES _"); + } + + //printf("vvtfv:%04X ", tmp_VVTFV); + PPU_Reg_Counter = ( PPU_Reg_Counter & 0x041F) | + ((tmp_VVTFV & 0x0100 ) << 3 ) | /* V */ + ((tmp_VVTFV & 0x00F8 ) << 2 ) | /* VT */ + ((tmp_VVTFV & 0x0007 ) << 12); /* FV */ + + //printf("counter:%04X ", PPU_Reg_Counter); + /* Update H & HT */ + PPU_Reg_Counter = (PPU_Reg_Counter & ~0x041F) | + (PPU_Reg_H << 10) | + PPU_Reg_HT; + } + } /* Increment only V & VT & FV*/ - + /* 8421 8421 8421 8421 @@ -626,7 +728,7 @@ xxxx 1111 1100 1111 1111 1100 0000 0000 5432 1098 7654 3210 _AAA BCDD DDDE EEEE - + xxx x xx xxx : vvtfv = 7BE0 x x xxxx : hht @@ -640,75 +742,13 @@ D = VT E = HT -*/ - if (ppu_backgroundVisibility == 1) - { - - tmp_VVTFV = ((PPU_Reg_Counter >> 3 ) & 0x0100) | /* V */ - ((PPU_Reg_Counter >> 2 ) & 0x00F8) | /* VT */ - ((PPU_Reg_Counter >> 12) & 0x0007); /* FV */ - //printf("counter:%04X vvtfv:%04X ", PPU_Reg_Counter, tmp_VVTFV); - - tmp_VVTFV++; - //printf("__ vvtfv:0x%04X == 0x%04X ? ", tmp_VVTFV, 30<<3); - if ((tmp_VVTFV&0x0F8) == 0xF0) - { - tmp_VVTFV &= ~0x0F8; - tmp_VVTFV ^= 0x100; - //printf("YES _"); - } - - //printf("vvtfv:%04X ", tmp_VVTFV); - PPU_Reg_Counter = ( PPU_Reg_Counter & 0x041F) | - ((tmp_VVTFV & 0x0100 ) << 3 ) | /* V */ - ((tmp_VVTFV & 0x00F8 ) << 2 ) | /* VT */ - ((tmp_VVTFV & 0x0007 ) << 12); /* FV */ - - //printf("counter:%04X ", PPU_Reg_Counter); - /* Update H & HT */ - PPU_Reg_Counter = (PPU_Reg_Counter & ~0x041F) | - (PPU_Reg_H << 10) | - PPU_Reg_HT; - } - - if (PPU_NbSpriteByScanLine[scanline] != 0) - { - for (j = 0; j < PPU_NbSpriteByScanLine[scanline]; j++) - { - static byte i = 0; - pixelColor = (i = (i+1)%4) | ((PPU_SCANLINESPRITE_GET_ATTRS(PPU_SpriteByScanLine[scanline][j]) << 2) & 0x0C); - - pixelColor = ppu_readMemory(0x3F, 0x10 + pixelColor); - line(VideoBuffer, - PPU_SCANLINESPRITE_GET_X(PPU_SpriteByScanLine[scanline][j]), - scanline, - PPU_SCANLINESPRITE_GET_X(PPU_SpriteByScanLine[scanline][j]) + 8, - scanline, pixelColor - ); - - if (PPU_SCANLINESPRITE_GET_ATTRS(PPU_SpriteByScanLine[scanline][j]) & 0x04) - { - //printf("Hit!\n"); - ppu_spriteZeroHit = 1; - } - - } - } - ppu_scanlineSpriteOverflow = 0; - if (PPU_NbSpriteByScanLineOverFlow[scanline] == 1) - ppu_scanlineSpriteOverflow = 1; - - } - - /* if (scanline == 100) - ppu_spriteZeroHit = 1;*/ - - if (scanline == 243) +*/ + if (scanline == 239) { ppu_inVBlankTime = 1; IF_N_KEY printf("============= enter vblank =================\n"); return ppu_execNMIonVBlank; - } + } if (key[KEY_B]) { @@ -717,26 +757,37 @@ E = HT } - //if (scanline >= (241 + VBLANK_TIME)) - if (scanline >= 262) - { + if (scanline >= (240 + VBLANK_TIME)) + { + /*for ( i = 0; i < 256; i++) + for ( j = 0; j < 256; j++) + { + int i2 = i<<1, j2 = j<<1; + putpixel(Buffer, i2 , j2 , Op6502(i+j*256)); + putpixel(Buffer, i2 , j2+1, Op6502(i+j*256)); + putpixel(Buffer, i2+1, j2 , Op6502(i+j*256)); + // putpixel(Buffer, i2+1, j2+1, Op6502(i+j*256)); + }*/ + //textprintf(Buffer, font, 5, 340, 4, "(SL:%d) FPS : %d IPS : %d", scanline, FPS, IPS); - textprintf(screen, font, 260, 3, 4, "FPS : %d (CPU@~%2.2fMhz : %d%%)", FPS, (float) (((float) IPS) / 1000000.0), (int) ((((float) IPS) / 1770000.0) * 100.0)); + textprintf(Buffer, font, 260, 3, 4, "FPS : %d (CPU@~%2.2fMhz : %d%%)", FPS, (float) (((float) IPS) / 1000000.0), (int) ((((float) IPS) / 1770000.0) * 100.0)); //printf("(SL:%d) FPS : %d IPS : %d\n", scanline, FPS, IPS); - - //ppu_dumpPalette(0, 241); - //ppu_dumpPattern(280, 150); - //ppu_dumpNameTable(256,0); + + ppu_dumpPalette(0, 241); + ppu_dumpPattern(280, 150); + ppu_dumpNameTable(256,0); //ppu_dumpAttributeTable(257, 0); - - //blit(VideoBuffer, Buffer, 0, 0, 0, 0, 256, 240); - blit(VideoBuffer, screen, 0, 0, 0, 0, 256, 240); - //blit(Buffer, screen, 0, 0, 0, 0, 512 + 256, 480); + + blit(VideoBuffer, Buffer, 0, 0, 0, 0, 256, 240); + blit(Buffer, screen, 0, 0, 0, 0, 512+256, 512); + //blit(VideoBuffer, screen, 0, 0, 0, 0, 256, 240); + IF_N_KEY printf("_____________ leave vblank _________________\n"); ppu_inVBlankTime = 0; ppu_spriteZeroHit = 0; - //ppu_updateCounters(); + ppu_scanlineSpriteOverflow = 0; + //ppu_updateCounters(); } return 0; } @@ -749,17 +800,17 @@ byte ppu_readReg(byte id) static byte garbage; static byte lastValue; switch(id) - { + { default: garbage = PPU_RegValues[id]; printf("%s: try to read 0x20%02X\n", __func__, id); break; case 0x02: /* PPU Status Register */ - + /* Reset VRam 2005/2006 flipflop */ ppu_VramAccessFlipFlop = 0; garbage = 0; - + garbage |= (ppu_inVBlankTime!=0) ?PPU_FLAG_SR_VBLANK:0; garbage |= (ppu_spriteZeroHit!=0) ?PPU_FLAG_SR_SPRT0:0; garbage |= (ppu_scanlineSpriteOverflow!=0)?PPU_FLAG_SR_8SPRT:0; @@ -769,12 +820,12 @@ byte ppu_readReg(byte id) ppu_inVBlankTime = 0; break; - + case 0x04: /* SPR-RAM I/O */ - garbage = ppu_mem_spritesTable[ppu_mem_sptrTablePtr]; + garbage = ppu_mem_spritesTable[ppu_mem_sptrTablePtr]; break; - - case 0x07: /* VRAM I/O */ + + case 0x07: /* VRAM I/O */ if (PPU_Reg_Counter < 0x3F00) { garbage = lastValue; @@ -786,12 +837,12 @@ byte ppu_readReg(byte id) lastValue = ppu_readMemory( 0x2F, PPU_Reg_Counter & 0xFF); garbage = ppu_readMemory( 0x3F, - PPU_Reg_Counter & 0xFF); + PPU_Reg_Counter & 0xFF); } - PPU_Reg_Counter += ppu_addrIncrement; + PPU_Reg_Counter += ppu_addrIncrement; - break; + break; } //printf("ppuread %02X return: %02X\n", id, garbage); return garbage; @@ -806,11 +857,11 @@ void ppu_writeReg(byte id, byte val) switch(id) { default: - printf("%s: try to write 0x%02X @ 0x20%02X\n", __func__, val, id); + //printf("%s: try to write 0x%02X @ 0x20%02X\n", __func__, val, id); break; - + case 0x00: /* PPU Control Register #1 */ - + /* +===============+===============================================+ |2000 | 1 0 4 | @@ -823,65 +874,64 @@ void ppu_writeReg(byte id, byte val) */ IF_N_KEY printf("%s(%02X, %02X); /* 2000: " - "NMI:%c SPRTSIZE:%02d BGTA:%04X[0x%04X] SPTA:%04X INC:%02d NTA:%04X */\n" - , __func__, id, val, - (val & 0x80)?'E':'D', - (val & 0x20)?16:8, - (val & 0x10)?0x1000:0x0000, PPU_Reg_S, - (val & 0x08)?0x1000:0x0000, - (val & 0x04)?32:1, - (val & 0x03)<<10|0x2000 - ); + "NMI:%c SPRTSIZE:%02d BGTA:%04X[0x%04X] SPTA:%04X INC:%02d NTA:%04X */\n", + __func__, id, val, + (val & 0x80)?'E':'D', + (val & 0x20)?16:8, + (val & 0x10)?0x1000:0x0000, PPU_Reg_S, + (val & 0x08)?0x1000:0x0000, + (val & 0x04)?32:1, + (val & 0x03)<<10|0x2000 + ); /* Set PPU internal registers */ - PPU_Reg_V = (val & 0x02)?1:0; + PPU_Reg_V = (val & 0x02)?1:0; PPU_Reg_H = (val & 0x01)?1:0; PPU_Reg_S = (val & 0x10)?0x1000:0x0000; - + /* Set Other parameters */ ppu_addrIncrement = (val & 0x04)?0x20:0x01; ppu_spritePatternTable = (val & 0x08)?0x1000:0; - ppu_spriteSize = (val & 0x20)?16:8; + ppu_spriteSize = (val & 0x20)?16:8; ppu_execNMIonVBlank = (val & 0x80)?1:0; break; - + case 0x01: /* PPU Control Register #2 */ ppu_spriteVisibility = (val & 0x10)?1:0; - ppu_backgroundVisibility = (val & 0x08)?1:0; - ppu_spriteClipping = (val & 0x04)?1:0; - ppu_backgroundClipping = (val & 0x02)?1:0; - ppu_displayType = (val & 0x01)?1:0; + ppu_backgroundVisibility = (val & 0x08)?1:0; + ppu_spriteClipping = (val & 0x04)?1:0; + ppu_backgroundClipping = (val & 0x02)?1:0; + ppu_displayType = (val & 0x01)?1:0; + + ppu_updateSpriteScanlineTable(); IF_N_KEY printf("%s(%02X, %02X); /* 2001 : " - "SprtV:%c BckgV:%c SprtC:%c BckgC:%c DispT:%c" + "SprtV:%c BckgV:%c SprtC:%c BckgC:%c DispT:%c" " */\n", __func__, id, val, ppu_spriteVisibility?'y':'n', ppu_backgroundVisibility?'y':'n', ppu_spriteClipping?'y':'n', ppu_backgroundClipping?'y':'n', ppu_displayType?'m':'c' - ); - + ); break; - + case 0x03: /* SPR-RAM Address Register */ ppu_mem_sptrTablePtr = val; break; case 0x04: /* SPR-RAM I/O */ ppu_mem_spritesTable[ppu_mem_sptrTablePtr++] = val; - ppu_updateSpriteScanlineTable(); - break; - + case 0x05: /* 2005 VRAM Register */ /* +===============+===============================================+ |2005/1 | 76543 210 | -|2005/2 | 210 76543 | +|2005/2 | 210 76543 | +---------------+-----------------------------------------------+ | |+===++=++=++=====++=====++===++=++========++==+| |PPU registers || FV||V||H|| VT|| HT|| FH||S|| PAR||AR|| @@ -892,7 +942,7 @@ void ppu_writeReg(byte id, byte val) if (ppu_VramAccessFlipFlop == 0) { ppu_VramAccessFlipFlop = ~0; - + PPU_Reg_FH = val & 0x07; PPU_Reg_HT = (val & 0xF8) >> 3; IF_N_KEY @@ -901,15 +951,15 @@ void ppu_writeReg(byte id, byte val) else { ppu_VramAccessFlipFlop = 0; - + PPU_Reg_FV = val & 0x07; PPU_Reg_VT = (val & 0xF8) >> 3; IF_N_KEY printf("2005/2[%04X]: fv:%01X v:%01X h:%01X vt:%01X ht:%01X fh:%01X\n",val,PPU_Reg_FV,PPU_Reg_V,PPU_Reg_H,PPU_Reg_VT,PPU_Reg_HT,PPU_Reg_FH); } - - break; - + + break; + case 0x06: /* 2006 VRAM Register */ /* +===============+===============================================+ @@ -926,10 +976,10 @@ void ppu_writeReg(byte id, byte val) { ppu_VramAccessFlipFlop = ~0; - PPU_Reg_FV = (val >> 4) & 0x03; + PPU_Reg_FV = (val >> 4) & 0x03; PPU_Reg_V = (val >> 3) & 0x01; PPU_Reg_H = (val >> 2) & 0x01; - PPU_Reg_VT = (PPU_Reg_VT & 0x07) | ((val & 0x03) << 3); + PPU_Reg_VT = (PPU_Reg_VT & 0x07) | ((val & 0x03) << 3); IF_N_KEY printf("2006/1[%04X]: fv:%01X v:%01X h:%01X vt:%01X ht:%01X fh:%01X\n",val,PPU_Reg_FV,PPU_Reg_V,PPU_Reg_H,PPU_Reg_VT,PPU_Reg_HT,PPU_Reg_FH); } @@ -938,15 +988,15 @@ void ppu_writeReg(byte id, byte val) ppu_VramAccessFlipFlop = 0; PPU_Reg_VT = (PPU_Reg_VT & 0x18) | ((val >> 5) & 0x07); PPU_Reg_HT = val & 0x1F; - + IF_N_KEY printf("2006/2[%04X]: fv:%01X v:%01X h:%01X vt:%01X ht:%01X fh:%01X\n",val,PPU_Reg_FV,PPU_Reg_V,PPU_Reg_H,PPU_Reg_VT,PPU_Reg_HT,PPU_Reg_FH); - - ppu_updateCounters(); - } - + + ppu_updateCounters(); + } + break; - + case 0x07: /* VRAM I/O */ /* +---------------+-----------------------------------------------+ @@ -956,10 +1006,10 @@ void ppu_writeReg(byte id, byte val) | |+===++=++=++=====++=====+ | +---------------+-----------------------------------------------+ |2007 access | DC B A 98765 43210 | -+===============+===============================================+ -*/ ++===============+===============================================+ +*/ + - //if ( (PPU_Reg_Counter&0xFF00) == 0x3F00) //{ @@ -967,8 +1017,8 @@ void ppu_writeReg(byte id, byte val) // printf("will write ppu: counter:%04X pa:%02X%02X v:%02X\n", // PPU_Reg_Counter, (PPU_Reg_Counter>>8) & 0x3F, PPU_Reg_Counter & 0xFF, val); // } - - ppu_writeMemory((PPU_Reg_Counter>>8) & 0x3F, PPU_Reg_Counter & 0xFF, val); + + ppu_writeMemory((PPU_Reg_Counter>>8) & 0x3F, PPU_Reg_Counter & 0xFF, val); IF_N_KEY { @@ -977,10 +1027,10 @@ void ppu_writeReg(byte id, byte val) ppu_dumpNameTable(256,0); blit(Buffer, screen, 0, 0, 0, 0, 512 + 256, 480); } - - PPU_Reg_Counter += ppu_addrIncrement; - break; + PPU_Reg_Counter += ppu_addrIncrement; + + break; } } diff --git a/src/ppu/ppu.memory.c b/src/ppu/ppu.memory.c index 463c822..3a80e52 100644 --- a/src/ppu/ppu.memory.c +++ b/src/ppu/ppu.memory.c @@ -12,15 +12,12 @@ * */ -#ifndef PPU_MEMORY_H -#define PPU_MEMORY_H - #include #include #define __TINES_PPU_INTERNAL__ -#include +#include #include #include @@ -39,7 +36,7 @@ byte ppu_SpriteRam[0x100]; /* * Memory management functions * - * Yes that true, PPU memory & CPU memory work in a nearly same fashion depite + * Yes that true, PPU memory & CPU memory work in a nearly same fashion despite * the fact that we actually didn't have any Read/Write hook and ReadWrite * protection. We even didn't need "attributes" for the page. One of the only * need is the "powerful" ghost system @@ -159,17 +156,13 @@ void ppu_writeMemory(byte page, byte addr, byte value) /* Here we will cheat with the palette miroring, since we didn't write as often as we read the palette, we will mirror here */ //printf("%s palette: color %02X new value : %02d (0x%02X%02X)\n", ((addr&0x10)< 0x10) ? "Bgnd" : "Sprt", addr&0x1F, value & 0x3F, page, addr); - if ((addr & 0x10) == 0x00) + if ((addr & 0xEF) == 0x00) { - ppu_memoryPages[0x3F][addr&0x1F] = value; - ppu_memoryPages[0x3F][(addr&0x1F) | 0x10] = value; + ppu_memoryPages[0x3F][0x00] = value; + ppu_memoryPages[0x3F][0x10] = value; } else - { ppu_memoryPages[0x3F][addr&0x1F] = value; - if (( addr & 0x1F ) == 0x10 ) - ppu_memoryPages[0x3F][(addr&0x1F) & 0xEF] = value; - } } else { @@ -177,5 +170,3 @@ void ppu_writeMemory(byte page, byte addr, byte value) ptr[addr] = value; } } - -#endif