A simulator for “mini-EDSAC” coded in C

Back in May, I entered into correspondence with Bill Purvis, who is involved with the recreation of EDSAC at The National Museum of Computing, at Bletchley Park.

Bill has created a simplified model of EDSAC, which runs on a 1K Lattice iCE40 IceStick FPGA.

Here are the main differences between his mini-EDSAC and the original:

Comparison between EDSAC and Mini-EDSAC

Mini-EDSAC is a simplified version of the EDSAC instruction set, suitable for implementation on machine with limited capacity. The main differences are listed below:

  • EDSAC uses 35-bit words, Mini-EDSAC uses 16-bit words

  • EDSAC packs two 17-bit orders into a word, Mini-EDSAC has a single 16-bit order in each word.

  • EDSAC uses the 5-bit tape code devised at Cambridge, Mini-EDSAC uses 8-bit ASCII coding, but reduced to 5-bit for the order codes.

  • EDSAC has multiply-and-add and multiply-and-subtract orders which take the content of a multiplier register, multiply it by the operand, and add or subtract it into the accumulator. Mini-EDSAC simply multiplies the accumulator by the operand, placing the result in the accumulator.

  • The EDSAC accumulator is double length 70 bits, the Mini-EDSAC accumulator is 32 bits.

  • The Mini-EDSAC shift orders use the numeric value of the address part to specify how many bits are to be shifted, EDSAC has a more subtle interpretation.

  • EDSAC handles long (35-bit) and short (17-bit) operands, Mini-EDSAC only handles 16-bit operands, hence there is no need for the Long/Short bit in the order format, reducing it to 16-bits.

  • EDSAC input order takes 5-bits from the reader, Mini-EDSAC takes all 8 bits from the ASCII-coded input.

  • EDSAC outputs the top 5 bits of the operand to the printer, Mini-EDSAC outputs the bottom 8 bits of the accumulator.

In general, the appearance is much the same, operation codes match (apart from the encoding). The input programs look much like those of EDSAC programs, using the Initial Orders 1, except the last character of each order is not required.

One noticeable difference is the use of @ in pseudo-orders. EDSAC programs used P as that is encoded as zero. @ maps to zero when the top 2 high bits are removed.

The initial orders are slightly longer – I have not been able to condense them into 31 orders, programs load from address 37 onwards. I have not yet attempted to replicate David Wheeler’s Initial Orders 2!

Bill Purvis, 25th May, 2017

Bill’s mini-EDSAC was the starting point for my simulation – written in Arduino C.  It’s relatively straight forward to get a modern microcontroller to emulate these early machines – by recreating their instruction set in the form of a switch-case statement in C.

This code uses an array of 16-bit locations in RAM  m[n]

A is  the Accumulator

It masks off the instruction field “insn” –  as the top 5 bits

It masks off the address field “n” as the lower 5 bits


 // mini-EDSAC CPU Model
 // -------------------------------------------------------------------
 static void execute(int instruction) // This is the EDSAC CPU model
 // The Alpha code is held in the top 5 bits of the instruction
 // The bottom 11 bits hold the address

 insn = (instruction & 0xF800)/2048 ;
 _pc = pc + 1;
 n = (instruction & 0x7FF); // n is the address field - lower 11 bits
 switch (insn) 
 case 0: A += m[n]           ; break; // ADD A
 case 1: A -= m[n]           ; break; // SUB B SuBtract
 case 2: A += (m[n] & R)     ; break; // COL C - logical AND
 case 3: m[n] = A            ; break; // DEP Deposit D -no clear
 case 4: if(A>=0) {_pc = n; }  break; // JGT E
 case 5:                       break; // VER F
 case 6: if(A<0) {_pc = n; } ; break; // JLT G
 case 7: R += m[n]           ; break; // CPY H - Load R register
 case 8: m[n]=uart_getc();     break; // INP I - get char from UART
 case 9: A = A>>n            ; break; // RHS J - Right Shift
 case 10: m[n] = A; A=0      ; break; // TRC K - Transfer and clear
 case 11: A = A<<n           ; break; // LSH L - Left Shift
 case 12: A += (m[n] * R)    ; break; // ML+ M - Multiply and ADD
 case 13: A -= m[n] * R      ; break; // ML- N - Multiply and SuBtract
 case 14: uart_putc(m[n])    ; break; // OUT O - Output character to UART
 case 15:                      break; // PUT P - PUT constant in memory

// These cases >= 16 are not used on 4-bit instruction model

 case 16:                      break; //     Q - Not Used
 case 17: A = m[n]>>1        ; break; // RHS R - Right Shift
 case 18: A -= m[n]          ; break; // SUB S - Subtract
 case 19: m[n] = A; A=0      ; break; // TRC T - Transfer and Clear Acc
 case 20: m[n] = A           ; break; // UPD U - Transfer - don't Clear
 case 21: A += (m[n] * R)    ; break; // ML+ V - Multiply and ADD
 case 22:                      break; //     W - Not Used
 case 23:                      break; // NOP X - No Operation
 case 24:                      break; // RND Y - Round Accumulator
 case 25:                      break; // END Z - Stop and ring Bell!
 case 26:                      break; 
 case 27:                      break; 
 case 28:                      break; 
 case 29:                      break; 
 case 30:                      break; 
 case 31:                      break; 

// Note - the most useful instructions crammed into top 16 cases
// to allow for 4-bit instruction selection
// So those below "P" are moved up to fill vacant slots 
// At "B", "D", "K", "M"
// Model can be extended in future for 5-bit instruction codes

pc = _pc;
 instruction = m[pc];

next_t = _t;

 // End of CPU model
 // ------------------------------------------------------------------


About monsonite

mostly human
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s