A couple of errors in the IBM 1410 System Fundamentals manual

For starters, I should say that the IBM Field Engineering Instructional materials, which I relied on heavily when creating my IBM 1410 Simulator software are excellent, especially considering these documents were typeset in more than a decade before anyone had heard of a word processor.

Nonetheless, I stumbled into two errors in the IBM 1410 System Fundamentals manual, S23-2589, this week. Both are instances where the output signals from gates are different from what is shown in the document.

The first one I ran into was the first Single Shot that I came across in the diagrams, SMS card type DHE, part number 370262. The timing diagram shown in figure 110, page 93 of the manual shows a negative going input pulse triggering a positive going output pulse. An analysis of the electronics in the first of two SMS card manuals (which have no number) and the use of this card in an ALD, 12.60.20.1, makes it apparent that a negative going incoming pulse creates a negative going output pulse. (This was implemented in my FPGA VHDL generation by triggering a counter on the leading negative going input pulse, which then counts down to 0.)

The other error applies to card type DFZ (and its companion, DGA), which I ran into on ALD page 12.61.13.1. The timing diagram in figure 107 on page 92 of the System Fundamentals manual shows NAND logic: If both inputs are high, the output goes negative. However, analysis of the circuit for DFZ, part number 370241 makes it apparent that it is actually NOR positive logic: If either input is high (approximately 0v), then the output is low. Only if both inputs are low (negative voltage) is the output voltage high. This was “sussed out” by looking at the intended logic on the ILD.

The first missing IBM 1410 ALD Sheet

Ran into the first case of needing to reconstruct an Automated Logic Diagram (ALD) page, as part of my ongoion IBM 1410 FPGA implementation project.

The page for the 2nd and 3rd Scan Controls, 12.30.04.1, was missing from my diagram set. I did have information about how many gates from which cards were present on the diagram, gleaned from the card location charts. Fortunately, the Instructional Logic Diagrams (ILD) covered the missing page. Between the two I was able to construct the page, using the original gates, and other than logic block placement on the printed sheet, I expect it is pretty accurate.

I only hope all of the missing pages are so “easy”. Easy is in quotes because on the 3rd Scan Control latch, there is a collector pullover to logic 1 to reset the latch that is not common. That same situation exists with the same card type (DFA), so I was able to verify the gate utilitzatin.

IBM 1410 ALD Volume II Completed

I have reached a sort of milestone in my efforts to replicate the IBM 1410 Data Processing System in an FPGA. The Automated Logic Diagrams (ALDs) comprise 11 volumes – I through XI. Volume I is power supply and general items, and so does not play into the process very much.

The milestone is that I have completed generating and running HDL test benches on all of the pages in Volume II (except for one, having to do with a clock, which is not critical, and may or may not be addressed later.)

I really am surprised about a couple of things. First, while I have fixed a smallish handful of bugs in the data gathering / HDL generation application, there really have not been very many problems in that area. The second is that, aided with the information in the Instruction Logic Diagrams (ILDs) in my testing, I have found very very few issues with the data that was actually captured – relatively few “clerical errors” – few enough that I am pretty surprised.

On to Volume III!

Instructional Logic Diagrams and Automated Logic Diagrams

As part of my project to create a Field Programmable Gate Array implementation (FPGA) of the IBM 1410 Data Processing System based on Automated Logic Diagrams (ALDs), I decided to look at using the Instructional Logic Diagrams (ILDs) to guide my testing, rather than using the ALDs directly.

The ILDs are written completely in “positive logic”. Going in, I sort of expected a pretty imperfect match – that the ILDs would not have all the signals, and be somewhat superficial in their treatment of the logic. For the IBM 1410, the circuits were:

  • AND
  • OR
  • Inverter
  • Indicator (Lamp)
  • Single Shot
  • Latch (Reset/Set)
  • Trigger (Flip Flop)

To my surprise I found that the ILDs are very accurate, and a great testing guide, providing a second view of the logic – a kind of redundancy check against my entry of ALD data into my system. They are good enough that they have given me considerable confidence that I can use them to help “fill in the blanks” related to the handful of ALD pages I am missing, and also for some of the IBM 1414 peripheral controllers for which I do not have ALDs.

Updated 6/28/2020, I discovered that not all of the ALDs are represented in the ILDs. I also had an interesting case where I thought, for a while, an ALD and the ILD that represents it were mismatched, but I was incorrect – the ILD matched the logic perfectly.

