5 ms·
Game Boy development was interesting in that you were always coding with battery in mind. You couldn't simply "NOP" your way through something, you had to "HALT
by sneakernets 8y ago
Game Boy development was interesting in that you were always coding with battery in mind. You couldn't simply "NOP" your way through something, you had to "HALT". So your game loop was always "halt and wait for interrupt, do action, halt again".
Allegedly, if you didn't do this, Nintendo would reject your game outright.
- anyfoo 8y agoI'm not too familiar with game development, is that unusual? It's pretty natural in other forms of software development. In user space, you mostly wait on system calls (e.g. select, blocking read/write, thread synchronization primitives), and in the kernel that usually translates to another process being scheduled. If there's nothing to be scheduled, you hit the idle loop, which, roughly spoken, halts the core until the next interrupt. Sometimes you need to poll a device that does not signal completion with an interrupt, or some locks may actually spin (for a while at least) before sleeping, but, conceptually at least, I'd almost call those exceptions to a rule.
- phamilton 8y agoRun something like the original starcraft on modern hardware. It'll use 100% of a cpu.
- anyfoo 8y agoAssuming the hardware is then fast enough to run at the full frame rate, what's it doing once it's done with everything that needed being done? Just burning cycles in a busy loop with no progress?
- pcwalton 8y agoTypically, yes. It didn't matter back in the day when the CPU had no way to enter an idle state to begin with. Wikipedia says that Intel CPUs didn't actually enter a low-power state on HLT until 1994 [1]. [1]: https://en.wikipedia.org/wiki/HLT_(x86_instruction)#History_on_x86 https://en.wikipedia.org/wiki/HLT_(x86_instruction)#History_...
- sbradford26 8y agoI think the main difference is really that in user space there is an os always doing something in the background. On a gameboy though when you say halt it truly halts the hardware unlike an idle loop which just spins. So an actual hardware interrupt is needed to restart things. For embedded software without an os it is not uncommon when not explicitly doing something to enter a spin table.
- anyfoo 8y agoThe idle loop of an OS usually halts the core and waits for an actual hardware interrupt, too. And if your user space program is e.g. waiting on a disk read, there is a pretty good chance that the OS has nothing else to do and hits that loop, halting the core, until the disk delivers, or maybe a timer interrupt kicks in. So there's not much difference between a Game Boy and a modern computer in that particular regard, other than the many thick abstraction layers between the system call invocation and the halt instruction.
- slezakattack 8y agoI think you may have misunderstood. I think OP meant that you have to explicitly "freeze" or "halt" the program to save on battery. In other forms of software development, it's not common to explicitly state in your code that you're waiting for the kernel to interrupt you. The kernel's scheduler decides when to interrupt and pre-empts the running process. There are definitely systems out there where the running process gives processor control back to the kernel scheduler but I don't think it's common.
- anyfoo 8y agoNo, almost all invocations of system calls are implicitly telling the kernel that you now wish to sleep, and want to be waken up once the system call completes. It's abstracted away from you by mostly looking like a regular function call, but it's there. It's more explicitly apparent if you e.g. wait on a semaphore, but the principle is the same. Just type "ps ax" into your shell, most processes will be in state "S", sleeping because of a system call. My point is, you kind of have to go out of your way to spin CPU without actually having any work in front of you.
- tom_ 8y agoIt's the opposite on 8-bit stuff, because there's nothing else running, and CPUs on such systems typically never stop working anyway - so if your game has nothing to do, it still has to do something. So it's normal to just enter a little loop in your code, often one that waits for a flag that's set by an interrupt routine that runs in response to vertical blank or a timer or something. So your loop is literally just waiting for time to pass. Load flag, is flag zero, repeat loop if zero, that sort of thing, over and over again. But with the gameboy's halt functionality, you can add a halt in there, I guess: halt, load flag, is flag zero, repeat loop if zero. Then the CPU can go dormant until the next interrupt, rather than spending its time running that loop. (It might wake up needlessly, if some other interrupt occurs, but it'll still be no more expensive than the loop.)
- anyfoo 8y agoSo the only difference really is whether you have a HALT at the end of your main loop or not, I guess. (Well, and that you sometimes had to poll, because there isn't an interrupt for everything you're waiting for.)
- white-flame 8y agoThis isn't necessarily different for game development, but it's different for Game Boy scale hardware, where there is no scheduler/kernel/OS/anything. You manually have to halt the hardware if you don't want the CPU to spin, and busy-loops were common on home computers & mains-powered consoles of the same era.
- anyfoo 8y agoI got that, I was just wondering if there was more to it between e.g. Game Boy and NES than having the extra HALT in your main/idle loop, and maybe less unconditional polling. Apparently not, thanks!
- boomlinde 8y agoCompared to contemporary non-battery powered video game consoles it is a bit of an unusual consideration. When you have no scheduler, no battery and the CPU stays comfortably cool no matter what it's up to, there are no reasons to write programs like this.