Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <iostream>
- #include <array>
- #include <map>
- #include <random>
- using onebyte = unsigned char;
- using twobyte = unsigned short;
- /* memory map of the system:
- 0x000 - 0x1FF: Chip 8 interpreter (contains font set in emu)
- 0x050 - 0x0A0: Used for the built in 4x5 pixel font set (0 - F)
- 0x200 - 0xFFF: Program ROM and work RAM
- Original Implemented
- +-+-+-+-+ +-+-+-+-+
- |1|2|3|C| |1|2|3|4|
- +-+-+-+-+ +-+-+-+-+
- |4|5|6|D| |Q|W|E|R|
- +-+-+-+-+ => +-+-+-+-+
- |7|8|9|E| |A|S|D|F|
- +-+-+-+-+ +-+-+-+-+
- |A|0|B|F| |Z|X|C|V|
- +-+-+-+-+ +-+-+-+-+ */
- class Chip8 {
- using funcptr = void (Chip8::*)();
- static constexpr int MEM_SIZE = 4096;
- static constexpr int GFX_SIZE = 128*64;//64*32;
- static constexpr int REG_SIZE = 16;
- static constexpr int STK_SIZE = 16;
- static constexpr int KEY_SIZE = 16;
- static constexpr int FNT_SIZE = 80;
- //static constexpr int RPL_SIZE = 8;
- private:
- twobyte opcode = 0; // operation code, specifies the operation to be performed
- twobyte pc = 0x200; // program counter. increased by 2 because every instruction is 2 bytes long (except on jump or subroutine call)
- twobyte I = 0; // index register
- twobyte sp = 0; // stack pointer, holds the current level of the stack
- onebyte delayTimer = '\0', soundTimer = '\0'; // timers that count at 60 Hz
- bool waitForKey = false;
- std::array<onebyte, MEM_SIZE> memory{};
- std::array<onebyte, REG_SIZE> V{}; // CPU registers, V0-VE are general purpose and VF is the 'carry flag'
- std::array<onebyte, GFX_SIZE> gfx{}; // graphics (black and white, so 1 and 0)
- std::array<onebyte, KEY_SIZE> key{}; // current state of the HEX based keypad (0x0 - 0xF)
- std::array<twobyte, STK_SIZE> stack{}; // remembers the starting location before a subroutine call
- std::map<twobyte, funcptr> opMap; // maps the opcodes to their respective function
- std::random_device rd;
- std::mt19937 mt;
- std::uniform_int_distribution<int> dist;
- //bool extendedScreen = false;
- //bool forceExit = false;
- //std::array<onebyte, RPL_SIZE> rpl{}}; // RPL user flags
- public:
- bool drawFlag = true;
- public:
- Chip8() = default;
- Chip8(const Chip8& rhs) = delete;
- Chip8& operator=(const Chip8& rhs) = delete;
- ~Chip8() = default;
- onebyte gfxValueAt(unsigned int index) const;
- void mapKey(unsigned int index, onebyte value);
- //bool extendedScreenEnabled() const { return extendedScreen; };
- //bool forceExitEnabled() const { return forceExit; };
- void initialize();
- bool loadGame(const std::string& name);
- void emulateCycle();
- void updateTimers();
- private:
- void initOpMap();
- void fetchOpcode();
- void executeOpcode();
- // opcodes
- void CLS();
- void RET();
- //void EXIT();
- //void LOW();
- //void HIGH();
- void JP();
- void CALL();
- void SE();
- void SNE();
- void LD();
- void ADD();
- void OR();
- void AND();
- void XOR();
- void SUB();
- void SHR();
- void SUBN();
- void SHL();
- void RND();
- void DRW();
- void SKP();
- void SKNP();
- };
Add Comment
Please, Sign In to add comment