First, a typo of sorts: Shouldn't JK in your first table be lower case?
Second: I remember one of my EE profs (Dr. Donald Schertz) pointing out to me the octal nature of the 8085 ISA, and how what would be "MOV M, M" ends up being HLT. We had multiple EE labs at the time that required us to hand-assemble and hex-key code into SDK-85 boards, which is probably why Dr. Schertz was so keenly aware of the ISA's encoding properties.
(Our SDK-85s were fancier than most, with a bank of LEDs and toggles on the left side of the board; but, I digress.)
Anyway, that observation has caused me to look for octalness in other ISAs from the era. Indeed, the CP-1600 ISA is /very/ octal. I don't want to spam your 8085 entry with a dissertation on another processor. If anyone's interested in hearing more about the CP-1600, comment on this entry and it'll email me.
Thanks, Mr Z. I've fixed the typo. Please feel free to post a long comment about the CP-1600 (which Wikipedia tells me is the processor in the Intellivision game).
I'd be happy to. Blogger apparently doesn't like my post too much (it's too long, contains HTML markup it doesn't like), so I've just moved it here: http://spatula-city.org/~im14u2c/intv/comment_for_ken_shirrifs_blog.html
Sorry if my question is completely irrelevant, but I had to know. In the Jump Statements of 8085, whenever the condition is satisfied, there are 3 Machine Cycles and 2 Machine Cycles if the condition isn't satisfied. I want to know what are these machine cycles? First one is Opcode Fetch, I'm confused about the rest. Please, do help.
@Anonymous: Each M cycle corresponds to a single memory fetch, if I recall correctly. Jumps are 3 bytes. You need all 3 bytes to take the jump, as the second and third bytes are the branch target address.
So then the question is "Why is it 2 M cycles when the jump isn't taken?" I imagine they're getting the first byte of the jump destination in the same M cycle as they're evaluating the jump condition, although I haven't traced through the PLAs to see if that's actually the case.
September 5, 2013 at 6:38 AM
table.oct8085 {
border-collapse: collapse;
font-size: 80%;
}
table.oct8085 td {
padding: 3px;
}
table.oct8085 td {
border: 1px solid #999;
padding: 3px;
}
table.oct8085 td.c0 {
background: #ffc;
}
table.oct8085 td.c1 {
background: #fcf;
}
table.oct8085 td.c2 {
background: #cff;
}
table.oct8085 td.c3 {
background: #ddf;
}
.oct8085 .b0 {background: #C2A1BD;}
.oct8085 .b1 {background: #CCFFFF;}
.oct8085 .b2 {background: #F09226;}
.oct8085 .b3 {background: #46BF9B;}
.oct8085 .b4 {background: #D97DF3;}
.oct8085 .b5 {background: #D9E56B;}
.oct8085 .b6 {background: #F87D72;}
.oct8085 .b7 {background: #C1B482;}
.oct8085 .b8 {background: #6DD1E2;}
.oct8085 .b9 {background: #949EEF;}
.oct8085 .b10 {background: #59EE86;}
.oct8085 .b11 {background: #EECA31;}
.oct8085 .b12 {background: #D3E0DF;}
.oct8085 .b13 {background: #F37D9E;}
.oct8085 .b14 {background: #A3E39D;}
.oct8085 .b15 {background: #C1AA4E;}
.oct8085 .b16 {background: #EF854F;}
.oct8085 .b17 {background: #7EB6E3;}
.oct8085 .b18 {background: #E29DA0;}
.oct8085 .b19 {background: #DAE7BD;}
.oct8085 .b20 {background: #8FC03D;}
.oct8085 .b21 {background: #DDE73A;}
.oct8085 .b22 {background: #A1E73A;}
.oct8085 .b23 {background: #C0B0A2;}
.oct8085 .b24 {background: #83C0B4;}
.oct8085 .b25 {background: #9EBB6C;}
.oct8085 .b26 {background: #E4A764;}
.oct8085 .b27 {background: #EB81D8;}
.oct8085 .b28 {background: #E4957A;}
.oct8085 .b29 {background: #E796C1;}
.oct8085 .b30 {background: #5AE4DA;}
.oct8085 .b31 {background: #90BA8E;}
.oct8085 .b32 {background: #98EA76;}
.oct8085 .b33 {background: #CBA9E4;}
.oct8085 .b34 {background: #52EFBE;}
.oct8085 .b35 {background: #9BB1C0;}
.oct8085 .b36 {background: #67B96D;}
.oct8085 .b37 {background: #D9EE99;}
.oct8085 .b38 {background: #97E7C0;}
.oct8085 .b39 {background: #E9D37F;}
.oct8085 .b40 {background: #54C455;}
.oct8085 .b41 {background: #DCAC37;}
.oct8085 .b42 {background: #B2B136;}
.oct8085 .b43 {background: #60DF92;}
.oct8085 .b44 {background: #EBC8DE;}
.oct8085 .b45 {background: #FFCCFF;}
.oct8085 .b46 {background: #E29A48;}
.oct8085 .b47 {background: #BDAB61;}
The instruction set of the 8085 microprocessor has an underlying structure that becomes much clearer if expressed in an octal-based table, rather than usual hexadecimal-based table:
\0_0\0_1\0_2\0_3\0_4\0_5\0_6\0_7\1_0\1_1\1_2\1_3\1_4\1_5\1_6\1_7\00_NOPLXI B,d16STAX BINX BINR BDCR BMVI B,d8RLCMOV B,BMOV B,CMOV B,DMOV B,EMOV B,HMOV B,LMOV B,MMOV B,A\01_dsubDAD BLDAX BDCX BINR CDCR CMVI C,d8RRCMOV C,BMOV C,CMOV C,DMOV C,EMOV C,HMOV C,LMOV C,MMOV C,A\02_arhlLXI D,d16STAX DINX DINR DDCR DMVI D,d8RALMOV D,BMOV D,CMOV D,DMOV D,EMOV D,HMOV D,LMOV D,MMOV D,A\03_rdelDAD DLDAX DDCX DINR EDCR EMVI E,d8RARMOV E,BMOV E,CMOV E,DMOV E,EMOV E,HMOV E,LMOV E,MMOV E,A\04_RIMLXI H,d16SHLD a16INX HINR HDCR HMVI H,d8DAAMOV H,BMOV H,CMOV H,DMOV H,EMOV H,HMOV H,LMOV H,MMOV H,A\05_ldhi r8DAD HLHLD a16DCX HINR LDCR LMVI L,d8CMAMOV L,BMOV L,CMOV L,DMOV L,EMOV L,HMOV L,LMOV L,MMOV L,A\06_SIMLXI SP,d16STA a16INX SPINR MDCR MMVI M,d8STCMOV M,BMOV M,CMOV M,DMOV M,EMOV M,HMOV M,LHLTMOV M,A\07_ldsi r8DAD SPLDA a16DCX SPINR ADCR AMVI A,d8CMCMOV A,BMOV A,CMOV A,DMOV A,EMOV A,HMOV A,LMOV A,MMOV A,A\20_ADD BADD CADD DADD EADD HADD LADD MADD ARNZPOP BJNZ a16JMP a16CNZ a16PUSH BADI d8RST 0\21_ADC BADC CADC DADC EADC HADC LADC MADC ARZRETJZ a16rstvCZ a16CALL a16ACI d8RST 1\22_SUB BSUB CSUB DSUB ESUB HSUB LSUB MSUB ARNCPOP DJNC a16OUT d8CNC a16PUSH DSUI d8RST 2\23_SBB BSBB CSBB DSBB ESBB HSBB LSBB MSBB ARCshlxJC a16IN d8CC a16jnk a16SBI d8RST 3\24_ANA BANA CANA DANA EANA HANA LANA MANA ARPOPOP HJPO a16XTHLCPO a16PUSH HANI d8RST 4\25_XRA BXRA CXRA DXRA EXRA HXRA LXRA MXRA ARPEPCHLJPE a16XCHGCPE a16lhlxXRI d8RST 5\26_ORA BORA CORA DORA EORA HORA LORA MORA ARPPOP PSWJP a16DICP a16PUSH PSWORI d8RST 6\27_CMP BCMP CCMP DCMP ECMP HCMP LCMP MCMP ARMSPHLJM a16EICM a16jk a16CPI d8RST 7
The large-scale structure of the instruction set is by quadrant (i.e. the top two bits): MOV instructions in the pink quadrant, arithmetic instructions in the cyan quadrant, increment, decrement, rotates in the yellow quadrant, and control flow (jump, call, return, push, pop, rst) in the purple quadrant. It's not totally regular, of course. Some instructions are wedged in where they can fit, for example the spot where memory-to-memory move (MOV M, M) would go is replaced by HLT.
Note how registers are controlled by an octal digit in the sequence B, C, D, E, H, L, M, and A. This is especially notable for the MOV instructions and arithmetic instructions. For instructions acting on register pairs, the structure is similar: BC, BC, DE, DE, HL, HL, SP, SP.
Although octal is unpopular now, early microprocessors were designed with octal in mind, using groups of three bits to select registers and operations. Now hexadecimal is popular, but when the opcodes are displayed in a hex-based table, the underlying structure of the instructions is obscured.
Note that the four blocks have been arranged for ease of display - strictly speaking they should be stacked vertically rather than a 2x2 grid. The table includes undocumented instructions, which are shown in lower case. Mouse over a cell to see the hex value of the instruction. Credits: original data from pastraiser.com 8085 instruction table.
How the 8085 decodes instructions internally
The 8085 uses a set of PLAs to decode and process instructions. In the first step of processing an instruction the instruction decode ROM (details) decodes the instruction into one of 48 different instruction groups. The grid below is colored according to the instruction group (0 through 47).
NOP LXI B,d16 42STAX B 40INX B 36INR B 38DCR B 38MVI B,d8 14RLC 25MOV B,B 45MOV B,C 45MOV B,D 45MOV B,E 45MOV B,H 45MOV B,L 45MOV B,M 44MOV B,A 45dsub 21DAD B 20LDAX B 41DCX B 37INR C 38DCR C 38MVI C,d8 14RRC 25MOV C,B 45MOV C,C 45MOV C,D 45MOV C,E 45MOV C,H 45MOV C,L 45MOV C,M 44MOV C,A 45arhl 24LXI D,d16 42STAX D 40INX D 36INR D 38DCR D 38MVI D,d8 14RAL 25MOV D,B 45MOV D,C 45MOV D,D 45MOV D,E 45MOV D,H 45MOV D,L 45MOV D,M 44MOV D,A 45rdel 22DAD D 20LDAX D 41DCX D 37INR E 38DCR E 38MVI E,d8 14RAR 25MOV E,B 45MOV E,C 45MOV E,D 45MOV E,E 45MOV E,H 45MOV E,L 45MOV E,M 44MOV E,A 45RIM 3LXI H,d16 42SHLD a16 12INX H 36INR H 38DCR H 38MVI H,d8 14DAA 6MOV H,B 45MOV H,C 45MOV H,D 45MOV H,E 45MOV H,H 45MOV H,L 45MOV H,M 44MOV H,A 45ldhi r8 23DAD H 20LHLD a16 13DCX H 37INR L 38DCR L 38MVI L,d8 14CMA 6MOV L,B 45MOV L,C 45MOV L,D 45MOV L,E 45MOV L,H 45MOV L,L 45MOV L,M 44MOV L,A 45SIM 3LXI SP,d16 42STA a16 8INX SP 36INR M 39DCR M 39MVI M,d8 16STC 6MOV M,B 43MOV M,C 43MOV M,D 43MOV M,E 43MOV M,H 43MOV M,L 43HLT 47MOV M,A 43ldsi r8 23DAD SP 20LDA a16 9DCX SP 37INR A 38DCR A 38MVI A,d8 14CMC 6MOV A,B 45MOV A,C 45MOV A,D 45MOV A,E 45MOV A,H 45MOV A,L 45MOV A,M 44MOV A,A 45ADD B 1ADD C 1ADD D 1ADD E 1ADD H 1ADD L 1ADD M 4ADD A 1RNZ 19POP B 27JNZ a16 29JMP a16 30CNZ a16 33PUSH B 26ADI d8 2RST 0 5ADC B 1ADC C 1ADC D 1ADC E 1ADC H 1ADC L 1ADC M 4ADC A 1RZ 19RET 18JZ a16 29rstv 7CZ a16 33CALL a16 34ACI d8 2RST 1 5SUB B 1SUB C 1SUB D 1SUB E 1SUB H 1SUB L 1SUB M 4SUB A 1RNC 19POP D 27JNC a16 29OUT d8 17CNC a16 33PUSH D 26SUI d8 2RST 2 5SBB B 1SBB C 1SBB D 1SBB E 1SBB H 1SBB L 1SBB M 4SBB A 1RC 19shlx 10JC a16 29IN d8 15CC a16 33jnk a16 31SBI d8 2RST 3 5ANA B 1ANA C 1ANA D 1ANA E 1ANA H 1ANA L 1ANA M 4ANA A 1RPO 19POP H 27JPO a16 29XTHL 35CPO a16 33PUSH H 26ANI d8 2RST 4 5XRA B 1XRA C 1XRA D 1XRA E 1XRA H 1XRA L 1XRA M 4XRA A 1RPE 19PCHL 32JPE a16 29XCHG 46CPE a16 33lhlx 11XRI d8 2RST 5 5ORA B 1ORA C 1ORA D 1ORA E 1ORA H 1ORA L 1ORA M 4ORA A 1RP 19POP PSW 27JP a16 29DI 0CP a16 33PUSH PSW 26ORI d8 2RST 6 5CMP B 1CMP C 1CMP D 1CMP E 1CMP H 1CMP L 1CMP M 4CMP A 1RM 19SPHL 28JM a16 29EI 0CM a16 33jk a16 31CPI d8 2RST 7 5
Colors by iWantHue
The internal decoding shown above reveals a few interesting things. The NOP instruction is literally no operation - it doesn't get decoded into any instruction group. The MOV instructions are all decoded together, except for the memory operations. Similarly, the arithmetic instructions are all grouped together, except for the memory instructions. There are other smaller groups (e.g. INR/DCR, conditional jumps, conditional calls, returns), and 21 instructions that are handled uniquely(e.g. CALL, PCHL, XCHG, HALT, and 6 undocumented instructions). Surprisingly, DAA, CMA, STC, and CMC are handled together at this stage, despite having very different actions.
posted by Ken Shirriff at 10:46 AM on Feb 23, 2013
"8085 instruction set: the octal table"
6 Comments -
First, a typo of sorts: Shouldn't JK in your first table be lower case?
Second: I remember one of my EE profs (Dr. Donald Schertz) pointing out to me the octal nature of the 8085 ISA, and how what would be "MOV M, M" ends up being HLT. We had multiple EE labs at the time that required us to hand-assemble and hex-key code into SDK-85 boards, which is probably why Dr. Schertz was so keenly aware of the ISA's encoding properties.
(Our SDK-85s were fancier than most, with a bank of LEDs and toggles on the left side of the board; but, I digress.)
Anyway, that observation has caused me to look for octalness in other ISAs from the era. Indeed, the CP-1600 ISA is /very/ octal. I don't want to spam your 8085 entry with a dissertation on another processor. If anyone's interested in hearing more about the CP-1600, comment on this entry and it'll email me.
February 23, 2013 at 10:00 PM
Thanks, Mr Z. I've fixed the typo. Please feel free to post a long comment about the CP-1600 (which Wikipedia tells me is the processor in the Intellivision game).
February 24, 2013 at 9:17 AM
Ken,
I'd be happy to. Blogger apparently doesn't like my post too much (it's too long, contains HTML markup it doesn't like), so I've just moved it here: http://spatula-city.org/~im14u2c/intv/comment_for_ken_shirrifs_blog.html
Enjoy!
--Joe
February 24, 2013 at 10:40 AM
I put together a Google Docs spreadsheet with a similar breakdown of CP1600/CP1610 opcodes, with a complete expansion of the opcode space here:
https://docs.google.com/spreadsheet/ccc?key=0Ar_02usomyeqdDlESlZLZ0NKcGhzT0xYdmxYb29BTVE&usp=sharing
February 24, 2013 at 3:41 PM
Sorry if my question is completely irrelevant, but I had to know.
In the Jump Statements of 8085, whenever the condition is satisfied, there are 3 Machine Cycles and 2 Machine Cycles if the condition isn't satisfied. I want to know what are these machine cycles? First one is Opcode Fetch, I'm confused about the rest. Please, do help.
September 4, 2013 at 11:21 PM
@Anonymous: Each M cycle corresponds to a single memory fetch, if I recall correctly. Jumps are 3 bytes. You need all 3 bytes to take the jump, as the second and third bytes are the branch target address.
So then the question is "Why is it 2 M cycles when the jump isn't taken?" I imagine they're getting the first byte of the jump destination in the same M cycle as they're evaluating the jump condition, although I haven't traced through the PLAs to see if that's actually the case.
September 5, 2013 at 6:38 AM