The game is written in C++, but far more of the code could compile on a C compiler than most C++ programs today. (ie. it doesn't use as many ++ features as it really should)
Most low level kernel routines, device drivers etc. have some element of Assembler, and since there really wasn't much of an "OS" on 8-bit systems, games included their own kernel and drivers. That's why there was so much machine code in them. Even at 16-bit code, games on the Amiga and Atari ST, as well as copy-protected floppies for the PC (A-10 Tank Killer etc.) would boot from the floppy, bypassing the slow bloat of a general OS and using a custom kernel with highly optimised machine code routines which directly interface between the game code and the hardware.
If you have a decent OS, and a powerful computer, you don't need to use machine code. (Assembler)
On the other hand, we don't have the source code, so everything we do requires us to reverse the compiled C++ back into Assembler, to work on it. It's helpful to have an idea what the C++ may have been which produced that, but it's also true that there is no reason why you should use C or C++ over Assembler, if you know what you're doing.
Higher-level languages are supposed to be easier to learn, read and maintain. However, well written x86 code, with extensive use of Macros and directives is (to my eye) as easy to understand, and easily as maintainable provided you don't change the target platform.
The point at which you can no longer maintain Assembler is the point where the CPU architecture of your target changes. It's hard to port x86 to x64, where it's just a compiler switch in C. It's so hard to port from x86 to ARM that you may as well start again from scratch... Again, in C it's just a compiler switch. ^_^ Beyond that, in .Net MSIL or Java you don't even need to re-compile when the CPU changes, because everything you do is executed in a Virtual Machine with a custom Virtual CPU.