There were actually some completely insane workarounds even before shaders. I don't think it was actually shipped in real software, but I saw something that used 11 or 18 passes or something to do dot3 texture blending even on unextended OpenGL 1.0. Painstakingly doing one color channel at a time, values above 0 and below 0 on source and destination also separately…
Granted, if you didn't have the “squared blend” extension, it would be an approximation, but still a pretty convincing one.