4 ms·
Plus, some limitations are impossible to correctly self-impose without just embracing the gestalt of the hardware. A few examples: Using the standard MBC1 mapp
by wk_end 5y ago
Plus, some limitations are impossible to correctly self-impose without just embracing the gestalt of the hardware. A few examples:
Using the standard MBC1 mapper, the Game Boy can only address two 16KB chunks of ROM at a time (one “home bank” that’s always accessible and one swappable one), and figuring out how to work with that limitation cleanly is fundamental to the structure of your engine for larger productions. How can you reproduce that on a modern machine? Even if you committed to only accessing data in the original GB formats, in 16KB chunks, the code itself is never going to be the same size, and code faces the exact same restrictions. You’d need to self-impose the restriction of only writing GBZ80 code - at which point you’re developing for the real thing!
Likewise, the GBZ80 processor has very limited addressing modes, even compared to many of its contemporaries; to compensate, a well-designed engine is going to focus on organizing data into 256 byte “pages” (because you can index them by manipulating a single byte of a pointer), focus on linear data (to take advantage of the auto-increment/decrement addressing modes), and avoid indexing that would require multiplication (i.e. prefer “structs of arrays” rather than “arrays of structs”). And if you do need indexable non-byte sized data, you of course would prefer data that’s power-of-two sized so you can do that multiplication using shifts, and ideally 16-byte sized so you can use the SWAP instruction to go from index to pointer in one cycle.
Also, the Game Boy video hardware locks you out of VRAM while it’s drawing the screen - that is, almost all the time. Any VRAM updates need to run during Vblank or less commonly Hblank, usually in ridiculously tight interrupt handlers. Again, your engine needs to be organized around doing these updates as quickly as possible; consider that even something like drawing a fresh column of tiles to the screen is much harder than drawing a row (since you can’t use the CPU’s auto-increment addressing) and might be too slow if care isn’t taken. There’s no real way to reproduce this on a different system - all of the timing is off. Challenges like this are the “fun” of developing for the platform and can’t really be correctly captured without just developing for the platform.