and I thought I'd dealt with things which were fussy over timing ...
I don't even think it was intentional. In Mortal Kombat II's case, it was setting the HIRQ counter for something like dot # 64, and the code it executed after that took just under the needed amount.
I'm sure the devs weren't even bothering to count cycles. They probably tried a few numbers, saw that 64 worked okay and went with it. So when I was off by one cycle, it was just missing the IRQ, stopping it from setting up all future IRQs for the frame, completely destroying things.
It's funny, too. ZSNES tends to run about 40% faster than the real hardware, so it finished with plenty of time to share before the IRQ event. You can get much better compatibility by running things way too fast than running them just a little too slow. These bugs don't even show up until you really start to hammer down all the hardware delays (DRAM refresh, penalty cycles, memory access speeds), and it makes your emulator appear to be the less accurate one when the bugs show up.
I think we should take it eventually.
Ah, that's good. I can see myself being active for another 5-10 years or so, but I certainly don't have the longevity of something like MAME.
Once cothreads are added to the MAME core (Aaron is interested, but I don't know what all would be involved)
Wow, is he really going to add that? I was under the impression the save state issue was a deal breaker.
Please see if he's interested in libco. Runs just about everywhere (even on SPARC, MIPS and PPC), and the x86-32/x86-64 ones are insanely optimized (~10 opcodes, in large part thanks to Aaron himself and Shay Green.) Any new platform modules could flow back to me which would be incredibly helpful.
I really feel they're a huge benefit to writing sane, easy-to-read code. I was disappointed that they never caught on with anyone.
Entire API, stable for 3 years now:
cothread_t co_active();
cothread_t co_create(unsigned int, void (*)(void));
void co_delete(cothread_t);
void co_switch(cothread_t);
Simple enough for a goldfish to figure out.
Haze: the timing in MAME used to be unstable when everything was float-based. The all-integer system used now is very solid in my (admittedly limited) testing.
Whew. I was about to cry, thinking MAME was still FP-based.
Are they see-saw counters, or are they all grouped?
See-saw: one signed counter represents a link between two components. When A moves, increment counter, when B moves, decrement it. When A does something that B can see, make sure counter < 0, when B does something A can see, make sure counter >= 0, else sync up the other chip.
Grouped: one unsigned counter per component, all counters get normalized periodically (subtract lowest counter from all of them) to prevent overflow. When A does something B can see, ensure Acounter >= Bcounter, and vice versa.
I like the former model a lot better myself, much easier and faster. But every emu source I've seen uses the latter.
Having an emotional attachment to code in MAME or MESS is dangerous
I would say that's the case for any project, but especially for MAME / MESS