--- /dev/null
+#ifndef MM80_GAMEBOYGRAPHICS_HH
+#define MM80_GAMEBOYGRAPHICS_HH
+
+#include "mm80.hh"
+
+#include "MemoryMap.hh"
+
+
+class GameboyGraphics
+{
+public:
+ void renderScanLine();
+
+private:
+ // Graphics system operates with 8x8 pixel tiles. There is space for 384
+ // tiles. 256 tiles map be used in a map. Map 1 uses tile numbers 0 to 255,
+ // other uses -128 to 127.
+ // There are 2 maps held in memory, but only one displayed at a time.
+ // 0x8000 - 0x87FF: Tile Set #1: 0 - 127.
+ // 0x8800 - 0x8FFF: Tile Set #1: 128-255. Tile Set #0: -1 to -128
+ // 0x9000 - 0x97FF: Tile Set #0: tiles 0-127
+ // 0x9800 - 0x9BFF: Tile map #0
+ // 0x9C00 - 0x9FFF: Tile map #1
+ std::tr1::shared_ptr<MemoryMap::Memory> m_vram;
+
+ enum SpriteOptions
+ {
+ SPRITE_PALETTE = 0x10, // 0 = Pallete #0, 1 = Pallete #2
+ SPRITE_XFLIP = 0x20, // 0 = Normal, 1 = flip.
+ SPRITE_YFLIP = 0x40, // 0 = Normal, 1 = flip
+ SPRITE_PRIORITY = 0x80 // 0 = Above Background, 1 = Below background
+ // (background colour 0 == transparent)
+ };
+
+ struct __attribute__ ((packed)) Sprite
+ {
+ uint8_t y; // Y-coordinate - 16
+ uint8_t x; // X-coordinate - 8
+ uint8_t tile; // Tile number
+ uint8_t options;
+ }
+
+ // Object Attribute Memory (Up to 40 sprites), as per Sprite struct.
+ std::tr1::shared_ptr<MemoryMap::Memory> m_oam; // 0xFE00 - 0xFE9F
+
+ struct __attribute__((packed)) Registers
+ {
+ uint8_t LCDC;
+ uint8_t STAT;
+ uint8_t SCY;
+ uint8_t SCX;
+ uint8_t LY;
+ uint8_t LYC;
+ uint8_t DMA;
+ uint8_t OBP0;
+ uint8_t OBP1;
+ uint8_t WY;
+ uint8_t WX;
+ };
+
+ // Memory-mapped IO Registers
+ std::tr1::shared_ptr<MemoryMap::Memory> m_reg;
+};
+
+#endif
+
--- /dev/null
+/** \r
+ * Flat memory-model emulation.\r
+ *\r
+ * Authors: Michael McMaster <email@michaelmcmaster.name>\r
+ * Copyright: Michael McMaster <email@michaelmcmaster.name>\r
+ */\r
+\r
+#include "mm80.hh"\r
+#include "Memory.hh"\r
+\r
+using namespace mm80;\r
+\r
+Memory::Memory(address_t initialSize)\r
+{\r
+ m_mem.resize(initialSize);\r
+}\r
+\r
+uint8_t\r
+Memory::read8(DWORD address, int8_t offset)\r
+{\r
+ return m_mem[address.host() + offset];\r
+}\r
+\r
+DWORD\r
+Memory::read16(DWORD address, int8_t offset)\r
+{\r
+ return CreateDWORD(&m_mem[address.host() + offset]);\r
+}\r
+\r
+void\r
+Memory::write8(DWORD address, uint8_t value)\r
+{\r
+ m_mem[address.host()] = value;\r
+}\r
+\r
+void\r
+Memory::write8(DWORD address, int8_t offset, uint8_t value)\r
+{\r
+ m_mem[address.host() + offset] = value;\r
+}\r
+\r
+void\r
+Memory::write16(DWORD address, DWORD value)\r
+{\r
+ m_mem[address.host()] = value.l;\r
+ m_mem[address.host() + 1] = value.h;\r
+}\r
+\r
+void\r
+Memory::write16(DWORD address, int8_t offset, DWORD value)\r
+{\r
+ m_mem[address.host() + offset] = value.l;\r
+ m_mem[address.host() + offset + 1] = value.h;\r
+}\r
+\r
--- /dev/null
+/** \r
+ * Flat memory-model emulation.\r
+ *\r
+ * Authors: Michael McMaster <email@michaelmcmaster.name>\r
+ * Copyright: Michael McMaster <email@michaelmcmaster.name>\r
+ */\r
+\r
+#ifndef MM80_MEMORYMAP_HH\r
+#define MM80_MEMORYMAP_HH\r
+\r
+#include "mm80.hh"\r
+#include "DWORD.hh"\r
+\r
+#include <memory>\r
+#include <vector>\r
+namespace mm80\r
+{\r
+\r
+class MemoryMap\r
+{\r
+public:\r
+ class Memory\r
+ {\r
+ public:\r
+ virtual ~Memory;\r
+\r
+ uint8_t read8(DWORD address) = 0;\r
+ void write8(DWORD address, uint8_t value) = 0;\r
+ };\r
+\r
+ Memory();\r
+\r
+ void map(\r
+ address_t base,\r
+ address_t size,\r
+ const std::tr1::shared_ptr<Memory>& mem\r
+ );\r
+\r
+ uint8_t read8(DWORD address, int8_t offset = 0);\r
+ void write8(DWORD address, uint8_t value);\r
+ void write8(DWORD address, int8_t offset, uint8_t value);\r
+\r
+ DWORD read16(DWORD address, int8_t offset = 0);\r
+ void write16(DWORD address, DWORD value);\r
+ void write16(DWORD address, int8_t offset, DWORD value);\r
+\r
+private:\r
+\r
+ std::vector<uint8_t> m_map;\r
+ std::vector<uint8_t> m_mem;\r
+};\r
+\r
+} // namespace mm80\r
+\r
+#endif\r
+\r
--- /dev/null
+#include "mm80.hh"\r
+#include "RAM.hh"\r
+\r
+using namespace mm80;\r
+\r
+RAM::RAM(uint16_t size)\r
+{\r
+ m_mem.resize(size);\r
+}\r
+\r
+uint8_t\r
+RAM::read8(uint16_t address)\r
+{\r
+ return m_mem[address];\r
+}\r
+\r
+void\r
+RAM::write8(uint16_t address, uint8_t value)\r
+{\r
+ m_mem[address] = value;\r
+}\r
+\r
--- /dev/null
+#ifndef MM80_RAM_HH\r
+#define MM80_RAM_HH\r
+\r
+#include "mm80.hh"\r
+#include "MemoryMap.hh"\r
+\r
+#include <vector>\r
+namespace mm80\r
+{\r
+\r
+class ROM : public MemoryMap::Memory\r
+{\r
+public:\r
+ RAM(uint16_t size);\r
+ virtual uint8_t read8(uint16_t address) = 0;\r
+ virtual void write8(uint16_t address, uint8_t value) = 0;\r
+\r
+private:\r
+ std::vector<uint8_t> m_mem;\r
+};\r
+\r
+} // namespace mm80\r
+\r
+#endif\r
+\r