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:
parent
bc118baac8
commit
5d3895f08a
@ -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;
|
||||||
|
|
||||||
|
|||||||
1671
src/corecpu/Codes.h
1671
src/corecpu/Codes.h
File diff suppressed because it is too large
Load Diff
@ -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 */
|
||||||
|
|||||||
@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -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() **********************************************/
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
937
src/main.c
937
src/main.c
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
@ -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);
|
||||||
@ -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;
|
||||||
|
}
|
||||||
@ -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);
|
||||||
@ -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);
|
||||||
|
|||||||
@ -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);
|
|
||||||
@ -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);
|
||||||
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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 */
|
||||||
|
|||||||
@ -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);
|
|
||||||
@ -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;
|
||||||
@ -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 }
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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]));
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
566
src/ppu/ppu.c
566
src/ppu/ppu.c
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user