1 of 69

「TW4」

れもん

2 of 69

自己紹介

れもん

↑残像

  • ID: lemoncmd
  • 低レイヤ全般好き
  • 自作と理解の繰り返し

3 of 69

技術書典で本を出しました

  • レトロゲームを知りたい人のための�特権命令・割り込み概論�
  • CPUにどうやって特権命令や割り込み�を乗っけるかを解説する本です

   ここから買えます→

4 of 69

技術書典で本を出しました

  • レトロゲームを知りたい人のための�特権命令割り込み概論�
  • CPUにどうやって特権命令割り込み�を乗っけるかを解説する本です

   ここから買えます→

5 of 69

特権命令

6 of 69

割り込み

7 of 69

4

8 of 69

特権命令

9 of 69

割り込み

10 of 69

4

もうお分かりですね?

11 of 69

「TW4」

12 of 69

「TW4」

Tokken Warikomi 4bitCPU

13 of 69

TD4に 特権 と 割り込み を載せました

  • アドレス長はそのまま4bit
  • 命令長はそのまま8bit
  • ナンもカンも互換性アリ〼。

     このラーメンタイマーも

     そのまま動きます。→

out 0111 // LEDを3つ点灯

loop1:

add a, 0001 // 16回ループ

jnc loop1

loop2:

add a, 0001 // また16回ループ

jnc loop2

out 0110 // LEDを2つ点灯

loop3:

add a, 0001 // 16回ループ

jnc loop3

loop4:

add a, 0001 // また16回ループ

jnc loop4

loop5:

out 0000 // LEDを滅

out 0100 // LEDを点

add a, 0001 // そして16回ループ

jnc loop5

out 1000 // 端のLEDを点灯する

jmp 1111 // おわり(無限ループ)

14 of 69

機能紹介

  • 4つのCPUモード

15 of 69

機能紹介

  • 4つのCPUモード
  • 3つの追加命令

16 of 69

機能紹介

  • 4つのCPUモード
  • 3つの追加命令
  • 2種類の割り込み

17 of 69

機能紹介

  • 4つのCPUモード
  • 3つの追加命令
  • 2種類の割り込み
  • あと例外

18 of 69

機能紹介

  • 4つのCPUモード
  • 3つの追加命令
  • 2種類の割り込み
  • あと例外
  • あと仮想メモリ

19 of 69

機能紹介

  • 4つのCPUモード
  • 3つの追加命令
  • 2種類の割り込み
  • あと例外
  • あと仮想メモリ
  • あとシステムレジスタ

20 of 69

機能紹介

  • 4つのCPUモード
  • 3つの追加命令
  • 2種類の割り込み
  • あと例外
  • あと仮想メモリ
  • あとシステムレジスタ
  • あと色々

21 of 69

4つのCPUモード

  • ユーザーモード
  • ソフトウェア割り込みモード
  • 例外モード
  • ハードウェア割り込みモード

特権モード

22 of 69

ちょっと待って?

23 of 69

どうやって互換性を保ちながら割り込みハンドラを?

  • 16個しか命令を入れられないはず
  • でもラーメンタイマーも動くって言ってたし……
  • どこに割り込みハンドラを詰め込むの?

24 of 69

どうやって互換性を保ちながら割り込みハンドラを?

  • 16個しか命令を入れられないはず
  • でもラーメンタイマーも動くって言ってたし……
  • どこに割り込みハンドラを詰め込むの?

→仮想メモリ空間を使います

25 of 69

仮想メモリ(?)

0

0

0

1

1

0

モード

アドレス

26 of 69

仮想メモリ(?)

0

0

0

1

1

0

1

0

0

0

0

1

モード

アドレス

†物理アドレス†

27 of 69

仮想メモリ(?)

0

0

0

1

1

0

1

0

0

0

0

1

モード

アドレス

†物理アドレス†

ユーザー

セクション

SW割り込み

セクション

HW割り込み

セクション

例外

セクション

