• Please review our updated Terms and Rules here

z80 vs 8080... Which to develop in and why? (from a historical POV)

The 6502 and 68000 also had this problem with their indirect modes. My guess is that teletype machines and early terminals do not support '[' and ']' characters.
The ASR-33 had square brackets, and pretty much everything that came after. ASCII defined them, and it was part of the standard upper-case-only character set. Early hobbyists had trouble getting "full ASCII" keyboards, but that would not be a reason to cripple an assembly language, especially for the 68000.
 
OK, let me try again then. Much of the early microprocessor software was done using a cross-assembler running on an IBM mainframe. EBCDIC does not have those characters.
 
The ASR33 does have brackets in its character set. See shift+K and shift+M:
teletype-model-33-top.jpg

I'm reasonably sure that the VT05 does also.
 
OK, let me try again then. Much of the early microprocessor software was done using a cross-assembler running on an IBM mainframe. EBCDIC does not have those characters.
There were solutions out of this: http://people.csail.mit.edu/saltzer...ents/MSPM/bb-3-02.670330.punch-card-codes.pdf
I would recommend that < and > be used, since neither is part of the Z80 assembler syntax. But not parentheses! Even CDC 63 character display code has square brackets! Square brackets were part of Algol-60, before EBCIDC was introduced.
 
Last edited:
Well, I remember programming Pascal on a mainframe and using:

Code:
(* for {
*) for }
(. for [
.) for ]

My last guess is that assemblers at the time had rudimentary expression evaluators. Strictly left to right with no operator precedence and parenthesis cannot be used for grouping. So there was not a strong reason not to use () for indexing. Cross-assemblers were written in FORTRAN in those days and it used parentheses for arrays. So did BASIC. Final answer as I am out of ideas...
 
OK, let me try again then. Much of the early microprocessor software was done using a cross-assembler running on an IBM mainframe. EBCDIC does not have those characters.
I know that PDP-11s and other minis, and even the VAX, were used extensively for this sort of thing. That makes more sense than using the precious resources of a mainframe, and one that forced you to use EBCDIC at that.
 
My last guess is that assemblers at the time had rudimentary expression evaluators. Strictly left to right with no operator precedence and parenthesis cannot be used for grouping. So there was not a strong reason not to use () for indexing. Cross-assemblers were written in FORTRAN in those days and it used parentheses for arrays. So did BASIC. Final answer as I am out of ideas...
Mainframe assemblers? Heck, I've used some with assembly-time multidimensional arrays and strong datatyping. For a sample of 1960s S/360 assembly sophistication, have a look at some of the DOS or OS/360 I/O macros. Even PL/I had a powerful preprocessor that put C to shame.
I suspect that the real reason experience was lacking in the language designers. You have to remember that, before 1970, the assembler was the linchpin of a system's software. MPUs were still pretty new in the early 1970s.

I know the folks who designed Sorcim's ACT cross-assemblers. CDC Mainframe programmers all--and it shows. Consider, for example, the distinction between the origin (ORG) counter and the location (LOC) counter--or even the VFD pseudo-op--all holdovers from CDC 6000/7000 COMPASS assembly. Remarkable for a cross-assembler suite hosted on CP/M-80.

I note the same lack of sophistication in some of the MCU assemblers--probably because assembly is now considered to be the back-end of HLL implementation. The progress of the Microsoft macro assembler (MASM) was agonizingly slow before version 6.
 
I note the same lack of sophistication in some of the MCU assemblers--probably because assembly is now considered to be the back-end of HLL implementation.

