Update PPU to new version, correct a lot of bugs:

- Scanline counts was wrongPAL counts was wrong, correct some bugs in the plugins manager, remove a lot of warning
This commit is contained in:
godzil 2008-02-21 12:21:01 +00:00
parent bc118baac8
commit 5d3895f08a
33 changed files with 2674 additions and 2390 deletions

View File

@ -1,16 +1,17 @@
/** EMULib Emulation Library *********************************/ /*
/** **/ * Allegro Sound Driver for EMULib Sound system - The TI-NESulator Project
/** SndUnix.c **/ * SndAlleg.C
/** **/ *
/** This file contains standard sound generation routines **/ * Created by Manoël Trapier
/** for Unix using /dev/dsp and /dev/audio. **/ * Copyright 2003-2008 986 Corp. All rights reserved.
/** **/ *
/** Copyright (C) Marat Fayzullin 1996-2002 **/ * $LastChangedDate: 2007-03-28 15:50:50 +0200 (mer, 28 mar 2007) $
/** You are not allowed to distribute this software **/ * $Author: mtrapier $
/** commercially. Please, notify me, if you make any **/ * $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/types.h $
/** changes to this file. **/ * $Revision: 25 $
/*************************************************************/ *
#include "Sound.h" */
#include <Sound.h>
#include <allegro.h> #include <allegro.h>
@ -27,7 +28,6 @@
AUDIOSTREAM *stream; AUDIOSTREAM *stream;
static pthread_t ThreadID; static pthread_t ThreadID;
static int SoundFD;
static int SoundRate = 0; static int SoundRate = 0;
static int MasterVolume = 64; static int MasterVolume = 64;
static int MasterSwitch = (1<<SND_CHANNELS)-1; static int MasterSwitch = (1<<SND_CHANNELS)-1;
@ -41,7 +41,7 @@ static struct
int Freq; /* Channel frequency (Hz) */ int Freq; /* Channel frequency (Hz) */
int Volume; /* Channel volume (0..255) */ int Volume; /* Channel volume (0..255) */
signed char *Data; /* Wave data (-128..127 each) */ const signed char *Data; /* Wave data (-128..127 each) */
int Length; /* Wave length in Data */ int Length; /* Wave length in Data */
int Rate; /* Wave playback rate (or 0Hz) */ int Rate; /* Wave playback rate (or 0Hz) */
int Pos; /* Wave current position in Data */ int Pos; /* Wave current position in Data */
@ -49,7 +49,7 @@ static struct
int Count; /* Phase counter */ int Count; /* Phase counter */
} CH[SND_CHANNELS]; } CH[SND_CHANNELS];
static void UnixSetWave(int Channel,signed char *Data,int Length,int Rate); static void UnixSetWave(int Channel,const signed char *Data,int Length,int Rate);
static void UnixSetSound(int Channel,int NewType); static void UnixSetSound(int Channel,int NewType);
static void UnixDrum(int Type,int Force); static void UnixDrum(int Type,int Force);
static void UnixSetChannels(int Volume,int Switch); static void UnixSetChannels(int Volume,int Switch);
@ -89,6 +89,7 @@ static void *DSPLoop(void *Arg)
unsigned char *Buf; unsigned char *Buf;
register int J,I,K,L,M,N,L1,L2,A1,A2,V; register int J,I,K,L,M,N,L1,L2,A1,A2,V;
int FreqCount; int FreqCount;
N = L = A2 = 0;
for(J=0;J<SND_CHANNELS;J++) for(J=0;J<SND_CHANNELS;J++)
{ {
@ -262,7 +263,7 @@ static void *DSPLoop(void *Arg)
for(I=0;I<SND_BUFSIZE;I++) for(I=0;I<SND_BUFSIZE;I++)
{ {
L2=L1+K; L2=L1+K;
Wave[I]+= L1&0x2000?V:-V /*(L2&0x8000? V:0):(L2&0x8000? 0:-V)*/; Wave[I]+= L1&0x8000?V:-V /*(L2&0x8000? V:0):(L2&0x8000? 0:-V)*/;
L1=L2; L1=L2;
} }
CH[J].Count=L1; CH[J].Count=L1;
@ -397,7 +398,7 @@ void UnixSetSound(int Channel,int NewType)
/** waveform to be an instrument or set it to the waveform **/ /** waveform to be an instrument or set it to the waveform **/
/** own playback rate. **/ /** own playback rate. **/
/*************************************************************/ /*************************************************************/
void UnixSetWave(int Channel,signed char *Data,int Length,int Rate) void UnixSetWave(int Channel,const signed char *Data,int Length,int Rate)
{ {
if((Channel<0)||(Channel>=SND_CHANNELS)||(Length<=0)) return; if((Channel<0)||(Channel>=SND_CHANNELS)||(Length<=0)) return;

View File

@ -835,3 +835,4 @@ case 0x6A:
M_ROR(R->A); M_ROR(R->A);
break; /* ROR a ACC */ break; /* ROR a ACC */

View File

@ -28,6 +28,8 @@
#include <ppu/ppu.h> #include <ppu/ppu.h>
#include <mappers/manager.h>
#include <memory/manager.h>
#include <Sound.h> #include <Sound.h>
#define RDWORD(A) (Rd6502(A+1)*256+Rd6502(A)) #define RDWORD(A) (Rd6502(A+1)*256+Rd6502(A))
@ -38,58 +40,58 @@ void showlastop();
enum Addressing_Modes enum Addressing_Modes
{ {
Ac = 0, Il, Im, Ab, Zp, Zx, Zy, Ax, Ay, Rl, Ix, Iy, In, No Ac = 0, Il, Im, Ab, Zp, Zx, Zy, Ax, Ay, Rl, Ix, Iy, In, No
}; };
static byte *mn[] = static char *mn[] =
{ {
"adc ", "and ", "asl ", "bcc ", "bcs ", "beq ", "bit ", "bmi ", "adc ", "and ", "asl ", "bcc ", "bcs ", "beq ", "bit ", "bmi ",
"bne ", "bpl ", "brk", "bvc ", "bvs ", "clc", "cld", "cli", "bne ", "bpl ", "brk", "bvc ", "bvs ", "clc", "cld", "cli",
"clv", "cmp ", "cpx ", "cpy ", "dec ", "dex", "dey", "inx", "clv", "cmp ", "cpx ", "cpy ", "dec ", "dex", "dey", "inx",
"iny", "eor ", "inc ", "jmp ", "jsr ", "lda ", "nop ", "ldx ", "iny", "eor ", "inc ", "jmp ", "jsr ", "lda ", "nop ", "ldx ",
"ldy ", "lsr ", "ora ", "pha", "php", "pla", "plp", "rol ", "ldy ", "lsr ", "ora ", "pha", "php", "pla", "plp", "rol ",
"ror ", "rti", "rts", "sbc ", "sta ", "stx ", "sty ", "sec ", "ror ", "rti", "rts", "sbc ", "sta ", "stx ", "sty ", "sec ",
"sed", "sei", "tax", "tay", "txa", "tya", "tsx", "txs" "sed", "sei", "tax", "tay", "txa", "tya", "tsx", "txs"
}; };
static byte ad[512] = static byte ad[512] =
{ {
10, Il, 34, Ix, No, No, No, No, No, No, 34, Zp, 2, Zp, No, No, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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 48, Il, 43, Ay, No, No, No, No, No, No, 43, Ax, 26, Ax, No, No
}; };
@ -225,8 +227,8 @@ byte Debug6502(M6502 * R)
); );
sprintf(S, ""); S[0] = 0;
remove_keyboard(); remove_keyboard();
#ifdef USE_SOUND #ifdef USE_SOUND
StopSound(); StopSound();
@ -274,7 +276,7 @@ byte Debug6502(M6502 * R)
puts("a : Dump all memory to memory.log"); puts("a : Dump all memory to memory.log");
puts("s : Dump sprite table to sprite.log"); puts("s : Dump sprite table to sprite.log");
puts("n <nb> : Dump name table <nb> to nt.log"); puts("n <nb> : Dump name table <nb> to nt.log");
puts("z : Show lastest opcode executed"); puts("z : Dump mapper status");
puts("i : SpriteTable Dump"); puts("i : SpriteTable Dump");
puts("g <nb> : Get sprite <nb> info"); puts("g <nb> : Get sprite <nb> info");
break; break;
@ -283,7 +285,7 @@ byte Debug6502(M6502 * R)
return (1); return (1);
case 'Z': case 'Z':
showlastop(); mapper_dump(stdout);
break; break;
case 'W': case 'W':

View File

@ -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; <Invalid OPcode>", OP / 2);
}
return (B - A);
}
#endif
/** Run6502() ************************************************/ /** Run6502() ************************************************/
/** This function will run 6502 code until Loop6502() call **/ /** This function will run 6502 code until Loop6502() call **/
@ -275,7 +424,28 @@ word Run6502(M6502 *R)
if(!Debug6502(R)) return(R->PC.W); if(!Debug6502(R)) return(R->PC.W);
#endif #endif
I=Op6502(R->PC.W++); #ifdef TRACE_EXECUTION
while(1)
{
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]; R->ICount-=Cycles[I];
//#ifdef DEBUG //#ifdef DEBUG
@ -289,6 +459,34 @@ word Run6502(M6502 *R)
#include "Codes.h" #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 cycle counter expired... */
if(R->ICount<=0) if(R->ICount<=0)
{ {

View File

@ -137,7 +137,6 @@ void MIDITicks(int N);
/** skip initialization and be silent. Pass Verbose!=0 to **/ /** skip initialization and be silent. Pass Verbose!=0 to **/
/** see initialization messages. **/ /** see initialization messages. **/
/*************************************************************/ /*************************************************************/
#warning You Suck !
int InitSound(int Rate,int Verbose); int InitSound(int Rate,int Verbose);
/** StopSound() **********************************************/ /** StopSound() **********************************************/

View File

@ -27,6 +27,9 @@ typedef void (*MapperDump) ();
#ifdef __TINES_MAPPERS__ #ifdef __TINES_MAPPERS__
#include <ppu/ppu.h>
#include <memory/manager.h>
extern NesCart *Cart; extern NesCart *Cart;
/* Available functions for mappers */ /* Available functions for mappers */
@ -34,9 +37,6 @@ extern NesCart *Cart;
#define GETLAST16KBANK(c) ((c->PROMSize>>14)-1) #define GETLAST16KBANK(c) ((c->PROMSize>>14)-1)
#define GETLAST32KBANK(c) ((c->PROMSize>>15)-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_1k(unsigned short addr,int slot);
void set_vrom_bank_2k(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); void set_vrom_bank_4k(unsigned short addr,int slot);
@ -57,4 +57,7 @@ extern void (*mapper_dump) (FILE *fp);
#endif /* __TINES_MAPPERS__ */ #endif /* __TINES_MAPPERS__ */
void map_sram(); /* Map SRAM */
void unmap_sram(); /* Unmap SRAM */
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,7 @@ MapperWriteHook mapper_hook;
typedef struct Mapper_ typedef struct Mapper_
{ {
byte id; byte id;
byte *name; char *name;
MapperInit init; MapperInit init;
MapperIRQ irq; MapperIRQ irq;

View File

@ -1,6 +1,6 @@
/* /*
* AOROM Mapper - The TI-NESulator Project * AOROM Mapper - The TI-NESulator Project
* aorom.h * aorom.c
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2007 986Corp. All rights reserved. * Copyright (c) 2003-2007 986Corp. All rights reserved.
@ -12,6 +12,8 @@
* *
*/ */
#include "aorom.h"
unsigned char aorom_load_bank; unsigned char aorom_load_bank;
void aorom_MapperWriteHook(register byte Addr, register byte Value); void aorom_MapperWriteHook(register byte Addr, register byte Value);

View File

@ -1,6 +1,6 @@
/* /*
* CNROM Mapper - The TI-NESulator Project * CNROM Mapper - The TI-NESulator Project
* cnrom.h * cnrom.c
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2007 986Corp. All rights reserved. * Copyright (c) 2003-2007 986Corp. All rights reserved.
@ -12,6 +12,8 @@
* *
*/ */
#include "cnrom.h"
unsigned char cnrom_load_bank; unsigned char cnrom_load_bank;
void cnrom_MapperWriteHook(register byte Addr, register byte Value); void cnrom_MapperWriteHook(register byte Addr, register byte Value);

View File

@ -1,6 +1,6 @@
/* /*
* IREMH3001 Mapper - The TI-NESulator Project * IREMH3001 Mapper - The TI-NESulator Project
* iremh3001.h * iremh3001.c
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2007 986Corp. All rights reserved. * Copyright (c) 2003-2007 986Corp. All rights reserved.
@ -12,6 +12,8 @@
* *
*/ */
#include "iremh3001.h"
unsigned short iremh3001_prom_slot[3]; unsigned short iremh3001_prom_slot[3];
unsigned short iremh3001_vrom_slot[8]; unsigned short iremh3001_vrom_slot[8];
@ -41,7 +43,7 @@ int iremh3001_InitMapper(NesCart * cart)
} }
int iremh3001_MapperWriteHook(register word Addr, register byte Value) int iremh3001_MapperWriteHook(register byte Addr, register byte Value)
{ {
switch(Addr) switch(Addr)

View File

@ -16,6 +16,5 @@
#include <mappers/manager.h> #include <mappers/manager.h>
int iremh3001_InitMapper(NesCart * cart); int iremh3001_InitMapper(NesCart * cart);
int iremh3001_MapperWriteHook(register word Addr, register byte Value);
void iremh3001_MapperDump(FILE *fp); void iremh3001_MapperDump(FILE *fp);
int iremh3001_MapperIRQ(int cycledone); int iremh3001_MapperIRQ(int cycledone);

View File

@ -14,9 +14,6 @@
#include "norom.h" #include "norom.h"
#include <ppu/ppu.h>
#include <memory/manager.h>
unsigned char MMC1_reg0; unsigned char MMC1_reg0;
unsigned char MMC1_reg1; unsigned char MMC1_reg1;
@ -52,7 +49,6 @@ unsigned char mmc1_CurrentBank;
#define MMC1_REG2_DEFAULT 0 #define MMC1_REG2_DEFAULT 0
#define MMC1_REG3_DEFAULT 0 #define MMC1_REG3_DEFAULT 0
void mmc1_MapperWriteReg0(register byte Addr, register byte Value); void mmc1_MapperWriteReg0(register byte Addr, register byte Value);
void mmc1_MapperWriteReg1(register byte Addr, register byte Value); void mmc1_MapperWriteReg1(register byte Addr, register byte Value);
void mmc1_MapperWriteReg2(register byte Addr, register byte Value); void mmc1_MapperWriteReg2(register byte Addr, register byte Value);

View File

@ -1,9 +1,14 @@
/* /*
* MMC1 Mapper - The TI-NESulator Project
* mmc1.h * mmc1.h
* TI-NESulator.X
* *
* Created by Manoël Trapier on 02/12/07. * Created by Manoel TRAPIER.
* Copyright 2007 986 Corp. All rights reserved. * 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 $
* *
*/ */
@ -13,4 +18,3 @@
int mmc1_InitMapper (NesCart *cart); int mmc1_InitMapper (NesCart *cart);
int mmc1_MapperIRQ (int cycledone); int mmc1_MapperIRQ (int cycledone);
void mmc1_MapperDump (); void mmc1_MapperDump ();
void mmc1_MapperWriteHook(register byte Addr, register byte Value);

View File

@ -12,6 +12,10 @@
* *
*/ */
#include "mmc3.h"
extern unsigned short ScanLine;
unsigned short mmc3_command; unsigned short mmc3_command;
unsigned char mmc3_irq_counter; unsigned char mmc3_irq_counter;
@ -43,8 +47,6 @@ void mmc3_MapperDump(FILE *fp)
int mmc3_InitMapper(NesCart * cart) int mmc3_InitMapper(NesCart * cart)
{ {
int i;
set_prom_bank_16k(0x8000, 0); set_prom_bank_16k(0x8000, 0);
set_prom_bank_16k(0xC000, GETLAST16KBANK(cart)); set_prom_bank_16k(0xC000, GETLAST16KBANK(cart));
@ -75,8 +77,6 @@ int mmc3_InitMapper(NesCart * cart)
mmc3_first_prom_page = 0x8000; mmc3_first_prom_page = 0x8000;
mmc3_second_prom_page = 0xA000; mmc3_second_prom_page = 0xA000;
//mmc3_first_prom_page = 0; // Set it to 0x8000
/* Register mapper write hook */ /* Register mapper write hook */
set_page_wr_hook(0x80, mmc3_MapperWrite80Hook); set_page_wr_hook(0x80, mmc3_MapperWrite80Hook);
@ -92,7 +92,6 @@ int mmc3_InitMapper(NesCart * cart)
set_page_writeable(0xE0, true); set_page_writeable(0xE0, true);
return 0; return 0;
} }
void mmc3_MapperWrite80Hook(byte addr, byte Value) 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) void mmc3_MapperWriteC0Hook(byte addr, byte Value)
{ {
//printf("%s(0x%02X, 0x%02X)\n", __func__, addr, Value); //printf("%s(0x%02X, 0x%02X)\n", __func__, addr, Value);

View File

@ -12,6 +12,8 @@
* *
*/ */
#include "mmc4.h"
byte mmc4_RegA; byte mmc4_RegA;
byte mmc4_RegB; byte mmc4_RegB;
byte mmc4_RegC; byte mmc4_RegC;
@ -88,7 +90,8 @@ int mmc4_InitMapper(NesCart * cart)
set_prom_bank_16k(0x8000,0); set_prom_bank_16k(0x8000,0);
set_prom_bank_16k(0xC000, GETLAST16KBANK(cart)); set_prom_bank_16k(0xC000, GETLAST16KBANK(cart));
if (cart->VROMSize > 0) set_vrom_bank_8k(0x0000,0); if (cart->VROMSize > 0)
set_vrom_bank_8k(0x0000,0);
/* Mapper should register itself for write hook */ /* Mapper should register itself for write hook */
for (i = 0xA0; i < 0xB0 ; i++) for (i = 0xA0; i < 0xB0 ; i++)

View File

@ -1,9 +1,14 @@
/* /*
* NOROM Mapper - The TI-NESulator Project
* norom.c * norom.c
* TI-NESulator.X
* *
* Created by Manoël Trapier on 25/10/07. * Created by Manoel TRAPIER.
* Copyright 2007 986 Corp. All rights reserved. * 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 norom_InitMapper(NesCart *cart)
{ {
int i;
set_page_ptr_16k(0x80, cart->PROMBanks); set_page_ptr_16k(0x80, cart->PROMBanks);
/* mUBank = 0xC000 */ /* mUBank = 0xC000 */

View File

@ -1,9 +1,14 @@
/* /*
* norom.h * NOROM Mapper - The TI-NESulator Project
* TI-NESulator.X * norom.c
* *
* Created by Manoël Trapier on 25/10/07. * Created by Manoel TRAPIER.
* Copyright 2007 986 Corp. All rights reserved. * 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 $
* *
*/ */
@ -13,4 +18,3 @@
int norom_InitMapper (NesCart *cart); int norom_InitMapper (NesCart *cart);
int norom_MapperIRQ (int cycledone); int norom_MapperIRQ (int cycledone);
void norom_MapperDump (); void norom_MapperDump ();
void norom_MapperWriteHook(register byte Addr, register byte Value);

View File

@ -12,9 +12,11 @@
* *
*/ */
#include "unrom.h"
unsigned char unrom_load_vbank; 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) 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); set_vrom_bank_8k(0x0000,Value);
unrom_load_vbank = Value; unrom_load_vbank = Value;

View File

@ -9,11 +9,27 @@
/* This file could be generated from the mappers directory... */ /* This file could be generated from the mappers directory... */
#include "mappers/norom.h" #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/mmc1.h"
#include "mappers/mmc3.h"
#include "mappers/mmc4.h"
Mapper Mappers[] = { Mapper Mappers[] = {
{ 0, "No Mapper", norom_InitMapper, norom_MapperIRQ, norom_MapperDump }, { 0 , "No Mapper", norom_InitMapper, norom_MapperIRQ, norom_MapperDump },
{ 1, "MMC1", mmc1_InitMapper, norom_MapperIRQ, mmc1_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 */ /* EOL tag */
{ 0, NULL, NULL, NULL, NULL } { 0, NULL, NULL, NULL, NULL }

View File

@ -23,6 +23,10 @@
#include <mappers/manager.h> #include <mappers/manager.h>
#include <memory/manager.h> #include <memory/manager.h>
#define __TINES_PPU_INTERNAL__
#include <ppu/ppu.memory.h>
#undef __TINES_PPU_INTERNAL__
extern NesCart *Cart; extern NesCart *Cart;
extern char MapperWantIRQ; extern char MapperWantIRQ;

View File

@ -19,7 +19,7 @@
typedef struct Plugin_ typedef struct Plugin_
{ {
byte *name; char *name;
PluginInit init; PluginInit init;
PluginDeinit deinit; PluginDeinit deinit;
@ -55,9 +55,15 @@ void plugin_list()
int plugin_load(int id) int plugin_load(int id)
{ {
Plugin *ptr = &(Plugins[0]); Plugin *ptr = &(Plugins[0]);
int i = id;
for ( ; id == 0 && ptr != NULL; id -- ) printf("%s(%d)", __func__, id);
for ( ; i > 1 && ptr->name != NULL; i -- )
{
printf("%d - %s\n", i, ptr->name);
ptr ++; ptr ++;
}
if (ptr == NULL) if (ptr == NULL)
return -1; return -1;

View File

@ -4,6 +4,7 @@
#define __TINES_PLUGINS__ #define __TINES_PLUGINS__
#include <plugins/manager.h> #include <plugins/manager.h>
#undef __TINES_PLUGINS_
#include <memory/manager.h> #include <memory/manager.h>
#include <types.h> #include <types.h>
@ -53,7 +54,6 @@ byte gg_RdHookPatch##d(byte addr) \
} }
#define GG_MAX_PATCH 10 #define GG_MAX_PATCH 10
/* Defines the rdhook patches */ /* Defines the rdhook patches */
GG_RDHOOKPATCH(0) GG_RDHOOKPATCH(0)
GG_RDHOOKPATCH(1) GG_RDHOOKPATCH(1)
@ -68,7 +68,7 @@ GG_RDHOOKPATCH(9)
void gg_SetPatch(int id, byte page, byte addr, byte value) void gg_SetPatch(int id, byte page, byte addr, byte value)
{ {
func_rdhook *fptr; func_rdhook fptr;
if (id >= GG_MAX_PATCH) if (id >= GG_MAX_PATCH)
return; return;
@ -418,7 +418,7 @@ byte gg_SelectPatch()
if (gg_PatchUsed[i] == 0x00) if (gg_PatchUsed[i] == 0x00)
sprintf(tmp, "Patch %d: Not used", i); sprintf(tmp, "Patch %d: Not used", i);
else 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], i, gg_PatchedValue[i], gg_PatchedPage[i], gg_PatchedAddr[i],
gg_MakeCode((gg_PatchedPage[i]<<8) | gg_PatchedAddr[i], gg_PatchedValue[i])); gg_MakeCode((gg_PatchedPage[i]<<8) | gg_PatchedAddr[i], gg_PatchedValue[i]));

View File

@ -218,7 +218,7 @@ void ppu_dumpOneNameTable(unsigned short nametable, int xd, int yd)
void ppu_dumpOneAttributeTable(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++) for (x = 0; x < 0x40; x++)
{ {
AttrByte = PPU_Rd(nametable + 0x23C0 + x); AttrByte = PPU_Rd(nametable + 0x23C0 + x);

View File

@ -23,6 +23,8 @@
#include <ppu/ppu.memory.h> #include <ppu/ppu.memory.h>
#include <ppu/ppu.debug.h> #include <ppu/ppu.debug.h>
#include <M6502.h>
#include <memory/manager.h> #include <memory/manager.h>
#define __TINES_PLUGINS__ #define __TINES_PLUGINS__
@ -186,6 +188,9 @@ int ppu_init()
{ {
int i; 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()) if (ppu_initMemory())
return -1; return -1;
@ -221,7 +226,6 @@ int ppu_init()
/* Third: set registers to defaults */ /* Third: set registers to defaults */
/* Now test the memory ! */ /* Now test the memory ! */
/* Fille PPU memory with garbage */ /* Fille PPU memory with garbage */
@ -232,6 +236,7 @@ int ppu_init()
for (i = 0x0000; i < 0x001F ; i++) 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 */ /* Dump PPU memory state */
//ppu_memoryDumpState(stdout); //ppu_memoryDumpState(stdout);
@ -299,7 +304,7 @@ void ppu_updateSpriteScanlineTable()
for ( i = 0; i < 64; i ++) for ( i = 0; i < 64; i ++)
{ {
/* Fill sprite_zzz variables */ /* 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_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_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]; sprite_x = ppu_mem_spritesTable[(i*4) + 3];
@ -312,15 +317,14 @@ void ppu_updateSpriteScanlineTable()
if ((curline < 0) || (curline > 240)) if ((curline < 0) || (curline > 240))
continue; /* Don't go beyond, this sprite go beyond the borders */ continue; /* Don't go beyond, this sprite go beyond the borders */
if (PPU_NbSpriteByScanLine[curline] < 7) if (PPU_NbSpriteByScanLine[curline] < 8)
PPU_NbSpriteByScanLine[curline] ++; PPU_NbSpriteByScanLine[curline] ++;
else else
{ {
PPU_NbSpriteByScanLineOverFlow[curline] = 1; 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 */ continue; /* We have 8 sprite in this line, don't continue */
} }
if (((sprite_x+8) < 0) && ((sprite_x-8) > 256)) if (((sprite_x+8) < 0) && ((sprite_x-8) > 256))
continue; /* this sprite isn't either displayable */ 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 */
@ -509,15 +513,20 @@ _AAA BCDD DDDE EEEE
IF_N_KEY printf("Counter update to %04X\n",PPU_Reg_Counter); IF_N_KEY printf("Counter update to %04X\n",PPU_Reg_Counter);
} }
extern M6502 MainCPU;
int ppu_hblank(int scanline) int ppu_hblank(int scanline)
{ {
int i, j; int i, j;
byte pixelColor = 0x42; byte pixelColor = 0x42;
byte Color = 0x42; byte BgColor = 0x42;
byte SpriteColor = 0x42;
unsigned short addr; unsigned short addr;
byte value; byte value;
unsigned short tmp_HHT = 0; 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 no plan activated, we have nothing to do ! */
@ -536,37 +545,12 @@ int ppu_hblank(int scanline)
/* For each PPU pixel of this scanline */ /* For each PPU pixel of this scanline */
for (i = 0; i < 256; i ++) for (i = 0; i < 256; i ++)
{ {
/* Set the current pixel color to the bg color */
/* determine which from sprite bg, bg and sprite fg is in the front */
pixelColor = ppu_readMemory(0x3F,00); pixelColor = ppu_readMemory(0x3F,00);
/* is there sprite(s) on this line ? */ /* Compute current pixel bg color if bg is visible */
/* */
/* Didn't display sprite for now, juste the BG */
/* Read NameTable */
if (ppu_backgroundVisibility == 1) 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 = (PPU_Reg_Counter & 0x0C00);
addr = addr | 0x03C0; addr = addr | 0x03C0;
addr |= (PPU_Reg_Counter >> 4 ) & 0x0038; addr |= (PPU_Reg_Counter >> 4 ) & 0x0038;
@ -574,31 +558,27 @@ xxxx 1111 1100 1111
PPU_Reg_AR = ppu_readMemory(0x20 | ((addr>>8) & 0x0F), addr& 0xFF); 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 >> (((PPU_Reg_Counter >> 4 ) & 0x04)|((PPU_Reg_Counter ) & 0x02));
PPU_Reg_AR = (PPU_Reg_AR<<2) & 0x0C; PPU_Reg_AR = (PPU_Reg_AR<<2) & 0x0C;
PPU_Reg_PAR = ppu_readMemory(0x20 | ((PPU_Reg_Counter>>8) & 0x0F), PPU_Reg_Counter& 0xFF); 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_S;
addr |= ((PPU_Reg_PAR & 0xFF) << 4); addr |= ((PPU_Reg_PAR & 0xFF) << 4);
addr |= ((PPU_Reg_Counter >> 12) & 0x07); addr |= ((PPU_Reg_Counter >> 12) & 0x07);
value = ppu_readMemory((addr >> 8) , addr ); value = ppu_readMemory((addr >> 8) , addr );
Color = (value & (1 << (7-(i + PPU_Reg_FH) % 8)))?0x01:0; BgColor = (value & (1 << (7-(i + PPU_Reg_FH) % 8)))?0x01:0;
value = ppu_readMemory((addr >> 8) , addr | 0x08 ); value = ppu_readMemory((addr >> 8) , addr | 0x08 );
Color |= (value & (1 << (7-(i + PPU_Reg_FH) % 8)))?0x02:0; BgColor |= (value & (1 << (7-(i + PPU_Reg_FH) % 8)))?0x02:0;
if (Color > 0x00) if (BgColor > 0x00)
{ {
BgColor |= PPU_Reg_AR;
BgColor &= 0x0F;
Color |= PPU_Reg_AR; pixelColor = ppu_readMemory(0x3F, BgColor);
Color &= 0x0F;
pixelColor = ppu_readMemory(0x3F, Color);
} }
if (((i + PPU_Reg_FH)%8) == 7) if (((i + PPU_Reg_FH)%8) == 7)
@ -607,16 +587,138 @@ xxxx 1111 1100 1111
(PPU_Reg_Counter & 0x001F); (PPU_Reg_Counter & 0x001F);
tmp_HHT = (tmp_HHT + 1) & 0x003F; tmp_HHT = (tmp_HHT + 1) & 0x003F;
/* Reassemble with HT & H */ /* Reassemble with HT & H */
PPU_Reg_Counter = (PPU_Reg_Counter & 0xFBE0) | PPU_Reg_Counter = (PPU_Reg_Counter & 0xFBE0) |
((tmp_HHT & 0x0020) << 5) | ((tmp_HHT & 0x0020) << 5) |
(tmp_HHT & 0x001F); (tmp_HHT & 0x001F);
}
} }
/* 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 */
_putpixel(VideoBuffer, i, scanline, pixelColor);
/* 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*/ /* Increment only V & VT & FV*/
/* /*
@ -641,69 +743,7 @@ E = HT
*/ */
if (ppu_backgroundVisibility == 1) if (scanline == 239)
{
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)
{ {
ppu_inVBlankTime = 1; ppu_inVBlankTime = 1;
IF_N_KEY printf("============= enter vblank =================\n"); IF_N_KEY printf("============= enter vblank =================\n");
@ -717,25 +757,36 @@ E = HT
} }
//if (scanline >= (241 + VBLANK_TIME)) if (scanline >= (240 + VBLANK_TIME))
if (scanline >= 262)
{ {
/*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(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); //printf("(SL:%d) FPS : %d IPS : %d\n", scanline, FPS, IPS);
//ppu_dumpPalette(0, 241); ppu_dumpPalette(0, 241);
//ppu_dumpPattern(280, 150); ppu_dumpPattern(280, 150);
//ppu_dumpNameTable(256,0); ppu_dumpNameTable(256,0);
//ppu_dumpAttributeTable(257, 0); //ppu_dumpAttributeTable(257, 0);
//blit(VideoBuffer, Buffer, 0, 0, 0, 0, 256, 240); 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, 512);
//blit(Buffer, screen, 0, 0, 0, 0, 512 + 256, 480); //blit(VideoBuffer, screen, 0, 0, 0, 0, 256, 240);
IF_N_KEY printf("_____________ leave vblank _________________\n"); IF_N_KEY printf("_____________ leave vblank _________________\n");
ppu_inVBlankTime = 0; ppu_inVBlankTime = 0;
ppu_spriteZeroHit = 0; ppu_spriteZeroHit = 0;
ppu_scanlineSpriteOverflow = 0;
//ppu_updateCounters(); //ppu_updateCounters();
} }
return 0; return 0;
@ -806,7 +857,7 @@ void ppu_writeReg(byte id, byte val)
switch(id) switch(id)
{ {
default: 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; break;
case 0x00: /* PPU Control Register #1 */ case 0x00: /* PPU Control Register #1 */
@ -823,15 +874,15 @@ void ppu_writeReg(byte id, byte val)
*/ */
IF_N_KEY IF_N_KEY
printf("%s(%02X, %02X); /* 2000: " printf("%s(%02X, %02X); /* 2000: "
"NMI:%c SPRTSIZE:%02d BGTA:%04X[0x%04X] SPTA:%04X INC:%02d NTA:%04X */\n" "NMI:%c SPRTSIZE:%02d BGTA:%04X[0x%04X] SPTA:%04X INC:%02d NTA:%04X */\n",
, __func__, id, val, __func__, id, val,
(val & 0x80)?'E':'D', (val & 0x80)?'E':'D',
(val & 0x20)?16:8, (val & 0x20)?16:8,
(val & 0x10)?0x1000:0x0000, PPU_Reg_S, (val & 0x10)?0x1000:0x0000, PPU_Reg_S,
(val & 0x08)?0x1000:0x0000, (val & 0x08)?0x1000:0x0000,
(val & 0x04)?32:1, (val & 0x04)?32:1,
(val & 0x03)<<10|0x2000 (val & 0x03)<<10|0x2000
); );
/* Set PPU internal registers */ /* Set PPU internal registers */
PPU_Reg_V = (val & 0x02)?1:0; PPU_Reg_V = (val & 0x02)?1:0;
@ -848,14 +899,16 @@ void ppu_writeReg(byte id, byte val)
case 0x01: /* PPU Control Register #2 */ case 0x01: /* PPU Control Register #2 */
ppu_spriteVisibility = (val & 0x10)?1:0; ppu_spriteVisibility = (val & 0x10)?1:0;
ppu_backgroundVisibility = (val & 0x08)?1:0; ppu_backgroundVisibility = (val & 0x08)?1:0;
ppu_spriteClipping = (val & 0x04)?1:0; ppu_spriteClipping = (val & 0x04)?1:0;
ppu_backgroundClipping = (val & 0x02)?1:0; ppu_backgroundClipping = (val & 0x02)?1:0;
ppu_displayType = (val & 0x01)?1:0; ppu_displayType = (val & 0x01)?1:0;
ppu_updateSpriteScanlineTable();
IF_N_KEY IF_N_KEY
printf("%s(%02X, %02X); /* 2001 : " 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, " */\n", __func__, id, val,
ppu_spriteVisibility?'y':'n', ppu_spriteVisibility?'y':'n',
ppu_backgroundVisibility?'y':'n', ppu_backgroundVisibility?'y':'n',
@ -863,7 +916,6 @@ void ppu_writeReg(byte id, byte val)
ppu_backgroundClipping?'y':'n', ppu_backgroundClipping?'y':'n',
ppu_displayType?'m':'c' ppu_displayType?'m':'c'
); );
break; break;
case 0x03: /* SPR-RAM Address Register */ case 0x03: /* SPR-RAM Address Register */
@ -872,9 +924,7 @@ void ppu_writeReg(byte id, byte val)
case 0x04: /* SPR-RAM I/O */ case 0x04: /* SPR-RAM I/O */
ppu_mem_spritesTable[ppu_mem_sptrTablePtr++] = val; ppu_mem_spritesTable[ppu_mem_sptrTablePtr++] = val;
ppu_updateSpriteScanlineTable(); ppu_updateSpriteScanlineTable();
break; break;
case 0x05: /* 2005 VRAM Register */ case 0x05: /* 2005 VRAM Register */

View File

@ -12,15 +12,12 @@
* *
*/ */
#ifndef PPU_MEMORY_H
#define PPU_MEMORY_H
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#define __TINES_PPU_INTERNAL__ #define __TINES_PPU_INTERNAL__
#include <ppu/ppu.h> #include <ppu.h>
#include <ppu/ppu.memory.h> #include <ppu/ppu.memory.h>
#include <types.h> #include <types.h>
@ -39,7 +36,7 @@ byte ppu_SpriteRam[0x100];
/* /*
* Memory management functions * 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 * 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 * protection. We even didn't need "attributes" for the page. One of the only
* need is the "powerful" ghost system * 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 /* Here we will cheat with the palette miroring, since we didn't write
as often as we read the palette, we will mirror here */ 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); //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][0x00] = value;
ppu_memoryPages[0x3F][(addr&0x1F) | 0x10] = value; ppu_memoryPages[0x3F][0x10] = value;
} }
else else
{
ppu_memoryPages[0x3F][addr&0x1F] = value; ppu_memoryPages[0x3F][addr&0x1F] = value;
if (( addr & 0x1F ) == 0x10 )
ppu_memoryPages[0x3F][(addr&0x1F) & 0xEF] = value;
}
} }
else else
{ {
@ -177,5 +170,3 @@ void ppu_writeMemory(byte page, byte addr, byte value)
ptr[addr] = value; ptr[addr] = value;
} }
} }
#endif