4 ms·
Wouldn't it be easier to put the repeated operations in subroutines rather than in a VM?
by eternauta3k 8y ago
Wouldn't it be easier to put the repeated operations in subroutines rather than in a VM?
- reaperducer 8y agoIn a way, that is what was done. "In effect, Z-code is like P-code: a string of subprogram calls, with the bodies of the subprograms executed by a Z-machine or ZIP. Any often-used sequence of pperations [sic] in Zork programs could, in principle, be compressed into a Z-code instruction, thereby moving the sequence of operations into the Z-machine or ZIP, where it needs to appear only once." The goal wasn't to do it the easy way, but to achieve something that happened to be difficult. It's also important to remember that loading a program into a computer back then was very different than today. Today, you load a program and it exists along with the operating system and all its support routines, needed or otherwise. For example, you may load a car racing game on Windows or macOS, but the printer drivers are still there. Back then, most games on most computers would wipe out the entirety of the machine down to the last byte. Even the fonts could be blown out if you needed the space. (Storing changing variables in what we would call the font space was a fun way to create an interesting display while heavy math was being done, but without wasting resources on a "loading..." progress bar.)
- psykotic 8y agoWith a VM, a single byte can encode one of 256 subroutines/jump targets. On the 6502 processor, whether you're using JSR or JMP, your shortest option is a 3-byte instruction. That's a 3x code size reduction. Of course you pay a cost in dispatch overhead. Incidentally, there's also an intermediate option which is called a direct-threaded interpreter in the Forth world, where your VM code stream consists of jump targets rather than opcodes. That requires 2 bytes per operation rather than 3 while eliminating the table lookup to map the 1-byte opcode to the 2-byte jump target. The 3:1 reduction doesn't necessarily apply to operations that would normally map directly to CPU instructions. But especially for that generation of 8-bit microprocessors like the 6502, as soon as you're working with 16-bit data (which you definitely want for something like Zork) you end up spending a lot of code space for even simple operations. There's a famous example of a VM designed for the 6502 explicitly for reducing the code size (and inconvenience) of working with 16-bit operands: https://en.wikipedia.org/wiki/SWEET16 https://en.wikipedia.org/wiki/SWEET16
- egypturnash 8y agoThere's another consideration: portability. Competition among home computer platforms was strong in those days, with new ones coming and going every year; Infocom could quickly make their entire catalog available for a new machine because all they had to do was port the VM interpreter, then stick it on a disc along with the already-compiled game files. New games would come out simultaneously on every platform they supported; Wikipedia lists those as "the Apple II family, Atari 800, IBM PC compatibles, Amstrad CPC/PCW (one disc worked on both machines), Commodore 64, Commodore Plus/4, Commodore 128,[3] Kaypro CP/M, Texas Instruments TI-99/4A, the Mac, Atari ST, the Commodore Amiga and the Radio Shack TRS-80." (Eventually they expanded the restrictions on the Z-Machine and began creating games too big to fit on the smaller machines, but they were still able to do simultaneous releases on everything with enough room to juggle the larger games.) Also, the VM implemented a domain-specific language, designed with "writing text adventure games" in mind; this was a huge advantage in a time when most games were programmed in assembly language. Both in terms of a faster development cycle, and in terms of building better text-based games by hiring people who were writers first and foremost rather than programmers. (The VM interpreter also implemented virtual memory; while a 128k game file doesn't sound like much, it was pretty huge in an era when typical home computers had 32 or 64k of RAM. Swapfiles didn't exist on anything but huge minicomputers.)