I worked with more than one excellent Z-80 assembler. The limiting factor in the market was using an 8080 processor instead of a Z-80. I had to break the heart of the owner of a company producing an 8080 color terminal because there was no way we would backport all of the Z-80 based code already developed. Z-80 chips also got faster and required less additional hardware to support the CPU. Intel knew that Zilog beat them on 8 bit functionality, but they got the jump on the 16 bit market, Zilog 16 bit chips were well designed but hardly used.
My Z-80 experience: Remember the Apple ][? There was a third-party add-on card that had a Z-80 processor on it. When you plugged that into the Apple and executed a certain instruction (somehow), it put the 6502 processor into some kind of suspended mode (I think it was just some particular instruction that the Z-80 card caused to never finish) until a certain other instruction was executed. Then the Z-80 processor took over. And presto! Your Apple ][ became a Z-80.
The card came with the CPM operating system and all its typical associated utility programs, including an 8080 assembler. There was a block of memory set aside for custom patching. The TTY terminal driver had a glitch that caused it to freeze up occasionally. I figured out what it was (it had to do with the way the Apple hardware does destructive memory reads followed by a re-write and an obscure timing glitch with the TTY card hardware status register). Then I wrote a new TTY driver (just about a dozen instructions), hand-assembled it, and poked it into the patch area. Then there was a way to save that permanently as part of the OS. Fixed!
Among other wonders of this set-up, the card (or maybe it was a separate card) turned the 40-column upper-case-only display into an 80-column full-ASCII display (although it was very noticeably slow). AND – wait for it! – this also got us WordStar, a CPM-based word processor with a command set that largely set the standard for keyboard-controlled word processor command sets to this day!
There was also a native 6502 terminal emulator that we used to connect to the IBM 370 on campus. It worked poorly. So I wrote an entire TTY emulator from scratch that worked a whole lot better, all in 6502 assembler code.
But then there was also the lab computer that drove the transducers that broadcast programmed whistle-tones into the salt-water tank where the dolphins were. That was a truly odd-ball machine, of which I remember nearly nothing except that the blinkenlights on the front panel were ten-digit nixie tubes.
One of the higher-ups wrote an assembler for that in BASIC to run on our low-end PDP-11. It produced a listing (a dozen or more pages long) showing all the machine code, which some poor student assistant then had to hand-key digit by digit into the odd-ball computer, there being no better way. Then another poor student assistant, or several, had to read all that out word-by-word to verify it all.
I wrote a downloader to do all that. It was a page or so of hand-coded code for the odd-ball machine (which still had to be keyed in by hand), then connect up the RS-232 wires and run the downloader in the PDP-11 (which IIRC I wrote in assembler, or maybe it was BASIC) to download all the rest.
That was thinking outside the box. It had never occurred to anybody there to do such a thing. I was a hero!
I mentioned the Univac SS-90 a few times above, and promised a link with more information.
Okay, for all you who want to read about an archaic computer, that was nevertheless current enough to be programmed by people within living memory, there was this.
http://www.ussc90.nl/ (Sorry, preview not available. You’ll have to click.) The site has another Intro page here and a menu page here and at least a dozen other pages.
Visit this page and scroll down to learn the contortions you had to do call subroutines and return from them. (I don’t remember doing it this way. But I don’t remember how we did it.)
See this page (well, actually, nearly all the pages) for close-up pics of the computer. See this page for a detailed description of the bizarre architecture of the instruction set, including some assembler and raw decimal code snippets.
This was all done by one Jan Lindeboom at the Christiaan Huygensschool in Rotterdam. On this page he tells his sad story – he was badly injured in a hang-gliding accident and ended up just a little bit too brain damaged to do much else in life, although he eventually found a therapist who was able to help (some).
When I found this page about 8 year ago, I and one of my friends from Berkeley SS-90 days had a brief e-mail conversation with him.
I had one of those cards. It was an easy way to demo Z-80 software because everybody had an Apple so I just had to bring the card with me and I could show them software on their Apple. It had a pretty short useful lifespan though, IBM PCs an clones were proliferating rapidly. I could cross assemble from Z-80 to x86 but the machines were jumping a level in speed, memory, and disk capacity so that old Z-80 software was of limited value moving forward.
Our lab likewise got an IBM PC (8086 I guess. Was there ever an 8088 IBM PC?) Hardly a day after that machine hit the market, the help-wanted ads were full of job listings for IBM PC programmers with five years IBM PC specific experience.
Hey, @TriPolar, have you ever wanted to be BiQuintPolar?
That Univac SS-90 had a bizarre number system too. Every word consisted of ten decimal digits, and every digit consited of four bits. But (hang onto your seat for this), it was a Bi-Quinary number system. The four bits of each digit had bit-values of 1, 2, 4, and 5. The rule was, digits from 5 to 9 used the 5-bit plus whichever other bits made the digit value. The other bit combinations were “un-digits”, a few of which had some miscellaneous odd-ball uses. The machine had a few Boolean operations, so you could manipulate all 16 bit patterns. If you tried to do arithmetic with un-digits, the results were well-defined, but mostly not useful for anything.
This is called Return Oriented Programming - a technique commonly used by malware that scans for known (and trusted) dlls, and then uses code fragments in those dlls to carry out it’s operations - and reducing the footprint and code complexity of the malware.
Both the IBM PC and the IBM XT were 8088 machines. Both 8088 and 8086 are the same 16 bit processor, in the same 40 pin package, but for the 8088, only 8 of the 20 address pins are dual-purposed as data pins: for the 8086, 16 of the 20 address pins are dual-purposed as data pins. IBM went cheap and used an 8 bit data bus. The architecture uses the same bus for Address and Data: a “Von Neumann architecture”. I believe that the address and data bits were decoded for the add-in cards: a “Harvard” architecture.
I have heard about some of those oddball machines. I started my career in the Philadelphia area which had been the center of computer development in the 50s and 60s. I met a lot of the engineers who worked on the development of all that off hardware, Univac, RCA, Burroughs, and numerous military and NASA contractors were in the area. Those things were before my time though, and were all doomed to a life on the island of obsolete computers. The bi-quinary system was similar to BCD except for the extra bit, which I don’t recall the reason for. Many varieties of word length and addressing structures were tried before everybody settled on powers of 2 for everything. Not sure what took them so long.
This is known as the One-instruction set computer and there are multiple different choices of instructions that are all provably turing complete.
Well, even in high school I was smart enough to not do arithmetic operations on random memory locations. So you don’t do anything without understanding what it means.
Though some of the students in the PDP11 Assembly Language class I TAed came close.
Multiplication and especially division are expensive in terms of logic gates needed to implement them. Processors have ALUs (Arithmetic Logic Units) which do both addition and logical operations on bytes and words. Multipliers are in block by themselves and are sometimes pipelined for speed, since the benchmarks tend to do lots of multiplications.
At Illinois they had a computer arithmetic class which I took but remember none of.
Just going to point out the very different scales of complexity for integer arithmetic vs. floating point arithmetic. Many CPU chips integrated integer multiplication and divide while the floating point logic made much more sense to off-load, and then also could incorporate far more instructions than just multiply and divide. The worst case typical of the 8 bit CPUs was performing all arithmetic more advanced than add and subtract in code.
Don’t know anything about how these functions were implemented in IBM 360 and 370 machines where I started with BAL, the instruction set was fleshed out with plenty of arithmetic functions with multiple numeric format options. Initially the hardware module to implement those functions might have been the size of a small a refrigerator
@Schnitte , I bet you wish you hadn’t asked.
This just hit me. The Apollo programming was woven in as core-rope memory and as such wasn’t the programming done as machine code?
They physically wove together read-only memory. You can call that programming if you like, but they didn’t originally create the code that way, it was just data entry. I don’t know how they originally created the code though.
I’ve seen printouts of the code and it was in assembly but the original programming may have been in machine code a la designing the core-ropes and then translated into assembly for the documentation. I don’t know either.
I think that might be the system invented by Hewlett-Packard for their calculators (which also use four-bit nybbles to encode BCD). I don’t remember the details, but it wasn’t the obvious hexidecimal-where-A-through-F-aren’t-used.
And one way that programmers dealt with multiplication and division being more expensive was to do all calculations slide-rule style: Immediately take the log of every input, then do additions and subtractions instead of multiplications or divisions, and only re-exponentiate when you actually need to add or subtract, or (maybe) for the output. My coding-from-Hell job was maintaining an old FORTRAN77 code for stellar modeling, that was mostly written that way.
Not to belabor this point, but what you call the “verb” – the instruction set – is only part of the machine architecture. The other part – the “nouns”, which comprise the registers and, most importantly, the memory addressing model, is equally important. When programming in a high-level language, you only need to know the language itself. When programming in assembler, you need to know the assembler syntax and assembler directives, but you also need to have an intimate knowledge of the machine architecture, usually specified in something that might be called an architecture reference manual, because that’s the level you’re writing in. One might say that for a high-level language, the language alone defines both its syntax and semantics, but for assembly languages, the language defines only syntax, and the semantics comes from the machine architecture itself. That’s what really matters. The fact that the assembler is managing memory addresses for you is very useful, but irrelevant from the fundamental standpoint of what the language represents. From that standpoint, you are writing in the language of the machine, and that’s what fundamentally defines assembly language.
This is quite true, and the PDP-8 is a great example, though it wasn’t a “CPU chip”, it was a set of discrete logic gates plugged into a backplane interconnect. A bit of computer history. The basic PDP-8 had only one arithmetic instruction, TAD (Twos-complement Add). Everything else was derived in software. For extra cost you could get an Extended Arithmetic Element that added divide and multiply instructions and a multiplier-quotient (MQ) register.
But floating point was a whole different kettle of fish. For the longest time it could only be done via a software subroutine library. But then DEC introduced a hardware floating point processor, the FPP-8. It was a bit of an oddball relationship to the PDP-8 because it was larger and more expensive than the PDP-8 itself, and it did in fact implement a much broader instruction set than just floating point computations. It was a classic case of the tail wagging the dog. With the advent of the FPP-8 DEC was able to introduce a full FORTRAN IV compiler for the PDP-8. Later on they introduced an FPP-8 software emulator so that anyone could use the FORTRAN IV compiler, albeit at much reduced speed.

how these functions were implemented in IBM 360 and 370 machines
The variation in capability from the bottom to the top of the line implementations of these machines was quite large. Being microcoded IBM was able to present the same ISA whilst building machines with significant variations in hardware under the hood. This was the really significant big idea that enabled IBM to dominate the mainframe market.
For a lot of work floating point was (and still is) just not an issue. Most business programming didn’t care, nor database work. I remember as a young graduate noting once that I had scarcely ever used floating point capability in any code I had written for over year, and that was only to generate a few performance statistics. Then life took me into the world of high performance computing, and the world of computational science. There everything is about floating point performance. From days of wondering why the heck I was being taught all about numerical analysis to it becoming the bread and butter of daily life. In the modern world, gaming has been the driver of high performance floating point, with the HPC crowd hanging on for the ride. We are seeing the crossover just about complete now. All the GPU vendors provide serious and useful high performance numerical packages for their top end hardware. What you can do with even a mid range $500 GPU card makes supercomputers of yore look like steam driven abacuses. What you don’t get is any sort of nice clean ISA. Getting the performance means you have to work for it. But interestingly, you usually don’t any sort of low level coding access. It is all higher level languages and libraries. FORTRAN in its modern variants can be the weapon of choice. Which for someone raised in the days of the Pascal cult is quite something.