ACE Introduction

        .cr     ace1101      To load the ACE-1101 cross overlay
        .cr     ace1202      To load the ACE-1202 cross overlay

Fairchild has created 2 low-end micro controllers which they call the Arithmetic Controller Engine. These controllers are specially tailored for security applications and for applications that need only a few I/O lines.

I must admit that I didn't enjoy writing this cross overlay very much. What appeared to be a very simple job became an enormous puzzle because of the great little mess Fairchild made of the documentation. I had to put 3 different documents together to find that they all had several differences concerning instructions and their operands. Finally I had to install the ACE simulator to filter out all differences.
I even found some instructions that are nowhere to be found in any of the documentation. These undocumented instructions are not included in the crosses because I don't know if they are really implemented on the processors.

You can find all the instructions and their operands in the opcode.tst directory. I hope they are all correct because I don't have an ACE controller to try things out. Please let me know if you find something wrong with the instruction set in my op-code test file.

Below you can find a list of the Fairchild documents that I've used. They can be downloaded from the Fairchild site.

ACE1101.PDF, ACE1202.PDF, AN-2000.PDF (is the same as: AN-8004.PDF)

Programming Model

The programming model in the picture below shows the register set of the ACE controllers. I only include a little summary about the features of the ACE's programming model here. It is not my intention to make the original documentation obsolete, so please refer to the original documentation for further details.

ACE1101/AC1202 programming model

The Accumulator A

The Accumulator is used for all arithmetic operations.

The Index register X

The index register X can be used to point to any location in data or program memory. The use of the index register may appear a bit unconventional at first, compared to other micros.

Please note that the index register is one bit longer than the program counter and is 11 or 12 bits long depending on the device type. The highest bit of the X register is a write only bit and will not be changed during increment or decrement instructions, nor will it be used in comparisons. Therefore the X register actually has the same length as the program counter PC, enabling you to let it point to any address in the program memory.
The highest bit is only used to make a selection between data memory (when MSB = '0'), or program memory (when MSB = '1'). When pointing to program memory an index of 0 actually points to the first location in program memory, which is address $0C00 on an ACE1101, and address $0800 on an ACE1202.

The index resister X can be used together with an 8-bit unsigned offset to point to any location in data or program memory by instructions that allow the [#offset,X] operand. Addressing data memory can be done with only 8 bits and there the more economical addressing mode with the [X] operand is preferred.
Please note that the [X] addressing mode uses only the 8 least significant bits of the X register and therefore can only point to data memory!

The X register can also be accessed from data memory at addresses $BE (XHI) and $BF (XLO). XHI holds only the available bits, writing to unimplemented bits has no effect.

Please note the inconsistent endian model with these two memory locations! Normally the little endian model is used by the ACE controllers, only the XHI and XLO memory locations use the big endian model!

The Program Counter

The program counter PC is 10 or 11 bits long, depending on the device type. Electrically this may be true, but to a software point of view the PC is always 12 bits long. On the ACE1101 bits b11 and b10 are always '1' while fetching instructions, this results in an addressing range from $0C00 to $0FFF. On the ACE1202 only b11 is fixed to '1' resulting in an address range of $0800 to $0FFF.
Please note that the ACE controllers cannot execute instructions from RAM because of this!

After reset the program counter starts execution at address $0C00 on an ACE1101, or $0800 on an ACE1202.

The Condition Code Register SR

The condition code register holds the following system flags

RReady Flag (EEPROM)
GGlobal Interrupt mask ('0' = disabled)
ZZero Flag
CCarry Flag
HHalf Carry Flag
NNegative Flag

I can't find anything about stacking and restoring the contents of the SR register during and after interrupts in the buggy user manuals of the ACE controllers. I assume that the bits Z, C, H and N are saved on the stack, next to the 4 MSBs of the program counter during an interrupt, but don't blame me if the ACE decides otherwise.

The Condition Code register can also be accessed from data memory at address $CF, which is usually called STATUS.

The Stack Pointer SP

The 4-bit stack pointer enables an 8-level deep stack because it is always incremented or decremented twice per Push or Pull. The stack itself is located in RAM at the addresses $30 to $3F. After reset the Stack pointer is initialized to $0F, effectively pointing to address $3F.

Only the PC can be stored on the stack by a JSR instruction, or by an interrupt. The low byte of the address following the JSR instruction is stored in the memory location pointed to by the Stack pointer, then SP is decremented. Then the high byte of the address is stored, again followed by a decrement of the Stack pointer.
This means that the stack grows down in memory and that the return addresses finally end up in big endian model! The Stack pointer always points to the next free location on the stack.

Please note that the Stack pointer will overflow at the 9th JSR call, destroying the oldest return address.

The Stack pointer register can also be accessed from data memory at address $CE.


SB-Assembler Version 3 can show you the cycle times of each instruction when the TON list flag is switched on. The numbers presented are the number of clock pulses the processor needs to execute the instruction.

Reserved Words

Only the letters A and X are reserved words. For the rest you may choose any label name you like.

Please note that none of the registers of the data memory are named yet. You may declare these registers using the .EQ directive yourself if you want.

Special Features

Pound sign #

The documentation is quite inconsistent with the use of the pound sign. Bit numbers sometimes are preceded by a pound sign and the offset indexed operand is sometimes written as [#offset,X] or as [offset,X]. The SB-Assembler will allow both syntaxes and treats them identically. However it won't allow any of the other immediate mode prefixes in combination with the above mentioned addressing modes. The 4 immediate mode prefixes #, /, = and \ are only allowed with immediate mode operands and with data generating directives.

Address limitations

Only exceeding of the upper address limit of $0FFF is checked by the assembler. So you can still use memory that is not physically implemented in the controller. It's the programmer's responsibility to stay clear of unused memory.

Program counter initialization

It's the programmer's responsibility to initialize the Program counter with an .OR $0C00 or an .OR $0800 instruction. The SB-Assembler will not do that automatically for you, nor will it warn you in case you forget.

Overlay Initialization

Two things are set while initializing the ACE overlay every time it is loaded by the .CR directive.

  • Little endian model is selected for the .DA and .DL directives. This means that words or long words are stored with their high byte first.
  • The maximum program counter value is set to $0FFF.

Differences Between Other Assemblers

There are some differences between the SB-Assembler and other assemblers for the ACE controllers. These differences require you to adapt existing source files before they can be assembled by the SB-Assembler. This is not too difficult though and is the (small) price you have to pay for having a very universal cross assembler.

  • None of the data memory locations are pre-defined in the SB-Assembler. Please name those registers by using the .EQ directive.
  • The obvious differences in notation of directives and radixes common to all SB-Assembler crosses.
  • Don't forget that the SB-Assembler does not allow spaces in or between operands. Only Version 3 will allow one space after each comma separating operands in the operand field.