マッピング

28 of 69

仮想メモリ(?)

↑の表を作るのに44回右クリックしました

0

0

0

1

1

0

1

0

0

0

0

1

モード

アドレス

†物理アドレス†

ユーザー

セクション

SW割り込み

セクション

HW割り込み

セクション

例外

セクション

マッピング

29 of 69

レジスタの退避は?

  • 割り込み処理しちゃったらユーザーモードのレジスタ壊しちゃいそう
  • でもTD4って退避する用のRAMとかないよね……?

30 of 69

参考:ARMのレジスタ

  • CPUのモードごとに独立した汎用レジスタがある(↓はARMv4~ARMv6)

31 of 69

レジスタの退避は?

  • 割り込み処理しちゃったらユーザーモードのレジスタ壊しちゃいそう
  • でもTD4って退避する用のRAMとかないよね……?�
  • 特権モード用にレジスタ作ろう!

ユーザーモード

B

A

C

特権モード

A

B

C

32 of 69

レジスタの切り替え

ユーザーモード

B

A

C

特権モード

A

B

C

ALU

(組合せ回路)

0

0

モード

33 of 69

レジスタの切り替え

ユーザーモード

B

A

C

特権モード

A

B

C

ALU

(組合せ回路)

0

1

モード

34 of 69

レジスタの入れ替え

ユーザーモード

B

A

C

特権モード

A

B

C

ALU

(組合せ回路)

0

1

モード

SWAP命令

35 of 69

ソフトウェア割り込み

  • ハンドラ内で特権が使えるだけのただのAPI

36 of 69

ソフトウェア割り込みの実装

  • SWI命令はモードとインストラクションポインタ切り替えるだけです
    • ただのジャンプとほぼほぼ変わらない
  • IRET命令で戻る時用にインストラクションポインタ+1は保存しておきましょう

0

0

0

0

1

0

0

1

0

0

0

0

0

1

0

1

0

1

0

0

0

0

1

1

ジャンプ!

ジャンプ!

なんやかんや処理して

37 of 69

例外

  • 命令の実行中に何か異常事態が発生した際に例外ハンドラ起動
  • 異常事態って何があるか考えてみよう!

38 of 69

例外

  • 命令の実行中に何か異常事態が発生した際に例外ハンドラ起動
  • 異常事態って何があるか考えてみよう!
    • 未使用のオペランド(TD4だと1000, 1010, 1100, 1101が未使用)

39 of 69

例外

  • 命令の実行中に何か異常事態が発生した際に例外ハンドラ起動
  • 異常事態って何があるか考えてみよう!
    • 未使用のオペランド(TD4だと1000, 1010, 1100, 1101が未使用)
    • 即値が使われていない命令で、即値が0000以外だった場合(OUT Bなど)

40 of 69

例外

  • 命令の実行中に何か異常事態が発生した際に例外ハンドラ起動
  • 異常事態って何があるか考えてみよう!
    • 未使用のオペランド(TD4だと1000, 1010, 1100, 1101が未使用)
    • 即値が使われていない命令で、即値が0000以外だった場合(OUT Bなど)
    • 16番目の命令から次に進んでしまった場合
      • TD4実装では最初の命令に戻ってしまう……これは本当に意図した挙動?

41 of 69

例外の実装

  • 異常事態が発生した命令を実行しなかったことにしたいね🌾

42 of 69

例外の実装

ユーザーモード

B

A

C

特権モード

A

B

C

ALU

(組合せ回路)

0

0

モード

異常事態

43 of 69

例外の実装

ユーザーモード

B

A

C

特権モード

A

B

C

ALU

(組合せ回路)

0

0

モード

異常事態

44 of 69

例外の実装

ユーザーモード

B

A

C

特権モード

A

B

C

ALU

(組合せ回路)

0

0

モード

異常事態

0

0

0

0

1

0

1

0

0

0

0

0

ジャンプ!

45 of 69

