6 ms·
I am a bit puzzled by this: "Before about the early 90s, we didn’t trust C compilers, so we wrote in assembly." There a lot of games released during the 80's,
by pulsarpietro 8y ago
I am a bit puzzled by this:
"Before about the early 90s, we didn’t trust C compilers, so we wrote in assembly."
There a lot of games released during the 80's, were they really all written in assembly ?
https://www.myabandonware.com/browse/year/ https://www.myabandonware.com/browse/year/
I don't have experience in the game industry at all, I must add.
- vardump 8y agoHeavier things, like graphics processing were typically written in assembler. Or sound mixing. Some things like texture mapping you could only write in assembler, because you'd need to use x86 lower/higher half of word (like AL and AH registers) due to register pressure. Spilling to stack could have caused 50%+ slowdown. 486 era you needed assembler to work around quirks like AGI stalls. On Pentium the reason for assembler was to use FPU efficiently in parallel with normal code (FPU per pixel divide for perspective correction). Of course you also needed to carefully hand optimize for Pentium U and V pipes. If you did it correctly, you could execute up to 2 instructions per clock. If not, you lose up to half of the performance (or even more if you messed up register dependency chains, which were a bit weird sometimes). One also needs to remember compilers in the nineties were not very amazing at optimization. You could run circles around them by using assembler. Mind you, I still need to write some things in assembler even on modern x86. But it's pretty little nowadays. SIMD stuff (SSE/AVX) you can mostly do in "almost assembler" with instruction intrinsics, but without needing to worry about instruction scheduling and so on.
- pulsarpietro 8y agoI must have been a bloody hard and interesting work, back then.
- vardump 8y agoThings are much harder nowadays due to complexity. From almost impossible to understand CPU cores to massive amounts of third party code to the modern requirements (IoT, ouch!). Debugging predictable single thread single core system was also child's play compared to distributed networked beasts each running on lots of cores and thousands of threads. Nineties problems were contained in a small box. Oh, and no internet like today, so needed to order books and magazines. And to use BBS and usenet. Even then, a lot of it was reinventing the wheel again and again. Modern problems are sometimes nearly uncontained (think software like web browsers, etc.).
- enjo 8y agoJust jumping in to agree here. I've always thought of this way: In the 90's the code I wrote was more difficult. Today coding is much easier (better languages, tooling, etc..). However the systems I build are many times more complex. In the 90's we hired the best programmers, today we hire the people who are best at managing ambiguity and complexity. All of this is very hand-wavy as there are certainly still disciplines where pure programming skill is most important, but those seem to be fewer and fewer every day.
- pulsarpietro 8y agoAnyway I envy you guys, now things tend to be too high level and you lose that holistic view of the computing machine. Back than you felt pretty skilled I am sure, now I feel anybody could do my job, often. Unless you are working for the big 4 or similar, many jobs don't give you that excitement.
- richardjdare 8y agoBack then assembly language was much more ergonomic than it is now, and the machines were simpler. Many of my favourite games in the 80s were made by teenagers programming in their bedrooms. Check out this 68000 assembly tutorial video from Scoopex, the Amiga demo scene group: https://youtu.be/bqT1jsPyUGw https://youtu.be/bqT1jsPyUGw He gets a simple graphical effect going on the Amiga in only a few lines of assembly. Doing the same thing using DirectX in c++ would take you all day!
- pjc50 8y ago> much more ergonomic than it is now, This is an interesting line of argument - in what way, and what could be done to improve the ergonomics? > He gets a simple graphical effect going on the Amiga in only a few lines of assembly. Doing the same thing using DirectX in c++ would take you all day! This is absolutely true, but in something like ShaderToy you can go back to producing complex pixel-bashing effects with a huge amount of processing power. It's just the external Tower of Babel from boot to usability has got a lot larger.
- richardjdare 8y agoMy notion of ergonomic mostly comes from programming the Amiga in 68000 and then moving to the PC and being horrified by x86! In 68k you had 8 32-bit data registers, (d0-d7) and 8 address registers (a0-a7) If you wanted to access bytes or 16 or 32 bits you could do so like this: move.w #123,d0 ; move 16bit number into d0 move.b #123,d1 ; move byte into d1 move.l #SOME_ADDRESS,a0; set address reg a0 to point to a memory location. move.b d1,(a0) ; move contents of d1 to memory location a0 is pointing to. Nice and easy to work with and remember. On x86, thanks to its long and convoluted history you have all kinds of doubled up registers which you have to refer to by different names depending on what you are doing, and tons of historical cruft. On top of the CPU, the old home computers had no historical cruft and it was very easy to talk to the hardware or system firmware; usually you'd just be getting and setting data at fixed memory locations. I can read an Amiga mouse click in one line of 68k. I've no idea how you'd do it on a modern PC or even Java! Modern systems just aren't as integrated, for better and worse. Assembly language was also part of mainstream programming back then. You'd learn Basic then go straight to assembly if you wanted to do anything serious. So there were computer magazine articles on assembly, childrens books[1]. My first assembler, Devpac, came from a magazine coverdisk with a tutorial from Bullfrog, Peter Molyneaux's old game company[2]. So there were a whole range of cultural and technical reasons for assembly language being much more of a human-useable technology back in the day. >It's just the external Tower of Babel from boot to usability has got a lot larger. Yes I agree, I kinda miss being able to see the ground, which is probably why I find retro programming so appealing. [1]https://archive.org/details/machine-code-for-beginners https://archive.org/details/machine-code-for-beginners [2]https://archive.org/details/amigaformat39/page/n61 https://archive.org/details/amigaformat39/page/n61
- coldtea 8y ago>486 era you needed assembler to work around quirks like AGI stalls. Plus, nobody had a 486 in the 80s (it was released in 1989). People would be lucky to have a 286, but usually just some home computer (Apple II, Spectrum, Commodore 64, Atari ST, Amiga 500, Amstrad CPC, etc).
- vardump 8y agoOh right, I missed it was about eighties. Yeah, back then assembler was even more pervasive. It was the only way to write something publishable on 8-bit systems. Well, there were some action games (like C64 Beach Head), trivia and adventure games written in BASIC. You spent a lot of time on 8-bitters getting code and asset size down, so that it'd even fit on the machine in the first place. Forget about luxuries like division and multiply, most advanced math those things could do was little more than adding (add, sub, and, or, xor) two 8 bit numbers together. Even shifts and rotates could only handle 1 bit left or right. CPU clocks were measured in low single digit MHz. On top of that, 8 bitters were very inefficient — each instruction would take 2-8 clock cycles (6510) or 4-23 cycles (Z80). On PAL C64 you have 19656 clock cycles per 50Hz screen frame minus 25 bad lines. So you could realistically expect to execute only 5-8k instructions. If you used all the frame time for just copying memory, you'd be able to transfer just about 2 kB. Just scrolling character RAM (ignoring color RAM) took half of the available raster time (yes, I know about VSP tricks, but it wasn't known in the eighties). 16-bit systems allowed some C, but most Amiga and Atari ST games were written in assembler. I'd guess same is true for 286 era, but not sure.
- aerique 8y agoI'm not sure this is correct but: I remember reading or hearing rumours that Psygnosis' Barbarian (for the Amiga and Atari ST) was written in C and that it was so slow because of that. What I mean is: we perceived it as being slow because of the rumours. Just typical nerd attitude that we still see now.
- vardump 8y agoSure, some games were written completely in C. I believe significant number were hybrids, performance sensitive parts in assembler and other code in C. Some games were prototyped in C and optimized afterwards. For example Amiga Turrican 2 required 33 MHz 68030 CPU during the development phase. Of course the final version ran fine on 7 MHz 68000 Amiga.
- CoolGuySteve 8y agoLast time I used SSE intrinsics, which was GCC 4.9 I think, I had a lot of trouble with register usage. It looked like it was compiling down to use only one SSE register for everything instead of parralelizing across them. I tried the same algorithm in godbolt with some clang versions and it was slightly better, using two or three registers, but not by much. So I had to break it into inline assembly. I wonder if GCC has improved since then.
- vardump 8y ago> It looked like it was compiling down to use only one SSE register for everything instead of parralelizing across them. Yeah, that's a common problem and leads to nasty dependency stalls. MSVC is horrible in the same way, at least 2015. Haven't tried newer versions yet. Intel's ICC seems to generate good code most of the time.
- exDM69 8y ago> I wonder if GCC has improved since then. Yes, it has. I've written a lot of SIMD code and spent a good amount of time reading the compiler assembly output and there has been huge improvement over the last decade. GCC register allocation wasn't great, then it got better with x86 SSE but still sucked at ARM NEON, and now it seems to be decent with both. Clang was better at SIMD code before GCC was. It was equally good with SSE and NEON. In my experience, compilers are much better than humans at instruction scheduling. Especially when using portable vector extensions, you don't have to write the same code twice and then tweak the scheduling for every architecture separately.
- vardump 8y ago> In my experience, compilers are much better than humans at instruction scheduling. It'd be more accurate to say they're much better than humans when the heuristics or whatever they use works. Sometimes the compiler messes up badly. The workflow is often to compile and then examine disassembly to see whether the compiler managed to generate something sensible or not. Other issue is that compiler pattern matching is sometimes not working and generating correct SIMD instruction. Even when data is SIMD width aligned. For example, recently I saw ICC not generating a horizontal add in the most basic scenario imaginable. * shrug *.
- codemusings 8y agoI can't recall if I read it or whether it was mentioned in that Mocap video diary on youtube but Prince of Persia is an example that comes to mind. EDIT: Found it. Of course Fabien wrote about it: http://fabiensanglard.net/prince_of_persia/ http://fabiensanglard.net/prince_of_persia/
- pavlov 8y agoAnything with realtime graphics was probably written in assembly. There were game companies whose entire business was porting games between platforms, essentially rewriting the code for each machine. Slower-moving adventure and RPG games might be in a higher-level language. (IIRC the original Wizardry was written in a VM-based Pascal for Apple II?) Companies that specialized in adventure games would have their own interpreter and VM — Infocom's ZIL, Sierra's AGI, Lucasfilm's SCUMM. Game developers would write code in a scripting language against that company-standard VM. Amateur games might be written in BASIC because every computer under the sun shipped with a BASIC interpreter back then. C wasn't a practical option because decent compilers didn't exist for most non-Unix systems until the end of the 1980s — or if they did, they'd cost an arm and a leg. (I think the retail price for Microsoft's C compiler for DOS was several thousand dollars.)
- coldtea 8y ago>There a lot of games released during the 80's, were they really all written in assembly ? Most of them, yes. Here's a well known game: http://fabiensanglard.net/prince_of_persia/index.php http://fabiensanglard.net/prince_of_persia/index.php
- simonh 8y agoI can support the trust issue with C compilers. I did my CS degree in the 80s and every C compiler I used had severe bugs. These weren’t on Unix to be fair, they were to run on PCs or to program embedded systems, but they were awful. I remember one (Aztec C?) crashing out because one of my statements had two lines of whitespace before it instead of one (or maybe it was an extra space in a blank line? I forget), which was fine elsewhere in the program but just caused a problem in that particular context. I first used GCC in the 90s and it was heaven.
- mark-r 8y agoIn the '80s I used a cross-compiler that ran on DOS and produced code for 68K. We probably ran into a compiler bug monthly on average. We always got great turnaround on our bug reports though - I think it was a one-man shop.
- gaius 8y agoWith a good macro assembler like DevPac on the ST or Amiga, writing assembly was actually not that far off a contemporary high level language. It helped that the 68k had a very programmer-friendly instruction set.
- flohofwoe 8y ago8-bit CPUs instruction sets were really aimed towards assembly programming instead of being compile targets for "high-level languages" like C, and coding tricks are required (not optional) that are not possible in C, like self-modifying code or exact cycle-timing of instruction sequences (e.g. to fit into a video scanline). Some more obscure languages were not that bad (e.g. Forth), but most game programming on 8-bit machines was definitely done in carefully hand-crafted assembly. This only changed slowly with 16-bit machines like the Amiga or Atari ST, they had more memory, the Motorola 68000 instruction set was more suited for compiled languages, and the custom chips (like copper and blitter) freed the CPU from many graphics tasks. Yet even on those machines the critical parts were usually written in assembly.
- sehugg 8y agoThey weren't all in assembly. Lots of games were published in BASIC or Pascal or even custom interpreters like Z-Code. But most arcade games and cartridge titles were coded in assembly back then.
- georgeecollins 8y agoIn the mid 90's teams I led wrote code in assembly for things that were very performance intensive, in particular 3D rendering without 3D cards. There was also a need to write in assembly for the PS2, which had a very complicated and idiosyncratic architecture. In both cases you were really desperate for every bit of performance you could get and you didn't necessarily trust compilers to make optimal code. Since then compilers have improved and CPUs are much smarter about predicting what memory they will need. Also, Microsoft Visual C became good, but it was not before version 4. I remember watching a team at Activision literally take more than an hour to compile their game. Perhaps they were doing something wrong, but similar teams had much less of a problem when 4.0 came out. You cannot imagine what a drag that is to a team's productivity and creativity.