I had trouble even finding assemblers that work under Windows 10/11.... :( The first time I tried to assemble a z80 source, I had to download a cross-assembler for Linux and ended up writing my own assembler for z80 for my project, which might not be very powerful or have good features, but it's amazingly fast on modern hardware even given how poorly it was written.

It was a good way to get back into programming z80 though. And it's been a while since I found a bug in it, though I would definitely write it differently if I did it again.

I never found the brackets issue a problem working with z80, but maybe the difference between the two is why I have so much trouble with 8080 menmonics.

It also annoys me when I find deeply embedded comments in Assembly within the code, rather than at the declaration with the EQUs - eg, if there's a reason to have a constant, based on other constants, which are declared with EQUs, why not declare the new constant with an EQU, so that when the code references it, there's a clear label that represents why the calculation was made.

I wonder if being introduced to something like that is kind of similar to Djikstra's take on teaching people basic.... I've probably been mangled by it.
 
Having written my own assemblers, I can say that it's a pain in the rear to deal with parens in the assembler syntax vs parens in numeric expressions. I think I mostly try the syntax way first, and back up if it doesn't parse. Yes, Z80 and 68000 are the big offenders on this.

I'm also somewhat annoyed by how some old assemblers would allow comments without a semicolon or other comment marker, because that can basically prohibit you from using blanks in the operand field to make your code more readable. It's also good to get an error when you've got too many operands, rather than silently being ignored as comments.
 
OK, I thought I figured this out, then I realized I didn't, then I thought it was an Octal joke, but then realized it wasn't that either...

So I'm going to ask the question - What is a Sixer? The closest I came was "6 bit cpu" but I can't think of any relevant 6 bit CPUs....

David
Back in the day things would often get rather heated between people who preferred CPUs who's names started with a '6' (the Sixers) vs people who preferred CPU's that started with an '8' (the Eighters).

More recently you could still see a bit of the "discussion" in a cleaned up suitable for family viewing version in ads like these:


To shift gears for a bit, I always thought the Motorola M68K chips were the top of the heap due to their lack of fiddly segment registers and a nearly orthogonal instruction set. Having a real MMU for the later versions was a plus. I remember someone calling it a "VAX on a chip" before you could actually get a VAX on a chip. (Now I've probably pissed of the VAX people.)

But because in the real world programmers have to deal with bosses who walk up and say "Make this work on that." people who did the work were rarely in a position of getting to decide how to implement things.

A computer science prof once told us that IBM never made the most technically advanced machines. IBM became the powerhouse it was because they made the most marketable machines.

So aside from a brief stint in MAC world, and use of a whole bunch of chips in WECo's #5ESS telephone switches, the MC68k family didn't make it in the marketplace.

"And that's all I have to say about that" -- Forrest Gump
 
Last edited:
...
A computer science prof once told us that IBM never made the most technically advanced machines. IBM became the powerhouse it was because they made the most marketable machines.
...
I also find this true. I think the other thing that made IBM successful was their service. An IBM customer was never left hanging. No matter how boring the technology might be, an IBM customer knew they were going to get the job done. Having lived through the early days of micros (as experienced by small businesses), the entry of IBM into that world made businesses heave a great sigh of relief - but it also essentially killed innovation - as well as any competition. Prior to the announcement of IBM intentions, there were some pretty interesting systems and technologies being explored. Things changed, for the worse in my opinion, after that.
 
...
My last guess is that assemblers at the time had rudimentary expression evaluators. Strictly left to right with no operator precedence and parenthesis cannot be used for grouping. So there was not a strong reason not to use () for indexing. Cross-assemblers were written in FORTRAN in those days and it used parentheses for arrays. So did BASIC. Final answer as I am out of ideas...
This sounds plausible. There wasn't a conflict with using parens since they weren't part of the expression syntax.
 
FORTRAN also used parens for grouping in expressions, as well as in I/O control statements. So I don't follow the logic. It also had no concept of white space or reserved words.
 
FORTRAN has a more complex parser that can differentiate between the various contexts where parens appear. The theory here is that the assemblers did not accept parens in expressions, so there was no need to have to differentiate between parens for indirection and thus the assembler never tried.
 
Okay, I'll accept that, so long as operator precedence is made clear. In other words, does 3+6*3 result in 21 or 27? Parens do have the advantage of making expression evaluation order clear.

As far as statement columns are concerned, I like CDC's convention. Anything after column 26 separated by whitespace from the last operand is a comment, which was quite common.
On the other hand, consider IBM 1620 SPS says that after one exhausts the required number of operands, everything else is a comment. It was common practice there to simply prefix each inline comment with three commas.

A friend of mine wrote the AMC assembler for the Z8000--there parentheses are used in comment delimiters, expression grouping operators and to signify an index, as well as list delimiters in macro calls.

 
Last edited:
I think that the most complicated assembler I've ever used had to be this one. You're into the manual well over 100 pages before machine instructions are even discussed. Written by a bunch of Canadians. It was so unpleasant to use that most systems programmers just used the IMPL (a dialect of LRLTRAN) compiler and its inline assembly feature--and that included the operating system itself.
 
Last edited:
OK, now that the topic is swinging that way, I'm going to ask about why do assignments go VARIABLE EQU VALUE, when from a lexical analyzer POV, it makes more sense to go EQU VARIABLE,VALUE - especially with z80, since it tells the z80 that the next assignment is a variable, and clearly separates the value...

Or did I miss something important there?
 
I think it is somewhat tradition, but even back in the days of the Z80 the assemblers needed to be as slim as possible. In the days of writing assembly language on punch cards things were done more-stricty by fields (columns), and even with less-rigid assemblers like the ones for CP/M it helps to know what to expect. Using VARIABLE EQU VALUE not only makes sense to programmers (that learned FORTRANs VARIABLE = VALUE syntax) but makes the parsing simpler as you always parse a variable name (more correctly, a "label") in the first field, then an opcode, then operands. VARIABLE EQU VALUE uses the same basic parsing as LABEL CALL SUBR, and the differentiation only comes when you interpret EQU vs. CALL.
 
OK, now that the topic is swinging that way, I'm going to ask about why do assignments go VARIABLE EQU VALUE, when from a lexical analyzer POV, it makes more sense to go EQU VARIABLE,VALUE - especially with z80, since it tells the z80 that the next assignment is a variable, and clearly separates the value...

Or did I miss something important there?
Variable = value is the way I read it. But consider the following in AVR assembly:
Code:
       Ascii mnemonic codes

.nolist

.equ    Ascii_nul       =       0x00    ; NULL
.equ    Ascii_soh       =       0x01    ; Start of header
.equ    Ascii_stx       =       0x02    ; Start of text
.equ    Ascii_etx       =       0x03    ; End of text
.equ    Ascii_eot       =       0x04    ; End of transmission
.equ    Ascii_enq       =       0x05    ; Enquiry
.equ    Ascii_ack       =       0x06    ; Acknowledge
.equ    Ascii_bel       =       0x07    ; Bell
...and so on...

As I've said before, get a dozen or so under your belt and nothing will look strange.

Also, note that the IEEE tried to standardize assembly syntax via IEEE Std. 694-1985. It didn't work.
 
I'm also somewhat annoyed by how some old assemblers would allow comments without a semicolon or other comment marker, because that can basically prohibit you from using blanks in the operand field to make your code more readable. It's also good to get an error when you've got too many operands, rather than silently being ignored as comments.
Worse than that, it has led to bugs which were difficult to detect.

There was a case in FLEX when something like
Code:
    ldaa    $45,X
assembled as
Code:
    ldaa    $45
because a space was typed by mistake before the comma. Requiring a comment to start with a special character would have caught that error.
 
Back
Top