例外中の例外

  • ところで例外ハンドラの中で例外が起こったらどうなるの?

46 of 69

例外中の例外

  • ところで例外ハンドラの中で例外が起こったらどうなるの?
  • ダブルフォールト!
    • 完全にCPUの動作を停止するよう実装をします

47 of 69

ハードウェア割り込み

  • 先に謝らないといけないのが、実は本の方で非同期のハードウェア割り込み対応できていません。

48 of 69

ハードウェア割り込み

  • 先に謝らないといけないのが、実は本の方で非同期のハードウェア割り込み対応できていません。
  • というわけで今回は非同期版について話します

49 of 69

ハードウェア割り込み

  • 先に謝らないといけないのが、実は本の方で非同期のハードウェア割り込み対応できていません。
  • というわけで今回は非同期版について話します

50 of 69

ハードウェア割り込み用ハードウェア

  • 単純なのでボタンを使いましょう

51 of 69

ハードウェア割り込み用ハードウェア

  • 単純なのでボタンを使いましょう
  • 押したら割り込み要求信号IRQを出します
  • 割り込み応答信号ACKが来たら割り込み要求を停止します
  • 以上!

52 of 69

CPUとハードウェアの挙動

CPU

ぼたん

IRQ

ACK

時刻: 0.5

53 of 69

CPUとハードウェアの挙動

CPU

ぼたん

IRQ

ACK

時刻: 1

54 of 69

CPUとハードウェアの挙動

CPU

ぼたん

IRQ

ACK

ACKが切れた瞬間IRQを切る!

時刻: 2

55 of 69

ハードウェアが複数の場合は?

  • 同時に割り込みなんてされたら大変
  • 割り込み調停を行う必要がある
    • どの割り込みに応答するかを決める
  • 今回はレトロゲームにしばしば採用されたデイジーチェーンを紹介

56 of 69

デイジーチェーン

CPU

ボタン

ボタン

ボタン

57 of 69

デイジーチェーン

CPU

ボタン

ボタン

ボタン

IRQ

58 of 69

デイジーチェーン

CPU

ボタン

ボタン

ボタン

ハイ・陰ピー・ダンス

IRQ

59 of 69

デイジーチェーン

CPU

ボタン

ボタン

ボタン

ハイ・陰ピー・ダンス

IRQ

60 of 69

デイジーチェーン

CPU

ボタン

ボタン

ボタン

High impedance

IRQ

61 of 69

デイジーチェーン

CPU

ボタン

ボタン

ボタン

High impedance

IRQ

62 of 69

デイジーチェーン

CPU

ボタン

ボタン

ボタン

IRQ

割り込み

許可信号

63 of 69

デイジーチェーン

CPU

ボタン

ボタン

ボタン

IRQ

割り込み

許可信号

割り込み

64 of 69

デイジーチェーン

CPU

ボタン

ボタン

ボタン

IRQ

割り込み

許可信号

割り込み

割り込み

割り込めないよ

65 of 69

デイジーチェーン

CPU

ボタン

ボタン

ボタン

IRQ

割り込み

許可信号

割り込み

66 of 69

割り込み無効化

  • ところで、全ハードウェアの割り込み要求に付き合っていたら日が暮れる
  • 欲しい割り込みのみに絞る機能

67 of 69

割り込み無効化

  • ところで、全ハードウェアの割り込み要求に付き合っていたら日が暮れる
  • 欲しい割り込みのみに絞る機能

68 of 69

割り込み無効化

  • ところで、全ハードウェアの割り込み要求に付き合っていたら日が暮れる
  • 欲しい割り込みのみに絞る機能
  • 初期状態で全ての割り込みを無効化
  • 有効化されたボタンだけ割り込み要求できる
  • 割り込み有効/無効を制御できる命令を追加

69 of 69

以上がTW4のあらましです

  • 今回の話についてこの本に書いてます�
  • GitHubにソースコードを上げています�https://github.com/lemoncmd/TW4�

   ここから買えます→