added mapper mbc1
This commit is contained in:
parent
e4c68c8b17
commit
e665f7a455
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required (VERSION 3.8)
|
||||
|
||||
add_executable (nesemu "main.c" "bus.c" "cpu.c" "cartridge.c" "opcodes.c" "log.c" "ppu.c" "mappers/mapper000.c" "mapper.c" "controller.c")
|
||||
add_executable (nesemu "main.c" "bus.c" "cpu.c" "cartridge.c" "opcodes.c" "log.c" "ppu.c" "mappers/mapper000.c" "mapper.c" "controller.c" "mappers/mapper001.h" "mappers/mapper001.c")
|
||||
|
||||
target_include_directories(nesemu PUBLIC ${SDL2_INCLUDE_DIRS})
|
||||
target_link_libraries(nesemu PUBLIC ${SDL2_LIBRARIES})
|
||||
|
|
|
@ -34,7 +34,7 @@ struct Bus* createBus(SDL_Renderer* renderer)
|
|||
memset(bus->ram, 0x00, 0x18);
|
||||
|
||||
// Create and insert cartridge
|
||||
bus->cartridge = createCartridge(bus, "roms/donkeykong.nes");
|
||||
bus->cartridge = createCartridge(bus, "roms/nestest.nes");
|
||||
|
||||
// Create CPU and attach it
|
||||
bus->cpu = createCPU(bus);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "mappers/mapper000.h"
|
||||
#include "mappers/mapper001.h"
|
||||
|
||||
struct Mapper* createMapper(Byte id, Byte prg_rom_size, Byte chr_rom_size, FILE* fp)
|
||||
{
|
||||
|
@ -30,6 +31,18 @@ struct Mapper* createMapper(Byte id, Byte prg_rom_size, Byte chr_rom_size, FILE*
|
|||
mapper->get_pattern_table_texture = &Mapper000_GetPatternTableTexture;
|
||||
} break;
|
||||
|
||||
case 1:
|
||||
{
|
||||
struct Mapper001* mp = createMapper001(prg_rom_size, chr_rom_size, fp);
|
||||
mapper->mapperStruct = (void*)mp;
|
||||
|
||||
mapper->read_cpu = &Mapper001_ReadCPU;
|
||||
mapper->read_ppu = &Mapper001_ReadPPU;
|
||||
mapper->write_cpu = &Mapper001_WriteCPU;
|
||||
mapper->write_ppu = &Mapper001_WritePPU;
|
||||
mapper->get_pattern_table_texture = &Mapper001_GetPatternTableTexture;
|
||||
} break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Mapper with ID %d is not implemented\n", id);
|
||||
exit(-1);
|
||||
|
|
175
NES Emulator/mappers/mapper001.c
Normal file
175
NES Emulator/mappers/mapper001.c
Normal file
|
@ -0,0 +1,175 @@
|
|||
#include "mapper001.h"
|
||||
|
||||
struct Mapper001* createMapper001(Byte prg_rom_size, Byte chr_rom_size, FILE* fp)
|
||||
{
|
||||
struct Mapper001* mapper = (struct Mapper001*)malloc(sizeof(struct Mapper001));
|
||||
if (mapper == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to create Mapper 000. Aborting\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
mapper->prg_rom_size = prg_rom_size;
|
||||
mapper->prg_rom = (Byte*)calloc(prg_rom_size, 0x4000);
|
||||
if (mapper->prg_rom == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to allocate cartridge PRG ROM. Aborting\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
mapper->chr_rom_size = chr_rom_size;
|
||||
mapper->chr_rom = (Byte*)calloc(chr_rom_size, 0x2000);
|
||||
if (mapper->chr_rom == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to allocate cartridge CHR ROM. Aborting\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
fread(mapper->prg_rom, 0x4000, prg_rom_size, fp);
|
||||
fread(mapper->chr_rom, 0x2000, chr_rom_size, fp);
|
||||
|
||||
mapper->lowerChrBank = mapper->chr_rom;
|
||||
mapper->upperChrBank = mapper->chr_rom + 0x1000;
|
||||
mapper->lowerPrgBank = mapper->prg_rom;
|
||||
mapper->upperPrgBank = mapper->prg_rom + 0x4000;
|
||||
|
||||
return mapper;
|
||||
}
|
||||
|
||||
void destroyMapper001(struct Mapper001* mapper)
|
||||
{
|
||||
free(mapper->chr_rom);
|
||||
free(mapper->prg_rom);
|
||||
|
||||
free(mapper);
|
||||
}
|
||||
|
||||
Byte Mapper001_ReadCPU(void* mapper, Word address)
|
||||
{
|
||||
struct Mapper001* sMapper = (struct Mapper000*)mapper;
|
||||
Byte val = 0x00;
|
||||
|
||||
if (address >= 0x6000 && address < 0x8000)
|
||||
{
|
||||
fprintf(stderr, "This Mapper 000 implementation doesnt support FamilyBasic PRG RAM\n");
|
||||
exit(-1);
|
||||
}
|
||||
else if (address >= 0x8000 && address <= 0xBFFF)
|
||||
{
|
||||
val = sMapper->lowerPrgBank[address & 0x3FFF];
|
||||
}
|
||||
else if (address >= 0xC000 && address <= 0xFFFF)
|
||||
{
|
||||
val = sMapper->upperPrgBank[address & 0x3FFF];
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Cartridge read access violation by the CPU at $%04X\n", address);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
Byte Mapper001_ReadPPU(void* mapper, Word address)
|
||||
{
|
||||
struct Mapper001* sMapper = (struct Mapper000*)mapper;
|
||||
Byte val = 0x00;
|
||||
|
||||
if (address >= 0x2000)
|
||||
{
|
||||
fprintf(stderr, "Cartridge read access violation by the PPU at $%04X\n", address);
|
||||
exit(-1);
|
||||
}
|
||||
else if (address < 0x1000 + 0x1000 * (1 - sMapper->control.chr_bank_mode))
|
||||
{
|
||||
val = sMapper->lowerChrBank[address];
|
||||
}
|
||||
else
|
||||
{
|
||||
val = sMapper->upperChrBank[address & 0x0FFF];
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void Mapper001_WriteCPU(void* mapper, Word address, Byte value)
|
||||
{
|
||||
struct Mapper001* sMapper = (struct Mapper000*)mapper;
|
||||
if ((value & 0x80) == 0x80)
|
||||
{
|
||||
sMapper->shiftRegister = 0x10;
|
||||
sMapper->control.raw |= 0x0C;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((sMapper->shiftRegister & 0x1) != 0x1)
|
||||
{
|
||||
sMapper->shiftRegister >>= 1;
|
||||
sMapper->shiftRegister |= ((value & 0x1) << 4);
|
||||
return;
|
||||
}
|
||||
|
||||
Byte valueToBeWritten = (sMapper->shiftRegister >> 1) | ((value & 0x1) << 4);
|
||||
if (address >= 0x8000 && address <= 0x9FFF)
|
||||
{
|
||||
sMapper->control.raw = valueToBeWritten;
|
||||
}
|
||||
else if (address >= 0xA000 && address <= 0xBFFF)
|
||||
{
|
||||
if (sMapper->control.chr_bank_mode == 0x00) // 8KB mode
|
||||
valueToBeWritten &= ~(0x1); // clear last bit
|
||||
|
||||
sMapper->lowerChrBank = sMapper->chr_rom + (size_t)valueToBeWritten * 0x1000;
|
||||
}
|
||||
else if (address >= 0xC000 && address <= 0xDFFF)
|
||||
{
|
||||
if (sMapper->control.chr_bank_mode == 0x00) // 8KB mode
|
||||
{
|
||||
return; // ignore
|
||||
}
|
||||
|
||||
sMapper->upperChrBank = sMapper->chr_rom + (size_t)valueToBeWritten * 0x1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (sMapper->control.prg_bank_mode)
|
||||
{
|
||||
case 0: // 32KB mode
|
||||
case 1:
|
||||
valueToBeWritten &= ~(0x1);
|
||||
sMapper->lowerPrgBank = sMapper->prg_rom + ((size_t)valueToBeWritten & 0xE) * 0x8000;
|
||||
sMapper->upperPrgBank = sMapper->lowerPrgBank + 0x4000;
|
||||
break;
|
||||
|
||||
case 2: // fix first bank, switch second
|
||||
sMapper->lowerPrgBank = sMapper->prg_rom;
|
||||
sMapper->upperPrgBank = sMapper->prg_rom + ((size_t)valueToBeWritten & 0xE) * 0x4000;
|
||||
break;
|
||||
|
||||
case 3: // fix last bank, switch first
|
||||
sMapper->lowerPrgBank = sMapper->prg_rom + ((size_t)valueToBeWritten & 0xE) * 0x4000;
|
||||
sMapper->upperPrgBank = sMapper->prg_rom + ((size_t)sMapper->prg_rom_size - 1) * 0x4000;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Mapper001_WritePPU(void* mapper, Word address, Byte value)
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
|
||||
void Mapper001_GetPatternTableTexture(void* mapper, SDL_Texture* texture, int index)
|
||||
{
|
||||
struct Mapper001* sMapper = (struct Mapper001*)mapper;
|
||||
Byte* selectedBank = ((index == 0) ? sMapper->lowerChrBank : sMapper->upperChrBank);
|
||||
|
||||
int pitch;
|
||||
void* pixels;
|
||||
SDL_LockTexture(texture, NULL, &pixels, &pitch);
|
||||
SDL_memcpy(pixels, selectedBank, 0x1000);
|
||||
SDL_UnlockTexture(texture);
|
||||
}
|
50
NES Emulator/mappers/mapper001.h
Normal file
50
NES Emulator/mappers/mapper001.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
#ifndef _MAPPER_001_
|
||||
#define _MAPPER_001_
|
||||
|
||||
#include <stdio.h>
|
||||
#include "../types.h"
|
||||
#include "SDL.h"
|
||||
|
||||
struct Mapper001
|
||||
{
|
||||
Byte prg_rom_size;
|
||||
Byte chr_rom_size;
|
||||
|
||||
Byte* prg_rom;
|
||||
Byte* chr_rom;
|
||||
|
||||
///////////////////////////
|
||||
/// REGISTERS ///
|
||||
///////////////////////////
|
||||
Byte shiftRegister;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
Byte mirroring : 2;
|
||||
Byte prg_bank_mode : 2;
|
||||
Byte chr_bank_mode : 1;
|
||||
Byte padding : 3;
|
||||
};
|
||||
|
||||
Byte raw;
|
||||
} control;
|
||||
|
||||
Byte* lowerChrBank;
|
||||
Byte* upperChrBank;
|
||||
Byte* lowerPrgBank;
|
||||
Byte* upperPrgBank;
|
||||
};
|
||||
|
||||
struct Mapper001* createMapper001(Byte prg_rom_size, Byte chr_rom_size, FILE* fp);
|
||||
void destroyMapper001(struct Mapper001* mapper);
|
||||
|
||||
Byte Mapper001_ReadCPU(void* mapper, Word address);
|
||||
Byte Mapper001_ReadPPU(void* mapper, Word address);
|
||||
void Mapper001_WriteCPU(void* mapper, Word address, Byte value);
|
||||
void Mapper001_WritePPU(void* mapper, Word address, Byte value);
|
||||
|
||||
void Mapper001_GetPatternTableTexture(void* mapper, SDL_Texture* texture, int index);
|
||||
|
||||
#endif // _MAPPER_001_
|
BIN
roms/coredump.nes
Normal file
BIN
roms/coredump.nes
Normal file
Binary file not shown.
Loading…
Reference in a new issue