mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2024-12-23 00:29:47 +00:00
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:
parent
2b5324cb43
commit
9796f9d600
@ -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;
|
||||
};
|
||||
|
@ -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)
|
||||
|
@ -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; }
|
||||
|
@ -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) {
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user