このMC6801を日立が独自にCMOS化したものがHD6301です。HD6301は内蔵のI/Oやメモリサイズのバリエーションによって多数の品種が作られています。1981年にHD6301Vシリーズが最初に発表されてから、集積されているメモリ容量やI/Oポートの違いによって、さまざまな品種が開発されています。
その中のもっとも小規模なLSIであるHD6301V1の開発用として背中にROMソケットを取り付けたものが、下の写真のHD63P01M1です。
HD6301やMC6801はマイクロプロセッサモードで外部にメモリを接続できますが、その場合にはアドレスやデータの入出力のために、本来の入出力ポートの端子を使用してしまいます。シングルチップコンピュータとして、内蔵のI/Oを利用するアプリケーションを開発する際に肝心のI/Oが使えないのは困りますから、ROMを取り付ける特別なソケットを背中に取り付けたものが開発者用に提供されていたわけです。当然ながら特殊なパッケージと特殊なチップというわけで、高価なものでした。これでプログラムの開発とテストを行ってから、マスクROM化して量産に移行します。
シングルチップコンピュータの開発者向けの専用チップには、他にROM外付け用のピンを増やした多ピンパッケージのものや、窓付きのパッケージに紫外線消去型ROM内蔵のチップを封入したものなどがあります。
HD6301シリーズのレジスタ構成はこのようになっています。
MC6800と異なる点は前述のように、A, Bアキュムレータを連結して16 bitアキュムレータのDレジスタとして使用可能なところだけです。それ以外はフラグまで共通になっています。
次に命令についてですが、MC6800に含まれる命令はバイナリコードまですべて共通でさらにいくつか命令が追加されているだけなので、その追加命令だけ紹介しようと思いましたら、命令実行時間がインデックスアドレッシング関係を中心にかなり変化しているため、全命令を紹介することにしました。
アキュムレータやメモリ関係の命令はこのくらいあります。
意味
ニーモニック IMMED DIRECT INDEX EXTEND IMPLIED 動作
Add
ADDA 8B 2 2 9B 3 2 AB 4*2 BB 4 3
A + M -> A
ADDB CB 2 2 DB 3 2 EB 4*2 FB 4 3
B + M -> B
*ADDD C3 3 3 D3 4 2 E3 5 2 F3 5 3
D + M -> D
Add Accumulators ABA
1B 1*1 A + B -> A
Add with Carry
ADCA 89 2 2 99 3 2 A9 4*2 B9 4 3
A + M + C -> A
ADCB C9 2 2 D9 3 2 E9 4*2 F9 4 3
B + M + C -> B
And
ANDA 84 2 2 94 3 2 A4 4*2 B4 4 3
A & M -> A
ANDB C4 2 2 D4 3 2 E4 4*2 F4 4 3
B & M -> B
And Immed. with Mem. *AIM
71 6 3 61 7 3
M & imm -> M
Bit Test
BITA 85 2 2 95 3 2 A5 4*2 B5 4 3
A & M
BITB C5 2 2 D5 3 2 E5 4*2 F5 4 3
B & M
Clear
CLR
6F 5*2 7F 5*3 0 -> M
CLRA
4F 1*1 0 -> A
CLRB
5F 1*1 0 -> B
Compare
CMPA 81 2 2 91 3 2 A1 4*2 B1 4 3
A - M
CMPB C1 2 2 D1 3 2 E1 4*2 F1 4 3
B - M
Compare Accumulators CBA
11 1*1 A - B
Complement
COM
63 6*2 73 6 3 not M ->
M
COMA
43 1*1 not A -> A
COMB
53 1*1 not B -> B
Negate
NEG
60 6*2 70 6 3 0 - M ->
M
NEGA
40 1*1 0 - A -> A
NEGB
50 1*1 0 - B -> B
Decimal Adjust
DAA
19 2 1 BCD補正
Decrement
DEC
6A 6*2 7A 6 3 M - 1 ->
M
DECA
4A 1*1 A - 1 -> A
DECB
5A 1*1 B - 1 -> B
Exclusive OR
EORA 88 2 2 98 3 2 A8 4*2 B8 4 3
A eor M -> A
EORB C8 2 2 D8 3 2 E8 4*2 F8 4 3
B eor M -> B
EOR Immed. with Mem. *EIM
75 6 3 65 7 3
M eor imm -> M
Increment
INC
6C 6*2 7C 6 3 M + 1 ->
M
INCA
4C 1*1 A + 1 -> A
INCB
5C 1*1 B + 1 -> B
Load Accumulator LDAA
86 2 2 96 3 2 A6 4*2 B6 4 3
M -> A
LDAB C6 2 2 D6 3 2 E6 4*2 F6 4 3
M -> B
*LDD CC 3 3 DC 4 2 EC 5 2 FC 5 3
M -> D
Multiply
*MUL
3D 7 1 A * B -> D
Or
ORAA 8A 2 2 9A 3 2 AA 4*2 BA 4 3
A or M -> A
ORAB CA 2 2 DA 3 2 EA 4*2 FA 4 3
B or M -> B
Or Immed. with Mem. *OIM
72 6 3 62 7 3
M or imm -> M
Push Data
PSHA
36 4 1 A -> M(SP--)
PSHB
37 4 1 B -> M(SP--)
Pull Data
PULA
32 3*1 M(++SP) -> A
PULB
33 3*1 M(++SP) -> B
Rotate Left
ROL
69 6*2 79 6 3 ROL(M)
ROLA
49 1*1 ROL(A)
ROLB
59 1*1 ROL(B)
Rotate Right
ROR
66 6*2 76 6 3 ROR(M)
RORA
46 1*1 ROR(A)
RORB
56 1*1 ROR(B)
Shift Left Arithmetic ASL
68 6*2 78 6 3 ASL(M)
ASLA
48 1*1 ASL(A)
ASLB
58 1*1 ASL(B)
*ASLD
05 1 1 ASL(D)
Shift Right Arithmetic ASR
67 6*2 77 6 3 ASR(M)
ASRA
47 1*1 ASR(A)
ASRB
57 1*1 ASR(B)
Shift Right Logic LSR
64 6*2 74 6 3 LSR(M)
LSRA
44 1*1 LSR(A)
LSRB
54 1*1 LSR(B)
*LSRD
04 1 1 LSR(D)
Store Accumulator STAA
97 3*2 A7 4*2 B7 4*3 A
-> M
STAB D7 3*2 E7 4*2 F7 4*3
B -> M
*STD DD 4 2 ED 5
2 FD 5 3 D -> M
Subtract
SUBA 80 2 2 90 3 2 A0 4*2 B0 4 3
A - M -> A
SUBB C0 2 2 D0 3 2 E0 4*2 F0 4 3
B - M -> B
*SUBD 83 3 3 93 4 2 A3 5 2 B3 5 3
D - M -> D
Subtract Accumulators SBA
10 1*1 A - B -> A
Subtract with Carry SBCA 82 2 2 92 3 2
A2 4*2 B2 4 3 A - M - C
-> A
SBCB C2 2 2 D2 3 2 E2 4*2 F2 4 3
B - M - C -> B
Transfer Accumulator TAB
16 1*1 A -> B
TBA
17 1*1 B -> A
Test Zero or Minus TST
6D 4*2 7D 4*3 M - 0
TSTA
4D 1*1 A - 0
TSTB
5D 1*1 B - 0
Test Immed. with Mem. *TIM
7B 4 3 6B 5 3
M & imm
この表で、ニーモニックの欄はアセンブラで使われるニーモニックを示します。この後の欄は数字3組の欄が五つ続いていますが、それぞれがアドレッシングモードに対応しています。数字3組のうち、最初の2桁の16進数が、その命令のオペコードです。次の1桁の数字が命令実行に必要なクロック数、最後の1桁がその命令全体のバイト数です。この数字が2や3になっている命令には、アドレス修飾に必要なバイトが1ないし2
Byteだけオペコードの後に続きます。
ニーモニックの直前に*が付けられているものがMC6800に存在せずにHD6301に新設されている命令です。また、命令実行クロック数の直後に*が付けられているものがMC6800と異なるクロック数で実行される命令です。
*印の付いている実行クロック数はたいてい1クロック短縮されていますが、中にはTST命令のインデックスアドレッシングモードのように3クロック短縮されている命令もあります。これは、MC6800では内部回路を単純化するため、TST命令やCLR命令もINC命令やDEC命令と同じ手順でメモリアクセスして処理を行っていたのを修正したことによります。つまりINC命令ではメモリ内容を読み出してからインクリメントして、その結果を同じアドレスのメモリに書き込んでいました。MC6800のTST命令でもデータをメモリから読み出して判定を行い、同じデータを書き込もうとします。実際には最後の書き込みはVMA信号によって無効にされるはずですが。MC6800のCLR命令も、単にメモリに0を書き込めばよさそうですが、実際にはINC命令と同じように、まず対象メモリのデータを読み出し、意味のない内部処理サイクルが実行されてから0が対象メモリに書き込まれます。HD6301では、そのような無意味なサイクルを省略しているため、高速化されています。
なお、インデックスアドレッシング関係の高速化はMC6800からMC6801へのときに行われて、HD6301はそれを踏襲しています。インプライドアドレッシング関係の命令とTST命令などの高速化はHD6301で初めて行われました。
追加された命令にはDレジスタ関係のロード、ストア、加減算やシフトの他、AIM,
EIM, OIM, TIM命令といったメモリ内容へのイミディエート操作とMUL命令があります。
AIM, EIM, OIM, TIM命令は一見それほど便利な命令には見えませんが、ゼロページ領域に配置されたI/Oポートへの操作に利用する場合に特にその力が発揮されます。つまり、I/Oのいくつかのビットのセットやリセットやテストが、アキュムレータの内容を変化させずに可能になるのです。汎用マイクロプロセッサよりI/Oポートのビット操作の回数が多くなりがちな組み込み用マイクロコンピュータにとっては大変便利です。この4種類の命令はMC6801にも存在せず、HD6301で初めて導入されたものです。MUL命令とDレジスタ関係命令はMC6801のときに導入されています。
次にインデックスレジスタやスタックポインタ操作 関係のグループです。
意味
ニーモニック IMMED DIRECT INDEX EXTEND IMPLIED 動作
Add B to Index *ABX
3A 1 1 B + X -> X
Compare Index Reg. CPX 8C 3
3 9C 4 2 AC 5*2 BC 5 3
X - M
Decrement Index Reg. DEX
09 1*1 X - 1 -> X
Decrement SP
DES
34 1*1 SP - 1 -> SP
Increment Index Reg. INX
08 1*1 X + 1 -> X
Increment SP
INS
31 1*1 SP + 1 -> SP
Load Index Reg. LDX
CE 3 3 DE 4 2 EE 5*2 FE 5 3
M -> X
Load SP
LDS 8E 3 3 9E 4 2 AE 5*2 BE 5 3
M -> SP
Push Index
*PSHX
3C 5 1 X -> M(SP--)
Pull Index
*PULX
38 4 1 M(++SP) -> X
Store Index Reg. STX
DF 4*2 EF 5*2 FF 5*3 X
-> M
Store SP
STS 9F 4*2 AF 5*2
BF 5*3 SP -> M
Transfer Index to SP TXS
35 1*1 X - 1 -> SP
Transfer SP to Index TSX
30 1*1 SP + 1 -> X
Exchange D with Index *XGDX
18 2 1 D <-> X
ここではMC6800と比較して4命令が追加されています。このうちXGDX命令だけがHD6301で新設された命令で、残りのABX,
PSHX, PULX命令はMC6801で追加されたものです。
ついにXレジスタのプッシュプルが可能になりました。これはインデックスレジスタが1本しか存在しないHD6301(やMC6801)ではとても有益な命令です。サブルーチン内でインデックスレジスタを使いたいけどメインルーチンでもインデックスレジスタを利用していて、サブルーチンの入り口でインデックスレジスタを退避しなくてはならない場面はよくありますが、MC6800ではスタックにプッシュできずにゼロページかどこかのRWMに退避場所を用意しなくてはならず、面倒でした。
次はプログラムカウンタ関係の命令ですね。このグループはプログラムカウンタ相対アドレッシングしか許されないブランチ系の命令と、それ以外に分けて表にします。
意味
ニーモニック REL 条件
Branch Always
BRA 20 3*2 常に分岐
Branch Never
*BRN 21 3 2 常に分岐せず(2 Byte NOP命令)
Branch If Carry Clear BCC 24 3*2
C = 0
Branch If Carry Set BCS
25 3*2 C = 1
Branch If = Zero
BEQ 27 3*2 Z = 1
Branch If >= Zero BGE
2C 3*2 N eor V = 0
Branch If > Zero
BGT 2E 3*2 Z + (N eor V) = 0
Branch If Higher
BHI 22 3*2 C + Z = 0
Branch If <= Zero
BLE 2F 3*2 Z + (N eor V) = 1
Branch If Lower or Same BLS 23 3*2 C +
Z = 1
Branch If < Zero
BLT 2D 3*2 N eor V = 1
Branch If Minus
BMI 2B 3*2 N = 1
Branch If Not Equal Zero BNE 26 3*2 Z = 0
Branch If Overflow Clear BVC 28 3*2 V = 0
Branch If Overflow Set BVS 29 3*2
V = 1
Branch If Plus
BPL 2A 3*2 N = 0
Branch to Subroutine BSR 8D
5*2 動作: PC -> (SP--), PC += offset
最後のだけがサブルーチン呼び出しで特別な動作をしますが、他は条件分岐命令です。
実行クロック数が短くなっているのを除けば、BRN命令だけが新設の命令です。これは絶対に条件が成立しない条件分岐命令ですが、実質的に2
ByteのNOP命令として利用されます。
その他のプログラムカウンタ回りの命令には、このようなものがあります。
意味
ニーモニック DIRECT INDEX EXTEND IMPLIED 動作
Jump
JMP 6E 3*2 7E 3 3
Addr -> PC
Jump To Subroutine JSR 9D*5
2 AD 5*2 BD 6*3 PC -> (SP--),
Addr -> PC
No Operation
NOP
01 1*1 Do nothing
Return From Interrupt RTI
3B 10 1
Return From Subroutine RTS
39 5 1 (++SP) -> PC
Sleep
*SLP
1A 4 1
Software Interrupt SWI
3F 12 1
Wait for Interrupt WAI
3E 9 1
HD6301でSLP命令が追加されています。これはスリープモードに入る命令で、低消費電力の装置に応用するためのものです。
他にJSR命令にダイレクトモードアドレッシングが追加されています。
最後に残ったのがCCR、フラグ関係の命令ですね。これには、次の8命令が含まれます。
意味
ニーモニック IMPLIED 動作
Clear Carry
CLC 0C 1*1 0 -> C
Clear Interrupt Mask CLI 0E 1*1 0
-> I
Clear Overflow
CLV 0A 1*1 0 -> V
Set Carry
SEC 0D 1*1 1 -> C
Set Interrupt Mask SEI 0F 1*1
1 -> I
Set Overflow
SEV 0B 1*1 1 -> V
Transfer A to CCR TAP
06 1*1 A -> CCR
Transfer CCR to A TPA
07 1*1 CCR -> A
クロック数が変化しているほかはMC6800と共通です。
総じて、MC6800とほとんど変わりませんが、MC6800で不便なところのいくつかが解消されるような形で命令が追加され、若干の高速化が行われていると考えられます。MC6800のプログラミングに慣れたプログラマなら、ニーモニックやバイナリコードの変更もありませんから、ほとんどそのままHD6301に移行できるはずです。アセンブラもマクロ機能のあるMC6800用アセンブラがあれば、ちょっとしたマクロ定義を追加するだけでHD6301用のアセンブラとして使えるでしょう。もちろんMC6800用コンパイラはそのまま流用できます。
MC6801/HD6301は1980年頃の組み込み用8 bitシングルチップコンピュータとしてはそれなりに機能の高いプロセッサ部であったということができると思います。
Return to IC Collection