Reading question and comment, it feels as if there is a confusion between address translation and virtual addressing vs. memory protection and separate (process) address spaces. These are more or less independent issues.
Address Translation is a mechanism to turn an address issued by a program into a real memory address to be used. There is no principal need for programs or processes to use different address spaces.
Virtual addressing is about allowing addressing more memory than there is, by providing a way to detect access to addresses that are currently not in main memory and have them brought in (one way or another)
Memory protection is about stopping one process from accessing memory assigned to another. This can and has been done long before usage of virtual addresses. For example the /360 family provides a 4-bit field for each memory page meant to hold a storage key. Similarly, a dedicated CPU register holds the key of the process running. Whenever it accesses memory with a different key, a protection fail is inserted.
Separate memory spaces are about giving every process the same (virtual) addresses, so it seems as if it's the only process on a machine - simplifying relocation issues a swell.
Equally important to this question, hardware support for virtual memory is the least important part here: it's all about an OS using this feature. An OS can still provide multi-processing without virtual memory, despite the hardware being present - like Classic MacOS on a 68040 LC475.
For the Questions:
Were there any computers that did not support virtual memory?
Yes, essentially every computer did in the early days.
There were already a number of computers working when the concept of virtual addressing was first described in 1956 by F. Güntsch at TU Berlin, Germany. It wasn't until 1959 when the Manchester MUSE project showed off a first prototype of virtual addressing. Still, it only reached mainstream usage in the late 60s with the IBM 360/67.
It's important to understand that, at that time, virtual addressing wasn't about separating processes, but to allow a process to grow beyond existing memory. We all know that there is never enough memory in a computer, but that was even more scarce back in the days when mainframes with 128 KiB were considered large.
And while virtual addressing as a tool to support multiprocessing became useful in universities during the 1970s, most commercial use stayed with real mode environments to avoid the speed penalty of address translation.
The same was true when minis became a thing in the 1960s/70s - and it repeated of course with micros. Here, much as before, virtual addressing became available quite early on in the 1970s, but it wasn't until the mid-1980s that it caught on with workstations and mid 90s with mass market PC - not at least as its usage is way more of an OS issue than hardware related.
if yes, were these computers able to run multiple processes at the same time?
Of course= multi-programming and multi-processing do not rely on having virtual addressing. It only needs well-behaved processes, staying away from accessing any resources (memory, I/O, Disk, etc.) not assigned to them. Something to be expected anyway from any program, isn't it?
There have been many examples for operating systems supporting concurrent execution without virtual addressing on all classes. By just focusing on micros, a short list may look like this:
- MP/M for 8080 compatible CPUs (1979)
- OS/9 for 6809 (1979)
- MP/M-86 (later Concurrent CP/M and Concurrent DOS) for x86 (1981)
- QNX for x86 (1982)
- [OS-9/68k] port of OS/9 to 68,000 (1983). Later ported to many other architectures
- (Classic) Mac-OS for 68,000 (1984)
- Sinclair QDOS for 68,000 (1984)
- GEM for x86 and 68,000 (1985)
- Amiga OS for 68,000 (1985)
- Windows for x86 (1987)
Please note that there are many ways to run different processes, and all of the above changed over time in what types were supported, or what restrictions applied. Also, some added virtual addressing (and memory protection) in later versions.