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++)
{ {
@ -252,7 +253,7 @@ static void *DSPLoop(void *Arg)
} }
CH[J].Count=L1; CH[J].Count=L1;
break; break;
case SND_TRIANGLE: /* Default Sound */ case SND_TRIANGLE: /* Default Sound */
/* Do not allow frequencies that are too high */ /* Do not allow frequencies that are too high */
if(CH[J].Freq>=SoundRate/3) break; if(CH[J].Freq>=SoundRate/3) break;
@ -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;

File diff suppressed because it is too large Load Diff

View File

@ -1,480 +1,482 @@
/** M6502: portable 6502 emulator ****************************/ /** M6502: portable 6502 emulator ****************************/
/** **/ /** **/
/** Debug.c **/ /** Debug.c **/
/** **/ /** **/
/** This file contains the built-in debugging routine for **/ /** This file contains the built-in debugging routine for **/
/** the 6502 emulator which is called on each 6502 step **/ /** the 6502 emulator which is called on each 6502 step **/
/** when Trap!=0. **/ /** when Trap!=0. **/
/** **/ /** **/
/** Copyright (C) Marat Fayzullin 1996-1997 **/ /** Copyright (C) Marat Fayzullin 1996-1997 **/
/** Alex Krasivsky 1996 **/ /** Alex Krasivsky 1996 **/
/** You are not allowed to distribute this software **/ /** You are not allowed to distribute this software **/
/** commercially. Please, notify me, if you make any **/ /** commercially. Please, notify me, if you make any **/
/** changes to this file. **/ /** changes to this file. **/
/*************************************************************/ /*************************************************************/
/* /*
* $LastChangedDate: 2007-04-19 18:18:57 +0200 (jeu, 19 avr 2007) $ * $LastChangedDate: 2007-04-19 18:18:57 +0200 (jeu, 19 avr 2007) $
* $Author: mtrapier $ * $Author: mtrapier $
* $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/Debug.c $ * $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/Debug.c $
* $Revision: 43 $ * $Revision: 43 $
*/ */
#include "M6502.h" #include "M6502.h"
#ifdef DEBUG #ifdef DEBUG
#include <allegro.h> #include <allegro.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <ppu/ppu.h> #include <ppu/ppu.h>
#include <Sound.h> #include <mappers/manager.h>
#include <memory/manager.h>
#define RDWORD(A) (Rd6502(A+1)*256+Rd6502(A)) #include <Sound.h>
extern unsigned char *Memory; #define RDWORD(A) (Rd6502(A+1)*256+Rd6502(A))
void showlastop(); extern unsigned char *Memory;
enum Addressing_Modes void showlastop();
{
Ac = 0, Il, Im, Ab, Zp, Zx, Zy, Ax, Ay, Rl, Ix, Iy, In, No 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 ", static char *mn[] =
"bne ", "bpl ", "brk", "bvc ", "bvs ", "clc", "cld", "cli", {
"clv", "cmp ", "cpx ", "cpy ", "dec ", "dex", "dey", "inx", "adc ", "and ", "asl ", "bcc ", "bcs ", "beq ", "bit ", "bmi ",
"iny", "eor ", "inc ", "jmp ", "jsr ", "lda ", "nop ", "ldx ", "bne ", "bpl ", "brk", "bvc ", "bvs ", "clc", "cld", "cli",
"ldy ", "lsr ", "ora ", "pha", "php", "pla", "plp", "rol ", "clv", "cmp ", "cpx ", "cpy ", "dec ", "dex", "dey", "inx",
"ror ", "rti", "rts", "sbc ", "sta ", "stx ", "sty ", "sec ", "iny", "eor ", "inc ", "jmp ", "jsr ", "lda ", "nop ", "ldx ",
"sed", "sei", "tax", "tay", "txa", "tya", "tsx", "txs" "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, static byte ad[512] =
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, 10, Il, 34, Ix, No, No, No, No, No, No, 34, Zp, 2, Zp, No, No,
13, Il, 34, Ay, No, No, No, No, No, No, 34, Ax, 2, Ax, No, No, 36, Il, 34, Im, 2, Ac, No, No, No, No, 34, Ab, 2, Ab, No, No,
28, Ab, 1, Ix, No, No, No, No, 6, Zp, 1, Zp, 39, Zp, No, No, 9, Rl, 34, Iy, No, No, No, No, No, No, 34, Zx, 2, Zx, No, No,
38, Il, 1, Im, 39, Ac, No, No, 6, Ab, 1, Ab, 39, Ab, No, No, 13, Il, 34, Ay, No, No, No, No, No, No, 34, Ax, 2, Ax, No, No,
7, Rl, 1, Iy, No, No, No, No, No, No, 1, Zx, 39, Zx, No, No, 28, Ab, 1, Ix, No, No, No, No, 6, Zp, 1, Zp, 39, Zp, No, No,
47, Il, 1, Ay, No, No, No, No, No, No, 1, Ax, 39, Ax, No, No, 38, Il, 1, Im, 39, Ac, No, No, 6, Ab, 1, Ab, 39, Ab, No, No,
41, Il, 25, Ix, No, No, No, No, No, No, 25, Zp, 33, Zp, No, No, 7, Rl, 1, Iy, No, No, No, No, No, No, 1, Zx, 39, Zx, No, No,
35, Il, 25, Im, 33, Ac, No, No, 27, Ab, 25, Ab, 33, Ab, No, No, 47, Il, 1, Ay, No, No, No, No, No, No, 1, Ax, 39, Ax, No, No,
11, Rl, 25, Iy, No, No, No, No, No, No, 25, Zx, 33, Zx, No, No, 41, Il, 25, Ix, No, No, No, No, No, No, 25, Zp, 33, Zp, No, No,
15, Il, 25, Ay, No, No, No, No, No, No, 25, Ax, 33, Ax, No, No, 35, Il, 25, Im, 33, Ac, No, No, 27, Ab, 25, Ab, 33, Ab, No, No,
42, Il, 0, Ix, No, No, No, No, No, No, 0, Zp, 40, Zp, No, No, 11, Rl, 25, Iy, No, No, No, No, No, No, 25, Zx, 33, Zx, No, No,
37, Il, 0, Im, 40, Ac, No, No, 27, In, 0, Ab, 40, Ab, No, No, 15, Il, 25, Ay, No, No, No, No, No, No, 25, Ax, 33, Ax, No, No,
12, Rl, 0, Iy, No, No, No, No, No, No, 0, Zx, 40, Zx, No, No, 42, Il, 0, Ix, No, No, No, No, No, No, 0, Zp, 40, Zp, No, No,
49, Il, 0, Ay, No, No, No, No, No, No, 0, Ax, 40, Ax, No, No, 37, Il, 0, Im, 40, Ac, No, No, 27, In, 0, Ab, 40, Ab, No, No,
No, No, 44, Ix, No, No, No, No, 46, Zp, 44, Zp, 45, Zp, No, No, 12, Rl, 0, Iy, No, No, No, No, No, No, 0, Zx, 40, Zx, No, No,
22, Il, No, No, 52, Il, No, No, 46, Ab, 44, Ab, 45, Ab, No, No, 49, Il, 0, Ay, No, No, No, No, No, No, 0, Ax, 40, Ax, No, No,
3, Rl, 44, Iy, No, No, No, No, 46, Zx, 44, Zx, 45, Zy, No, No, No, No, 44, Ix, No, No, No, No, 46, Zp, 44, Zp, 45, Zp, No, No,
53, Il, 44, Ay, 55, Il, No, No, No, No, 44, Ax, No, No, No, No, 22, Il, No, No, 52, Il, No, No, 46, Ab, 44, Ab, 45, Ab, No, No,
32, Im, 29, Ix, 31, Im, No, No, 32, Zp, 29, Zp, 31, Zp, No, No, 3, Rl, 44, Iy, No, No, No, No, 46, Zx, 44, Zx, 45, Zy, No, No,
51, Il, 29, Im, 50, Il, No, No, 32, Ab, 29, Ab, 31, Ab, No, No, 53, Il, 44, Ay, 55, Il, No, No, No, No, 44, Ax, No, No, No, No,
4, Rl, 29, Iy, No, No, No, No, 32, Zx, 29, Zx, 31, Zy, No, No, 32, Im, 29, Ix, 31, Im, No, No, 32, Zp, 29, Zp, 31, Zp, No, No,
16, Il, 29, Ay, 54, Il, No, No, 32, Ax, 29, Ax, 31, Ay, No, No, 51, Il, 29, Im, 50, Il, No, No, 32, Ab, 29, Ab, 31, Ab, No, No,
19, Im, 17, Ix, No, No, No, No, 19, Zp, 17, Zp, 20, Zp, No, No, 4, Rl, 29, Iy, No, No, No, No, 32, Zx, 29, Zx, 31, Zy, No, No,
24, Il, 17, Im, 21, Il, No, No, 19, Ab, 17, Ab, 20, Ab, No, No, 16, Il, 29, Ay, 54, Il, No, No, 32, Ax, 29, Ax, 31, Ay, No, No,
8, Rl, 17, Iy, No, No, No, No, No, No, 17, Zx, 20, Zx, No, No, 19, Im, 17, Ix, No, No, No, No, 19, Zp, 17, Zp, 20, Zp, No, No,
14, Il, 17, Ay, No, No, No, No, No, No, 17, Ax, 20, Ax, No, No, 24, Il, 17, Im, 21, Il, No, No, 19, Ab, 17, Ab, 20, Ab, No, No,
18, Im, 43, Ix, No, No, No, No, 18, Zp, 43, Zp, 26, Zp, No, No, 8, Rl, 17, Iy, No, No, No, No, No, No, 17, Zx, 20, Zx, No, No,
23, Il, 43, Im, 30, Il, No, No, 18, Ab, 43, Ab, 26, Ab, No, No, 14, Il, 17, Ay, No, No, No, No, No, No, 17, Ax, 20, Ax, No, No,
5, Rl, 43, Iy, No, No, No, No, No, No, 43, Zx, 26, Zx, No, No, 18, Im, 43, Ix, No, No, No, No, 18, Zp, 43, Zp, 26, Zp, No, No,
48, Il, 43, Ay, No, No, No, No, No, No, 43, Ax, 26, Ax, 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. **/ /** DAsm() ****************************************************/
/**************************************************************/ /** This function will disassemble a single command and **/
int DAsm(char *S, word A) /** return the number of bytes disassembled. **/
{ /**************************************************************/
int DAsm(char *S, word A)
byte J; {
word B, OP, TO; byte J;
word B, OP, TO;
B = A;
OP = Rd6502(B++) * 2;
B = A;
OP = Rd6502(B++) * 2;
switch (ad[OP + 1])
{ switch (ad[OP + 1])
case Ac: {
sprintf(S, "%s a", mn[ad[OP]]);
break; case Ac:
sprintf(S, "%s a", mn[ad[OP]]);
case Il: break;
sprintf(S, "%s", 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)); case Rl:
J = Rd6502(B++);
sprintf(S, "%s $%04X", mn[ad[OP]], TO); TO = A + 2 + ((J < 0x80) ? J : (J - 256));
break;
sprintf(S, "%s $%04X", mn[ad[OP]], TO);
break;
case Im:
sprintf(S, "%s #$%02X", mn[ad[OP]], Rd6502(B++));
break; case Im:
sprintf(S, "%s #$%02X", mn[ad[OP]], Rd6502(B++));
case Zp: break;
sprintf(S, "%s $%02X", mn[ad[OP]], Rd6502(B++));
break; case Zp:
sprintf(S, "%s $%02X", mn[ad[OP]], Rd6502(B++));
case Zx: break;
sprintf(S, "%s $%02X,x", mn[ad[OP]], Rd6502(B++));
break; case Zx:
sprintf(S, "%s $%02X,x", mn[ad[OP]], Rd6502(B++));
case Zy: break;
sprintf(S, "%s $%02X,y", mn[ad[OP]], Rd6502(B++));
break; case Zy:
sprintf(S, "%s $%02X,y", mn[ad[OP]], Rd6502(B++));
case Ix: break;
sprintf(S, "%s ($%02X,x)", mn[ad[OP]], Rd6502(B++));
break; case Ix:
sprintf(S, "%s ($%02X,x)", mn[ad[OP]], Rd6502(B++));
case Iy: break;
sprintf(S, "%s ($%02X),y", 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; case Ab:
break; sprintf(S, "%s $%04X", mn[ad[OP]], RDWORD(B));
B += 2;
case Ax: break;
sprintf(S, "%s $%04X,x", mn[ad[OP]], RDWORD(B));
B += 2; case Ax:
break; sprintf(S, "%s $%04X,x", mn[ad[OP]], RDWORD(B));
B += 2;
case Ay: break;
sprintf(S, "%s $%04X,y", mn[ad[OP]], RDWORD(B));
B += 2; case Ay:
break; sprintf(S, "%s $%04X,y", mn[ad[OP]], RDWORD(B));
B += 2;
case In: break;
sprintf(S, "%s ($%04X)", mn[ad[OP]], RDWORD(B));
B += 2; case In:
break; sprintf(S, "%s ($%04X)", mn[ad[OP]], RDWORD(B));
B += 2;
break;
default:
sprintf(S, ".db $%02X; <Invalid OPcode>", OP / 2);
default:
} sprintf(S, ".db $%02X; <Invalid OPcode>", OP / 2);
return (B - A);
}
} return (B - A);
}
/** Debug6502() **********************************************/
/** This function should exist if DEBUG is #defined. When **/
/** Trace!=0, it is called after each command executed by **/ /** Debug6502() **********************************************/
/** the CPU, and given the 6502 registers. Emulation exits **/ /** This function should exist if DEBUG is #defined. When **/
/** if Debug6502() returns 0. **/ /** Trace!=0, it is called after each command executed by **/
/*************************************************************/ /** the CPU, and given the 6502 registers. Emulation exits **/
byte Debug6502(M6502 * R) /** if Debug6502() returns 0. **/
{ /*************************************************************/
static char FA[8] = "NVRBDIZC"; byte Debug6502(M6502 * R)
char S[128]; {
byte F; static char FA[8] = "NVRBDIZC";
int J, I; char S[128];
byte F;
DAsm(S, R->PC.W); int J, I;
printf DAsm(S, R->PC.W);
(
"A:%02X P:%02X X:%02X Y:%02X S:%04X PC:%04X Flags:[", printf
R->A, R->P, R->X, R->Y, R->S + 0x0100, R->PC.W (
); "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] : '.'); for (J = 0, F = R->P; J < 8; J++, F <<= 1)
puts("]"); printf("%c", F & 0x80 ? FA[J] : '.');
puts("]");
printf
(
"AT PC: [%02X - %s] AT SP: [%02X %02X %02X]\n", printf
Rd6502(R->PC.W), S, (
Rd6502(0x0100 + (byte) (R->S + 1)), "AT PC: [%02X - %s] AT SP: [%02X %02X %02X]\n",
Rd6502(0x0100 + (byte) (R->S + 2)), Rd6502(R->PC.W), S,
Rd6502(0x0100 + (byte) (R->S + 3)) Rd6502(0x0100 + (byte) (R->S + 1)),
); Rd6502(0x0100 + (byte) (R->S + 2)),
Rd6502(0x0100 + (byte) (R->S + 3))
);
sprintf(S, "");
remove_keyboard();
S[0] = 0;
#ifdef USE_SOUND remove_keyboard();
StopSound();
#endif #ifdef USE_SOUND
StopSound();
#endif
while (1)
{
printf("\n[Command,'?']-> "); while (1)
{
fflush(stdout); printf("\n[Command,'?']-> ");
fflush(stdin);
fflush(stdout);
fflush(stdin);
fgets(S, 50, stdin);
for (J = 0; S[J] >= ' '; J++) fgets(S, 50, stdin);
S[J] = toupper(S[J]);
for (J = 0; S[J] >= ' '; J++)
S[J] = '\0'; S[J] = toupper(S[J]);
S[J] = '\0';
switch (S[0])
{
case 'H': switch (S[0])
case '?': {
puts("\n***** Built-in 6502 Debugger Commands *****"); case 'H':
puts("<CR> : Break at the next instruction"); case '?':
puts("= <addr> : Break at addr"); puts("\n***** Built-in 6502 Debugger Commands *****");
puts("+ <offset> : Break at PC + offset"); puts("<CR> : Break at the next instruction");
puts("t <addr> : Set PC to addr"); puts("= <addr> : Break at addr");
puts("c : Continue without break"); puts("+ <offset> : Break at PC + offset");
puts("j <addr> : Continue from addr"); puts("t <addr> : Set PC to addr");
puts("m <addr> : Memory dump at addr"); puts("c : Continue without break");
puts("d <addr> : Disassembly at addr"); puts("j <addr> : Continue from addr");
puts("v : Show ;interrupt vectors"); puts("m <addr> : Memory dump at addr");
puts("?,h : Show this help text"); puts("d <addr> : Disassembly at addr");
puts("r : Show Register Status"); puts("v : Show ;interrupt vectors");
puts("q : Exit 6502 emulation"); puts("?,h : Show this help text");
puts("r : Show Register Status");
puts("----- TI-NES Specific -----"); puts("q : Exit 6502 emulation");
puts("w : Dump Memory State");
puts("o : Show PPU registers"); puts("----- TI-NES Specific -----");
puts("p <addr> : Dump PPU memory at addr"); puts("w : Dump Memory State");
puts("a : Dump all memory to memory.log"); puts("o : Show PPU registers");
puts("s : Dump sprite table to sprite.log"); puts("p <addr> : Dump PPU memory at addr");
puts("n <nb> : Dump name table <nb> to nt.log"); puts("a : Dump all memory to memory.log");
puts("z : Show lastest opcode executed"); puts("s : Dump sprite table to sprite.log");
puts("i : SpriteTable Dump"); puts("n <nb> : Dump name table <nb> to nt.log");
puts("g <nb> : Get sprite <nb> info"); puts("z : Dump mapper status");
break; puts("i : SpriteTable Dump");
puts("g <nb> : Get sprite <nb> info");
case '\0': break;
return (1);
case '\0':
case 'Z': return (1);
showlastop();
break; case 'Z':
mapper_dump(stdout);
case 'W': break;
DumpMemoryState(stdout);
break; case 'W':
DumpMemoryState(stdout);
break;
case 'A':
{
case 'A':
FILE * fpDmpMem; {
if ((fpDmpMem = fopen("memory.log", "wb")) != NULL) FILE * fpDmpMem;
{ if ((fpDmpMem = fopen("memory.log", "wb")) != NULL)
// fwrite(Memory, 1, 0x8000, fpDmpMem); {
//fwrite(mLBank, 1, 0x4000, fpDmpMem);
//fwrite(mUBank, 1, 0x4000, fpDmpMem); // fwrite(Memory, 1, 0x8000, fpDmpMem);
//fwrite(mLBank, 1, 0x4000, fpDmpMem);
fclose(fpDmpMem); //fwrite(mUBank, 1, 0x4000, fpDmpMem);
} fclose(fpDmpMem);
}
break; }
}
break;
case '=':
if (strlen(S) >= 2)
case '=':
{ if (strlen(S) >= 2)
sscanf(S + 1, "%hX", &(R->Trap));
R->Trace = 0; {
return (1); sscanf(S + 1, "%hX", &(R->Trap));
} R->Trace = 0;
break; return (1);
}
case '+': break;
if (strlen(S) >= 2)
case '+':
{ if (strlen(S) >= 2)
sscanf(S + 1, "%hX", &(R->Trap)); {
R->Trap += R->PC.W; sscanf(S + 1, "%hX", &(R->Trap));
R->Trace = 0;
R->Trap += R->PC.W;
return (1); R->Trace = 0;
} return (1);
break;
}
case 'J': break;
if (strlen(S) >= 2)
case 'J':
{ if (strlen(S) >= 2)
sscanf(S + 1, "%hX", &(R->PC.W));
R->Trace = 0; {
return (1); sscanf(S + 1, "%hX", &(R->PC.W));
} R->Trace = 0;
break; return (1);
}
case 'T': break;
if (strlen(S) >= 2)
case 'T':
{ if (strlen(S) >= 2)
sscanf(S + 1, "%hX", &(R->PC.W));
R->Trace = 1; {
} sscanf(S + 1, "%hX", &(R->PC.W));
break; R->Trace = 1;
}
case 'C': break;
R->Trap = 0xFFFF;
R->Trace = 0; case 'C':
install_keyboard(); R->Trap = 0xFFFF;
R->Trace = 0;
//ResumeSound(); install_keyboard();
SetSound(0, SND_RECTANGLE); //ResumeSound();
SetSound(1, SND_RECTANGLE);
SetSound(2, SND_TRIANGLE); SetSound(0, SND_RECTANGLE);
SetSound(3, SND_NOISE); SetSound(1, SND_RECTANGLE);
SetSound(2, SND_TRIANGLE);
return (1); SetSound(3, SND_NOISE);
case 'Q': return (1);
return (0);
case 'Q':
return (0);
case 'V':
puts("\n6502 Interrupt Vectors:");
printf("[$FFFC] INIT: $%04X\n", Rd6502(0xFFFC) + 256 * Rd6502(0xFFFD)); case 'V':
printf("[$FFFE] IRQ: $%04X\n", Rd6502(0xFFFE) + 256 * Rd6502(0xFFFF)); puts("\n6502 Interrupt Vectors:");
printf("[$FFFA] NMI: $%04X\n", Rd6502(0xFFFA) + 256 * Rd6502(0xFFFB)); printf("[$FFFC] INIT: $%04X\n", Rd6502(0xFFFC) + 256 * Rd6502(0xFFFD));
break; printf("[$FFFE] IRQ: $%04X\n", Rd6502(0xFFFE) + 256 * Rd6502(0xFFFF));
printf("[$FFFA] NMI: $%04X\n", Rd6502(0xFFFA) + 256 * Rd6502(0xFFFB));
case 'M': break;
{
word Addr; case 'M':
{
if (strlen(S) > 1) word Addr;
sscanf(S + 1, "%hX", &Addr);
else if (strlen(S) > 1)
Addr = R->PC.W; sscanf(S + 1, "%hX", &Addr);
puts(""); else
for (J = 0; J < 16; J++) Addr = R->PC.W;
{ puts("");
printf("%04X: ", Addr); for (J = 0; J < 16; J++)
for (I = 0; I < 16; I++, Addr++) {
printf("%04X: ", Addr);
printf("%02X ", Rd6502(Addr)); for (I = 0; I < 16; I++, Addr++)
printf(" | "); printf("%02X ", Rd6502(Addr));
Addr -= 16;
printf(" | ");
for (I = 0; I < 16; I++, Addr++) Addr -= 16;
putchar(isprint(Rd6502(Addr)) ? Rd6502(Addr) : '.'); for (I = 0; I < 16; I++, Addr++)
puts(""); putchar(isprint(Rd6502(Addr)) ? Rd6502(Addr) : '.');
} puts("");
}
break; }
}
case 'R': break;
printf case 'R':
(
"A:%02X P:%02X X:%02X Y:%02X S:%04X PC:%04X Flags:[", printf
R->A, R->P, R->X, R->Y, R->S + 0x0100, R->PC.W (
); "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] : '.'); for (J = 0, F = R->P; J < 8; J++, F <<= 1)
puts("]"); printf("%c", F & 0x80 ? FA[J] : '.');
puts("]");
printf
(
"AT PC: [%02X - %s] AT SP: [%02X %02X %02X]\n", printf
Rd6502(R->PC.W), S, (
Rd6502(0x0100 + (byte) (R->S + 1)), "AT PC: [%02X - %s] AT SP: [%02X %02X %02X]\n",
Rd6502(0x0100 + (byte) (R->S + 2)), Rd6502(R->PC.W), S,
Rd6502(0x0100 + (byte) (R->S + 3)) Rd6502(0x0100 + (byte) (R->S + 1)),
); Rd6502(0x0100 + (byte) (R->S + 2)),
Rd6502(0x0100 + (byte) (R->S + 3))
break; );
break;
case 'D':
{ case 'D':
word Addr; {
word Addr;
if (strlen(S) > 1)
sscanf(S + 1, "%hX", &Addr);
else if (strlen(S) > 1)
Addr = R->PC.W; sscanf(S + 1, "%hX", &Addr);
else
puts(""); Addr = R->PC.W;
for (J = 0; J < 16; J++) puts("");
{ for (J = 0; J < 16; J++)
printf("%04X: ", Addr); {
Addr += DAsm(S, Addr); printf("%04X: ", Addr);
puts(S); Addr += DAsm(S, Addr);
} puts(S);
}
break; }
}
} break;
}
}
/* Continue with emulation */ }
return (1);
/* Continue with emulation */
} return (1);
}
#endif /* DEBUG */
#endif /* DEBUG */

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 **/
@ -274,8 +423,29 @@ word Run6502(M6502 *R)
if(R->Trace) if(R->Trace)
if(!Debug6502(R)) return(R->PC.W); if(!Debug6502(R)) return(R->PC.W);
#endif #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]; 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

@ -18,24 +18,24 @@
* $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/Tables.h $ * $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/Tables.h $
* $Revision: 52 $ * $Revision: 52 $
*/ */
static byte Cycles[256] = static byte Cycles[256] =
{ {
7, 6, 2, 1, 5, 3, 5, 5, 3, 2, 2, 1, 6, 4, 6, 2, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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 2, 5, 5, 1, 4, 4, 6, 5, 2, 4, 4, 1, 4, 4, 6, 2
}; };

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,63 +1,65 @@
/* /*
* 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.
* *
* $LastChangedDate: 2007-04-26 18:47:34 +0200 (jeu, 26 avr 2007) $ * $LastChangedDate: 2007-04-26 18:47:34 +0200 (jeu, 26 avr 2007) $
* $Author: mtrapier $ * $Author: mtrapier $
* $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/aorom.h $ * $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/aorom.h $
* $Revision: 46 $ * $Revision: 46 $
* *
*/ */
unsigned char aorom_load_bank; #include "aorom.h"
void aorom_MapperWriteHook(register byte Addr, register byte Value); unsigned char aorom_load_bank;
extern byte *ppu_mem_nameTables; void aorom_MapperWriteHook(register byte Addr, register byte Value);
int aorom_InitMapper(NesCart * cart) extern byte *ppu_mem_nameTables;
{
int i; int aorom_InitMapper(NesCart * cart)
{
set_prom_bank_32k(0x8000,0); int i;
ppu_setScreenMode(PPU_SCMODE_SINGLE); set_prom_bank_32k(0x8000,0);
aorom_load_bank = 0; ppu_setScreenMode(PPU_SCMODE_SINGLE);
/* Register the write hook */ aorom_load_bank = 0;
for (i = 0x80; i < 0x100; i++)
{ /* Register the write hook */
set_page_wr_hook(i, aorom_MapperWriteHook); for (i = 0x80; i < 0x100; i++)
set_page_writeable(i, true); {
} set_page_wr_hook(i, aorom_MapperWriteHook);
set_page_writeable(i, true);
}
return 0;
} return 0;
void aorom_MapperWriteHook(register byte Addr, register byte Value) }
{
int BankNb; void aorom_MapperWriteHook(register byte Addr, register byte Value)
{
if (Value & (1 << 4)) int BankNb;
ppu_setSingleScreen(PPU_SCREEN_000);
else if (Value & (1 << 4))
ppu_setSingleScreen(PPU_SCREEN_400); ppu_setSingleScreen(PPU_SCREEN_000);
else
BankNb = Value & 0x0F; ppu_setSingleScreen(PPU_SCREEN_400);
aorom_load_bank = BankNb; BankNb = Value & 0x0F;
//printf("aorom: Asking bank %d (giving %d & %d) - mirror is %d\n",BankNb,BankNb,(Value<<1)+1,Value&0x0F); aorom_load_bank = BankNb;
set_prom_bank_32k(0x8000,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); void aorom_MapperDump(FILE *fp)
} {
fprintf(fp,"aorom: bank:%d\n",aorom_load_bank);
}

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,125 +1,127 @@
/* /*
* 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.
* *
* $LastChangedDate: 2007-04-16 01:55:35 +0200 (lun, 16 avr 2007) $ * $LastChangedDate: 2007-04-16 01:55:35 +0200 (lun, 16 avr 2007) $
* $Author: godzil $ * $Author: godzil $
* $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/iremh3001.h $ * $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/iremh3001.h $
* $Revision: 39 $ * $Revision: 39 $
* *
*/ */
unsigned short iremh3001_prom_slot[3]; #include "iremh3001.h"
unsigned short iremh3001_vrom_slot[8]; unsigned short iremh3001_prom_slot[3];
int iremh3001_InitMapper(NesCart * cart) unsigned short iremh3001_vrom_slot[8];
{
int iremh3001_InitMapper(NesCart * cart)
set_prom_bank_16k(0x8000, 0); {
set_prom_bank_16k(0xC000, GETLAST16KBANK(cart));
set_prom_bank_16k(0x8000, 0);
iremh3001_prom_slot[0] = 0; set_prom_bank_16k(0xC000, GETLAST16KBANK(cart));
iremh3001_prom_slot[1] = 1;
iremh3001_prom_slot[2] = GETLAST16KBANK(cart); iremh3001_prom_slot[0] = 0;
iremh3001_prom_slot[1] = 1;
set_vrom_bank_8k(0x0000,4); iremh3001_prom_slot[2] = GETLAST16KBANK(cart);
iremh3001_vrom_slot[0] = 0; set_vrom_bank_8k(0x0000,4);
iremh3001_vrom_slot[1] = 0;
iremh3001_vrom_slot[2] = 0; iremh3001_vrom_slot[0] = 0;
iremh3001_vrom_slot[3] = 0; iremh3001_vrom_slot[1] = 0;
iremh3001_vrom_slot[4] = 0; iremh3001_vrom_slot[2] = 0;
iremh3001_vrom_slot[5] = 0; iremh3001_vrom_slot[3] = 0;
iremh3001_vrom_slot[6] = 0; iremh3001_vrom_slot[4] = 0;
iremh3001_vrom_slot[7] = 0; iremh3001_vrom_slot[5] = 0;
iremh3001_vrom_slot[6] = 0;
return 0; iremh3001_vrom_slot[7] = 0;
} return 0;
int iremh3001_MapperWriteHook(register word Addr, register byte Value) }
{
int iremh3001_MapperWriteHook(register byte Addr, register byte Value)
switch(Addr) {
{
case 0x8000: /* Set 8k PROM @ 8000 */ switch(Addr)
printf("iremh3001: %X: change PROM to %d[%X]\n", Addr, Value, Value); {
set_prom_bank_8k(0x8000, Value); case 0x8000: /* Set 8k PROM @ 8000 */
iremh3001_prom_slot[0] = Value; printf("iremh3001: %X: change PROM to %d[%X]\n", Addr, Value, Value);
break; set_prom_bank_8k(0x8000, Value);
iremh3001_prom_slot[0] = Value;
case 0x9003: /* Mirroring ??? */ break;
printf("iremh3001: Mirroring[0x%X:%d] ?\n", Value, Value);
break; case 0x9003: /* Mirroring ??? */
printf("iremh3001: Mirroring[0x%X:%d] ?\n", Value, Value);
case 0x9005: /* IRQ ??? */ break;
printf("iremh3001: IRQ[0x%X:%d] ?\n", Value, Value);
break; case 0x9005: /* IRQ ??? */
printf("iremh3001: IRQ[0x%X:%d] ?\n", Value, Value);
case 0x9006: /* IRQ ??? */ break;
printf("iremh3001: IRQ[0x%X:%d] ?\n", Value, Value);
break; case 0x9006: /* IRQ ??? */
printf("iremh3001: IRQ[0x%X:%d] ?\n", Value, Value);
case 0xA000: /* Set 8k PROM @ A000 */ break;
printf("iremh3001: %X: change PROM to %d[%X]\n", Addr, Value, Value);
set_prom_bank_8k(0xA000, Value); case 0xA000: /* Set 8k PROM @ A000 */
iremh3001_prom_slot[1] = Value; printf("iremh3001: %X: change PROM to %d[%X]\n", Addr, Value, Value);
break; set_prom_bank_8k(0xA000, Value);
iremh3001_prom_slot[1] = Value;
case 0xB000: /* Set 1k VROM @ 0000 */ break;
case 0xB001: /* Set 1k VROM @ 0400 */
case 0xB002: /* Set 1k VROM @ 0800 */ case 0xB000: /* Set 1k VROM @ 0000 */
case 0xB003: /* Set 1k VROM @ 0C00 */ case 0xB001: /* Set 1k VROM @ 0400 */
case 0xB004: /* Set 1k VROM @ 1000 */ case 0xB002: /* Set 1k VROM @ 0800 */
case 0xB005: /* Set 1k VROM @ 1400 */ case 0xB003: /* Set 1k VROM @ 0C00 */
case 0xB006: /* Set 1k VROM @ 1800 */ case 0xB004: /* Set 1k VROM @ 1000 */
case 0xB007: /* Set 1k VROM @ 1C00 */ case 0xB005: /* Set 1k VROM @ 1400 */
printf("iremh3001: %X: change VROM to %d[%X]\n", (Addr&0x0F)<<10, Value, Value); case 0xB006: /* Set 1k VROM @ 1800 */
set_vrom_bank_1k((Addr&0xF)<<10, Value); case 0xB007: /* Set 1k VROM @ 1C00 */
iremh3001_vrom_slot[Addr&0x0F] = Value; printf("iremh3001: %X: change VROM to %d[%X]\n", (Addr&0x0F)<<10, Value, Value);
break; set_vrom_bank_1k((Addr&0xF)<<10, Value);
iremh3001_vrom_slot[Addr&0x0F] = Value;
case 0xC000: /* Set 8k PROM @ C000 */ break;
printf("iremh3001: %X: change PROM to %d[%X]\n", Addr, Value, Value);
set_prom_bank_8k(0xC000, Value); case 0xC000: /* Set 8k PROM @ C000 */
iremh3001_prom_slot[2] = Value; printf("iremh3001: %X: change PROM to %d[%X]\n", Addr, Value, Value);
break; set_prom_bank_8k(0xC000, Value);
iremh3001_prom_slot[2] = Value;
default: break;
printf("@:%X -- V:%X", Addr, Value);
return 0; default:
printf("@:%X -- V:%X", Addr, Value);
} return 0;
return 1; }
}
return 1;
void iremh3001_MapperDump(FILE *fp) }
{
fprintf(fp,"iremh3001: prom: $8000:%d $A000:%d $C000:%d\n", void iremh3001_MapperDump(FILE *fp)
iremh3001_prom_slot[0], {
iremh3001_prom_slot[1], fprintf(fp,"iremh3001: prom: $8000:%d $A000:%d $C000:%d\n",
iremh3001_prom_slot[2]); iremh3001_prom_slot[0],
iremh3001_prom_slot[1],
fprintf(fp,"iremh3001: vrom: $0000:%d $0400:%d $0800:%d $0C00:%d\n" \ iremh3001_prom_slot[2]);
" $1000:%d $1400:%d $1800:%d $1C00:%d\n",
iremh3001_vrom_slot[0], fprintf(fp,"iremh3001: vrom: $0000:%d $0400:%d $0800:%d $0C00:%d\n" \
iremh3001_vrom_slot[1], " $1000:%d $1400:%d $1800:%d $1C00:%d\n",
iremh3001_vrom_slot[2], iremh3001_vrom_slot[0],
iremh3001_vrom_slot[3], iremh3001_vrom_slot[1],
iremh3001_vrom_slot[4], iremh3001_vrom_slot[2],
iremh3001_vrom_slot[5], iremh3001_vrom_slot[3],
iremh3001_vrom_slot[6], iremh3001_vrom_slot[4],
iremh3001_prom_slot[7]); iremh3001_vrom_slot[5],
} iremh3001_vrom_slot[6],
iremh3001_prom_slot[7]);
}
int iremh3001_MapperIRQ(int cycledone)
{
int iremh3001_MapperIRQ(int cycledone)
return 0; {
}
return 0;
}

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 $
* *
*/ */
@ -12,5 +17,4 @@
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

@ -1,23 +1,25 @@
/* /*
* MMC4 Mapper - The TI-NESulator Project * MMC4 Mapper - The TI-NESulator Project
* mmc4.h * mmc4.h
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2007 986Corp. All rights reserved. * Copyright (c) 2007 986Corp. All rights reserved.
* *
* $LastChangedDate: 2007-05-31 18:00:41 +0200 (jeu, 31 mai 2007) $ * $LastChangedDate: 2007-05-31 18:00:41 +0200 (jeu, 31 mai 2007) $
* $Author: mtrapier $ * $Author: mtrapier $
* $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/mmc4.h $ * $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/mmc4.h $
* $Revision: 56 $ * $Revision: 56 $
* *
*/ */
#include "mmc4.h"
byte mmc4_RegA; byte mmc4_RegA;
byte mmc4_RegB; byte mmc4_RegB;
byte mmc4_RegC; byte mmc4_RegC;
byte mmc4_RegD; byte mmc4_RegD;
byte mmc4_RegE; byte mmc4_RegE;
byte mmc4_RegF; byte mmc4_RegF;
#ifdef DEBUG #ifdef DEBUG
#define LOG #define LOG
@ -25,8 +27,8 @@ byte mmc4_RegF;
#else #else
#define LOG #define LOG
#endif #endif
void mmc4_MapperWriteRegA(register byte Addr, register byte Value) void mmc4_MapperWriteRegA(register byte Addr, register byte Value)
{ {
LOG("%s(%02X, %02X)\n", __func__, Addr, 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); ppu_setMirroring(PPU_MIRROR_VERTICAL);
} }
void mmc4_MapperDump(FILE *fp) void mmc4_MapperDump(FILE *fp)
{ {
} }
int mmc4_InitMapper(NesCart * cart) int mmc4_InitMapper(NesCart * cart)
{ {
int i; 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));
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 */
for (i = 0xA0; i < 0xB0 ; i++) /* 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); set_page_wr_hook(i, mmc4_MapperWriteRegA);
} set_page_writeable(i, true);
for (i = 0xB0; i < 0xC0 ; i++) }
{ for (i = 0xB0; i < 0xC0 ; i++)
set_page_wr_hook(i, mmc4_MapperWriteRegB); {
set_page_writeable(i, true); set_page_wr_hook(i, mmc4_MapperWriteRegB);
set_page_writeable(i, true);
} }
for (i = 0xC0; i < 0xD0 ; i++) for (i = 0xC0; i < 0xD0 ; i++)
{ {
set_page_wr_hook(i, mmc4_MapperWriteRegC); set_page_wr_hook(i, mmc4_MapperWriteRegC);
set_page_writeable(i, true); set_page_writeable(i, true);
} }
for (i = 0xD0; i < 0xE0 ; i++) for (i = 0xD0; i < 0xE0 ; i++)
{ {
set_page_wr_hook(i, mmc4_MapperWriteRegD); set_page_wr_hook(i, mmc4_MapperWriteRegD);
set_page_writeable(i, true); set_page_writeable(i, true);
} }
for (i = 0xE0; i < 0xF0 ; i++) for (i = 0xE0; i < 0xF0 ; i++)
{ {
set_page_wr_hook(i, mmc4_MapperWriteRegE); set_page_wr_hook(i, mmc4_MapperWriteRegE);
set_page_writeable(i, true); set_page_writeable(i, true);
} }
for (i = 0xF0; i < 0x100 ; i++) for (i = 0xF0; i < 0x100 ; i++)
{ {
set_page_wr_hook(i, mmc4_MapperWriteRegF); set_page_wr_hook(i, mmc4_MapperWriteRegF);
set_page_writeable(i, true); set_page_writeable(i, true);
} }
for (i = 0x60; i < 0x80 ; i++) for (i = 0x60; i < 0x80 ; i++)
@ -130,8 +133,8 @@ int mmc4_InitMapper(NesCart * cart)
//ppu_setScreenMode(PPU_SCMODE_NORMAL); //ppu_setScreenMode(PPU_SCMODE_NORMAL);
//ppu_setMirroring(PPU_MIRROR_HORIZTAL); //ppu_setMirroring(PPU_MIRROR_HORIZTAL);
return 0; return 0;
} }

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 $
* *
*/ */
@ -12,5 +17,4 @@
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

@ -11,10 +11,12 @@
* $Revision: 39 $ * $Revision: 39 $
* *
*/ */
#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,12 +9,28 @@
/* 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);
ptr ++;
for ( ; i > 1 && ptr->name != NULL; i -- )
{
printf("%d - %s\n", i, ptr->name);
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

@ -1,9 +1,9 @@
/* /*
* PPU emulation - The TI-NESulator Project * PPU emulation - The TI-NESulator Project
* ppu.c * ppu.c
* *
* Define and emulate the PPU (Picture Processing Unit) of the real NES * Define and emulate the PPU (Picture Processing Unit) of the real NES
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2007 986Corp. All rights reserved. * Copyright (c) 2003-2007 986Corp. All rights reserved.
* *
@ -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__
@ -185,43 +187,45 @@ byte ppu_screenMode;
int ppu_init() 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;
/* Set ppu memory parameters */ /* Set ppu memory parameters */
/* First: Allocate each memory zone */ /* First: Allocate each memory zone */
ppu_mem_patternTables = (byte*) malloc(PPU_MEM_PATTERNTABLES_SIZE); ppu_mem_patternTables = (byte*) malloc(PPU_MEM_PATTERNTABLES_SIZE);
if (!ppu_mem_patternTables) if (!ppu_mem_patternTables)
return -1; return -1;
ppu_mem_nameTables = (byte*) malloc(PPU_MEM_NAMETABLE_SIZE); ppu_mem_nameTables = (byte*) malloc(PPU_MEM_NAMETABLE_SIZE);
if (!ppu_mem_nameTables) if (!ppu_mem_nameTables)
return -1; return -1;
ppu_mem_paletteValues = (byte*) malloc(PPU_MEM_PALETTEVALUES_SIZE); ppu_mem_paletteValues = (byte*) malloc(PPU_MEM_PALETTEVALUES_SIZE);
if (!ppu_mem_paletteValues) if (!ppu_mem_paletteValues)
return -1; return -1;
printf("ppu_mem_nameTables :%p\n" printf("ppu_mem_nameTables :%p\n"
"ppu_mem_patternTables:%p\n" "ppu_mem_patternTables:%p\n"
"ppu_mem_paletteValues:%p\n", "ppu_mem_paletteValues:%p\n",
ppu_mem_nameTables, ppu_mem_nameTables,
ppu_mem_patternTables, ppu_mem_patternTables,
ppu_mem_paletteValues); ppu_mem_paletteValues);
/* Second: make the ppu memory manager point on the memory zones */ /* Second: make the ppu memory manager point on the memory zones */
ppu_setPagePtr8k(0x00, ppu_mem_patternTables); ppu_setPagePtr8k(0x00, ppu_mem_patternTables);
ppu_setPagePtr4k(0x20, ppu_mem_nameTables); ppu_setPagePtr4k(0x20, ppu_mem_nameTables);
ppu_setPagePtr (0x3F, ppu_mem_paletteValues); ppu_setPagePtr (0x3F, ppu_mem_paletteValues);
for ( i = 0x00; i < 0x0F; i++ ) for ( i = 0x00; i < 0x0F; i++ )
ppu_setPageGhost(0x30 + i, true, 0x20 + i); ppu_setPageGhost(0x30 + i, true, 0x20 + i);
/* 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 */
@ -230,9 +234,10 @@ int ppu_init()
for (i = 0x0000; i < 0x1000 ; i++) for (i = 0x0000; i < 0x1000 ; i++)
ppu_mem_nameTables[i] = rand()%0xFF; ppu_mem_nameTables[i] = rand()%0xFF;
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);
@ -241,8 +246,8 @@ int ppu_init()
ppu_addrIncrement = 1; ppu_addrIncrement = 1;
ppu_spritePatternTable = 0; ppu_spritePatternTable = 0;
ppu_spriteSize = 8; ppu_spriteSize = 8;
ppu_execNMIonVBlank = 0; ppu_execNMIonVBlank = 0;
ppu_spriteVisibility = 0; ppu_spriteVisibility = 0;
ppu_backgroundVisibility = 0; ppu_backgroundVisibility = 0;
@ -254,29 +259,29 @@ int ppu_init()
ppu_bgColor = 0; ppu_bgColor = 0;
/* Set PPU registers on CPU side */ /* 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_wr_hook(0x20, ppu_writeReg);
set_page_readable(0x20, true); set_page_readable(0x20, true);
set_page_writeable(0x20, true); set_page_writeable(0x20, true);
/* Set PPU Ghost Registers */ /* Set PPU Ghost Registers */
for(i = 0x21; i < 0x40; i++) for(i = 0x21; i < 0x40; i++)
set_page_ghost(i, true, 0x20); set_page_ghost(i, true, 0x20);
// plugin_install_keypressHandler('i', ppu_debugSprites); // plugin_install_keypressHandler('i', ppu_debugSprites);
// plugin_install_keypressHandler('I', ppu_debugSprites); // plugin_install_keypressHandler('I', ppu_debugSprites);
// plugin_install_keypressHandler('u', ppu_debugColor); // plugin_install_keypressHandler('u', ppu_debugColor);
// plugin_install_keypressHandler('U', ppu_debugColor); // plugin_install_keypressHandler('U', ppu_debugColor);
/* allocate the PPU Video memory */ /* allocate the PPU Video memory */
VideoBuffer = create_bitmap(256, 240); VideoBuffer = create_bitmap(256, 240);
if (VideoBuffer == NULL) if (VideoBuffer == NULL)
return -1; return -1;
return 0; return 0;
} }
@ -284,46 +289,45 @@ void ppu_updateSpriteScanlineTable()
{ {
int i, line, j, k; int i, line, j, k;
volatile int sprite_x, sprite_y, sprite_idx, sprite_attr; volatile int sprite_x, sprite_y, sprite_idx, sprite_attr;
int curline; int curline;
for (line = 0; line < 241; line ++) for (line = 0; line < 241; line ++)
{ {
PPU_NbSpriteByScanLine[line] = 0; PPU_NbSpriteByScanLine[line] = 0;
PPU_NbSpriteByScanLineOverFlow[line] = 0; PPU_NbSpriteByScanLineOverFlow[line] = 0;
for (i = 0; i < 9; i++) for (i = 0; i < 9; i++)
PPU_SpriteByScanLine[line][i] = 0xFFFFFFFF; PPU_SpriteByScanLine[line][i] = 0xFFFFFFFF;
} }
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];
/* For each line covered by the sprite */ /* For each line covered by the sprite */
for (line = 0; line < ppu_spriteSize; line ++) for (line = 0; line < ppu_spriteSize; line ++)
{ {
curline = line + sprite_y; curline = line + sprite_y;
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 */
for (j = 0; j <= PPU_NbSpriteByScanLine[curline]; j++) for (j = 0; j <= PPU_NbSpriteByScanLine[curline]; j++)
{ {
/* sprite are ordered by their y value, so, the first time that /* sprite are ordered by their y value, so, the first time that
@ -334,21 +338,21 @@ void ppu_updateSpriteScanlineTable()
if needed the rightest item. */ if needed the rightest item. */
for (k = 7; k >= j; k--) for (k = 7; k >= j; k--)
PPU_SpriteByScanLine[curline][k] = PPU_SpriteByScanLine[curline][k-1]; PPU_SpriteByScanLine[curline][k] = PPU_SpriteByScanLine[curline][k-1];
PPU_SpriteByScanLine[curline][j] = 0; PPU_SpriteByScanLine[curline][j] = 0;
PPU_SCANLINESPRITE_SET_ATTRS (PPU_SpriteByScanLine[curline][j], sprite_attr); PPU_SCANLINESPRITE_SET_ATTRS (PPU_SpriteByScanLine[curline][j], sprite_attr);
//printf("new sprite [%02X:%02X:%02X:%02X] at sl:%d : 0x%08X ", //printf("new sprite [%02X:%02X:%02X:%02X] at sl:%d : 0x%08X ",
//sprite_attr, sprite_idx, curline - sprite_x, sprite_y, //sprite_attr, sprite_idx, curline - sprite_x, sprite_y,
//curline, PPU_SpriteByScanLine[curline][j]); //curline, PPU_SpriteByScanLine[curline][j]);
PPU_SCANLINESPRITE_SET_TILIDX(PPU_SpriteByScanLine[curline][j], sprite_idx); PPU_SCANLINESPRITE_SET_TILIDX(PPU_SpriteByScanLine[curline][j], sprite_idx);
//printf("- 0x%08X ", PPU_SpriteByScanLine[curline][j]); //printf("- 0x%08X ", PPU_SpriteByScanLine[curline][j]);
PPU_SCANLINESPRITE_SET_RELY (PPU_SpriteByScanLine[curline][j], curline - sprite_y); PPU_SCANLINESPRITE_SET_RELY (PPU_SpriteByScanLine[curline][j], curline - sprite_y);
//printf("- 0x%08X ", PPU_SpriteByScanLine[curline][j]); //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]); //printf("- 0x%08X\n", PPU_SpriteByScanLine[curline][j]);
break; /* Stop the for, we don't need to go further in the line list */ 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: default:
direction = PPU_MIRROR_HORIZTAL; direction = PPU_MIRROR_HORIZTAL;
ppu_mirrorMode = direction; ppu_mirrorMode = direction;
case PPU_MIRROR_HORIZTAL: /* Horizontal */ case PPU_MIRROR_HORIZTAL: /* Horizontal */
//printf("Set mirror to Hor\n"); //printf("Set mirror to Hor\n");
ppu_setPagePtr1k(0x20, ppu_mem_nameTables + 0x000); ppu_setPagePtr1k(0x20, ppu_mem_nameTables + 0x000);
@ -396,13 +400,13 @@ void ppu_setSingleScreen(byte screen)
return; return;
if (ppu_singleScreenMode == screen) if (ppu_singleScreenMode == screen)
return; /* Same value, no need to change! */ return; /* Same value, no need to change! */
switch(screen) switch(screen)
{ {
default: default:
screen = PPU_SCREEN_000; screen = PPU_SCREEN_000;
ppu_singleScreenMode = screen; ppu_singleScreenMode = screen;
case PPU_SCREEN_000: /* 0x2000 */ case PPU_SCREEN_000: /* 0x2000 */
//printf("Set screen to 0x000\n"); //printf("Set screen to 0x000\n");
ppu_setPagePtr1k(0x20, ppu_mem_nameTables + 0x000); 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(0x28, ppu_mem_nameTables + 0x000);
ppu_setPagePtr1k(0x2C, ppu_mem_nameTables + 0x000); ppu_setPagePtr1k(0x2C, ppu_mem_nameTables + 0x000);
break; break;
case PPU_SCREEN_400: /* 0x2400 */ case PPU_SCREEN_400: /* 0x2400 */
//printf("Set screen to 0x400\n"); //printf("Set screen to 0x400\n");
ppu_setPagePtr1k(0x20, ppu_mem_nameTables + 0x400); 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(0x28, ppu_mem_nameTables + 0x400);
ppu_setPagePtr1k(0x2C, ppu_mem_nameTables + 0x400); ppu_setPagePtr1k(0x2C, ppu_mem_nameTables + 0x400);
break; break;
case PPU_SCREEN_800: /* 0x2800 */ case PPU_SCREEN_800: /* 0x2800 */
//printf("Set screen to 0x800\n"); //printf("Set screen to 0x800\n");
ppu_setPagePtr1k(0x20, ppu_mem_nameTables + 0x800); 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(0x28, ppu_mem_nameTables + 0x800);
ppu_setPagePtr1k(0x2C, ppu_mem_nameTables + 0x800); ppu_setPagePtr1k(0x2C, ppu_mem_nameTables + 0x800);
break; break;
case PPU_SCREEN_C00: /* 0x2C00 */ case PPU_SCREEN_C00: /* 0x2C00 */
//printf("Set screen to 0xC00\n"); //printf("Set screen to 0xC00\n");
ppu_setPagePtr1k(0x20, ppu_mem_nameTables + 0xC00); ppu_setPagePtr1k(0x20, ppu_mem_nameTables + 0xC00);
@ -458,7 +462,7 @@ void ppu_setScreenMode(byte mode)
default: default:
mode = PPU_SCMODE_NORMAL; mode = PPU_SCMODE_NORMAL;
ppu_screenMode = mode; ppu_screenMode = mode;
case PPU_SCMODE_NORMAL: /* Normal screen (2 NT with mirroring) */ case PPU_SCMODE_NORMAL: /* Normal screen (2 NT with mirroring) */
//printf("Set Normal Screen\n"); //printf("Set Normal Screen\n");
@ -491,7 +495,7 @@ void ppu_updateCounters()
| |+===++=++=++=====++=====+ | | |+===++=++=++=====++=====+ |
+---------------+-----------------------------------------------+ +---------------+-----------------------------------------------+
|2007 access | DC B A 98765 43210 | |2007 access | DC B A 98765 43210 |
+===============+===============================================+ +===============+===============================================+
8421 8421 8421 8421 8421 8421 8421 8421
------------------- -------------------
@ -505,120 +509,218 @@ _AAA BCDD DDDE EEEE
PPU_Reg_Counter |= PPU_Reg_H << 10; PPU_Reg_Counter |= PPU_Reg_H << 10;
PPU_Reg_Counter |= PPU_Reg_VT << 5; PPU_Reg_Counter |= PPU_Reg_VT << 5;
PPU_Reg_Counter |= PPU_Reg_HT; PPU_Reg_Counter |= PPU_Reg_HT;
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 ! */
if (scanline == 0) if (scanline == 0)
{ {
ppu_bgColor = ppu_readMemory(0x3F,00); ppu_bgColor = ppu_readMemory(0x3F,00);
clear_to_color(VideoBuffer, ppu_bgColor); clear_to_color(VideoBuffer, ppu_bgColor);
if ((ppu_spriteVisibility != 0) || (ppu_backgroundVisibility != 0)) if ((ppu_spriteVisibility != 0) || (ppu_backgroundVisibility != 0))
ppu_updateCounters(); ppu_updateCounters();
} }
if (scanline < 240) 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); 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;
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_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 );
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; value = ppu_readMemory((addr >> 8) , addr );
Color &= 0x0F; 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) 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); (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);
} }
} }
/* 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*/ /* Increment only V & VT & FV*/
/* /*
8421 8421 8421 8421 8421 8421 8421 8421
@ -626,7 +728,7 @@ xxxx 1111 1100 1111
1111 1100 0000 0000 1111 1100 0000 0000
5432 1098 7654 3210 5432 1098 7654 3210
_AAA BCDD DDDE EEEE _AAA BCDD DDDE EEEE
xxx x xx xxx : vvtfv = 7BE0 xxx x xx xxx : vvtfv = 7BE0
x x xxxx : hht x x xxxx : hht
@ -640,75 +742,13 @@ D = VT
E = HT 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");
return ppu_execNMIonVBlank; return ppu_execNMIonVBlank;
} }
if (key[KEY_B]) if (key[KEY_B])
{ {
@ -717,26 +757,37 @@ 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_updateCounters(); ppu_scanlineSpriteOverflow = 0;
//ppu_updateCounters();
} }
return 0; return 0;
} }
@ -749,17 +800,17 @@ byte ppu_readReg(byte id)
static byte garbage; static byte garbage;
static byte lastValue; static byte lastValue;
switch(id) switch(id)
{ {
default: default:
garbage = PPU_RegValues[id]; garbage = PPU_RegValues[id];
printf("%s: try to read 0x20%02X\n", __func__, id); printf("%s: try to read 0x20%02X\n", __func__, id);
break; break;
case 0x02: /* PPU Status Register */ case 0x02: /* PPU Status Register */
/* Reset VRam 2005/2006 flipflop */ /* Reset VRam 2005/2006 flipflop */
ppu_VramAccessFlipFlop = 0; ppu_VramAccessFlipFlop = 0;
garbage = 0; garbage = 0;
garbage |= (ppu_inVBlankTime!=0) ?PPU_FLAG_SR_VBLANK:0; garbage |= (ppu_inVBlankTime!=0) ?PPU_FLAG_SR_VBLANK:0;
garbage |= (ppu_spriteZeroHit!=0) ?PPU_FLAG_SR_SPRT0:0; garbage |= (ppu_spriteZeroHit!=0) ?PPU_FLAG_SR_SPRT0:0;
garbage |= (ppu_scanlineSpriteOverflow!=0)?PPU_FLAG_SR_8SPRT:0; garbage |= (ppu_scanlineSpriteOverflow!=0)?PPU_FLAG_SR_8SPRT:0;
@ -769,12 +820,12 @@ byte ppu_readReg(byte id)
ppu_inVBlankTime = 0; ppu_inVBlankTime = 0;
break; break;
case 0x04: /* SPR-RAM I/O */ case 0x04: /* SPR-RAM I/O */
garbage = ppu_mem_spritesTable[ppu_mem_sptrTablePtr]; garbage = ppu_mem_spritesTable[ppu_mem_sptrTablePtr];
break; break;
case 0x07: /* VRAM I/O */ case 0x07: /* VRAM I/O */
if (PPU_Reg_Counter < 0x3F00) if (PPU_Reg_Counter < 0x3F00)
{ {
garbage = lastValue; garbage = lastValue;
@ -786,12 +837,12 @@ byte ppu_readReg(byte id)
lastValue = ppu_readMemory( 0x2F, lastValue = ppu_readMemory( 0x2F,
PPU_Reg_Counter & 0xFF); PPU_Reg_Counter & 0xFF);
garbage = ppu_readMemory( 0x3F, 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); //printf("ppuread %02X return: %02X\n", id, garbage);
return garbage; return garbage;
@ -806,11 +857,11 @@ 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 */
/* /*
+===============+===============================================+ +===============+===============================================+
|2000 | 1 0 4 | |2000 | 1 0 4 |
@ -823,65 +874,64 @@ 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;
PPU_Reg_H = (val & 0x01)?1:0; PPU_Reg_H = (val & 0x01)?1:0;
PPU_Reg_S = (val & 0x10)?0x1000:0x0000; PPU_Reg_S = (val & 0x10)?0x1000:0x0000;
/* Set Other parameters */ /* Set Other parameters */
ppu_addrIncrement = (val & 0x04)?0x20:0x01; ppu_addrIncrement = (val & 0x04)?0x20:0x01;
ppu_spritePatternTable = (val & 0x08)?0x1000:0; ppu_spritePatternTable = (val & 0x08)?0x1000:0;
ppu_spriteSize = (val & 0x20)?16:8; ppu_spriteSize = (val & 0x20)?16:8;
ppu_execNMIonVBlank = (val & 0x80)?1:0; ppu_execNMIonVBlank = (val & 0x80)?1:0;
break; break;
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',
ppu_spriteClipping?'y':'n', ppu_spriteClipping?'y':'n',
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 */
ppu_mem_sptrTablePtr = val; ppu_mem_sptrTablePtr = val;
break; break;
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 */
/* /*
+===============+===============================================+ +===============+===============================================+
|2005/1 | 76543 210 | |2005/1 | 76543 210 |
|2005/2 | 210 76543 | |2005/2 | 210 76543 |
+---------------+-----------------------------------------------+ +---------------+-----------------------------------------------+
| |+===++=++=++=====++=====++===++=++========++==+| | |+===++=++=++=====++=====++===++=++========++==+|
|PPU registers || FV||V||H|| VT|| HT|| FH||S|| PAR||AR|| |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) if (ppu_VramAccessFlipFlop == 0)
{ {
ppu_VramAccessFlipFlop = ~0; ppu_VramAccessFlipFlop = ~0;
PPU_Reg_FH = val & 0x07; PPU_Reg_FH = val & 0x07;
PPU_Reg_HT = (val & 0xF8) >> 3; PPU_Reg_HT = (val & 0xF8) >> 3;
IF_N_KEY IF_N_KEY
@ -901,15 +951,15 @@ void ppu_writeReg(byte id, byte val)
else else
{ {
ppu_VramAccessFlipFlop = 0; ppu_VramAccessFlipFlop = 0;
PPU_Reg_FV = val & 0x07; PPU_Reg_FV = val & 0x07;
PPU_Reg_VT = (val & 0xF8) >> 3; PPU_Reg_VT = (val & 0xF8) >> 3;
IF_N_KEY 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); 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 */ case 0x06: /* 2006 VRAM Register */
/* /*
+===============+===============================================+ +===============+===============================================+
@ -926,10 +976,10 @@ void ppu_writeReg(byte id, byte val)
{ {
ppu_VramAccessFlipFlop = ~0; ppu_VramAccessFlipFlop = ~0;
PPU_Reg_FV = (val >> 4) & 0x03; PPU_Reg_FV = (val >> 4) & 0x03;
PPU_Reg_V = (val >> 3) & 0x01; PPU_Reg_V = (val >> 3) & 0x01;
PPU_Reg_H = (val >> 2) & 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 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); 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_VramAccessFlipFlop = 0;
PPU_Reg_VT = (PPU_Reg_VT & 0x18) | ((val >> 5) & 0x07); PPU_Reg_VT = (PPU_Reg_VT & 0x18) | ((val >> 5) & 0x07);
PPU_Reg_HT = val & 0x1F; PPU_Reg_HT = val & 0x1F;
IF_N_KEY 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); 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; break;
case 0x07: /* VRAM I/O */ case 0x07: /* VRAM I/O */
/* /*
+---------------+-----------------------------------------------+ +---------------+-----------------------------------------------+
@ -956,10 +1006,10 @@ void ppu_writeReg(byte id, byte val)
| |+===++=++=++=====++=====+ | | |+===++=++=++=====++=====+ |
+---------------+-----------------------------------------------+ +---------------+-----------------------------------------------+
|2007 access | DC B A 98765 43210 | |2007 access | DC B A 98765 43210 |
+===============+===============================================+ +===============+===============================================+
*/ */
//if ( (PPU_Reg_Counter&0xFF00) == 0x3F00) //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", // 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_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 IF_N_KEY
{ {
@ -977,10 +1027,10 @@ void ppu_writeReg(byte id, byte val)
ppu_dumpNameTable(256,0); ppu_dumpNameTable(256,0);
blit(Buffer, screen, 0, 0, 0, 0, 512 + 256, 480); blit(Buffer, screen, 0, 0, 0, 0, 512 + 256, 480);
} }
PPU_Reg_Counter += ppu_addrIncrement;
break; PPU_Reg_Counter += ppu_addrIncrement;
break;
} }
} }

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