First stab at associating the "Display" class more closely with the Bus.

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2017-10-04 15:37:11 +01:00
parent 2b5324cb43
commit 9796f9d600
5 changed files with 32 additions and 30 deletions

View File

@ -5,18 +5,18 @@
namespace EightBit {
class Bus;
class Ram;
namespace GameBoy {
class CharacterDefinition {
public:
CharacterDefinition();
CharacterDefinition(EightBit::Bus* bus, uint16_t address, int height);
CharacterDefinition(Ram* ram, uint16_t address, int height);
std::array<int, 8> get(int row) const;
private:
EightBit::Bus* m_bus;
Ram* m_ram;
uint16_t m_address;
int m_height;
};

View File

@ -124,6 +124,9 @@ namespace EightBit {
Signal<int> DisplayStatusModeUpdated;
Ram& VRAM() { return m_videoRam; }
Ram& OAMRAM() { return m_oamRam; }
void reset();
void triggerInterrupt(int cause) {
@ -200,7 +203,7 @@ namespace EightBit {
void transferDma() {
if (m_dmaTransferActive) {
m_oamRam.poke(m_dmaAddress.low, peek(m_dmaAddress.word));
OAMRAM().poke(m_dmaAddress.low, peek(m_dmaAddress.word));
m_dmaTransferActive = ++m_dmaAddress.low < 0xa0;
}
}
@ -263,7 +266,7 @@ namespace EightBit {
rom = false;
if (address < 0xa000)
return m_videoRam.reference(address - 0x8000);
return VRAM().reference(address - 0x8000);
if (address < 0xc000)
return m_ramBanks.size() == 0 ? rom = true, placeDATA(0xff) : m_ramBanks[m_ramBank].reference(address - 0xa000);
if (address < 0xe000)
@ -271,7 +274,7 @@ namespace EightBit {
if (address < 0xfe00)
return m_lowInternalRam.reference(address - 0xe000); // Low internal RAM mirror
if (address < 0xfea0)
return m_oamRam.reference(address - 0xfe00);
return OAMRAM().reference(address - 0xfe00);
if (address < 0xff00)
return rom = true, placeDATA(0xff);
if (address < 0xff80)

View File

@ -2,7 +2,7 @@
#include <cstdint>
#include <Bus.h>
#include <Ram.h>
#include <Processor.h>
namespace EightBit {
@ -10,13 +10,13 @@ namespace EightBit {
class ObjectAttribute {
public:
ObjectAttribute() {}
ObjectAttribute(Bus& bus, uint16_t address, int height) {
m_positionY = bus.peek(address);
m_positionX = bus.peek(address + 1);
m_pattern = bus.peek(address + 2);
ObjectAttribute(Ram& ram, uint16_t address, int height) {
m_positionY = ram.peek(address);
m_positionX = ram.peek(address + 1);
m_pattern = ram.peek(address + 2);
if (height == 16)
m_pattern >>= 1;
m_flags = bus.peek(address + 3);
m_flags = ram.peek(address + 3);
}
uint8_t positionY() const { return m_positionY; }

View File

@ -1,16 +1,16 @@
#include "stdafx.h"
#include "CharacterDefinition.h"
#include <Bus.h>
#include <Ram.h>
EightBit::GameBoy::CharacterDefinition::CharacterDefinition()
: m_bus(nullptr),
: m_ram(nullptr),
m_address(~0),
m_height(0) {
}
EightBit::GameBoy::CharacterDefinition::CharacterDefinition(EightBit::Bus* bus, uint16_t address, int height)
: m_bus(bus),
EightBit::GameBoy::CharacterDefinition::CharacterDefinition(Ram* ram, uint16_t address, int height)
: m_ram(ram),
m_address(address),
m_height(height) {
}
@ -21,8 +21,8 @@ std::array<int, 8> EightBit::GameBoy::CharacterDefinition::get(int row) const {
auto planeAddress = m_address + row * 2;
auto planeLow = m_bus->peek(planeAddress);
auto planeHigh = m_bus->peek(planeAddress + 1);
auto planeLow = m_ram->peek(planeAddress);
auto planeHigh = m_ram->peek(planeAddress + 1);
for (int bit = 0; bit < 8; ++bit) {

View File

@ -50,13 +50,10 @@ void EightBit::GameBoy::Display::renderObjects() {
}
void EightBit::GameBoy::Display::loadObjectAttributes() {
const auto oamAddress = 0xfe00;
const auto objBlockHeight = (m_control & Bus::ObjectBlockCompositionSelection) ? 16 : 8;
auto& oam = m_bus.OAMRAM();
for (int i = 0; i < 40; ++i) {
m_objectAttributes[i] = ObjectAttribute(m_bus, oamAddress + 4 * i, objBlockHeight);
m_objectAttributes[i] = ObjectAttribute(oam, 4 * i, objBlockHeight);
}
}
@ -66,13 +63,12 @@ void EightBit::GameBoy::Display::renderObjects(int objBlockHeight) {
palettes[0] = createPalette(Bus::OBP0);
palettes[1] = createPalette(Bus::OBP1);
const auto objDefinitionAddress = 0x8000;
auto& vram = m_bus.VRAM();
for (int i = 0; i < 40; ++i) {
const auto& current = m_objectAttributes[i];
const auto sprite = current.pattern();
const auto spriteY = current.positionY();
const auto drawY = spriteY - 16;
@ -81,7 +77,8 @@ void EightBit::GameBoy::Display::renderObjects(int objBlockHeight) {
const auto spriteX = current.positionX();
const auto drawX = spriteX - 8;
const auto definition = CharacterDefinition(&m_bus, objDefinitionAddress + 16 * sprite, objBlockHeight);
const auto sprite = current.pattern();
const auto definition = CharacterDefinition(&vram, 16 * sprite, objBlockHeight);
const auto& palette = palettes[current.palette()];
const auto flipX = current.flipX();
const auto flipY = current.flipY();
@ -101,8 +98,8 @@ void EightBit::GameBoy::Display::renderBackground() {
auto palette = createPalette(Bus::BGP);
const auto window = (m_control & Bus::WindowEnable) != 0;
const auto bgArea = (m_control & Bus::BackgroundCodeAreaSelection) ? 0x9c00 : 0x9800;
const auto bgCharacters = (m_control & Bus::BackgroundCharacterDataSelection) ? 0x8000 : 0x8800;
const auto bgArea = (m_control & Bus::BackgroundCodeAreaSelection) ? 0x1c00 : 0x1800;
const auto bgCharacters = (m_control & Bus::BackgroundCharacterDataSelection) ? 0 : 0x800;
const auto wx = m_bus.peekRegister(Bus::WX);
const auto wy = m_bus.peekRegister(Bus::WY);
@ -121,15 +118,17 @@ void EightBit::GameBoy::Display::renderBackground(
int offsetX, int offsetY,
const std::array<int, 4>& palette) {
auto& vram = m_bus.VRAM();
const int row = (m_scanLine - offsetY) / 8;
const auto baseAddress = bgArea + row * BufferCharacterWidth;
for (int column = 0; column < BufferCharacterWidth; ++column) {
const auto address = baseAddress + column;
const auto character = m_bus.peek(address);
const auto character = vram.peek(address);
const auto definition = CharacterDefinition(&m_bus, bgCharacters + 16 * character, 8);
const auto definition = CharacterDefinition(&vram, bgCharacters + 16 * character, 8);
renderTile(
8,
column * 8 + offsetX, row * 8 + offsetY,