Porting INMOS T400/B004 Development Tools to Linux

Brian Holt6 min read
Other ManufacturerOther TopicTutorial / How-to
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

The restored chain compiles, links, and runs an occam program on the physical IMS T400B, producing The answer is 42. Reach that result by commissioning each boundary separately: Linux host, USB2ISA adapter, IMS B004 registers, boot link, target memory, packet transport, and TDS 2.0 services.

Reject the usual quick fixes

Do not start by repeatedly changing compilers, retransmitting the boot image, or byte-swapping every multibyte field. Those actions change several variables while the failing boundary remains unknown. An idle target may result from reset control, unreadable status, a broken boot transfer, malformed packets, or a missing host service.

Quick fix Why it fails Test first
Retry the complete launch Hides whether reset, boot, or runtime messaging failed Host-link register access
Apply global byte swapping Corrupts fields that were already encoded correctly Known packet fields at the byte level
Trust the nominal RAM size Aliased addresses can make a smaller working region appear larger Non-destructive address-pattern tests
Port the later server first The target software may expect the older multiplexed interface Identify requests generated by TDS 2.0

Write down the commissioning chain as Linux -> USB2ISA -> B004 -> T400 -> TDS2 -> occam compiler -> executable. Gate check: name one observable test for every arrow before changing software.

Prove direct host-link register access

Start at the first hardware boundary. The Linux program must reach the B004 host-link registers through the USB-to-ISA path without register selection, access width, or ordering errors. A successful process start proves only that Linux opened the adapter; it does not prove that a transaction reached the board.

  1. Read the applicable host-link status through the direct register-access path.
  2. Repeat the read and compare stable bits with bits that reflect link state.
  3. Exercise reset control, then read status again.
  4. Record the raw values before interpreting them in higher-level code.

If register reads are fixed at an all-zero or all-one pattern, stop at the bridge-to-board boundary. Check adapter configuration, board selection, access width, and physical seating before touching the TDS server. Gate check: reset control produces a repeatable status transition visible from Linux.

Bring up the boot link one transfer at a time

The T400 cannot process the development protocol until the boot-link transfer succeeds. Reset and boot are separate tests: reset places the processor in a known starting condition, while the boot link delivers the first executable content. A status transition without target activity does not prove that the payload arrived intact.

  1. Assert and release reset using the already verified control path.
  2. Confirm the expected post-reset status change.
  3. Send the boot payload while logging every host-side byte count and status observation.
  4. Compare the requested transfer length with the length accepted by the host-link layer.
  5. Wait for a target response before starting the TDS protocol.

Diagnose the earliest mismatch. No post-reset transition points back to control or register access. A partial transfer points to link flow handling. A complete transfer followed by invalid messages points toward packing, byte order, or the wrong target-side interface. Gate check: the target accepts a complete boot transfer and returns a repeatable first response.

Confirm the T400 and external RAM map

Use the T400 boot-ROM PEEK/POKE capability before loading a larger runtime. It gives a small diagnostic path for proving processor execution and checking the external memory independently of the compiler and file services.

  1. Read a location in the intended RAM region and save its original value.
  2. Write a test pattern, read it back, then write and verify its complement.
  3. Restore the original value.
  4. Repeat at separated addresses across the claimed range.
  5. Write distinct patterns to address pairs and check whether changing one changes the other.

The physical configuration uses 1 MiB of external RAM, but capacity is proven only when separated addresses retain independent values. Mirrored results identify address aliasing rather than a successful full-range test. Avoid destructive locations and restore every value used for diagnosis. Gate check: the processor completes PEEK/POKE operations and the tested RAM addresses do not alias.

Port the host C path without changing the wire format

Legacy host-side C often relies on assumptions about integer width, structure padding, alignment, and byte order. A modern Linux build can compile cleanly while emitting a different packet layout. Treat the protocol as an array of bytes, not as an in-memory C structure.

  1. Replace implicit integer-size assumptions with explicitly sized storage selected for each decoded field.
  2. Serialize and deserialize multibyte values byte by byte in the order required by the captured protocol.
  3. Keep transport lengths separate from payload values.
  4. Log complete packets at the host-link boundary before multiplexing or service dispatch.
  5. Compare request type, channel identity, declared length, and actual byte count for each exchange.

Do not apply one global endian conversion. Text bytes, single-byte control fields, and packed length fields may require different handling. Compiler structure packing directives can reproduce one build layout while leaving the protocol dependent on toolchain behavior; explicit serialization makes the boundary testable. Gate check: repeated target requests decode into the same fields and can be re-encoded to the same byte sequence.

Implement TDS 2.0 services and run the full chain

The breakthrough path uses the older TDS 2.0 host interface rather than relying on the later server model. Its host protocol multiplexes logical channels over the physical link, so transport success is not enough. The Linux server must route each request to the matching terminal or file service and return the response on the correct channel.

  1. Decode the channel-multiplexing envelope before interpreting the service payload.
  2. Implement terminal input and output so the original environment can interact with the Linux host.
  3. Implement the file operations requested by the editor, compiler, and linker.
  4. Keep channel state isolated; never let one request consume bytes belonging to another logical channel.
  5. Create source in the original editor, compile it, link it, and launch the resulting executable on the physical T400.
  6. Capture both host-side protocol completion and target-side program output.

A working terminal alone does not prove file service operation, and a generated binary does not prove target execution. The end-to-end acceptance result is the physical IMS T400B executing the compiled program and returning The answer is 42. Gate check: repeat the complete edit-to-execution sequence after a fresh reset without manual packet intervention.

FAQ

How do I tell whether the B004 or the T400 boot is failing?

Read B004 status, exercise reset, and confirm a repeatable transition first. If that passes but the boot payload is only partly accepted or produces no target response, move the fault boundary to boot-link transfer handling.

How do I test the 1 MiB RAM for address aliasing?

Use boot-ROM PEEK/POKE to place different patterns at separated addresses, then verify that changing one address does not change the other. Save and restore original contents around every test.

How do I fix endian and packet-packing errors on Linux?

Log the raw packet bytes, decode each multibyte field explicitly, and compare declared lengths with transferred lengths. Avoid casting byte buffers to C structures or applying a global byte swap.

When should I stop troubleshooting the INMOS host chain?

Stop when reset cannot produce a repeatable status change, raw register access remains invalid after checking the adapter and board connection, or diagnostic writes risk unknown memory locations. Record raw status values, packet bytes, transfer counts, and the last passing gate. Escalate to the available official support channel for the component that owns the failing boundary before applying more unknown register or memory writes.

Back to blog