gbdev / gb-opcodes

https://gbdev.io/gb-opcodes/optables/
Creative Commons Zero v1.0 Universal
24 stars 10 forks source link

Change STOP byte count to 1 #31

Open SonoSooS opened 1 year ago

SonoSooS commented 1 year ago

It doesn't make sense to have a 2-byte instruction which takes 1 M-cycle, as that's impossible to actually achieve on the CPU in any way (yes, that even includes ADD HL, r16, as it does ALU operation on both M-cycles, lower half first, then upper half in the second cycle).

There are two ways to solve this issue:

And yes, STOP is actually a single byte opcode, which can be observed when STOP fails to stop due to a button being held. The short explaination of why STOP consumes two bytes can be summarized in these points:

The reason HALT does not consume two bytes is because PC is not incremented when HALT fetches the next opcode, but otherwise works similar to STOP. More details here.

ISSOtm commented 1 year ago

I think we'd want to not give a cycle count for it, like we (probably?) already do for halt. And add an asterisk (or tooltip or whatever) listing the more complete explanation, or alternatively a link to it (in Pan Docs?).

SonoSooS commented 1 year ago

Yeah, HALT and STOP are quite complex, so I'd agree with the idea of removing both cycle and byte count from HALT and STOP, especially considering that HALT is listed as 1B, even though we also pad it with NOP to avoid HALT bug, while STOP is listed as 2B, even though it's an 1B instruction just like HALT is.

We'd just need to make both a terse and a detailed explaination we could link to. The terse part is really important, as I think it's a bad idea to collapse too much information onto someone who just wants to know if HALT or STOP are 1B or 2B, and also why we can't just say 1M as cycle count.

ISSOtm commented 1 year ago

Maybe the full explanation can be added to Pan Docs instead?

SonoSooS commented 1 year ago

It is possible, although I have encountered two issues:

ISSOtm commented 1 year ago

Pan Docs can get away with a simplified explanation (isn't the flowchart sufficient?), and link to a separate document for more details, I think.

nitro2k01 commented 1 year ago

The answer to all of the above is: "it depends" or "it comes down to semantics". Just like with some previous discussions I've engaged with regarding the documentation (like the APU frequency/wavelength/whatever discussion) I've argued for sometimes leading the text with what's useful for the reader, and then nitty gritty technical details can be explained further down.

How many bytes is stop? Yes, it's technically 1 byte, but externally it behaves like 2 bytes. You can prove it is technically 1 byte by specifically doing everything Nintendo warned you not to do (button activated and held, and interrupt pending) but this is more of a curiosity.

How many cycles does stop use? The simple answer is of course that it varies, but this depends on semantics. You could for example argue that stop itself takes 1 M whereas, the side effects of stop may take a varying number of cycles, for example 32768 M.

My recommendation would be to specify stop as 2 bytes, since that's how it appears externally in all reasonable use cases, and specify the cycles as something like 1+x M or 1+? M. The latter would apply to halt as well btw.

SonoSooS commented 1 year ago

Yeah, that's fair about unnecessary complexity. I guess there could be a separate page with more detail for emulator devs, as opposed to programmers who only need to know to encode STOP as $10 $00 if they really need to use it, and it takes either 1 or 2 bytes, and 1+variable cycles.

There could be a middle-ish ground: specify STOP as 1/2 bytes, and cycle count as 1+x, that sounds terse enough if you only need a quick lookup, but also encourages people to dig further if they really need to know more about this fandango of specifying two possibilities instead of just a fix one.

HALT should also receive the 1+x M-cycle treatment as well, although I'm not sure about the byte count, as it could be 1 or 0, but I guess that's way too pedantic, and it should stay as 1 with an asterisk to encode HALT as $76 $00 to avoid the HALT bug at all cost.

ISSOtm commented 1 year ago

The halt bug is well documented elsewhere, I don't think that last asterisk is necessary. Similarly, I'd only document STOP as "1/2"-byte, and have the asterisk say "the byte following STOP is usually ignored, see this document for details".

Agreed about the special cycle notation.