I've already had a good time getting started in the emulator world, I decided to stop trying to make an emulator of a complex system and start with a very basic, emulator of CHIP-8, which is what many indicate in forums of emulation. Well let's break it down:
First operation I do not see the logic:
std::uint16_t opcode = m_Memory[reg.PC] << 8 | m_Memory[reg.PC + 1];
Basically 1 CHIP-8 opcode is 2 bytes, but rom is 8 bits, first I access the array of std :: uint8_t that I call m_Memory that I used to store the ROM and the font set at the position of Program Counter that starts as 0x200 which is where most programs / games of CHIP-8 begin, then add 8 more zeros, which is easy to understand, 1 byte = 8 bits, then 2 bytes are 16 bits, but then the confusion starts, if you already got the opcode then why masking a 16-bit value with 8? and why use the rom itself however advancing the position of the pc?
Here we go to the second part of my problem:
switch (opcode & 0xF000) {
...
}
In a discussion I started in a reddit forum about emulators people told me they masked the opcode with 0xF000 to get the actual opcode, but what I did not understand is how they came to the conclusion that they should mask and why with that value .
The final part:
I use this documentation in which I and many others are guided, first we go to opcode 0x6000 or 6xkk or LD V x, byte:
//LD Vx, byte
case 0x6000:
reg.Vx[(opcode & 0x0F00) >> 8] = (opcode & 0x00FF);
reg.PC += 2;
std::cout << "OPCODE LD Vx, byte executado." << std::endl;
break;
The CHIP-8 has 16 registers of 8 bits that I called of Vx, we go the:
reg.Vx [(opcode & 0x0F00)> > 8]
First I converted opcode 0x6000 to binary and performed the and:
0110 0000 0000 0000 //0x6000
0000 1111 0000 0000 //0x0F00
-------------------
0000 0000 0000 0000 //0x0
Then >> 8
moves 8 bits to the right which would be 0000 0000
ie index 0 of Vx, then = (opcode & 0x00FF)
that is:
0110 0000 0000 0000 //0x6000
0000 0000 1111 1111 //0x00FF
-------------------
0000 0000 0000 0000 //0x0
So why not just reg.Vx[0] = 0;
?
Remembering that I've never had to do Bit Bit operations before on any project, I just know what the books told me about the AND operation, OR, XOR, NOT etc ...
I would like to be able to understand this logic that people use to be able to use in future projects.