intel 4004 Instruction Set author Neil Franklin, last modification 2014.05.15 Sources for this data: ---------------------- 1. PDF with scanned in copy of Intel MCS-4 Micro Computer Set Users Manual Rev 4 of Feb 1973, from http://www.bitsavers.org/pdf/intel/MCS4/MCS-4_UsersManual_Feb73.pdf Very unlikely to contain errors. Of course errors of my own are to be expected. Registers: ---------- (in order: data, address, pc, flag) A 4bit Accumulator 00..17 16*4bit Index Registers (2 octal digits, 4 bits) 0..7 8*8bit Register Pairs (1 octal digit, 3bits) (0 = 00,01 1 = 02,03 .. 7 = 16,17) -nameless- 2bit Stack Pointer, selects active PC PC0..PC3 4*12bit Program Counter Stack -nameless- 1bit Control Flipflop (= flag) Control Flipflop, Flag: ----------------------- (only one flag, no actual register) CY Carry (arithmetic result carry bit3->"bit4") General policy is: - arithmetic: set C - decrement/increment accumulator: set C - decrement/increment index register: leave C unchanged - shift/rotate: set C - load/store/in/out: leave C unchanged - jump/call/return: leave C unchanged Memory: ------- Program memory up to 16 special ROMs (4001) a 256*8bit (12bit address space) alternative use address decoder 4008 and data multiplexer 4009 which allow normal ROMs/PROMs/EPROMs to be used, and also RAMs for program Data memory up to 4 DRAMs (4002) a 4*(16main+4status)*4bit (8bit address space) can be 4 (direct driven) or (8 external 3:8 decoder driven) banks of these Output+Input devices 1*4bit per ROM (4001) chip alternative 16*4bit in normal FFs, if 4008+4009 chips used Output devices 1*4bit per DRAM (4002) chip Output expander 3->10bit SIPO shift register with out enable (4003) chip Addressing Modes, in Assembler Syntax: -------------------------------------- (in order: reg, immediate, reg indirect, pc) A accumulator dd immediate4 (2 octal digits 00..17, 4 bits) ddd immediate8 (3 octal digits 000..377, 8 bits) (only FIM instr source) rr register (2 octal address digits 00..17, 4 bits) r register pair (only FIM instr target) r register pair indirect (only SRC/JIN/FIN instr) aaa adddress8 (3 octal digits 000..377, 8 bits) (only JCN/ISZ instr) aaaa address12 (4 octal digits 0000..7777, 12 bits) (only JUN/JMS instr) Instruction Formats, in Machine Code Bytes: ------------------------------------------- (in order: simple, immediate, register, memory/in/out, progmem, jump, condit) oo opcode8 od opcode4+immediate4 or opcode4+reg-address4 or opcode5+regpair-address3 ordd opcode5+regpair-address3 immediate8 oraa opcode4+reg-address4 program-memory-address8 oaaa opcode4+progmem-address-high4 progmem-address-low8 (= big endian) ocaa opcode4+condition4 program-memory-address8 Instruction Bit Patterns and Operations: ---------------------------------------- (in order: functional grouping: arithmetic, data transfer, jumps) arithmetic/load/exchange index reg 10oorrrr ..oo.... opcode operation ..00.... ADD A = A + indexreg + FlagCY; FlagCY "ADD index to acc" ..01.... SUB A = A - indexreg - FlagCY; FlagCY "SUBtract infex from acc" ..10.... LD A = indexreg "LoaD index to acc" ..11.... XCH A <=> indexreg; "eXCHange index and acc" ....rrrr indexreg (octal 00..17) arithmetic memory 111010oo ......oo opcode operation ......00 SBM A = A - mem[-mem-addr-] - FlagCY; FlagCY "SuBtract fr Mem" ......11 ADM A = A + mem[-mem-addr-] + FlagCY; FlagCY "ADd from Memory" increment/decrement 1111o0o0 ....o.o. opcode operation ....0.1. IAC A = A + 1; FlagCY "Increment Accumulator" ....1.0. DAC A = A - 1; FlagCY "Decrement Accumulator" oooooooo opcode operation 0110rrrr INC indexreg = indexreg + 1 "INCrement index register" ....rrrr indexreg (octal 00..17) shift/rotate 111110oo ......oo opcode operation ......01 RAL FlagCY,A = A,FlagCY "Rotate Accumulator Left" ......10 RAR A,FlagCY = FlagCY,A "Rotate Accumulator Right" other specialised arithmetic oooooooo opcode operation 11110000 CLB A = 0; FlagCY = 0 "CLear Both" 11110100 CMA A = NOT A "CoMplement Accumulator" 11110111 TCC A = FlagCY; FlagCY=0 "Transfer Carry and Clear" 11111001 TCS A = 9 + FlagCY; FlagCY=0 "Transfer Carry Subtract" 11111011 DAA if A > 9 or FlagCY = 1 then A = A + 6; FlagCY "Decimal Adjust Accumulator" 11111100 KBP A = table{ 0 1 2 3 4 15 15 ... 15}[A] "KeyBoard Process" load immediate4 oooodddd opcode operation 1101.... LDM A = immediate4 "Load Data from prog Memory to acc" ....dddd immediate4 (octal 00..17) load immediate8 oooorrro opcode operation 0010...0 FIM indexregpair = progmem[PC+] (immediate8) "Fetch IMmediate" ....rrr. indexregpair (0..7) load table/indexed8 oooorrro opcode operation 0011...0 FIN indexregpair = progmem[PC(bit11..8),indexreg0,indexreg1] "Fetch INdirec" ....rrr. indexregpair (0..7) set memory address 0010rrr1 SRC -mem-addr-(bit7..0) = indexreg,indexreg+1 ....rrr. indexregpair (0..7) "Send Register Control" 11111101 DCL -mem-addr-(bit9..8) = A(bit2..0) "Designate Command Line" load memory 11100ooo opcode operation .....ooo .....000 WRM mem[-mem-addr-] = A "WRite Memory" .....001 WMP RAM-output-port[-mem-addr-(bit9..4)] = A "Write Mem Port" .....010 WRR ROM-output-port[-mem-addr-(bit7..4)] = A "Write Rom port" .....011 WPM progmem[-mem-addr-(bit7..0)](bit7..4-or-bit3..0) = A (only with 4008/4009, not with 4001 ROMs) "Write Prg Mem" .....100 WR0 status0mem[-mem-addr-(bit9..4)] = A "WRite status 0" .....101 WR1 status1mem[-mem-addr-(bit9..4)] = A "WRite status 1" .....110 WR2 status2mem[-mem-addr-(bit9..4)] = A "WRite status 2" .....111 WR3 status3mem[-mem-addr-(bit9..4)] = A "WRite status 3" store memory 11101ooo opcode operation .....ooo .....000 (used for SBM) .....001 RDM A = mem[-mem-addr-] "ReaD Memory" .....010 RDR A = ROM-input-port[-mem-addr-(bit7..4)] "ReaD Rom port" .....011 (used for ADM) .....100 RD0 A = status0mem[-mem-addr-(bit9..4)] "ReaD status 0" .....101 RD1 A = status1mem[-mem-addr-(bit9..4)] "ReaD status 1" .....110 RD2 A = status2mem[-mem-addr-(bit9..4)] "ReaD status 2" .....111 RD3 A = status3mem[-mem-addr-(bit9..4)] "ReaD status 3" jumps/subroutines and reset oooooooo opcode operation 00000000 NOP do nothing "No OPeration" 0011rrr1 JIN PC = PC(bit11..8),indexreg,indexreg+1 "Jump INdirect" 0100aaaa JUN aaaa PC = aaaa(bit11..8),progmem[PC+] (address12, 4 oct digit) "Jump UNconditional" 0101aaaa JMS aaaa PC stack advance one; PC = aaaa(bit11..8),progmem[PC+] (address12, 4 oct digit) "JuMp to Subroutine" 1100dddd BBL PC stack retreat one; A = immediate4 "Branch Back a Load" ....dddd immediate4 (octal 00..17) ---- pin RESET PC = 0 "RESET" ---- pin TEST test condition = 0 (for spinloop JCN ) "TEST" branches/conditionals 0001cccc JCN cond aaa if condition PC = PC(bit11..8),progmem[PC+] (address8) "Jump CoNditional" ....cccc condition ....1... NOT AZ->AN, CN->CZ, TZ->TN .....1.. ( AZ A = 0 ......1. OR{ CN FlagCY = 1 .......1 ( TZ pin TEST = 0 0111rrrr ISZ indexreg = indexreg + 1; "Increment index a Skip if Zero" if indexreg != 0 PC = PC(bit11..8),progmem[PC+] (address8) ....rrrr indexreg (octal 00..17) flag oooooooo opcode operation 11110001 CLC FlagCY = 0 "CLear Carry" 11110011 CMC FlagCY = NOT FlagCY "CoMplement Carry" 11111010 STC FlagCY = 1 "SeT Carry" Instruction Code List: ---------------------- (full machine code bytes, in order: opcode number) 00 NOP 10aa JCN NC aaa 20dd FIM 0 dd,dd 30 FIN 0 01 - 11aa JCN TZ aaa 21 SRC 0 31 JIN 0 02 - 12aa JCN CN aaa 22dd FIM 1 dd,dd 32 FIN 1 03 - 13aa JCN 03 aaa 23 SRC 1 33 JIN 1 04 - 14aa JCN AZ aaa 24dd FIM 2 dd,dd 34 FIN 2 05 - 15aa JCN 05 aaa 25 SRC 2 35 JIN 2 06 - 16aa JCN 06 aaa 26dd FIM 3 dd,dd 36 FIN 3 07 - 17aa JCN 07 aaa 27 SRC 3 37 JIN 3 08 - 18aa JCN 10 aaa 28dd FIM 4 dd,dd 38 FIN 4 09 - 19aa JCN TN aaa 29 SRC 4 39 JIN 4 0A - 1Aaa JCN CZ aaa 2Add FIM 5 dd,dd 3A FIN 5 0B - 1Baa JCN 13 aaa 2B SRC 5 3B JIN 5 0C - 1Caa JCN AN aaa 2Cdd FIM 6 dd,dd 3C FIN 6 0D - 1Daa JCN 15 aaa 2D SRC 6 3D JIN 6 0E - 1Eaa JCN 16 aaa 2Edd FIM 7 dd,dd 3E FIN 7 0F - 1Faa JCN 17 aaa 2F SRC 7 3F JIN 7 40aa JUN 00aa 50aa JMS 00aa 60 INC 00 70aa ISZ 00 aaa 41aa JUN 04aa 51aa JMS 04aa 61 INC 01 71aa ISZ 01 aaa 42aa JUN 10aa 52aa JMS 10aa 62 INC 02 72aa ISZ 02 aaa 43aa JUN 14aa 53aa JMS 14aa 63 INC 03 73aa ISZ 03 aaa 44aa JUN 20aa 54aa JMS 20aa 64 INC 04 74aa ISZ 04 aaa 45aa JUN 24aa 55aa JMS 24aa 65 INC 05 75aa ISZ 05 aaa 46aa JUN 30aa 56aa JMS 30aa 66 INC 06 76aa ISZ 06 aaa 47aa JUN 34aa 57aa JMS 34aa 67 INC 07 77aa ISZ 07 aaa 48aa JUN 40aa 58aa JMS 40aa 68 INC 10 78aa ISZ 10 aaa 49aa JUN 44aa 59aa JMS 44aa 69 INC 11 79aa ISZ 11 aaa 4Aaa JUN 50aa 5Aaa JMS 50aa 6A INC 12 7Aaa ISZ 12 aaa 4Baa JUN 54aa 5Baa JMS 54aa 6B INC 13 7Baa ISZ 13 aaa 4Caa JUN 60aa 5Caa JMS 60aa 6C INC 14 7Caa ISZ 14 aaa 4Daa JUN 64aa 5Daa JMS 64aa 6D INC 15 7Daa ISZ 15 aaa 4Eaa JUN 70aa 5Eaa JMS 70aa 6E INC 16 7Eaa ISZ 16 aaa 4Faa JUN 74aa 5Faa JMS 74aa 6F INC 17 7Faa ISZ 17 aaa 80 ADD 00 90 SUB 00 A0 LD 00 B0 XCH 00 81 ADD 01 91 SUB 01 A1 LD 01 B1 XCH 01 82 ADD 02 92 SUB 02 A2 LD 02 B2 XCH 02 83 ADD 03 93 SUB 03 A3 LD 03 B3 XCH 03 84 ADD 04 94 SUB 04 A4 LD 04 B4 XCH 04 85 ADD 05 95 SUB 05 A5 LD 05 B5 XCH 05 86 ADD 06 96 SUB 06 A6 LD 06 B6 XCH 06 87 ADD 07 97 SUB 06 A7 LD 07 B7 XCH 07 88 ADD 10 98 SUB 10 A8 LD 10 B8 XCH 10 89 ADD 11 99 SUB 11 A9 LD 11 B9 XCH 11 8A ADD 12 9A SUB 12 AA LD 12 BA XCH 12 8B ADD 13 9B SUB 13 AB LD 13 BB XCH 13 8C ADD 14 9C SUB 14 AC LD 14 BC XCH 14 8D ADD 15 9D SUB 15 AD LD 15 BD XCH 15 8E ADD 16 9E SUB 16 AE LD 16 BE XCH 16 8F ADD 17 9F SUB 17 AF LD 17 BF XCH 17 C0 BBL 00 D0 LDM 00 E0 WRM F0 CLB C1 BBL 01 D1 LDM 01 E1 WMP F1 CLC C2 BBL 02 D2 LDM 02 E2 WRR F2 IAC C3 BBL 03 D3 LDM 03 E3 WPM F3 CMC C4 BBL 04 D4 LDM 04 E4 WR0 F4 CMA C5 BBL 05 D5 LDM 05 E5 WR1 F5 RAL C6 BBL 06 D6 LDM 06 E6 WR2 F6 RAR C7 BBL 07 D7 LDM 07 E7 WR3 F7 TCC C8 BBL 10 D8 LDM 10 E8 SBM F8 DAC C9 BBL 11 D9 LDM 11 E9 RDM F9 TCS CA BBL 12 DA LDM 12 EA RDR FA STC CB BBL 13 DB LDM 13 EB ADM FB DAA CC BBL 14 DC LDM 14 EC RD0 FC KBP CD BBL 15 DD LDM 15 ED RD1 FD DCL CE BBL 16 DE LDM 16 EE RD2 FE - CF BBL 17 DF LDM 17 EF RD3 FF - E3: only implemented if 4008/4009 memory control chips, not with 4001 ROMs Instruction Code Table: ----------------------- (only opcodes, in order: ver: bit7..6/5..3, hor: bit2..0) + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00 NOP - - - - - - - - - - - - - - - 10 JCN NC JCN TZ JCN CN JCN 03 JCN AZ JCN 05 JCN 06 JCN 07 JCN 10 JCN TN JCN CZ JCN 13 JCN AN JCN 15 JCN 16 JCN 17 20 FIM 0 SRC 0 FIM 1 SRC 1 FIM 2 SRC 2 FIM 3 SRC 3 FIM 4 SRC 4 FIM 5 SRC 5 FIM 6 SRC 6 FIM 7 SRC 7 30 FIN 0 JIN 0 FIN 1 JIN 1 FIN 2 JIN 2 FIN 3 JIN 3 FIN 4 JIN 4 FIN 5 JIN 5 FIN 6 JIN 6 FIN 7 JIN 7 40 JUN 00aa JUN 04aa JUN 10aa JUN 14aa JUN 20aa JUN 24aa JUN 30aa JUN 34aa JUN 40aa JUN 44aa JUN 50aa JUN 54aa JUN 60aa JUN 64aa JUN 70aa JUN 74aa 50 JMS 00aa JMS 04aa JMS 10aa JMS 14aa JMS 20aa JMS 24aa JMS 30aa JMS 34aa JMS 40aa JMS 44aa JMS 50aa JMS 54aa JMS 60aa JMS 64aa JMS 70aa JMS 74aa 60 INC 00 INC 01 INC 02 INC 03 INC 04 INC 05 INC 06 INC 07 INC 10 INC 11 INC 12 INC 13 INC 14 INC 15 INC 16 INC 17 70 ISZ 00 ISZ 01 ISZ 02 ISZ 03 ISZ 04 ISZ 05 ISZ 06 ISZ 07 ISZ 10 ISZ 11 ISZ 12 ISZ 13 ISZ 14 ISZ 15 ISZ 16 ISZ 17 80 ADD 00 ADD 01 ADD 02 ADD 03 ADD 04 ADD 05 ADD 06 ADD 07 ADD 10 ADD 11 ADD 12 ADD 13 ADD 14 ADD 15 ADD 16 ADD 17 90 SUB 00 SUB 01 SUB 02 SUB 03 SUB 04 SUB 05 SUB 06 SUB 07 SUB 10 SUB 11 SUB 12 SUB 13 SUB 14 SUB 15 SUB 16 SUB 17 A0 LD 00 LD 01 LD 02 LD 03 LD 04 LD 05 LD 06 LD 07 LD 10 LD 11 LD 12 LD 13 LD 14 LD 15 LD 16 LD 17 B0 XCH 00 XCH 01 XCH 02 XCH 03 XCH 04 XCH 05 XCH 06 XCH 07 XCH 10 XCH 11 XCH 12 XCH 13 XCH 14 XCH 15 XCH 16 XCH 17 C0 BBL 00 BBL 01 BBL 02 BBL 03 BBL 04 BBL 05 BBL 06 BBL 07 BBL 10 BBL 11 BBL 12 BBL 13 BBL 14 BBL 15 BBL 16 BBL 17 D0 LDM 00 LDM 01 LDM 02 LDM 03 LDM 04 LDM 05 LDM 06 LDM 07 LDM 10 LDM 11 LDM 12 LDM 13 LDM 14 LDM 15 LDM 16 LDM 17 E0 WRM WMP WRR WPM WR0 WR1 WR2 WR3 SBM RDM RDR ADM RD0 RD1 RD2 RD3 F0 CLB CLC IAC CMC CMA RAL RAR TCC DAC TCS STC DAA KBP DCL - -