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 *********************************/
|
||||
/** **/
|
||||
/** SndUnix.c **/
|
||||
/** **/
|
||||
/** This file contains standard sound generation routines **/
|
||||
/** for Unix using /dev/dsp and /dev/audio. **/
|
||||
/** **/
|
||||
/** Copyright (C) Marat Fayzullin 1996-2002 **/
|
||||
/** You are not allowed to distribute this software **/
|
||||
/** commercially. Please, notify me, if you make any **/
|
||||
/** changes to this file. **/
|
||||
/*************************************************************/
|
||||
#include "Sound.h"
|
||||
/*
|
||||
* Allegro Sound Driver for EMULib Sound system - The TI-NESulator Project
|
||||
* SndAlleg.C
|
||||
*
|
||||
* Created by Manoël Trapier
|
||||
* Copyright 2003-2008 986 Corp. All rights reserved.
|
||||
*
|
||||
* $LastChangedDate: 2007-03-28 15:50:50 +0200 (mer, 28 mar 2007) $
|
||||
* $Author: mtrapier $
|
||||
* $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/types.h $
|
||||
* $Revision: 25 $
|
||||
*
|
||||
*/
|
||||
#include <Sound.h>
|
||||
|
||||
#include <allegro.h>
|
||||
|
||||
@ -27,7 +28,6 @@
|
||||
AUDIOSTREAM *stream;
|
||||
|
||||
static pthread_t ThreadID;
|
||||
static int SoundFD;
|
||||
static int SoundRate = 0;
|
||||
static int MasterVolume = 64;
|
||||
static int MasterSwitch = (1<<SND_CHANNELS)-1;
|
||||
@ -41,7 +41,7 @@ static struct
|
||||
int Freq; /* Channel frequency (Hz) */
|
||||
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 Rate; /* Wave playback rate (or 0Hz) */
|
||||
int Pos; /* Wave current position in Data */
|
||||
@ -49,7 +49,7 @@ static struct
|
||||
int Count; /* Phase counter */
|
||||
} 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 UnixDrum(int Type,int Force);
|
||||
static void UnixSetChannels(int Volume,int Switch);
|
||||
@ -89,6 +89,7 @@ static void *DSPLoop(void *Arg)
|
||||
unsigned char *Buf;
|
||||
register int J,I,K,L,M,N,L1,L2,A1,A2,V;
|
||||
int FreqCount;
|
||||
N = L = A2 = 0;
|
||||
|
||||
for(J=0;J<SND_CHANNELS;J++)
|
||||
{
|
||||
@ -262,7 +263,7 @@ static void *DSPLoop(void *Arg)
|
||||
for(I=0;I<SND_BUFSIZE;I++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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 **/
|
||||
/** 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;
|
||||
|
||||
|
||||
@ -835,3 +835,4 @@ case 0x6A:
|
||||
M_ROR(R->A);
|
||||
break; /* ROR a ACC */
|
||||
|
||||
|
||||
|
||||
@ -28,6 +28,8 @@
|
||||
|
||||
#include <ppu/ppu.h>
|
||||
|
||||
#include <mappers/manager.h>
|
||||
#include <memory/manager.h>
|
||||
#include <Sound.h>
|
||||
|
||||
#define RDWORD(A) (Rd6502(A+1)*256+Rd6502(A))
|
||||
@ -38,58 +40,58 @@ void showlastop();
|
||||
|
||||
enum Addressing_Modes
|
||||
{
|
||||
Ac = 0, Il, Im, Ab, Zp, Zx, Zy, Ax, Ay, Rl, Ix, Iy, In, No
|
||||
Ac = 0, Il, Im, Ab, Zp, Zx, Zy, Ax, Ay, Rl, Ix, Iy, In, No
|
||||
};
|
||||
|
||||
|
||||
|
||||
static byte *mn[] =
|
||||
static char *mn[] =
|
||||
{
|
||||
"adc ", "and ", "asl ", "bcc ", "bcs ", "beq ", "bit ", "bmi ",
|
||||
"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"
|
||||
"adc ", "and ", "asl ", "bcc ", "bcs ", "beq ", "bit ", "bmi ",
|
||||
"bne ", "bpl ", "brk", "bvc ", "bvs ", "clc", "cld", "cli",
|
||||
"clv", "cmp ", "cpx ", "cpy ", "dec ", "dex", "dey", "inx",
|
||||
"iny", "eor ", "inc ", "jmp ", "jsr ", "lda ", "nop ", "ldx ",
|
||||
"ldy ", "lsr ", "ora ", "pha", "php", "pla", "plp", "rol ",
|
||||
"ror ", "rti", "rts", "sbc ", "sta ", "stx ", "sty ", "sec ",
|
||||
"sed", "sei", "tax", "tay", "txa", "tya", "tsx", "txs"
|
||||
};
|
||||
|
||||
|
||||
|
||||
static byte ad[512] =
|
||||
{
|
||||
10, Il, 34, Ix, No, No, No, No, No, No, 34, Zp, 2, Zp, No, No,
|
||||
36, Il, 34, Im, 2, Ac, No, No, No, No, 34, Ab, 2, Ab, No, No,
|
||||
9, Rl, 34, Iy, No, No, No, No, No, No, 34, Zx, 2, Zx, No, No,
|
||||
13, Il, 34, Ay, No, No, No, No, No, No, 34, Ax, 2, Ax, No, No,
|
||||
28, Ab, 1, Ix, No, No, No, No, 6, Zp, 1, Zp, 39, Zp, No, No,
|
||||
38, Il, 1, Im, 39, Ac, No, No, 6, Ab, 1, Ab, 39, Ab, No, No,
|
||||
7, Rl, 1, Iy, No, No, No, No, No, No, 1, Zx, 39, Zx, No, No,
|
||||
47, Il, 1, Ay, No, No, No, No, No, No, 1, Ax, 39, Ax, No, No,
|
||||
41, Il, 25, Ix, No, No, No, No, No, No, 25, Zp, 33, Zp, No, No,
|
||||
35, Il, 25, Im, 33, Ac, No, No, 27, Ab, 25, Ab, 33, Ab, No, No,
|
||||
11, Rl, 25, Iy, No, No, No, No, No, No, 25, Zx, 33, Zx, No, No,
|
||||
15, Il, 25, Ay, No, No, No, No, No, No, 25, Ax, 33, Ax, No, No,
|
||||
42, Il, 0, Ix, No, No, No, No, No, No, 0, Zp, 40, Zp, No, No,
|
||||
37, Il, 0, Im, 40, Ac, No, No, 27, In, 0, Ab, 40, Ab, No, No,
|
||||
12, Rl, 0, Iy, No, No, No, No, No, No, 0, Zx, 40, Zx, No, No,
|
||||
49, Il, 0, Ay, No, No, No, No, No, No, 0, Ax, 40, Ax, No, No,
|
||||
No, No, 44, Ix, No, No, No, No, 46, Zp, 44, Zp, 45, Zp, No, No,
|
||||
22, Il, No, No, 52, Il, No, No, 46, Ab, 44, Ab, 45, Ab, No, No,
|
||||
3, Rl, 44, Iy, No, No, No, No, 46, Zx, 44, Zx, 45, Zy, No, No,
|
||||
53, Il, 44, Ay, 55, Il, No, No, No, No, 44, Ax, No, No, No, No,
|
||||
32, Im, 29, Ix, 31, Im, No, No, 32, Zp, 29, Zp, 31, Zp, No, No,
|
||||
51, Il, 29, Im, 50, Il, No, No, 32, Ab, 29, Ab, 31, Ab, No, No,
|
||||
4, Rl, 29, Iy, No, No, No, No, 32, Zx, 29, Zx, 31, Zy, No, No,
|
||||
16, Il, 29, Ay, 54, Il, No, No, 32, Ax, 29, Ax, 31, Ay, No, No,
|
||||
19, Im, 17, Ix, No, No, No, No, 19, Zp, 17, Zp, 20, Zp, No, No,
|
||||
24, Il, 17, Im, 21, Il, No, No, 19, Ab, 17, Ab, 20, Ab, No, No,
|
||||
8, Rl, 17, Iy, No, No, No, No, No, No, 17, Zx, 20, Zx, No, No,
|
||||
14, Il, 17, Ay, No, No, No, No, No, No, 17, Ax, 20, Ax, No, No,
|
||||
18, Im, 43, Ix, No, No, No, No, 18, Zp, 43, Zp, 26, Zp, No, No,
|
||||
23, Il, 43, Im, 30, Il, No, No, 18, Ab, 43, Ab, 26, Ab, No, No,
|
||||
5, Rl, 43, Iy, No, No, No, No, No, No, 43, Zx, 26, Zx, No, No,
|
||||
48, Il, 43, Ay, No, No, No, No, No, No, 43, Ax, 26, Ax, No, No
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
@ -225,8 +227,8 @@ byte Debug6502(M6502 * R)
|
||||
);
|
||||
|
||||
|
||||
sprintf(S, "");
|
||||
remove_keyboard();
|
||||
S[0] = 0;
|
||||
remove_keyboard();
|
||||
|
||||
#ifdef USE_SOUND
|
||||
StopSound();
|
||||
@ -274,7 +276,7 @@ byte Debug6502(M6502 * R)
|
||||
puts("a : Dump all memory to memory.log");
|
||||
puts("s : Dump sprite table to sprite.log");
|
||||
puts("n <nb> : Dump name table <nb> to nt.log");
|
||||
puts("z : Show lastest opcode executed");
|
||||
puts("z : Dump mapper status");
|
||||
puts("i : SpriteTable Dump");
|
||||
puts("g <nb> : Get sprite <nb> info");
|
||||
break;
|
||||
@ -283,7 +285,7 @@ byte Debug6502(M6502 * R)
|
||||
return (1);
|
||||
|
||||
case 'Z':
|
||||
showlastop();
|
||||
mapper_dump(stdout);
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
|
||||
@ -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() ************************************************/
|
||||
/** This function will run 6502 code until Loop6502() call **/
|
||||
@ -275,7 +424,28 @@ word Run6502(M6502 *R)
|
||||
if(!Debug6502(R)) return(R->PC.W);
|
||||
#endif
|
||||
|
||||
I=Op6502(R->PC.W++);
|
||||
#ifdef TRACE_EXECUTION
|
||||
while(1)
|
||||
{
|
||||
|
||||
static char FA[8] = "NV.BDIZC";
|
||||
char S[128];
|
||||
byte F;
|
||||
int J, I;
|
||||
|
||||
DAsm(S, R->PC.W);
|
||||
|
||||
printf
|
||||
(
|
||||
"AT PC: [%02x - %s]\n",
|
||||
Rd6502(R->PC.W), S
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
I=Op6502(R->PC.W++);
|
||||
R->ICount-=Cycles[I];
|
||||
|
||||
//#ifdef DEBUG
|
||||
@ -289,6 +459,34 @@ word Run6502(M6502 *R)
|
||||
#include "Codes.h"
|
||||
}
|
||||
|
||||
#ifdef TRACE_EXECUTION
|
||||
while(1)
|
||||
{
|
||||
static char FA[8] = "NV.BDIZC";
|
||||
char S[128];
|
||||
byte F;
|
||||
int J, I;
|
||||
|
||||
printf
|
||||
(
|
||||
"A:%02x X:%02x Y:%02x S:%04x, PC:%04x Flags:[",
|
||||
R->A, R->X, R->Y, R->S + 0x0100, R->PC.W
|
||||
);
|
||||
|
||||
|
||||
for (J = 0, F = R->P; J < 8; J++, F <<= 1)
|
||||
|
||||
printf("%c", F & 0x80 ? FA[J] : '.');
|
||||
|
||||
printf("], Stack[%02x, %02x, %02x]\n",
|
||||
Rd6502(0x0100 + (byte) (R->S + 1)),
|
||||
Rd6502(0x0100 + (byte) (R->S + 2)),
|
||||
Rd6502(0x0100 + (byte) (R->S + 3)));
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If cycle counter expired... */
|
||||
if(R->ICount<=0)
|
||||
{
|
||||
|
||||
@ -137,7 +137,6 @@ void MIDITicks(int N);
|
||||
/** skip initialization and be silent. Pass Verbose!=0 to **/
|
||||
/** see initialization messages. **/
|
||||
/*************************************************************/
|
||||
#warning You Suck !
|
||||
int InitSound(int Rate,int Verbose);
|
||||
|
||||
/** StopSound() **********************************************/
|
||||
|
||||
@ -27,6 +27,9 @@ typedef void (*MapperDump) ();
|
||||
|
||||
#ifdef __TINES_MAPPERS__
|
||||
|
||||
#include <ppu/ppu.h>
|
||||
#include <memory/manager.h>
|
||||
|
||||
extern NesCart *Cart;
|
||||
|
||||
/* Available functions for mappers */
|
||||
@ -34,9 +37,6 @@ extern NesCart *Cart;
|
||||
#define GETLAST16KBANK(c) ((c->PROMSize>>14)-1)
|
||||
#define GETLAST32KBANK(c) ((c->PROMSize>>15)-1)
|
||||
|
||||
void map_sram(); /* Map SRAM */
|
||||
void unmap_sram(); /* Unmap SRAM */
|
||||
|
||||
void set_vrom_bank_1k(unsigned short addr,int slot);
|
||||
void set_vrom_bank_2k(unsigned short addr,int slot);
|
||||
void set_vrom_bank_4k(unsigned short addr,int slot);
|
||||
@ -57,4 +57,7 @@ extern void (*mapper_dump) (FILE *fp);
|
||||
|
||||
#endif /* __TINES_MAPPERS__ */
|
||||
|
||||
void map_sram(); /* Map SRAM */
|
||||
void unmap_sram(); /* Unmap SRAM */
|
||||
|
||||
#endif
|
||||
|
||||
827
src/main.c
827
src/main.c
File diff suppressed because it is too large
Load Diff
@ -19,7 +19,7 @@ MapperWriteHook mapper_hook;
|
||||
typedef struct Mapper_
|
||||
{
|
||||
byte id;
|
||||
byte *name;
|
||||
char *name;
|
||||
|
||||
MapperInit init;
|
||||
MapperIRQ irq;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* AOROM Mapper - The TI-NESulator Project
|
||||
* aorom.h
|
||||
* aorom.c
|
||||
*
|
||||
* Created by Manoel TRAPIER.
|
||||
* Copyright (c) 2003-2007 986Corp. All rights reserved.
|
||||
@ -12,6 +12,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "aorom.h"
|
||||
|
||||
unsigned char aorom_load_bank;
|
||||
|
||||
void aorom_MapperWriteHook(register byte Addr, register byte Value);
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CNROM Mapper - The TI-NESulator Project
|
||||
* cnrom.h
|
||||
* cnrom.c
|
||||
*
|
||||
* Created by Manoel TRAPIER.
|
||||
* Copyright (c) 2003-2007 986Corp. All rights reserved.
|
||||
@ -12,6 +12,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "cnrom.h"
|
||||
|
||||
unsigned char cnrom_load_bank;
|
||||
|
||||
void cnrom_MapperWriteHook(register byte Addr, register byte Value);
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IREMH3001 Mapper - The TI-NESulator Project
|
||||
* iremh3001.h
|
||||
* iremh3001.c
|
||||
*
|
||||
* Created by Manoel TRAPIER.
|
||||
* Copyright (c) 2003-2007 986Corp. All rights reserved.
|
||||
@ -12,6 +12,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "iremh3001.h"
|
||||
|
||||
unsigned short iremh3001_prom_slot[3];
|
||||
|
||||
unsigned short iremh3001_vrom_slot[8];
|
||||
@ -41,7 +43,7 @@ int iremh3001_InitMapper(NesCart * cart)
|
||||
|
||||
}
|
||||
|
||||
int iremh3001_MapperWriteHook(register word Addr, register byte Value)
|
||||
int iremh3001_MapperWriteHook(register byte Addr, register byte Value)
|
||||
{
|
||||
|
||||
switch(Addr)
|
||||
@ -16,6 +16,5 @@
|
||||
#include <mappers/manager.h>
|
||||
|
||||
int iremh3001_InitMapper(NesCart * cart);
|
||||
int iremh3001_MapperWriteHook(register word Addr, register byte Value);
|
||||
void iremh3001_MapperDump(FILE *fp);
|
||||
int iremh3001_MapperIRQ(int cycledone);
|
||||
@ -14,9 +14,6 @@
|
||||
|
||||
#include "norom.h"
|
||||
|
||||
#include <ppu/ppu.h>
|
||||
#include <memory/manager.h>
|
||||
|
||||
unsigned char MMC1_reg0;
|
||||
|
||||
unsigned char MMC1_reg1;
|
||||
@ -52,7 +49,6 @@ unsigned char mmc1_CurrentBank;
|
||||
#define MMC1_REG2_DEFAULT 0
|
||||
#define MMC1_REG3_DEFAULT 0
|
||||
|
||||
|
||||
void mmc1_MapperWriteReg0(register byte Addr, register byte Value);
|
||||
void mmc1_MapperWriteReg1(register byte Addr, register byte Value);
|
||||
void mmc1_MapperWriteReg2(register byte Addr, register byte Value);
|
||||
|
||||
@ -1,9 +1,14 @@
|
||||
/*
|
||||
* MMC1 Mapper - The TI-NESulator Project
|
||||
* mmc1.h
|
||||
* TI-NESulator.X
|
||||
*
|
||||
* Created by Manoël Trapier on 02/12/07.
|
||||
* Copyright 2007 986 Corp. All rights reserved.
|
||||
* Created by Manoel TRAPIER.
|
||||
* Copyright (c) 2003-2007 986Corp. All rights reserved.
|
||||
*
|
||||
* $LastChangedDate: 2007-05-02 18:37:41 +0200 (mer, 02 mai 2007) $
|
||||
* $Author: mtrapier $
|
||||
* $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/mmc1.h $
|
||||
* $Revision: 50 $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -13,4 +18,3 @@
|
||||
int mmc1_InitMapper (NesCart *cart);
|
||||
int mmc1_MapperIRQ (int cycledone);
|
||||
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 char mmc3_irq_counter;
|
||||
@ -43,8 +47,6 @@ void mmc3_MapperDump(FILE *fp)
|
||||
|
||||
int mmc3_InitMapper(NesCart * cart)
|
||||
{
|
||||
int i;
|
||||
|
||||
set_prom_bank_16k(0x8000, 0);
|
||||
set_prom_bank_16k(0xC000, GETLAST16KBANK(cart));
|
||||
|
||||
@ -75,8 +77,6 @@ int mmc3_InitMapper(NesCart * cart)
|
||||
|
||||
mmc3_first_prom_page = 0x8000;
|
||||
mmc3_second_prom_page = 0xA000;
|
||||
//mmc3_first_prom_page = 0; // Set it to 0x8000
|
||||
|
||||
|
||||
/* Register mapper write hook */
|
||||
set_page_wr_hook(0x80, mmc3_MapperWrite80Hook);
|
||||
@ -92,7 +92,6 @@ int mmc3_InitMapper(NesCart * cart)
|
||||
set_page_writeable(0xE0, true);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void mmc3_MapperWrite80Hook(byte addr, byte Value)
|
||||
@ -250,8 +249,6 @@ void mmc3_MapperWriteA0Hook(byte addr, byte Value)
|
||||
|
||||
}
|
||||
|
||||
extern unsigned short ScanLine;
|
||||
|
||||
void mmc3_MapperWriteC0Hook(byte addr, byte Value)
|
||||
{
|
||||
//printf("%s(0x%02X, 0x%02X)\n", __func__, addr, Value);
|
||||
@ -12,6 +12,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mmc4.h"
|
||||
|
||||
byte mmc4_RegA;
|
||||
byte mmc4_RegB;
|
||||
byte mmc4_RegC;
|
||||
@ -88,7 +90,8 @@ int mmc4_InitMapper(NesCart * cart)
|
||||
set_prom_bank_16k(0x8000,0);
|
||||
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++)
|
||||
@ -1,9 +1,14 @@
|
||||
/*
|
||||
* NOROM Mapper - The TI-NESulator Project
|
||||
* norom.c
|
||||
* TI-NESulator.X
|
||||
*
|
||||
* Created by Manoël Trapier on 25/10/07.
|
||||
* Copyright 2007 986 Corp. All rights reserved.
|
||||
* Created by Manoel TRAPIER.
|
||||
* Copyright (c) 2003-2007 986Corp. All rights reserved.
|
||||
*
|
||||
* $LastChangedDate: 2007-04-16 01:55:35 +0200 (lun, 16 avr 2007) $
|
||||
* $Author: godzil $
|
||||
* $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/unrom.h $
|
||||
* $Revision: 39 $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -11,8 +16,6 @@
|
||||
|
||||
int norom_InitMapper(NesCart *cart)
|
||||
{
|
||||
int i;
|
||||
|
||||
set_page_ptr_16k(0x80, cart->PROMBanks);
|
||||
|
||||
/* mUBank = 0xC000 */
|
||||
|
||||
@ -1,9 +1,14 @@
|
||||
/*
|
||||
* norom.h
|
||||
* TI-NESulator.X
|
||||
* NOROM Mapper - The TI-NESulator Project
|
||||
* norom.c
|
||||
*
|
||||
* Created by Manoël Trapier on 25/10/07.
|
||||
* Copyright 2007 986 Corp. All rights reserved.
|
||||
* Created by Manoel TRAPIER.
|
||||
* Copyright (c) 2003-2007 986Corp. All rights reserved.
|
||||
*
|
||||
* $LastChangedDate: 2007-04-16 01:55:35 +0200 (lun, 16 avr 2007) $
|
||||
* $Author: godzil $
|
||||
* $HeadURL: file:///media/HD6G/SVNROOT/trunk/TI-NESulator/src/unrom.h $
|
||||
* $Revision: 39 $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -13,4 +18,3 @@
|
||||
int norom_InitMapper (NesCart *cart);
|
||||
int norom_MapperIRQ (int cycledone);
|
||||
void norom_MapperDump ();
|
||||
void norom_MapperWriteHook(register byte Addr, register byte Value);
|
||||
@ -12,9 +12,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "unrom.h"
|
||||
|
||||
unsigned char unrom_load_vbank;
|
||||
|
||||
void unrom_MapperWriteHook(register byte Addr, register byte Value);
|
||||
void unrom_MapperWriteHook(byte Addr, byte Value);
|
||||
|
||||
int unrom_InitMapper(NesCart * cart)
|
||||
{
|
||||
@ -39,7 +41,7 @@ int unrom_InitMapper(NesCart * cart)
|
||||
}
|
||||
|
||||
|
||||
void unrom_MapperWriteHook(register byte Addr, register byte Value)
|
||||
void unrom_MapperWriteHook(byte Addr, byte Value)
|
||||
{
|
||||
set_vrom_bank_8k(0x0000,Value);
|
||||
unrom_load_vbank = Value;
|
||||
@ -9,11 +9,27 @@
|
||||
|
||||
/* This file could be generated from the mappers directory... */
|
||||
#include "mappers/norom.h"
|
||||
#include "mappers/aorom.h"
|
||||
#include "mappers/unrom.h"
|
||||
#include "mappers/cnrom.h"
|
||||
|
||||
#include "mappers/iremh3001.h"
|
||||
|
||||
#include "mappers/mmc1.h"
|
||||
#include "mappers/mmc3.h"
|
||||
#include "mappers/mmc4.h"
|
||||
|
||||
Mapper Mappers[] = {
|
||||
{ 0, "No Mapper", norom_InitMapper, norom_MapperIRQ, norom_MapperDump },
|
||||
{ 1, "MMC1", mmc1_InitMapper, norom_MapperIRQ, mmc1_MapperDump },
|
||||
{ 0 , "No Mapper", norom_InitMapper, norom_MapperIRQ, norom_MapperDump },
|
||||
{ 7 , "AOROM", aorom_InitMapper, norom_MapperIRQ, aorom_MapperDump },
|
||||
{ 2 , "CNROM", cnrom_InitMapper, norom_MapperIRQ, cnrom_MapperDump },
|
||||
{ 3 , "UNROM", unrom_InitMapper, norom_MapperIRQ, unrom_MapperDump },
|
||||
|
||||
{ 1 , "MMC1", mmc1_InitMapper, norom_MapperIRQ, mmc1_MapperDump },
|
||||
{ 4 , "MMC3", mmc3_InitMapper, mmc3_MapperIRQ, mmc3_MapperDump },
|
||||
{ 10, "MMC4", mmc3_InitMapper, norom_MapperIRQ, mmc4_MapperDump },
|
||||
|
||||
{ 65, "Irem H3001", iremh3001_InitMapper, iremh3001_MapperIRQ, iremh3001_MapperDump },
|
||||
|
||||
/* EOL tag */
|
||||
{ 0, NULL, NULL, NULL, NULL }
|
||||
|
||||
@ -23,6 +23,10 @@
|
||||
#include <mappers/manager.h>
|
||||
#include <memory/manager.h>
|
||||
|
||||
#define __TINES_PPU_INTERNAL__
|
||||
#include <ppu/ppu.memory.h>
|
||||
#undef __TINES_PPU_INTERNAL__
|
||||
|
||||
extern NesCart *Cart;
|
||||
|
||||
extern char MapperWantIRQ;
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
|
||||
typedef struct Plugin_
|
||||
{
|
||||
byte *name;
|
||||
char *name;
|
||||
|
||||
PluginInit init;
|
||||
PluginDeinit deinit;
|
||||
@ -55,9 +55,15 @@ void plugin_list()
|
||||
int plugin_load(int id)
|
||||
{
|
||||
Plugin *ptr = &(Plugins[0]);
|
||||
int i = id;
|
||||
|
||||
for ( ; id == 0 && ptr != NULL; id -- )
|
||||
printf("%s(%d)", __func__, id);
|
||||
|
||||
for ( ; i > 1 && ptr->name != NULL; i -- )
|
||||
{
|
||||
printf("%d - %s\n", i, ptr->name);
|
||||
ptr ++;
|
||||
}
|
||||
|
||||
if (ptr == NULL)
|
||||
return -1;
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
#define __TINES_PLUGINS__
|
||||
#include <plugins/manager.h>
|
||||
#undef __TINES_PLUGINS_
|
||||
|
||||
#include <memory/manager.h>
|
||||
#include <types.h>
|
||||
@ -53,7 +54,6 @@ byte gg_RdHookPatch##d(byte addr) \
|
||||
}
|
||||
|
||||
#define GG_MAX_PATCH 10
|
||||
|
||||
/* Defines the rdhook patches */
|
||||
GG_RDHOOKPATCH(0)
|
||||
GG_RDHOOKPATCH(1)
|
||||
@ -68,7 +68,7 @@ GG_RDHOOKPATCH(9)
|
||||
|
||||
void gg_SetPatch(int id, byte page, byte addr, byte value)
|
||||
{
|
||||
func_rdhook *fptr;
|
||||
func_rdhook fptr;
|
||||
|
||||
if (id >= GG_MAX_PATCH)
|
||||
return;
|
||||
@ -418,7 +418,7 @@ byte gg_SelectPatch()
|
||||
if (gg_PatchUsed[i] == 0x00)
|
||||
sprintf(tmp, "Patch %d: Not used", i);
|
||||
else
|
||||
sprintf(tmp, "Patch %d: Put 0x%02X on address 0x%02X%02X (Code: %08X)",
|
||||
sprintf(tmp, "Patch %d: Put 0x%02X on address 0x%02X%02X (Code: %08lX)",
|
||||
i, gg_PatchedValue[i], gg_PatchedPage[i], gg_PatchedAddr[i],
|
||||
gg_MakeCode((gg_PatchedPage[i]<<8) | gg_PatchedAddr[i], gg_PatchedValue[i]));
|
||||
|
||||
|
||||
@ -218,7 +218,7 @@ void ppu_dumpOneNameTable(unsigned short nametable, int xd, int yd)
|
||||
|
||||
void ppu_dumpOneAttributeTable(unsigned short nametable, int xd, int yd)
|
||||
{
|
||||
int x, y, x1, y1, Color, AttrByte;
|
||||
int x, x1, y1, Color, AttrByte;
|
||||
for (x = 0; x < 0x40; x++)
|
||||
{
|
||||
AttrByte = PPU_Rd(nametable + 0x23C0 + x);
|
||||
|
||||
330
src/ppu/ppu.c
330
src/ppu/ppu.c
@ -23,6 +23,8 @@
|
||||
#include <ppu/ppu.memory.h>
|
||||
#include <ppu/ppu.debug.h>
|
||||
|
||||
#include <M6502.h>
|
||||
|
||||
#include <memory/manager.h>
|
||||
|
||||
#define __TINES_PLUGINS__
|
||||
@ -186,6 +188,9 @@ int ppu_init()
|
||||
{
|
||||
int i;
|
||||
|
||||
/*byte defaultColors[] = { 0x09,0x01,0x00,0x01,0x00,0x02,0x02,0x0D,0x08,0x10,0x08,0x24,0x00,0x00,0x04,0x2C,
|
||||
0x09,0x01,0x34,0x03,0x00,0x04,0x00,0x14,0x08,0x3A,0x00,0x02,0x00,0x20,0x2C,0x08 };*/
|
||||
|
||||
if (ppu_initMemory())
|
||||
return -1;
|
||||
|
||||
@ -221,7 +226,6 @@ int ppu_init()
|
||||
|
||||
/* Third: set registers to defaults */
|
||||
|
||||
|
||||
/* Now test the memory ! */
|
||||
|
||||
/* Fille PPU memory with garbage */
|
||||
@ -232,6 +236,7 @@ int ppu_init()
|
||||
for (i = 0x0000; i < 0x001F ; i++)
|
||||
ppu_mem_paletteValues[i] = rand()%0xFF;
|
||||
|
||||
//memcpy(ppu_mem_paletteValues, defaultColors, 32);
|
||||
|
||||
/* Dump PPU memory state */
|
||||
//ppu_memoryDumpState(stdout);
|
||||
@ -299,7 +304,7 @@ void ppu_updateSpriteScanlineTable()
|
||||
for ( i = 0; i < 64; i ++)
|
||||
{
|
||||
/* Fill sprite_zzz variables */
|
||||
sprite_y = ppu_mem_spritesTable[(i*4) + 0];
|
||||
sprite_y = ppu_mem_spritesTable[(i*4) + 0] + 1;
|
||||
sprite_idx = ppu_mem_spritesTable[(i*4) + 1];
|
||||
sprite_attr = ppu_mem_spritesTable[(i*4) + 2] | ((i==0)?0x04:0); /* Add a flag for the sprite #0 */
|
||||
sprite_x = ppu_mem_spritesTable[(i*4) + 3];
|
||||
@ -312,15 +317,14 @@ void ppu_updateSpriteScanlineTable()
|
||||
if ((curline < 0) || (curline > 240))
|
||||
continue; /* Don't go beyond, this sprite go beyond the borders */
|
||||
|
||||
if (PPU_NbSpriteByScanLine[curline] < 7)
|
||||
if (PPU_NbSpriteByScanLine[curline] < 8)
|
||||
PPU_NbSpriteByScanLine[curline] ++;
|
||||
else
|
||||
{
|
||||
PPU_NbSpriteByScanLineOverFlow[curline] = 1;
|
||||
//printf("sprite of: %d - %d\n", curline, PPU_NbSpriteByScanLine[curline]);
|
||||
//printf("sprite of: %u - %u\n", curline, PPU_NbSpriteByScanLine[curline]);
|
||||
continue; /* We have 8 sprite in this line, don't continue */
|
||||
}
|
||||
|
||||
if (((sprite_x+8) < 0) && ((sprite_x-8) > 256))
|
||||
continue; /* this sprite isn't either displayable */
|
||||
/* Now test if this sprite can be put in the sprite list */
|
||||
@ -509,15 +513,20 @@ _AAA BCDD DDDE EEEE
|
||||
IF_N_KEY printf("Counter update to %04X\n",PPU_Reg_Counter);
|
||||
}
|
||||
|
||||
extern M6502 MainCPU;
|
||||
|
||||
int ppu_hblank(int scanline)
|
||||
{
|
||||
int i, j;
|
||||
byte pixelColor = 0x42;
|
||||
byte Color = 0x42;
|
||||
byte BgColor = 0x42;
|
||||
byte SpriteColor = 0x42;
|
||||
unsigned short addr;
|
||||
byte value;
|
||||
unsigned short tmp_HHT = 0;
|
||||
unsigned short tmp_VVTFV = 0;
|
||||
unsigned long CurrentSprite;
|
||||
byte SpriteVFlip;
|
||||
|
||||
/* If no plan activated, we have nothing to do ! */
|
||||
|
||||
@ -536,37 +545,12 @@ int ppu_hblank(int scanline)
|
||||
/* For each PPU pixel of this scanline */
|
||||
for (i = 0; i < 256; i ++)
|
||||
{
|
||||
|
||||
/* determine which from sprite bg, bg and sprite fg is in the front */
|
||||
/* Set the current pixel color to the bg color */
|
||||
pixelColor = ppu_readMemory(0x3F,00);
|
||||
|
||||
/* is there sprite(s) on this line ? */
|
||||
|
||||
/* */
|
||||
/* Didn't display sprite for now, juste the BG */
|
||||
|
||||
/* Read NameTable */
|
||||
/* Compute current pixel bg color if bg is visible */
|
||||
if (ppu_backgroundVisibility == 1)
|
||||
{
|
||||
/*
|
||||
xxxx AABB BxxC CCxx
|
||||
xxxx AA11 11BB BCCC
|
||||
*/
|
||||
/*
|
||||
s:32 i:235 cnt:089D addr:0BCF cba:0 addr:0000
|
||||
|
||||
0000 BBBB CCCC FFFF
|
||||
0000 1100 1101 1111
|
||||
|
||||
AABB B C CC
|
||||
|
||||
BA98 7654 3210
|
||||
|
||||
xxxx 1111 1100 1111
|
||||
FFFF CCCC FFFF
|
||||
|
||||
*/
|
||||
|
||||
addr = (PPU_Reg_Counter & 0x0C00);
|
||||
addr = addr | 0x03C0;
|
||||
addr |= (PPU_Reg_Counter >> 4 ) & 0x0038;
|
||||
@ -574,31 +558,27 @@ xxxx 1111 1100 1111
|
||||
|
||||
PPU_Reg_AR = ppu_readMemory(0x20 | ((addr>>8) & 0x0F), addr& 0xFF);
|
||||
|
||||
|
||||
PPU_Reg_AR = PPU_Reg_AR >> (((PPU_Reg_Counter >> 4 ) & 0x04)|((PPU_Reg_Counter ) & 0x02));
|
||||
PPU_Reg_AR = (PPU_Reg_AR<<2) & 0x0C;
|
||||
|
||||
PPU_Reg_PAR = ppu_readMemory(0x20 | ((PPU_Reg_Counter>>8) & 0x0F), PPU_Reg_Counter& 0xFF);
|
||||
/* C BA98 7654 3210 */
|
||||
/* 1 8421 8421 8421 */
|
||||
|
||||
addr = PPU_Reg_S;
|
||||
addr |= ((PPU_Reg_PAR & 0xFF) << 4);
|
||||
addr |= ((PPU_Reg_Counter >> 12) & 0x07);
|
||||
|
||||
value = ppu_readMemory((addr >> 8) , addr );
|
||||
Color = (value & (1 << (7-(i + PPU_Reg_FH) % 8)))?0x01:0;
|
||||
BgColor = (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;
|
||||
BgColor |= (value & (1 << (7-(i + PPU_Reg_FH) % 8)))?0x02:0;
|
||||
|
||||
if (Color > 0x00)
|
||||
if (BgColor > 0x00)
|
||||
{
|
||||
BgColor |= PPU_Reg_AR;
|
||||
BgColor &= 0x0F;
|
||||
|
||||
Color |= PPU_Reg_AR;
|
||||
Color &= 0x0F;
|
||||
|
||||
pixelColor = ppu_readMemory(0x3F, Color);
|
||||
|
||||
pixelColor = ppu_readMemory(0x3F, BgColor);
|
||||
}
|
||||
|
||||
if (((i + PPU_Reg_FH)%8) == 7)
|
||||
@ -607,16 +587,138 @@ xxxx 1111 1100 1111
|
||||
(PPU_Reg_Counter & 0x001F);
|
||||
tmp_HHT = (tmp_HHT + 1) & 0x003F;
|
||||
|
||||
/* Reassemble with HT & H */
|
||||
PPU_Reg_Counter = (PPU_Reg_Counter & 0xFBE0) |
|
||||
((tmp_HHT & 0x0020) << 5) |
|
||||
(tmp_HHT & 0x001F);
|
||||
/* Reassemble with HT & H */
|
||||
PPU_Reg_Counter = (PPU_Reg_Counter & 0xFBE0) |
|
||||
((tmp_HHT & 0x0020) << 5) |
|
||||
(tmp_HHT & 0x001F);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now calculate if there is a sprite here and sprite visibility is on */
|
||||
if ((ppu_spriteVisibility == 1) &&
|
||||
(PPU_NbSpriteByScanLine[scanline] != 0))
|
||||
{
|
||||
/* scan each sprite on this line to find the one (or more) that is on this pixel */
|
||||
for (j = 0; j < PPU_NbSpriteByScanLine[scanline]; j++)
|
||||
{
|
||||
/* they are orderer by X, so if this one is too far on the right
|
||||
it's not need to go further */
|
||||
CurrentSprite = PPU_SpriteByScanLine[scanline][j];
|
||||
|
||||
if (PPU_SCANLINESPRITE_GET_X(CurrentSprite) > i)
|
||||
break; /* break the current for */
|
||||
|
||||
if ((PPU_SCANLINESPRITE_GET_X(CurrentSprite) + 8) < i)
|
||||
continue; /* Not this one too (too far on the left) try next one*/
|
||||
|
||||
/* Ok if we arrive here, the current sprite is on the good position */
|
||||
/* Does the sprite is a BG or FG sprite ? */
|
||||
|
||||
/* Ok we could now get the sprite current pixel color */
|
||||
/* Read sprite scanline pattern */
|
||||
SpriteVFlip = PPU_SCANLINESPRITE_GET_ATTRS(CurrentSprite) & PPU_SPRITE_FLAGS_VFLIP;
|
||||
|
||||
if (ppu_spriteSize == 8)
|
||||
{
|
||||
addr = (PPU_SCANLINESPRITE_GET_TILIDX(CurrentSprite) << 4) + ppu_spritePatternTable;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PPU_SCANLINESPRITE_GET_RELY(CurrentSprite) < 8)
|
||||
addr = (((PPU_SCANLINESPRITE_GET_TILIDX(CurrentSprite)&0xFE) + (SpriteVFlip?1:0)) << 4) + ((PPU_SCANLINESPRITE_GET_TILIDX(CurrentSprite)&0x01)?0x1000:0x0000);
|
||||
else
|
||||
addr = (((PPU_SCANLINESPRITE_GET_TILIDX(CurrentSprite)&0xFE) + (SpriteVFlip?0:1)) << 4) + ((PPU_SCANLINESPRITE_GET_TILIDX(CurrentSprite)&0x01)?0x1000:0x0000);
|
||||
}
|
||||
//printf("sprite addr: %04X\n", addr);
|
||||
if (SpriteVFlip)
|
||||
{
|
||||
addr += 7;
|
||||
addr -= (PPU_SCANLINESPRITE_GET_RELY(CurrentSprite) % 8);
|
||||
}
|
||||
else
|
||||
addr += (PPU_SCANLINESPRITE_GET_RELY(CurrentSprite) % 8);
|
||||
|
||||
|
||||
if (PPU_SCANLINESPRITE_GET_ATTRS(CurrentSprite) & PPU_SPRITE_FLAGS_HFLIP)
|
||||
{
|
||||
value = ppu_readMemory((addr >> 8) , addr );
|
||||
SpriteColor = (value & (1 << (i-PPU_SCANLINESPRITE_GET_X(CurrentSprite))))?0x01:0;
|
||||
|
||||
value = ppu_readMemory((addr >> 8) , addr | 0x08 );
|
||||
SpriteColor |= (value & (1 << (i-PPU_SCANLINESPRITE_GET_X(CurrentSprite))))?0x02:0;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = ppu_readMemory((addr >> 8) , addr );
|
||||
SpriteColor = (value & (1 << (7-(i-PPU_SCANLINESPRITE_GET_X(CurrentSprite)))))?0x01:0;
|
||||
|
||||
value = ppu_readMemory((addr >> 8) , addr | 0x08 );
|
||||
SpriteColor |= (value & (1 << (7-(i-PPU_SCANLINESPRITE_GET_X(CurrentSprite)))))?0x02:0;
|
||||
}
|
||||
|
||||
if (SpriteColor > 0x00)
|
||||
{
|
||||
SpriteColor |= ((PPU_SCANLINESPRITE_GET_ATTRS(CurrentSprite) & PPU_SPRITE_FLAGS_UPPERCOLOR) << 2);
|
||||
SpriteColor &= 0x0F;
|
||||
}
|
||||
|
||||
if ((PPU_SCANLINESPRITE_GET_ATTRS(CurrentSprite) & 0x04) &&
|
||||
(SpriteColor != 0x00) && (BgColor != 0x00))
|
||||
{
|
||||
ppu_spriteZeroHit = 1;
|
||||
}
|
||||
if ( ( (PPU_SCANLINESPRITE_GET_ATTRS(CurrentSprite) & PPU_SPRITE_FLAGS_BGPRIO) && (BgColor == 0x0000)) ||
|
||||
(!(PPU_SCANLINESPRITE_GET_ATTRS(CurrentSprite) & PPU_SPRITE_FLAGS_BGPRIO)) )
|
||||
{
|
||||
if (SpriteColor != 0x00) pixelColor = ppu_readMemory(0x3F, (0x10 + SpriteColor));
|
||||
}
|
||||
}
|
||||
}
|
||||
/* draw the pixel */
|
||||
_putpixel(VideoBuffer, i, scanline, pixelColor);
|
||||
|
||||
|
||||
/* draw the pixel */
|
||||
/*if (ppu_displayType)
|
||||
pixelColor &= 0x30;*/
|
||||
_putpixel(VideoBuffer, i, scanline, pixelColor);
|
||||
}
|
||||
|
||||
if (ppu_backgroundVisibility || ppu_spriteVisibility)
|
||||
if (PPU_NbSpriteByScanLineOverFlow[scanline] == 1)
|
||||
ppu_scanlineSpriteOverflow = 1;
|
||||
|
||||
//blit(VideoBuffer, screen, 0, scanline, 0, scanline, 256, 1);
|
||||
|
||||
|
||||
if (ppu_backgroundVisibility == 1)
|
||||
{
|
||||
|
||||
tmp_VVTFV = ((PPU_Reg_Counter >> 3 ) & 0x0100) | /* V */
|
||||
((PPU_Reg_Counter >> 2 ) & 0x00F8) | /* VT */
|
||||
((PPU_Reg_Counter >> 12) & 0x0007); /* FV */
|
||||
//printf("counter:%04X vvtfv:%04X ", PPU_Reg_Counter, tmp_VVTFV);
|
||||
|
||||
tmp_VVTFV++;
|
||||
//printf("__ vvtfv:0x%04X == 0x%04X ? ", tmp_VVTFV, 30<<3);
|
||||
if ((tmp_VVTFV&0x0F8) == 0xF0)
|
||||
{
|
||||
tmp_VVTFV &= ~0x0F8;
|
||||
tmp_VVTFV ^= 0x100;
|
||||
//printf("YES _");
|
||||
}
|
||||
|
||||
//printf("vvtfv:%04X ", tmp_VVTFV);
|
||||
PPU_Reg_Counter = ( PPU_Reg_Counter & 0x041F) |
|
||||
((tmp_VVTFV & 0x0100 ) << 3 ) | /* V */
|
||||
((tmp_VVTFV & 0x00F8 ) << 2 ) | /* VT */
|
||||
((tmp_VVTFV & 0x0007 ) << 12); /* FV */
|
||||
|
||||
//printf("counter:%04X ", PPU_Reg_Counter);
|
||||
/* Update H & HT */
|
||||
PPU_Reg_Counter = (PPU_Reg_Counter & ~0x041F) |
|
||||
(PPU_Reg_H << 10) |
|
||||
PPU_Reg_HT;
|
||||
}
|
||||
}
|
||||
/* Increment only V & VT & FV*/
|
||||
|
||||
/*
|
||||
@ -641,69 +743,7 @@ E = HT
|
||||
|
||||
|
||||
*/
|
||||
if (ppu_backgroundVisibility == 1)
|
||||
{
|
||||
|
||||
tmp_VVTFV = ((PPU_Reg_Counter >> 3 ) & 0x0100) | /* V */
|
||||
((PPU_Reg_Counter >> 2 ) & 0x00F8) | /* VT */
|
||||
((PPU_Reg_Counter >> 12) & 0x0007); /* FV */
|
||||
//printf("counter:%04X vvtfv:%04X ", PPU_Reg_Counter, tmp_VVTFV);
|
||||
|
||||
tmp_VVTFV++;
|
||||
//printf("__ vvtfv:0x%04X == 0x%04X ? ", tmp_VVTFV, 30<<3);
|
||||
if ((tmp_VVTFV&0x0F8) == 0xF0)
|
||||
{
|
||||
tmp_VVTFV &= ~0x0F8;
|
||||
tmp_VVTFV ^= 0x100;
|
||||
//printf("YES _");
|
||||
}
|
||||
|
||||
//printf("vvtfv:%04X ", tmp_VVTFV);
|
||||
PPU_Reg_Counter = ( PPU_Reg_Counter & 0x041F) |
|
||||
((tmp_VVTFV & 0x0100 ) << 3 ) | /* V */
|
||||
((tmp_VVTFV & 0x00F8 ) << 2 ) | /* VT */
|
||||
((tmp_VVTFV & 0x0007 ) << 12); /* FV */
|
||||
|
||||
//printf("counter:%04X ", PPU_Reg_Counter);
|
||||
/* Update H & HT */
|
||||
PPU_Reg_Counter = (PPU_Reg_Counter & ~0x041F) |
|
||||
(PPU_Reg_H << 10) |
|
||||
PPU_Reg_HT;
|
||||
}
|
||||
|
||||
if (PPU_NbSpriteByScanLine[scanline] != 0)
|
||||
{
|
||||
for (j = 0; j < PPU_NbSpriteByScanLine[scanline]; j++)
|
||||
{
|
||||
static byte i = 0;
|
||||
pixelColor = (i = (i+1)%4) | ((PPU_SCANLINESPRITE_GET_ATTRS(PPU_SpriteByScanLine[scanline][j]) << 2) & 0x0C);
|
||||
|
||||
pixelColor = ppu_readMemory(0x3F, 0x10 + pixelColor);
|
||||
line(VideoBuffer,
|
||||
PPU_SCANLINESPRITE_GET_X(PPU_SpriteByScanLine[scanline][j]),
|
||||
scanline,
|
||||
PPU_SCANLINESPRITE_GET_X(PPU_SpriteByScanLine[scanline][j]) + 8,
|
||||
scanline, pixelColor
|
||||
);
|
||||
|
||||
if (PPU_SCANLINESPRITE_GET_ATTRS(PPU_SpriteByScanLine[scanline][j]) & 0x04)
|
||||
{
|
||||
//printf("Hit!\n");
|
||||
ppu_spriteZeroHit = 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
ppu_scanlineSpriteOverflow = 0;
|
||||
if (PPU_NbSpriteByScanLineOverFlow[scanline] == 1)
|
||||
ppu_scanlineSpriteOverflow = 1;
|
||||
|
||||
}
|
||||
|
||||
/* if (scanline == 100)
|
||||
ppu_spriteZeroHit = 1;*/
|
||||
|
||||
if (scanline == 243)
|
||||
if (scanline == 239)
|
||||
{
|
||||
ppu_inVBlankTime = 1;
|
||||
IF_N_KEY printf("============= enter vblank =================\n");
|
||||
@ -717,25 +757,36 @@ E = HT
|
||||
}
|
||||
|
||||
|
||||
//if (scanline >= (241 + VBLANK_TIME))
|
||||
if (scanline >= 262)
|
||||
if (scanline >= (240 + VBLANK_TIME))
|
||||
{
|
||||
/*for ( i = 0; i < 256; i++)
|
||||
for ( j = 0; j < 256; j++)
|
||||
{
|
||||
int i2 = i<<1, j2 = j<<1;
|
||||
putpixel(Buffer, i2 , j2 , Op6502(i+j*256));
|
||||
putpixel(Buffer, i2 , j2+1, Op6502(i+j*256));
|
||||
putpixel(Buffer, i2+1, j2 , Op6502(i+j*256));
|
||||
// putpixel(Buffer, i2+1, j2+1, Op6502(i+j*256));
|
||||
}*/
|
||||
|
||||
//textprintf(Buffer, font, 5, 340, 4, "(SL:%d) FPS : %d IPS : %d", scanline, FPS, IPS);
|
||||
textprintf(screen, font, 260, 3, 4, "FPS : %d (CPU@~%2.2fMhz : %d%%)", FPS, (float) (((float) IPS) / 1000000.0), (int) ((((float) IPS) / 1770000.0) * 100.0));
|
||||
textprintf(Buffer, font, 260, 3, 4, "FPS : %d (CPU@~%2.2fMhz : %d%%)", FPS, (float) (((float) IPS) / 1000000.0), (int) ((((float) IPS) / 1770000.0) * 100.0));
|
||||
//printf("(SL:%d) FPS : %d IPS : %d\n", scanline, FPS, IPS);
|
||||
|
||||
//ppu_dumpPalette(0, 241);
|
||||
//ppu_dumpPattern(280, 150);
|
||||
//ppu_dumpNameTable(256,0);
|
||||
ppu_dumpPalette(0, 241);
|
||||
ppu_dumpPattern(280, 150);
|
||||
ppu_dumpNameTable(256,0);
|
||||
//ppu_dumpAttributeTable(257, 0);
|
||||
|
||||
//blit(VideoBuffer, Buffer, 0, 0, 0, 0, 256, 240);
|
||||
blit(VideoBuffer, screen, 0, 0, 0, 0, 256, 240);
|
||||
//blit(Buffer, screen, 0, 0, 0, 0, 512 + 256, 480);
|
||||
blit(VideoBuffer, Buffer, 0, 0, 0, 0, 256, 240);
|
||||
blit(Buffer, screen, 0, 0, 0, 0, 512+256, 512);
|
||||
//blit(VideoBuffer, screen, 0, 0, 0, 0, 256, 240);
|
||||
|
||||
|
||||
IF_N_KEY printf("_____________ leave vblank _________________\n");
|
||||
ppu_inVBlankTime = 0;
|
||||
ppu_spriteZeroHit = 0;
|
||||
ppu_scanlineSpriteOverflow = 0;
|
||||
//ppu_updateCounters();
|
||||
}
|
||||
return 0;
|
||||
@ -806,7 +857,7 @@ void ppu_writeReg(byte id, byte val)
|
||||
switch(id)
|
||||
{
|
||||
default:
|
||||
printf("%s: try to write 0x%02X @ 0x20%02X\n", __func__, val, id);
|
||||
//printf("%s: try to write 0x%02X @ 0x20%02X\n", __func__, val, id);
|
||||
break;
|
||||
|
||||
case 0x00: /* PPU Control Register #1 */
|
||||
@ -823,15 +874,15 @@ void ppu_writeReg(byte id, byte val)
|
||||
*/
|
||||
IF_N_KEY
|
||||
printf("%s(%02X, %02X); /* 2000: "
|
||||
"NMI:%c SPRTSIZE:%02d BGTA:%04X[0x%04X] SPTA:%04X INC:%02d NTA:%04X */\n"
|
||||
, __func__, id, val,
|
||||
(val & 0x80)?'E':'D',
|
||||
(val & 0x20)?16:8,
|
||||
(val & 0x10)?0x1000:0x0000, PPU_Reg_S,
|
||||
(val & 0x08)?0x1000:0x0000,
|
||||
(val & 0x04)?32:1,
|
||||
(val & 0x03)<<10|0x2000
|
||||
);
|
||||
"NMI:%c SPRTSIZE:%02d BGTA:%04X[0x%04X] SPTA:%04X INC:%02d NTA:%04X */\n",
|
||||
__func__, id, val,
|
||||
(val & 0x80)?'E':'D',
|
||||
(val & 0x20)?16:8,
|
||||
(val & 0x10)?0x1000:0x0000, PPU_Reg_S,
|
||||
(val & 0x08)?0x1000:0x0000,
|
||||
(val & 0x04)?32:1,
|
||||
(val & 0x03)<<10|0x2000
|
||||
);
|
||||
|
||||
/* Set PPU internal registers */
|
||||
PPU_Reg_V = (val & 0x02)?1:0;
|
||||
@ -848,14 +899,16 @@ void ppu_writeReg(byte id, byte val)
|
||||
case 0x01: /* PPU Control Register #2 */
|
||||
|
||||
ppu_spriteVisibility = (val & 0x10)?1:0;
|
||||
ppu_backgroundVisibility = (val & 0x08)?1:0;
|
||||
ppu_spriteClipping = (val & 0x04)?1:0;
|
||||
ppu_backgroundClipping = (val & 0x02)?1:0;
|
||||
ppu_displayType = (val & 0x01)?1:0;
|
||||
ppu_backgroundVisibility = (val & 0x08)?1:0;
|
||||
ppu_spriteClipping = (val & 0x04)?1:0;
|
||||
ppu_backgroundClipping = (val & 0x02)?1:0;
|
||||
ppu_displayType = (val & 0x01)?1:0;
|
||||
|
||||
ppu_updateSpriteScanlineTable();
|
||||
|
||||
IF_N_KEY
|
||||
printf("%s(%02X, %02X); /* 2001 : "
|
||||
"SprtV:%c BckgV:%c SprtC:%c BckgC:%c DispT:%c"
|
||||
"SprtV:%c BckgV:%c SprtC:%c BckgC:%c DispT:%c"
|
||||
" */\n", __func__, id, val,
|
||||
ppu_spriteVisibility?'y':'n',
|
||||
ppu_backgroundVisibility?'y':'n',
|
||||
@ -863,7 +916,6 @@ void ppu_writeReg(byte id, byte val)
|
||||
ppu_backgroundClipping?'y':'n',
|
||||
ppu_displayType?'m':'c'
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case 0x03: /* SPR-RAM Address Register */
|
||||
@ -872,9 +924,7 @@ void ppu_writeReg(byte id, byte val)
|
||||
|
||||
case 0x04: /* SPR-RAM I/O */
|
||||
ppu_mem_spritesTable[ppu_mem_sptrTablePtr++] = val;
|
||||
|
||||
ppu_updateSpriteScanlineTable();
|
||||
|
||||
break;
|
||||
|
||||
case 0x05: /* 2005 VRAM Register */
|
||||
|
||||
@ -12,15 +12,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PPU_MEMORY_H
|
||||
#define PPU_MEMORY_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define __TINES_PPU_INTERNAL__
|
||||
|
||||
#include <ppu/ppu.h>
|
||||
#include <ppu.h>
|
||||
#include <ppu/ppu.memory.h>
|
||||
|
||||
#include <types.h>
|
||||
@ -39,7 +36,7 @@ byte ppu_SpriteRam[0x100];
|
||||
/*
|
||||
* Memory management functions
|
||||
*
|
||||
* Yes that true, PPU memory & CPU memory work in a nearly same fashion depite
|
||||
* Yes that true, PPU memory & CPU memory work in a nearly same fashion despite
|
||||
* the fact that we actually didn't have any Read/Write hook and ReadWrite
|
||||
* protection. We even didn't need "attributes" for the page. One of the only
|
||||
* need is the "powerful" ghost system
|
||||
@ -159,17 +156,13 @@ void ppu_writeMemory(byte page, byte addr, byte value)
|
||||
/* Here we will cheat with the palette miroring, since we didn't write
|
||||
as often as we read the palette, we will mirror here */
|
||||
//printf("%s palette: color %02X new value : %02d (0x%02X%02X)\n", ((addr&0x10)< 0x10) ? "Bgnd" : "Sprt", addr&0x1F, value & 0x3F, page, addr);
|
||||
if ((addr & 0x10) == 0x00)
|
||||
if ((addr & 0xEF) == 0x00)
|
||||
{
|
||||
ppu_memoryPages[0x3F][addr&0x1F] = value;
|
||||
ppu_memoryPages[0x3F][(addr&0x1F) | 0x10] = value;
|
||||
ppu_memoryPages[0x3F][0x00] = value;
|
||||
ppu_memoryPages[0x3F][0x10] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
ppu_memoryPages[0x3F][addr&0x1F] = value;
|
||||
if (( addr & 0x1F ) == 0x10 )
|
||||
ppu_memoryPages[0x3F][(addr&0x1F) & 0xEF] = value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -177,5 +170,3 @@ void ppu_writeMemory(byte page, byte addr, byte value)
|
||||
ptr[addr] = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user