Small improvements.
This commit is contained in:
parent
3e731a55bf
commit
5dffc23a99
|
@ -9,4 +9,4 @@ env = Environment(ENV = { 'TERM' : environ['TERM'] },
|
|||
LINKFLAGS = flags,
|
||||
LIBS = ['SDL2'])
|
||||
|
||||
env.Program('laines', Glob('src/*.cpp'))
|
||||
env.Program('laines', Glob('src/*.cpp') + Glob('src/*/*.cpp'))
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
namespace Cartridge {
|
||||
|
||||
|
||||
Mapper* mapper;
|
||||
Mapper* mapper; // Mapper chip.
|
||||
|
||||
/* PRG-ROM access */
|
||||
template <bool wr> u8 access(u16 addr, u8 v)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
namespace IO {
|
||||
|
||||
|
||||
// Screen size:
|
||||
const unsigned width = 256;
|
||||
const unsigned height = 240;
|
||||
|
@ -18,6 +19,7 @@ u32 pixels[width * height]; // Video buffer.
|
|||
u8 joypad_bits[2]; // Joypad shift registers.
|
||||
bool strobe; // Joypad strobe latch.
|
||||
|
||||
/* Initialize SDL */
|
||||
void init()
|
||||
{
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
|
@ -37,6 +39,7 @@ void init()
|
|||
signal(SIGINT, SIG_DFL);
|
||||
}
|
||||
|
||||
/* Get the joypad state from SDL */
|
||||
u8 get_joypad_state(int n)
|
||||
{
|
||||
u8 j = 0;
|
||||
|
@ -56,6 +59,7 @@ u8 get_joypad_state(int n)
|
|||
return j;
|
||||
}
|
||||
|
||||
/* Read joypad state (NES register format) */
|
||||
u8 read_joypad(int n)
|
||||
{
|
||||
// When strobe is high, it keeps reading A:
|
||||
|
@ -78,11 +82,13 @@ void write_joypad_strobe(bool v)
|
|||
strobe = v;
|
||||
}
|
||||
|
||||
/* Draw a pixel at the given coordinates */
|
||||
void draw_pixel(unsigned x, unsigned y, u32 rgb)
|
||||
{
|
||||
pixels[y*width + x] = rgb;
|
||||
}
|
||||
|
||||
/* Put the pixels on screen */
|
||||
void flush_screen()
|
||||
{
|
||||
SDL_UpdateTexture(texture, NULL, pixels, width * sizeof(u32));
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
Mapper::Mapper(u8* rom)
|
||||
{
|
||||
// Read infos from header:
|
||||
prgSize = rom[4] * 0x4000;
|
||||
chrSize = rom[5] * 0x2000;
|
||||
prgRamSize = rom[8] ? rom[8] * 0x2000 : 0x2000;
|
||||
|
@ -9,8 +10,10 @@ Mapper::Mapper(u8* rom)
|
|||
this->prg = rom + 16;
|
||||
this->prgRam = new u8[prgRamSize];
|
||||
|
||||
// CHR ROM:
|
||||
if (chrSize)
|
||||
this->chr = rom + 16 + prgSize;
|
||||
// CHR RAM:
|
||||
else
|
||||
{
|
||||
chrSize = 0x2000;
|
||||
|
|
76
src/mappers/mapper1.cpp
Normal file
76
src/mappers/mapper1.cpp
Normal file
|
@ -0,0 +1,76 @@
|
|||
#include "mappers/mapper1.hpp"
|
||||
|
||||
|
||||
/* Apply the registers state */
|
||||
void Mapper1::apply()
|
||||
{
|
||||
// Mirroring.
|
||||
|
||||
// 16KB PRG:
|
||||
if (regs[0] & 0b1000)
|
||||
{
|
||||
// 0x8000 swappable, 0xC000 fixed to bank 0x0F:
|
||||
if (regs[0] & 0b100)
|
||||
{
|
||||
map_prg16k(0, regs[3] & 0xF);
|
||||
map_prg16k(1, 0xF);
|
||||
}
|
||||
// 0x8000 fixed to bank 0x00, 0xC000 swappable:
|
||||
else
|
||||
{
|
||||
map_prg16k(0, 0);
|
||||
map_prg16k(1, regs[3] & 0xF);
|
||||
}
|
||||
}
|
||||
// 32KB PRG:
|
||||
else
|
||||
map_prg32k((regs[3] & 0xF) >> 1);
|
||||
|
||||
// 4KB CHR:
|
||||
if (regs[0] & 0b10000)
|
||||
{
|
||||
map_chr4k(0, regs[1]);
|
||||
map_chr4k(1, regs[2]);
|
||||
}
|
||||
// 8KB CHR:
|
||||
else
|
||||
map_chr8k(regs[1] >> 1);
|
||||
}
|
||||
|
||||
u8 Mapper1::write(u16 addr, u8 v)
|
||||
{
|
||||
// PRG RAM write;
|
||||
if (addr < 0x8000)
|
||||
prgRam[addr - 0x6000] = v;
|
||||
// Mapper register write:
|
||||
else if (addr & 0x8000)
|
||||
{
|
||||
// Reset:
|
||||
if (v & 0x80)
|
||||
{
|
||||
writeN = 0;
|
||||
tmpReg = 0;
|
||||
regs[0] |= 0x0C;
|
||||
apply();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Write a bit into the temporary register:
|
||||
tmpReg = ((v & 1) << 4) | (tmpReg >> 1);
|
||||
// Finished writing all the bits:
|
||||
if (++writeN == 5)
|
||||
{
|
||||
regs[(addr >> 13) & 0b11] = tmpReg;
|
||||
writeN = 0;
|
||||
tmpReg = 0;
|
||||
apply();
|
||||
}
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
u8 Mapper1::chr_write(u16 addr, u8 v)
|
||||
{
|
||||
return chr[addr] = v;
|
||||
}
|
|
@ -4,45 +4,11 @@
|
|||
|
||||
class Mapper1 : public Mapper
|
||||
{
|
||||
private:
|
||||
int writeN;
|
||||
u8 tmpReg;
|
||||
u8 regs[4];
|
||||
|
||||
void apply()
|
||||
{
|
||||
// Mirroring.
|
||||
|
||||
// 16KB PRG:
|
||||
if (regs[0] & 0b1000)
|
||||
{
|
||||
// 0x8000 swappable, 0xC000 fixed to bank 0x0F:
|
||||
if (regs[0] & 0b100)
|
||||
{
|
||||
map_prg16k(0, regs[3] & 0xF);
|
||||
map_prg16k(1, 0xF);
|
||||
}
|
||||
// 0x8000 fixed to bank 0x00, 0xC000 swappable:
|
||||
else
|
||||
{
|
||||
map_prg16k(0, 0);
|
||||
map_prg16k(1, regs[3] & 0xF);
|
||||
}
|
||||
}
|
||||
// 32KB PRG:
|
||||
else
|
||||
map_prg32k((regs[3] & 0xF) >> 1);
|
||||
|
||||
// 4KB CHR:
|
||||
if (regs[0] & 0b10000)
|
||||
{
|
||||
map_chr4k(0, regs[1]);
|
||||
map_chr4k(1, regs[2]);
|
||||
}
|
||||
// 8KB CHR:
|
||||
else
|
||||
map_chr8k(regs[1] >> 1);
|
||||
}
|
||||
void apply();
|
||||
|
||||
public:
|
||||
Mapper1(u8* rom) : Mapper(rom)
|
||||
|
@ -52,38 +18,6 @@ class Mapper1 : public Mapper
|
|||
apply();
|
||||
}
|
||||
|
||||
u8 write(u16 addr, u8 v)
|
||||
{
|
||||
if (addr < 0x8000)
|
||||
{
|
||||
prgRam[addr - 0x6000] = v;
|
||||
}
|
||||
else if (addr & 0x8000)
|
||||
{
|
||||
if (v & 0x80)
|
||||
{
|
||||
writeN = 0;
|
||||
tmpReg = 0;
|
||||
regs[0] |= 0x0C;
|
||||
apply();
|
||||
}
|
||||
else
|
||||
{
|
||||
tmpReg = ((v & 1) << 4) | (tmpReg >> 1);
|
||||
if (++writeN == 5)
|
||||
{
|
||||
regs[(addr >> 13) & 0b11] = tmpReg;
|
||||
writeN = 0;
|
||||
tmpReg = 0;
|
||||
apply();
|
||||
}
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
u8 chr_write(u16 addr, u8 v)
|
||||
{
|
||||
return chr[addr] = v;
|
||||
}
|
||||
u8 write(u16 addr, u8 v);
|
||||
u8 chr_write(u16 addr, u8 v);
|
||||
};
|
||||
|
|
Reference in a new issue