Intel/Pittman 4004 Assembler for SIM-04


This Web page created Dec 29 2024. It's part of a number of Intel 4004 4040 repair and restoration Web pages I have. This page links to my Web content on the Intel 4004 and 4040 items and artifacts I have. - Herb Johnson

The Intel SIM-04 is a single development board for 4004 for 4004 and 4040 development. Intel also provided a 1702 or a 1702A programming board to work with the SIM-04 across a small chassis. Tom Pittman, an early 4-bit and 8-bit computer programmer, developed a ROM based assembler for this board. IN recent years (2020's) early Intel programmer/developer Dwight Elvey obtained the ROM sets for both boards and disassembled them. I discussed with Dwight in 2023-24 his results and produced my own disassembly which compliments his. - Herb JOhnson

SIM-04 ROM based assembler and disassembly; SKIP instruction; 4004 stack

In 2018 Dwight Elvey initiated an online discussion in this vintage computing Web forum, about a 4004 design he developed from a project overseen by Gary Kildall as a professor at the Naval College. The discussion progressed in 2020, to a discussion of a set of Intel intellec SIM-04 (4004 coded) ROMs he dumped and disassembled. Later he obtained similar ROM images to verify. These four 1702 ROMS, marked A0740 through A0743, contained an Intel 4004 native assembler. "It was written by Tom Pittman, in the early Intel days" on an Intel SIM-04, a 4004 development board, such as Dwight owns and still operates. (Other Intel native assemblers ran from RAM or ROM in the Intel intellect 4/40 systems.) Archives of Intel 4004 4040 documents include an assembler manual. Dwight added the ROM images to his Github site for his 4004 project.

At this Github link, Dwight describes the four ROMs as an assembler and archived the ROM binaries. "With some help from Dave Roberts, I fixed an error in my [SIM-04] simulator and was able to successfully run Tom's assembler. Instructions [for the assembler] can be had from bitsavers.org in the "MCS4 user Manual", in Appendix F. "Dwight also archived a set of PROMs for programming a 1702A with an additional card for the SIM-04. Read his notes there for some details, other details are below.

In Feb 2023, I had email conversations with Dwight Elvey, Sid Jones (an intellec 4/40 owner), Jon Hales (works with vintage intel at a UK museum), Al Kossow. Dwight brought up the 4004 assembler ROMs at Sid's request.

During 2023-24 I had discussions with Dwight Elvey about disassembly of the four ROMs. Contrary to his GitHub notes, he believes he has a good set of those ROMS and their code. But it's hard to interpret the code as Tom Pittman used a few tricks to jam the assembler into four 1702 ROMs for 1Kbyte of total 4004 code space. One trick from the era is using a JCN jump-never two-byte instruction, as a "SKIP" to hide a one byte instruction as the JCN address byte. SKIP will be explained later. Other coding tricks by Pittman are harder to figure out. There's alsosome variance, in how Intel assemblers (and Dwight's disassembler) processed JCN condition code syntax. Additionally, as in any disassembly, it's hard to know what is code and what is data.

some actual code results

Dwight Elvey produced a disassembly; however he uses a FORTH-like syntax which is unfamilar to modern programmers. Here's Dwight's FORTH-syntax disassembly listing. Dwight's correspondents about the 4004 assembler, found those results unsatisfactory. As it happened, I could modify an 8085 disassembler into a 4004 disassembler. My disassembler (entirely derived from code for 8085 disassembly by Bill Beech) is table driven so it's a matter of changing tables and some decision logic. My disassembler produces Intel-syntax 4004 source.

Here's my resulting Intel-compatible 4004 disassembly. Also, from Dwight's correspondence, here's a commented Intel-format disassembly of the first ROM image by Dave Roberts. The ROM images, are archived on Dwight Elvey's github page, and also at bitsavers.org's MCS4 components archive. The disassemblies are not archived at those locations.

In all three disassemblies I provide, the "SKIP" instruction is disassembled as such. It's very likely intended in the first two instances of the ROM code. In the third instance, it's unclear. If you wish to assemble the code without implementing the SKIP, change it to "DB 10H ;SKIP" for your 4004 assembler. (I'll refer you to my 4004 assembler in a future revision of this Web page.)

Operation of the assembler and PROM programmer

In Nov 2024, Dwight Elvey described how the SIM-04 ROM-based assembler is to be used. He's run it on a simulated SIM-04.

"The assembler is [on 1702 ROMs marked by Intel as] A0740, A0741, A0742 and A0743. It is intended to be connected from the SIM4-01 (or -02,-03) to an ASR-33 Teletype, with paper tape punch and reader. It needs to have flow control [of the reader and punch] as described in the MCS-4 User's Manual Feb 1973, Appendix D, as found on bitsavers.org Intel components page.

"The assembler is a two pass assembler. The first pass result is put on the punch tape. The resulting tape is then run through the second pass, to punch the ROM image punch tape. The tape data format [later called "BNPF format] is what Intel was using for mask ROMs and such, as shown in the MCS-4 User's Manual [section XIII, "MCS-4 PROM Programming System"]. The result of the second pass can be used on the SIM4-01 with MP7-03 [board] to program 1702A, using the prom set A0450, A0451 and A0453. Note that for 1702 ( non-A ) programming, PROM A0542 is used in place of A0543 . The code listing for the 1702A programming prom set is in the User Manual, Appendix I ["MCS-4 Programming Example"]. I'm hoping to recover A0542 from a PROM I have. - Dwight Elvey"

Dwight added a description for use of the Pittman 4004 assembler ROMs followed by the 1702A programming ROMS:

"Changing the EPROMs for the assembler to the [ROMs for the 1702a} programmer code. The assembler runs on the SIM4-01 without the programmer card. Here are the steps.

Place the A074x EPROMs on the SIM4.
Connect it to power and the ASR33.
Feed the source tape into the ASR33.
When pass 1 is done, take the tape created above with the output of pass 1 to the reader.
When the pass 2 tape is done remove the A074x EPROMs and replace them with the A045x EPROMs..
Add the Programmer and programmer power ( 60 volts dc ).
Then use the pass 2 tape as the source for the programming.. - Dwight

4004 SKIP pseudo-instruction

When Dwight Elvey's disassmbled of Tom Pittman's SIM-04 ROM based assembler (see above), he found that Pittman used the JCN "never jump" instruction (0x10 ) as a kind of "skip", when the address byte of the instruction contained a 4004 one-byte opcode. Entering the code at the address, executes the byte; entering the code from the JCN, simply skips the one-byte instruction. A series of these "SKIP"s permits loading a 4-bit register with one of a number of values. That's what Dwight discovered in Pittman's coding. This document based on my discussion with Dwight Elvey provides details.

Semi-documented 4004 stack vs 4040

In Dwight's discussions about the Intel/Pittman SIM-04 4004 ROM assembler, Dwight notes that the 4004 has a short four-address stack for the JMS (subroutine call) return address; and how it handles a stack overflow. The Intel 4040 stack is implemented very differently. Dwight found the Pittman assembler uses the 4004 overflow "as a feature". In various discussions Dwight describes some details, as I try to show below. Also below is documentation from the MCS-4 User's Manual. - Herb

From vcfed.org forums, "Genres", "Others" "Interest in I4004" discussion thread Mar 4, 2018 forwards

Oct 13, 2020
Dwight Elvey #52

I thought I might add this here. There are several simulators for the 4004 on the web. There is a mostly undocumented operation of the 4004 when you do a fourth JMS without a return. It over writes the last stack value. What the document doesn't say is what it over writes it with. Tom's assembler expects the 4004 to do what the actual silicon does. Here is a simple program to verify your version of simulating the 4004. Do note, the 4040 has a deeper stack and this code will produce the wrong result if run on a 4040. Tom's assembler will also fail on a 4040. This code is written to be compatible with Tom's [SIM-04 4004] assembler. - Dwight

/ STACK TEST FOR 4004, NOT 4040
/ ENDS WITH 15 IN ACC SIMULATION IS CORRECT
   JMS L1
   LDM 0
   JUN ENDTEST
L1,  JMS L2
   BBL 1
L2, JMS L3
   BBL 2
L3,  JMS L4
   BBL 3
L4,  BBL 4
OVER,  LDM 15
ENDTEST,  JUN ENDTEST
$

In Feb 2024, Dwight Elvey discussed the Pittman assembler with Sid Jones, myself (Herb), and others. Dwight describes the 4004 stack and how Pittman handled it. Also discussed, was a baud rate issue in the Pittman assembler and how the SIM-04 hardware on the Teletype (ASR33) was managed. -

One thing I mentioned on the VCF list post that is important for Tom's code, it that the stack has to be implemented correctly. It is 4 registers of which one is the current PC counter. The other three are the current return stack. Tom used this in his code by intentionally overflowing the stack. Make sure your emulations does that, correctly. This can't be done with the 4040 processor because the stack depth is wrong. You'd need to patch the code to overflow the stack at the right location. I didn't make a note of where he does that.

As I recall, if you are emulating [Pittman's] code, you'll find a piece of code that follows one of the calls that looks like it seems to be the deepest it should go, most of the time as part of a loop, and that code has no other entry, if the stack didn't overflow.

Tom does his Baud rate with loops, similar to the 4/40 code. The thing to realize is that it throttles the incoming data with the relay control as described in the user manual. If you just send input data at 110 baud, you'll overflow the input code.

It is still 110 baud as I counted the cycles and compared it to the 4004 clock speed. The timing loops are different code than the 4/40 does. It seems like one of the code listings that Herb had was not 110 baud. I forget what I calculated it was. It was faster and not slower as I recall, so I've no idea where things go wrong. Anyway, it sounds like you [Sid] are getting there. - Dwight

Discussions of Reading the MCS-4 Users Manual and implementing a 4 level stack & PC

In Jan 2024, Dwight Elvey discussed the 4004 stack with a developer of another 4004 software emulator. The discussion was alank2 and Dwight discussed the 4004 stack in this thread "The beginnings of my 4004 project" in a vcfed.org forum. I The emulator was posted as executables in the thread, in late Feb 2024. Here's exerpts of what Dwight had to say about emulating the 4004 stack for JMS and BBL instruction handling. Also, Dwight's interpretations of the INtel MCS-4 Users Manual and MCS-4 Assembly Manual. I've added comments in []'s to give more context. - Herb

Reading the User's Manual

MCS-4 User's manual exerpts on 4004 stack. The full MCS-4 Users manual is on bitsavers, as is the full MCS-4 Assembly language manual.

Dwight posts:

"I know you'll just say I'm wrong but you can look at yourself: [page 12 and 13], at the top of the page. It clearly shows the JMS #4 over writing Return Address #1.

The text notes that the "If a fourth JMS occurs, the deepest return address (the first one stored) is lost." The diagram shows a "blank spot" but the address is not blank, it is the address after the fourth JMS just like any other JMS but the first address is lost replace with the return of the fourth JMS. Like I said, Tom [Pittman] uses this feature to change from the first pass of his assembler to the second pass. So, it is not 3 rolling registers, it is 4 registers, like I said, with one register being the current PC. It is truly implemented that way in hardware if you care to look at the chip diagram ( on the web someplace ). As a note Tom's code can not be run on the 4040 without some modification to handle this feature. I'd be curious where you saw the 3 rolling stack?"

"I can [also] see on [Users Manual] page 27, [Under 2-word instructions descriptions, for JMS,] that it also says the deepest return address is lost. But doesn't mention that the return address of the 4th JMS overwrites the deepest one. This is a clear omission as it is what the real silicon does. I don't know why they didn't state it. It would have been difficult for the hardware to do anything else, special, with the 4th JMS." - Dwight

Implementing a four-word stack, correcting the Assembly Manual

"There is no special 4004 hardware to handle any of this. There is a two bit pointer for the [stack] registers. It either increments of decrements and wraps around. It points to the current PC. To JMS, it changes the pointer in one direction, after getting the start [address] of the subroutine. And [for] a BBL it goes the other direction ignoring the old PC.

Each JMS has no knowledge of how many JMS's have preceded it. It does exactly the same thing.

Each BBL does exactly the same thing as any other BBL. It has no knowledge of how many BBL's before it.

There is no special knowledge about when [JMS] will overwrite the first return. It is just the number of JMS's There are 4 registers of which one is the current PC. This gives you 3 levels of nesting without getting lost.

The [3-register cylinder] visual model [in the Intel 4004 MCS-4 Assembly manual, section 2.4, page 2-7, "The Stack"] works as long as you don't over do the stack depth. Then you have to go to the actual physical design. It is actually 4 registers, with one being the current PC [as shown in the MCS-4 Users Manual].

[When] the JMS instruction is executed the PC is incremented and reads the destination pointed to by the JMS instruction into the next register of the 4 register cylinder-like stack] and move the current PC to be that register. The one that used to be the PC is now the address for the BBL instruction.

To properly emulate this action you need to indirectly access the PC and the [stack] location + or - from the PC register to get the location that has the return. The roll [direction of] the 4 bit registers is not important, the only thing is that it does require 4 locations.

To tell you the truth, I don't think [about] set[ting] the [2-bit] pointer on power up, since it isn't important where it starts. It is just 2 bits. Incrementing or decrementing the pointer for JMS and BBL is only important that they are opposite, so pick what you like.

It is still best to fetch the PC through an indirect pointer, that is always update modulo 4 ( a nice 2 bit number ). Then you don't even have to think about what it is doing, it will always matches the silicon. ... ( 00, 01, 10, 11, 00, 01 and so on )." - Dwight Elvey


Contact information:
Herb Johnson
New Jersey, USA
To email @ me, see
see my ordering & contact Web page.

Copyright © 2024 Herb Johnson