small fixes
This commit is contained in:
@@ -33,9 +33,9 @@ public:
|
|||||||
Byte oam[0xA0]; //Mapped to 0xFE00
|
Byte oam[0xA0]; //Mapped to 0xFE00
|
||||||
Byte notUsable[0x60]; //Mapped to 0xFEA0
|
Byte notUsable[0x60]; //Mapped to 0xFEA0
|
||||||
//General purpose hardware registers
|
//General purpose hardware registers
|
||||||
Byte JOYP;
|
Byte JOYP = 0xCF;
|
||||||
Byte SB;
|
Byte SB;
|
||||||
Byte SC;
|
Byte SC = 0x7E;
|
||||||
Byte DIV;
|
Byte DIV;
|
||||||
//Timer registers
|
//Timer registers
|
||||||
Byte TIMA;
|
Byte TIMA;
|
||||||
@@ -263,8 +263,11 @@ public:
|
|||||||
return (*MBCRead(address));
|
return (*MBCRead(address));
|
||||||
if (address < 0xA000)
|
if (address < 0xA000)
|
||||||
return memoryLayout.vram[address - 0x8000];
|
return memoryLayout.vram[address - 0x8000];
|
||||||
if (address < 0xC000)
|
if (address < 0xC000) {
|
||||||
|
if (externalRamSize == 0)
|
||||||
|
return dummyVal;
|
||||||
return memoryLayout.externalRam[address - 0xA000];
|
return memoryLayout.externalRam[address - 0xA000];
|
||||||
|
}
|
||||||
if (address < 0xD000)
|
if (address < 0xD000)
|
||||||
return memoryLayout.memoryBank1[address - 0xC000];
|
return memoryLayout.memoryBank1[address - 0xC000];
|
||||||
if (address < 0xE000)
|
if (address < 0xE000)
|
||||||
|
|||||||
110
src/gameboy.cpp
110
src/gameboy.cpp
@@ -51,51 +51,113 @@ void GameBoy::start(const std::string& bootrom, const std::string& game) {
|
|||||||
addressSpace.determineMBCInfo();
|
addressSpace.determineMBCInfo();
|
||||||
addressSpace.createRamBank();
|
addressSpace.createRamBank();
|
||||||
|
|
||||||
//init some registers that won't otherwise by set
|
|
||||||
addressSpace.memoryLayout.JOYP = 0xDF;
|
|
||||||
addressSpace.memoryLayout.SC = 0x7E;
|
|
||||||
|
|
||||||
bool quit = false;
|
bool quit = false;
|
||||||
bool setIME = false;
|
bool setIME = false;
|
||||||
bool display = false;
|
bool debug = false;
|
||||||
|
|
||||||
while (!quit) {
|
while (!quit) {
|
||||||
// Event loop
|
// Event loop
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
if (event.type == SDL_QUIT) {
|
switch (event.type) {
|
||||||
|
case SDL_QUIT:
|
||||||
quit = true;
|
quit = true;
|
||||||
}
|
break;
|
||||||
if (event.type == SDL_KEYUP) {
|
case SDL_KEYDOWN:
|
||||||
display = true;
|
switch (event.key.keysym.sym) {
|
||||||
|
case SDLK_a:
|
||||||
|
joypadInput.LEFT = true;
|
||||||
|
break;
|
||||||
|
case SDLK_d:
|
||||||
|
joypadInput.RIGHT = true;
|
||||||
|
break;
|
||||||
|
case SDLK_w:
|
||||||
|
joypadInput.UP = true;
|
||||||
|
break;
|
||||||
|
case SDLK_s:
|
||||||
|
joypadInput.DOWN = true;
|
||||||
|
break;
|
||||||
|
case SDLK_k:
|
||||||
|
joypadInput.A = true;
|
||||||
|
break;
|
||||||
|
case SDLK_l:
|
||||||
|
joypadInput.B = true;
|
||||||
|
break;
|
||||||
|
case SDLK_o:
|
||||||
|
joypadInput.SELECT = true;
|
||||||
|
break;
|
||||||
|
case SDLK_p:
|
||||||
|
joypadInput.START = true;
|
||||||
|
break;
|
||||||
|
case SDLK_h:
|
||||||
|
debug = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDL_KEYUP:
|
||||||
|
switch (event.key.keysym.sym) {
|
||||||
|
case SDLK_a:
|
||||||
|
joypadInput.LEFT = false;
|
||||||
|
break;
|
||||||
|
case SDLK_d:
|
||||||
|
joypadInput.RIGHT = false;
|
||||||
|
break;
|
||||||
|
case SDLK_w:
|
||||||
|
joypadInput.UP = false;
|
||||||
|
break;
|
||||||
|
case SDLK_s:
|
||||||
|
joypadInput.DOWN = false;
|
||||||
|
break;
|
||||||
|
case SDLK_k:
|
||||||
|
joypadInput.A = false;
|
||||||
|
break;
|
||||||
|
case SDLK_l:
|
||||||
|
joypadInput.B = false;
|
||||||
|
break;
|
||||||
|
case SDLK_o:
|
||||||
|
joypadInput.SELECT = false;
|
||||||
|
break;
|
||||||
|
case SDLK_p:
|
||||||
|
joypadInput.START = false;
|
||||||
|
break;
|
||||||
|
case SDLK_h:
|
||||||
|
debug = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!rendered) {
|
while (!rendered) {
|
||||||
|
joypadHandler();
|
||||||
if (PC > 0xFF && addressSpace.getBootromState()) {
|
if (PC > 0xFF && addressSpace.getBootromState()) {
|
||||||
addressSpace.unmapBootrom();
|
addressSpace.unmapBootrom();
|
||||||
}
|
}
|
||||||
ppuEnabled = addressSpace.memoryLayout.LCDC & 0x80;
|
ppuEnabled = addressSpace.memoryLayout.LCDC & 0x80;
|
||||||
prevTMA = addressSpace.memoryLayout.TMA;
|
prevTMA = addressSpace.memoryLayout.TMA;
|
||||||
|
|
||||||
if (PC == 0x100)
|
if (debug) {
|
||||||
display = true;
|
printf(
|
||||||
if (display) {
|
"A: %.2X F: %.2X B: %.2X C: %.2X D: %.2X E: %.2X H: %.2X L: %.2X SP: %.4X PC: 00:%.4X (%.2X %.2X %.2X %.2X)\n",
|
||||||
// printf("A: %.2X F: %.2X B: %.2X C: %.2X D: %.2X E: %.2X H: %.2X L: %.2X SP: %.4X PC: 00:%.4X (%.2X %.2X %.2X %.2X)\n",
|
AF.hi, AF.lo, BC.hi, BC.lo, DE.hi, DE.lo, HL.hi, HL.lo, SP, PC, readOnlyAddressSpace[PC],
|
||||||
// AF.hi, AF.lo, BC.hi, BC.lo, DE.hi, DE.lo, HL.hi, HL.lo, SP, PC, readOnlyAddressSpace[PC],
|
readOnlyAddressSpace[PC + 1], readOnlyAddressSpace[PC + 2], readOnlyAddressSpace[PC + 3]);
|
||||||
// readOnlyAddressSpace[PC + 1], readOnlyAddressSpace[PC + 2], readOnlyAddressSpace[PC + 3]);
|
|
||||||
|
|
||||||
|
|
||||||
// printf("Cycles: %lu, Opcode: 0x%.2x PPU cycles: %lu, PPMode: %d\n", cycles, readOnlyAddressSpace[PC],
|
// printf("Cycles: %lu, Opcode: 0x%.2x PPU cycles: %lu, PPMode: %d\n", cycles, readOnlyAddressSpace[PC],
|
||||||
// cyclesSinceLastScanline(), currentMode);
|
// cyclesSinceLastScanline(), currentMode);
|
||||||
// printf("AF:0x%.4x, BC:0x%.4x\n", AF.reg, BC.reg);
|
// printf("AF:0x%.4x, BC:0x%.4x\n", AF.reg, BC.reg);
|
||||||
// printf("DE:0x%.4x, HL:0x%.4x\n", DE.reg, HL.reg);
|
// printf("DE:0x%.4x, HL:0x%.4x\n", DE.reg, HL.reg);
|
||||||
// printf("IME:%d IF:0x%.2x IE:0x%.2x\n", IME, (*IF), (*IE));
|
// printf("IME:%d IF:0x%.2x IE:0x%.2x\n", IME, (*IF), (*IE));
|
||||||
// printf("PC:0x%.4x, SP:0x%.4x\n", PC, SP);
|
// printf("PC:0x%.4x, SP:0x%.4x\n", PC, SP);
|
||||||
// printf("LCDC:%.2x STAT:0x%.2x LY:%d LYC:%d\n", (*LCDC), (*STAT), (*LY), (*LYC));
|
// printf("LCDC:%.2x STAT:0x%.2x LY:%d LYC:%d\n", (*LCDC), (*STAT), (*LY), (*LYC));
|
||||||
// printf("\n");
|
// printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!halted) {
|
if (!halted) {
|
||||||
opcodeResolver();
|
opcodeResolver();
|
||||||
addressSpace.MBCUpdate();
|
addressSpace.MBCUpdate();
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ class GameBoy {
|
|||||||
const int frameDelay = 1000 / V_SYNC;
|
const int frameDelay = 1000 / V_SYNC;
|
||||||
|
|
||||||
Input joypadInput;
|
Input joypadInput;
|
||||||
|
void joypadHandler();
|
||||||
|
|
||||||
void opcodeResolver();
|
void opcodeResolver();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#include "gameboy.hpp"
|
||||||
|
#include "defines.hpp"
|
||||||
|
|
||||||
|
void GameBoy::joypadHandler() {
|
||||||
|
const Byte joyP = addressSpace.memoryLayout.JOYP;
|
||||||
|
const bool buttons = (joyP & 0x20) == 0;
|
||||||
|
const bool dpad = (joyP & 0x10) == 0;
|
||||||
|
|
||||||
|
addressSpace.memoryLayout.JOYP |= 0xCF;
|
||||||
|
|
||||||
|
if (buttons && !dpad) {
|
||||||
|
if (joypadInput.A)
|
||||||
|
addressSpace.memoryLayout.JOYP &= ~0x1;
|
||||||
|
if (joypadInput.B)
|
||||||
|
addressSpace.memoryLayout.JOYP &= ~0x2;
|
||||||
|
if (joypadInput.SELECT)
|
||||||
|
addressSpace.memoryLayout.JOYP &= ~0x4;
|
||||||
|
if (joypadInput.START)
|
||||||
|
addressSpace.memoryLayout.JOYP &= ~0x8;
|
||||||
|
}
|
||||||
|
if (!buttons && dpad) {
|
||||||
|
if (joypadInput.RIGHT)
|
||||||
|
addressSpace.memoryLayout.JOYP &= ~0x1;
|
||||||
|
if (joypadInput.LEFT)
|
||||||
|
addressSpace.memoryLayout.JOYP &= ~0x2;
|
||||||
|
if (joypadInput.UP)
|
||||||
|
addressSpace.memoryLayout.JOYP &= ~0x4;
|
||||||
|
if (joypadInput.DOWN)
|
||||||
|
addressSpace.memoryLayout.JOYP &= ~0x8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buttons && dpad) {
|
||||||
|
addressSpace.memoryLayout.JOYP |= 0xCF;
|
||||||
|
|
||||||
|
if (joypadInput.RIGHT && joypadInput.A)
|
||||||
|
addressSpace.memoryLayout.JOYP &= ~0x1;
|
||||||
|
if (joypadInput.LEFT && joypadInput.B)
|
||||||
|
addressSpace.memoryLayout.JOYP &= ~0x2;
|
||||||
|
if (joypadInput.UP && joypadInput.SELECT)
|
||||||
|
addressSpace.memoryLayout.JOYP &= ~0x4;
|
||||||
|
if (joypadInput.DOWN && joypadInput.START)
|
||||||
|
addressSpace.memoryLayout.JOYP &= ~0x8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ void runJSONTests(GameBoy* gb);
|
|||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
std::cout << "Usage: " << argv[0] << " <bios> <game>" << std::endl;
|
std::cerr << "Usage: " << argv[0] << " <bios> <game>\n" << std::endl;
|
||||||
return -1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* gb = new GameBoy();
|
auto* gb = new GameBoy();
|
||||||
|
|||||||
13
src/mbc.cpp
13
src/mbc.cpp
@@ -5,7 +5,8 @@ void AddressSpace::determineMBCInfo() {
|
|||||||
romSize = 32768 * (1 << memoryLayout.romBank0[0x147]);
|
romSize = 32768 * (1 << memoryLayout.romBank0[0x147]);
|
||||||
romBanks = 1 << (memoryLayout.romBank0[0x147] + 1);
|
romBanks = 1 << (memoryLayout.romBank0[0x147] + 1);
|
||||||
|
|
||||||
switch (memoryLayout.romBank0[0x0149]) {
|
const Byte ramSize = memoryLayout.romBank0[0x0149];
|
||||||
|
switch (ramSize) {
|
||||||
case 0x02:
|
case 0x02:
|
||||||
externalRamSize = 8196;
|
externalRamSize = 8196;
|
||||||
externalRamBanks = 1;
|
externalRamBanks = 1;
|
||||||
@@ -96,23 +97,19 @@ void AddressSpace::MBCUpdate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AddressSpace::loadRomBank() {
|
void AddressSpace::loadRomBank() {
|
||||||
Byte* old = memoryLayout.romBankSwitch;
|
|
||||||
memoryLayout.romBankSwitch = game.data() + (ROM_BANK_SIZE * selectedRomBank);
|
memoryLayout.romBankSwitch = game.data() + (ROM_BANK_SIZE * selectedRomBank);
|
||||||
if (old != memoryLayout.romBankSwitch)
|
|
||||||
printf("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressSpace::createRamBank() {
|
void AddressSpace::createRamBank() {
|
||||||
if (externalRamSize)
|
if (externalRamSize) {
|
||||||
cartridgeRam = new Byte[externalRamSize];
|
cartridgeRam = new Byte[externalRamSize];
|
||||||
|
memoryLayout.externalRam = cartridgeRam;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressSpace::loadRamBank() {
|
void AddressSpace::loadRamBank() {
|
||||||
Byte* old = memoryLayout.externalRam;
|
|
||||||
if (cartridgeRam != nullptr)
|
if (cartridgeRam != nullptr)
|
||||||
memoryLayout.externalRam = cartridgeRam + (RAM_BANK_SIZE * selectedExternalRamBank);
|
memoryLayout.externalRam = cartridgeRam + (RAM_BANK_SIZE * selectedExternalRamBank);
|
||||||
if (old != memoryLayout.externalRam)
|
|
||||||
printf("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -336,7 +336,7 @@ void GameBoy::drawLine() {
|
|||||||
const uint32_t finalColor = getColourFromPalette(paletteColor);
|
const uint32_t finalColor = getColourFromPalette(paletteColor);
|
||||||
oamPixels[pixel] = finalColor;
|
oamPixels[pixel] = finalColor;
|
||||||
}
|
}
|
||||||
else {
|
else if (oamPixels[pixel] == 0) {
|
||||||
oamPixels[pixel] = currentLinePixels[pixel];
|
oamPixels[pixel] = currentLinePixels[pixel];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user