Post Reply 
new HP-IL software implementation in C++20
05-25-2024, 11:09 PM
Post: #1
new HP-IL software implementation in C++20
Lately I've been writing a from-scratch HP-IL implementation in C++20. My older HP-IL firmware implementations in 6502 assembler and in C were rather ad-hoc affairs, but this time I'm following the HP-IL Interface Specification as closely as possible, implementing all of the interface function state machines, local messages, etc. I expect to use this implementation in Nonpareil II to support the PIL-Box and/or virtual loops, but I might also release it separately if it is of use to any other developers.

To my knowledge, most of the HP-IL implementations in real product, from HP or others, use the ad-hoc approach, because they used microcontroller with only 2K of ROM and 128 bytes of RAM. The Interface Specification explicitly states that devices are not required to implement the state machines as presented, as long as the actual behavior matches them. I'm sure the HP engineers spent time validating this for their devices, but I never did any validation for my prior implementations beyond "it works fine with an HP-41C".

I suspect that HP-IL devices with more memory (e.g. 9114, 1630/31) may have implemented the actual state machines as shown, but the only device I've personally reverse-engineered that follows the state machines fairly closely is the HP 92198A/Mountain Computer MC00701A 80-column video interface.

I'm interested in discussing HP-IL interface implementation with others that have done it. In my reading of the HP-IL Interface Specification, I find that the author(s) have made some assumptions that I didn't recognize until fairly far into my implementation. Perhaps I should docu,emt these for the benefit of anyone else who goes down this path in the future (i.e., probably no one).
Find all posts by this user
Quote this message in a reply
05-30-2024, 08:48 AM
Post: #2
RE: new HP-IL software implementation in C++20
Great work Eric, especially doing this from scratch. I have implemented the HP82160A interface for the HP41 in my PICO/HP41 interface, and used the existing V41 sources (Christoph Giesselink), which in turn are based in JF Garniers EMU41. I was really happy to have something existing which I could adapt. But a validated reference source would be good to have, as it may cover corner cases.

Regards, Meindert
Find all posts by this user
Quote this message in a reply
05-30-2024, 11:52 AM (This post was last modified: 05-30-2024 11:53 AM by Martin Hepperle.)
Post: #3
RE: new HP-IL software implementation in C++20
In case you do not have it: attached is a paper by Gary Muhonen about an HP-IL implementation by Mountain View using state machines.
I guess they used the same core for different products.

The paper is part of the available PPC conference papers on DVD/USB stick. I believe I have seen something similar for the Steinmetz & Brown floppy disk drive, but can only find an overview presentation without technical details.

Martin


Attached File(s)
.pdf  HP-IL - Implementation Mountain View 1983LV-3.pdf (Size: 371.98 KB / Downloads: 32)
Find all posts by this user
Quote this message in a reply
05-30-2024, 01:08 PM
Post: #4
RE: new HP-IL software implementation in C++20
(05-30-2024 11:52 AM)Martin Hepperle Wrote:  In case you do not have it: attached is a paper by Gary Muhonen about an HP-IL implementation by Mountain View using state machines.

There is an augmented version of this paper here, with some code snippets.
I don't remember where I got it.

J-F
Visit this user's website Find all posts by this user
Quote this message in a reply
05-30-2024, 03:24 PM (This post was last modified: 05-30-2024 03:38 PM by J-F Garnier.)
Post: #5
RE: new HP-IL software implementation in C++20
(05-25-2024 11:09 PM)brouhaha Wrote:  My older HP-IL firmware implementations in 6502 assembler and in C were rather ad-hoc affairs,

I too started with the 6502, and my first HP-IL implementation (1984) was indeed in 6502 assembler.
It was a HP-IL/Centronics interface (since HP didn't do it) with a HP-GL translator mode to drive a Tandy/RadioShack printer/plotter from a HP-41C Plotter module.
Source code is still archived on my site with the later (1985/86) NSC800-based HP-IL devices I designed for the French Kristal company.
One specificity of the NSC800/Z80 implementation is that it supports the little-known and little-used EAR mode (asynchronous requests), as well as the extended addresses.

I re-used the 6502 code several times with some clean-up and improvements for my first (1986) private ILPER code, then ported it to the x86 first again in assembly, then in C (for integration into my Emu41/71), and much later (2008) as ILPer in Visual Basic for PIL-Box support.

But all shared the same "ad-hoc" approach.

J-F
Visit this user's website Find all posts by this user
Quote this message in a reply
06-01-2024, 05:50 AM (This post was last modified: 06-01-2024 03:54 PM by brouhaha.)
Post: #6
RE: new HP-IL software implementation in C++20
Thanks! This might eventually be useful as a reference, but it won't be suitable to run on small microcontroolers as the memory footprint is fairly large. Part of that might be due to use of some STL containers, which I don't really need. However, in general I think HP's app note on HP-IL device design is a better guide for designing non-controller devices that use a 1LB3 (or later equivalents).

I worked very hard to get the configuration to be generated statically, using C++ templates with constexpr, etc., so that the compiler can leave out all code paths not needed. For instance, a very basic non-controller device would have its configuration statically generated at compile time from an HP-IL capabilities string and a few more parameters. In the following example, an HP-IL interface configuration is created for a "Fidget" electronic instrument that supports talk, receive, service request, extended (secondary) addressing, remote-local, parallel clear, and device trigger.

Code:

constexpr hpil::Configuration fidget_config =
    hpil::configure<"T1,2,3,4,6 L1,3 SR1 RL2 AA2 PP1 DC2 DT1",  // HP-IL interface capabilities
                    "Fidget",   // device ID
                    "\x55">();  // accessory ID: instrument, signal source & measurement

Since the configuration is "constexpr" (which required quite a bit of template trickery under the hood), the HP-IL capabilities string is parsed at compile time, and the structure is static (ROMable). Each HP-IL interface function has a bitfield in the hpil::Configuration, so in this example, fidget_config.c[0], fidget_config.t[3], and fidget_config.sr[1] are true, but fidget_config.c[1], fidget_config.t[5], fidget_config.l[2], and fidget_config.dd[1] are false.

The HP-IL "interface" is then instantiated using that configuration. Here is an example of creating a fidget interface:

Code:

hpil::Interface<fidget_config> fidget1("fidget1");

The configuration is used as a template parameter, which means that the HP-IL interface code will be compiled for exactly the configuration needed, with none of the code needed to support capabilities that aren't used. In this example, the C (controller), PD1 (power down command), and DD1 (device dependent talker/listener) code will be omitted, as will many of the state transition tests and actions.

Note that there could potentially be mroe than one HP-IL interface of type "fidget" in the same program, or HP-IL interfaces of different configurations.

I certainly understand some aspects of HP-IL much better than I did previously.

Once I've debugged it enough that it might be worthwhile, I'll put it on github, and post a link here.
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)