In 1962 IBM published an article in the IEEE Transactions “Information Processing — from Engineering Drawing to Manufacture” by R. K. Grim that describes how the data the ended up generated ALDs was entered and the ALDs produced, but it does not mention where the ILDs come from. They are definitely artwork – not machine generated per se. The article did not address ILDs.

I have corresponded with IBM to see if they might have, in their archives, the data from these 1960s era engineering systems, but it seems that they do not (or have lost the pointers to them.)

It seems that the SMS automation was first done using an IBM 709, then they later added IBM 7090 and IBM 1401 systems (which of course could not have been there for the original design of the IBM 7090 and 1401, which used the SMS system), using tape files. The article also describes future plans to use a 1301 disk drive attached to an IBM 1410 for remote (tele-processing) access (which was supported by the IBM 1410-PR155 operating system.

The accuracy of the ILDs is such that I expect that they evolved along with the design of the machine and entry of the data used for the ALDs. I’d expect that doing it after the fact, from the ALDs, would be quite error prone — besides the one difference I have found is in the signal names, which do not always exactly match those used in the ALDs, but are close enough that the intent is obvious. But I don’t know the timing: which came first — the ILDs or the ALDs, or did they perhaps begin together in some form and co-evolve?

In summary, it seems to me that one could do a pretty decent positive logic implementation of IBM machines of that era using these ILDs. This was a real eye-opener.

IBM SMS Generation Application

A lot of development of the IBM SMS data collection / HDL synthesis application has occurred over the past couple of weeks. Recent posts discussed generation of the IBM 1410 oscillator and main logic clock, and the I Ring – the instruction readout ring.

The application now supports Lamps, as well.

Also, the application now supports gathering signals into an HDL bus for economy of representation. Bussed signals are defined in a database table which translates an individual signal name to a bus name and which bit of the bus it occupies.

Update 6/20/2020: In this most recent week, support for switches has also been completed.

Update 6/27/2020: In this most recent week, I added the capability import information from a CSV file describing “bused” signals to create HDL bit vectors.

IBM 1410 FPGA Simulation – The Brainstem

Additional work has resulted in another step forward in my efforts to reproduce the IBM 1410 (in particular, the IBM 1411 CPU component) in an FPGA.

I now have pages 11.10.0*.1, 11.10.10*.1 and 11.10.20*.1 generated and tested (see the image, below).

One very hopeful sign is that easily 90% of the effort in the last couple of days was enhancing the application to preserve a section of VHDL declarations in a test bench, and debugging VHDL test bench code. The generated HDL had performed nearly flawlessly.

In the image below one case see the following (MS… signals are a translation of -S IBM signals – active low. PS are +S – active high.

  • The simulated 100 MHz FPGA clock
  • The 1.5 MC (MHz for you modern people) system oscillator
  • The two phase system clock pulses
  • A test bench provided MS_PROGRAM_RESET_3 signal, provided by the test bench.
  • The logic ring gates A through K and R through W. The latter are only active in the last part of the test, and represent an overlapped I/O request (cycle-stealing, if you prefer)
  • A test bench provided PS_LAST_LOGIC_GATE_1 signal – telling the logic gate ring that it can go back to the initial “A” state.
  • A non-overlapped I/O cycle request (E Cycle means a cycle taken for the first, or E channel – not to be confused with logic gate E)
  • An overlapped I/O cycle request on the first channel
  • The PS_COM_DISABLE_CYCLE which “freezes” the logic ring – overridden by the non-overlapped E cycle request.
IBM 1410 Logic Gate Ring Simulation
A Xilinx Vivado simulation of the IBM 1410 Logic Gate Ring

The FPGA Simulated IBM 1410 has a “pulse”

Having spent the past few months cleaning up my IBM 1410 SMS database program, and posting it to github at https://github.com/cube1us/IBM1410SMS , I have spent the past couple of weeks focused on the HDL (currently VHDL) generation, using GHDL and Xilinx’s Vivado toolset, with an eventual destination of my Digilent Nexys4 FPGA (Field Programmable Gate Array) board.

After fixing a few bugs, and implementing the oscillator (by way of a counter/divider from the 100 MHz FPGA clock), I loaded the results into the FPGA, and as show below, my IBM 1410 now has a clock, running at the right frequency for an IBM 1410 with the accerated throughput feature, as shown below:

IBM 1410 FPGA Clock
IBM 1410 FPGA Clock

On the original machine the lower signal, on channel 2 of the oscilloscope, was derived from the first using a delay line – about 330 ns of delay. Kinda hard to do with an FPGA. 😉 So, I implemented delay lines using a series of flip flops clocked by the 100 MHz FPGA clock – so, in this case, there are 33 of them.

This signal is not simulated – it is a real signal that exists in the FPGA.

Python: the Good and the Mostly Bad

(Updated 5/31/2021 – another for the “bad” list – see below.)

Let me admit, right up front, that I have some biases against Python. I have been programming in C and its descendants since 1976, and have used Perl for more than two decades. In particular in the past I have regarded Python’s abandonment of the usual c-style { and } for blocks particularly irritating, along with the requisite indentation rules that go along with that, particularly eccentric and irritating.

You can add to that formal training in compiler design and construction dated back to the 1970’s, and extensive experience with many different machine language assemblers and a long litany of higher level languages including BASIC, FORTRAN, ALGOL, COBOL, PL/I, LISP, SNOBOL, UNIVAC PLUS, C, C++, C# Perl, Java, javascript, PHP and more. I am no stranger to trying new things.

So, as an experiment, when I needed to write some code to check out the logical integrity of my IBM 1410 SMS database, I decided to try it with Python, since I had already read some of the “Learning Python” book by Mark Lutz and David Ascher (pub. Oreilly). And since this was a one-off that would not require ongoing maintenance, it seemed an ideal time to give Python a try.

What I found did not disappoint – I do indeed really dislike Python with good reason. And here is why.

On the Good Side

Python does have some nice features.

  • It has several IDEs — but since I was already using Microsoft’s Visual Studio for my project, I used that for coding.
  • I found its error checking for things like unassigned variables and miss-matches when assigning to a list (tuple) of variables attractive.
  • The tracebacks it provides on errors are extremely useful.
  • Finally, because it is still relatively new and because it has a rich library to begin with, it doesn’t (yet) suffer from the same kind of “CPAN Hell” that I have encountered with Perl from time to time.
  • And, an update about that: In July 2021 I wanted to install some code developed in Python that needed adjunct libraries – and very specific versions of those, at that. It suggested isolating them in a Python “virtual environment” to avoid any potential version conflicts on those modules, however, at least with ActiveState Python, the venv module does not function correctly, complaining about missing executables venvlauncher.exe and venvwlauncher.exe. Instead, ActiveState has chosen to include a similar module “virtualenv” – and also provide a platform-native tool called the State tool. Thus, it seems we have already entered the portal to “PIP Hell”.

But…. that is about it. I found nothing else to recommend in Python.

On the Bad Side

The list on the bad side is much much longer. The pity is that if it were not for the obstinance of those in control of the language, ALL of these would be easy to fix. Most of these cost me measurable time over the course of five days I spent developing my 850 line script.

And here is another “bad” entry, from 5/31/2021 . I use a Python based application, “weewx” to monitor my weather instruments and post to the web pages on this site (and weather underground). Last week my weather station started having issues, and I decided to replace it. As part of that, I decided to upgrade where I could – my Linux OS was quite old, the weewx software was a couple of years old and the Python in use was 2.7. Well…. guess what. This older version of weewx will not run under Python 3 because they decided to remove the file() method, replacing it with open(). Would it really have been so very very horrible to keep the old method around for compatibility sake? Could you imagine doing that to “C” programmers, or any other reasonable language? No, of course not. Of course, I do plan on upgrading weewx, as well, but this kind of things makes for “coupled upgrades” where interdependencies force upgrades to multiple components of a system at the same time – and this is not a good thing. (So, another instances of “rendering old code inoperable” as mentioned below.

First lets tackle the whole braces vs. indentation thing from a pragmatic standpoint, rather than just a religious one. This list is long, so I’ll do it with bullet points:

  • It already has half the combination there: you have to introduce blocks with a colon (“:”) anyway.
  • Any modern IDE can parse and clean up indentation anyway. This causes me to discard the various arguments that the indentation is somehow better because of the discipline it enforces on programmers.
  • Then there is the entire tab vs. spaces thing. Within a given IDE it tends to not come up at all, but, if you move code to another IDE, or someone else uses different tab to space conventions, watch out!!
  • It is so easy to do, and so compatible with Python, that a front-end, “pythonb” exists to translate from brace style to indentation. So, Python “gods”, why not make it an option?
  • The indentation rules make a mess of ordinary token-based parsing. As a result, you cannot break just any expression after any token as one can do with most other languages. No, you have to put the expression in what would otherwise be redundant parentheses. This costs real programmer time.
  • This same issue tends to confuse IDEs when you do continuations. It also means that every time you introduce a new block, the IDE starts in error mode because you don’t yet have anything indented below it, which slows the IDE down. More wasted time.

Next up comments. Python has no multi-line comments. I suppose some IDE’s can do that automagically, but Visual Studio didn’t seem to have a way to do that (even though it can do so for C#). So instead, when I wanted to make major changes, but keep the old code around just in case I either had to do a source control system (git or svn) commit of code that was not yet syntactically correct (which I really don’t like to do), fudge temporary code in (which I really don’t like to do), or copy the code into some kind of file-backed clipboard or text file to hold for a while. More wasted time.

Rendering old code inoperable, particularly between version 2 and version 3. Now, many languages and environments have had this issue over the years, but usually only on the fringes of what programmers do, leaving most code from and older versions compatible with newer versions. But not Python 3. All your old Print statements fail, integer representations change, octal constants change, and on and on. Again, this costs real time, when someone has to convert. I ran into it when the examples from my Python 2.3 book failed. So not only does this affect old code, it affects all the old publications and tons of examples out on the Internet. You guessed it: more wasted time.

Python also abandons some common-sense standard object methods one sees in most other languages. For example, converting an integer to a string automatically, and/or not having basic object notation compatibility so that things like object.string() or object.toString() or object.len() or object.length() or string.toint() when it makes sense. Instead you have to use a “built in function” to do this sort of thing, which can really mess up beginners trying to understand objects because the primitive types don’t behave like objects. This is especially bewildering in a dynamically typed language.

Even a Python dictionary can provide its string representation, but not primitives. How very primitive.

And, while you are at it, why not provide an implicit string to integer conversion too, based on context, and trigger an exception (which Python is really good at) if it fails? In languages like C# where good error checking up front is paramount, it is understandable that you have to code for this. But not in a “scripting language” like Python.

The lack of built-in integer to string conversion is particularly annoying in dealing with databases — you have to be constantly aware of whether a column is integer or a string. Now, when writing “real” code that is going to be around for a long time, that is perfectly fine (well, almost), plus you have strong compile-time type checking to help out. But when trying to write a script in limited time, in a dynamically-typed language, it gets in the way and wastes time.

This affected me in a several ways:

  • It prevents useful auto-completions for these basic things. You have to lead with an arbitrary function name, instead of simply typing the object you want, hitting “.” and then picking the method you want. Time lost.
  • It introduces parentheses around things like str(string) and len(string) which also makes editing harder. More time lost.
  • You can reasonably code tupleVariable.count(), but not stringVariable.count() . The latter exists, but counts sub-strings, not symbols in the string.
  • It results in str() sprinkled all over the place to do basic integer to string conversion. (Fortunately, str(string object) works, otherwise I probably would have thrown in the towel when I first ran across this. )
  • I had to be really careful to be consistent with indexes into Python dictionaries (akin to Perl hashes), because dict[i] does not match dict[str(i)]

Single element tuples are problematic because the designers chose () to designate a tuple. So (“string”) is just the same as “string” whereas (“string1″,”string2”) is a tuple. But () is an exception, and creates an empty tuple.

When I was retrieving data from MySQL, if a row had only one column, I could not use “(variable) = cursor.fetchone()” for example. I had to use “variable = cursor.fetchone()[0]”. This may well actually be a bug in the MySQL library, but it was very confusing until I figured it out, and cost me time. (I just realized that maybe if I had used “(variable,) = cursor.fetchone()” it may have worked. )

Also, the result is also that a print(singleElementTuple) has a trailing comma where as a print of (twoElementTuple) does not. (really, to be consistent, the notation for a zero element tuple should be (,). Instead, that generates a syntax error. Its just inconsistent as heck.

And these were annoyances that I found after only maybe 10 hours of time.

Hello world!

Welcome to my website, which I have just released in November, 2019. This is my Blog section – if you are looking for something else, then see the menu at the top of the page, or visit my home page.

My website used to be at webpages.charter.net/thecomputercollection . However Charter (now Spectrum) stopped supporting subscriber webpages, so I moved it to a linode system. Their prices are great, and support has been availability has been great as well.

The site has been restructured, although quite a few similarities exist between this site and my old one. One obvious difference is the sidebar over on the right hand side, and the existence of “posts” — a capability provided by WordPress (a link for which is at the bottom of the pages in the website).

You can visit this link to see what the old one looked like.