パスワードを忘れた? アカウント作成
16550221 journal
日記

kitune-sanの日記: Verilog HDLでマイクロシーケンサ(CPU)を作る

日記 by kitune-san

ひさしぶりの日記。

MMC(SD)にアクセスしたり、カードにIDE(ATA)のプロトコルを使用してアクセスするためのラッパーなどを無理やりHDLコードを書いていたのだが、
ステートマシンを含めた組み合わせ回路が複雑化してきた。

そこで組み合わせ回路の部分をシーケンサに置き換えることで、全体の設計をシンプルに、そしてLEの使用量を削減できるのではないだろうか?という考えから、
勉強がてらマイクロシーケンサを作ってみることにした。多分初めて設計した自作CPU。
結果として結構使いにくそうなものができたので、実用になるかはわからん。

完成したものはその特徴からLD/STシーケンサ(仮)と名付けた。

ブロック図はこれ
https://github.com/kitune-san/LDST_Sequencer/blob/main/DOC/img/LDST_DIAGRAM.png

CPUのコードはこれ
https://github.com/kitune-san/LDST_Sequencer/blob/main/HDL/LDST_SEQUENCER.v

## 命令

命令は、12ビット固定長で、LD/LDI/ST/CALL/RET/JZ/JC/JO/JMPの9種類。
命令の形式はシンプルで、上位4ビットにOPコード、残りの下位8ビットをデータやレジスタの指定に割り当てた。
後述するが、ALUの操作命令はシーケンサの命令から取り除いた。
最初は、subleq命令のみを実装しようかと思ったが、プログラムの作成の難易度が上がるのと、コードの効率が悪そうだと考えたためこれはやめた。

0000 rrrr rrrr : LD: rに指定したレジスタNo.の値をワークレジスタにロードする。
0010 dddd dddd : LDI: データdをワークレジスタにロードする。
0001 rrrr rrrr : ST: ワークレジスタの値をrに指定したレジスタへストアする。
0100 dddd dddd : CALL: 現在のアドレスをスタックへプッシュし、(ワークレジスタ * 256 + データd)のアドレスへジャンプする。
0101 0000 0000 : RET: アドレスをスタックからポップし、そこへジャンプする。
1001 dddd dddd : JZ: ゼロフラグが1ならば、(ワークレジスタ * 256 + データd)のアドレスへジャンプする。
1010 dddd dddd : JC: キャリーフラグが1ならば、(ワークレジスタ * 256 + データd)のアドレスへジャンプする。
1100 dddd dddd : JO: オーバーフローフラグが1ならば、(ワークレジスタ * 256 + データd)のアドレスへジャンプする。
1000 dddd dddd : JMP: 無条件ジャンプ。(ワークレジスタ * 256 + データd)のアドレスへジャンプする。

## レジスタ
マイクロシーケンサ内部のレジスタは、5つ。この内ワークレジスタを除く4つのレジスタは、以下のアドレスに割り当てられている。

アドレス : 名前 : 機能
0 : A : Aレジスタ。ALU実行時に使用する。一時レジスタとしても使用できる。
1 : B : Bレジスタ。ALU実行時に使用する。一時レジスタとしても使用できる。
2 : FLAGS : ALUの計算結果に応じて対応するフラグが立つ。ジャンプ命令の条件判定として使用する。
3 : ALU OP/RESULT : ST命令で、ALU OPコードを設定する。 LD命令でALUOPコードが実行され、結果を取得する。
4-255 : ユーザー定義エリア : 外部バスを使用してユーザーが設定できる。

これらのレジスタに値を設定するときや、値を移動させるときは、LD/ST命令を使用してワークレジスタを介さなければならない。

例えば、
Aレジスタに5を入力する場合は:
0010 0000 0101: LD #5
0001 0000 0000: ST A

Aレジスタの値をBレジスタに入力する場合は:
0000 0000 0000: LD A
0001 0000 0001: ST B
となる。

レジスタのアドレス幅は、8ビットであるため、万が一255を超えるメモリなどが必要となった場合は、レジスタバンクなどを用意する必要がある。

## ALU
よくあるCPUの命令コードには、ALUの操作が含まれているが、
今回設計したシーケンサには、ALU操作命令は含まず、LD/STによるレジスタアクセスを介してALUを操作および結果の取得を行うようにした。
つまり、ALUを動作させる場合は、
1. ST ALU(0001 0000 0011)で実行したいALU OPコードをセットし、
2. LD ALU(0000 0000 0011)でALUを実行させ、結果をワークレジスタにセット。(同時にフラグが更新)
という手順を取る必要がある。

当初はこのようなことを考えておらず、subleq命令のみのシーケンサを考えていたが、このLD/STシーケンサよりもプログラムメモリ消費が多くなりそうに思えた。
プログラムメモリの消費がそれほど多くなく(ただし少なくもなく)、回路の規模もそれほど多くなく(ただし少なくもなく)といった、
都合のいい塩梅を考えてみた結果、このような構成にすることにした。ただし本当にうまい具合になっているかは検証してないのでわからない。

ALU OPコードは以下の通り、
OP Code : OP : 動作
0000 0000 : AND : A and B
0000 0100 : NAND : A nand B
0010 0000 : OR : A or B
0010 0100 : NOR : A nor B
0010 1100 : NOT : not A
0100 0000 : XOR : A xor B
0100 0100 : XNOR : A xnor B
1000 0000 : ADD : A add B
1000 0001 : ADC : A + B + carry
1000 0011 : SUB : A - B
1000 0011 : SBC : A - B - !carry
1010 0000 : SHL : A << 1
1010 0001 : SHCL : A << 1 最下位ビットにキャリーを格納
1100 0000 : SHR : A >> 1
1100 0001 : SHCR : A >> 1 最上位ビットにキャリーを格納
1110 0000 : SAR : A >> 1 最上位ビットはシフト前と同じ

ALU使用例:10+5の場合
---
# A ← 10
0010 0000 1010: LD #10
0001 0000 0000: ST A

# B ← 5
0010 0000 0101: LD #5
0001 0000 0001: ST B

# ALU ← ADD
0010 1000 0000: LD #ADD
0001 0000 0011: ST ALU

# work_reg ← A + B
0000 0000 0011: LD ALU
---

今でも、ALU操作命令をシーケンサのOPコードに含めるかどうか悩んでいる。
プログラムコードの効率という考え方で行くと、
今のやり方では一回の計算で12bit x 2命令 = 24bitかかるのに対し、
シーケンサのOPコードにALU操作命令を含んだ場合、OPコード長が4bit長くなるとしても、16bit x 1命令 = 16bitで済むため、24 - 16 = 8bit分コード効率がいいと考えることができる。
しかし、計算以外の単純な転送命令、ジャンプ命令などは16-12=4bitつねに無駄が生じることになる。

命令を可変長にすればいいのだろうか?まあでも今のやり方も可変長命令みたいなものである。

16209293 journal
日記

kitune-sanの日記: Chisel

日記 by kitune-san

久しぶりの日記

コロナの濃厚接触者になってしまい、会社に出社できなかったので、
今日は積読していた「RISC-VとChiselで学ぶはじめてのCPU自作」を読んで(コードの写経)をしていた。

テストの出力と脳内デバッグ結果とが一致しなくて第8章あたりで手が止まってしまっていた。
で、「:=」がVerilogでいうノンブロッキング代入のことだと思っていたが、そうではなく、ただの信号間の接続だということに気がついた。
一旦思い込んでしまうと、思い込みを解消するまで大変だ。やっとスッキリした。

alwaysやprocessといった記述がないのでここでレジスタに代入しているんだぞって感じがなく、今の時点では読みにくいなぁと思ってしまう。
これは馴れが必要だ。

15554599 journal
日記

kitune-sanの日記: 今更だけど、サイバーパンク2077クリアした

日記 by kitune-san

クリアと言ってもメインストーリーのクリアだけど。決して実績100%とかではない。
今日3回アダムスマッシャーを倒した。
なんというか・・・バッドエンドではないけど、ハッピーエンドでもないなこれ。

個人的に印象に残ってるクエストは
・デラマン
・ブレンダン
・ペラレス
・ケンタウロスーアルファー星人のー仕業だー
かなぁ

15535804 journal
日記

kitune-sanの日記: DDR4 SPDの読み書きがしたい!

日記 by kitune-san

フリーソフト使えばいいじゃんと思ったあなた!そのとおりなので戻るボタンを押しましょう。

マイXMPをメモリに書き込んで自分専用のオーバークロックメモリを作ろうと思ったことはありませんか?私はありません。
ただ、SPD設定を意味もなく読み書きしたいなとふと思ったのです。
いろいろ調べているとセンチュリーマイクロが販売しているみたいだけれども、個人が買える感じではない。
そもそもフリーソフトでSPD書き換えができるのだけれども、どれが本家かわからん。そして怖い。あとなにより面白くない。
というわけで基板から作ってみることにした。

実際、ちょっと変わったEEPROMと接続するだけなので、回路はそんなに難しくない。EEPROMの資料はSPD EEPROMとかで検索すると出てくる。
回路図はこれ(笑)。KiCAD使おうと思ったけど、部品作成からする必要があり面倒だったので手で書いた。
マイコンは練習も兼ねてRaspberry pi picoにした。
面倒なのはEEPROMの電源は仕様上は2.5V±10%だということで、3.3Vから降圧する必要がある。(いくつかのSPD EEPROMのデータシートとか見るとそのまま3.3Vぶっ込んでも問題はなさそうである。)
LDOレギュレータ使うかツェナーダイオード使うか迷った末、LDOレギュレータ(BH25MA3)を使用することにした。
表面実装なのはパーツ屋にあった2.5VLDOレギュレータがこれしかなかったため。普通に3本足のものとかあるのでそちらを使うことをおすすめする。だれもやらないと思うが。

完成図はこれ
パーツを外したときの上からの写真
はんだ面

プログラムはC/C++で書いた。Pico-SDKめっちゃ楽。クラスを使ったのは、久しぶりのC++を体験したかったから。それだけ(普段はC言語)。だからC++できているかはわからん。
最後にC++触ったのって、いつだろう。shared_ptrが標準に入るとか入らないとか言ってたころだと思う。

SPD読み出しの出力はこんな感じ。
書き込み機能もつくったけどまだ確認できてない。

コードは以下に記録した。
https://github.com/kitune-san/SPD_RW

15497658 journal
日記

kitune-sanの日記: PCケース変更 4

日記 by kitune-san

CoolerMaster Silencio 650からFractal Design Define R5に変更
ええ、好きですとも静音と窒息型。

というか、側面スケスケケース多すぎてびっくり。流行ってるのか。
きれいな配線と光らせる自信ががないよ。

15461771 journal
日記

kitune-sanの日記: 下側が可動する小型のLANポートあるじゃん? 4

日記 by kitune-san

意識していないとたまーに、
あそこにUSB(タイプAオス)を突っ込んじゃうんだけど、なんかいい対策ないかな。

え、そんなことしたことないって?ほんとに〜?

15449860 journal
日記

kitune-sanの日記: 8086マイクロコードの読み方 6

日記 by kitune-san

2021/10/24 改めて読み返すと勘違いがいくつもあり、間違っている。とてもいいコメントをもらっており、消すのはもったいないので日記を残しておくが、日記の内容自体は参考にならないため注意。

------
8086のマイクロコードってどうなんているんだろうと思って調べていたら、メタルレイヤの画像から読み出している人がいてびっくり。
せっかくなのでマイクロコードを読めるように少しだけ調べてみた。
まだ少しだけしか読めていないけれど、自分の備忘録として残しておく。

読んでくれる人がいるかどうか微妙だが…もしも間違いなどを見つけたら忌憚なく教えてほしい。でも優しく教えてね。

理解するのに重要な資料はUS patent 4363091。ここに必要なこと全て書いてあると思う。
ただし、ここに書いてあることが8086/88と完全に一致していない可能性があることを考慮に入れておく必要がある。

前半はCPUのハードウェア的な説明と一部命令の説明が延々と続く。レジスタ、ALU、フラグの関係を理解していれば読む必要がないと思う。最終ページにあるFig.1〜3を必要に応じて参照する。
マイクロコードに関する詳細な記述は、27ページ目(PDFで15ページ目)のTABLE 7の上の「The microcode routines for〜」からである。

マイクロコードは21ビットで構成されている。この21ビットには前半10ビットと後半11ビットとで2種類の操作命令が格納できるようになっている。
ただし今回の説明では、実際のコードやビット配置については追求しない。自分もまだよくわかっていない。
なのでニーモニックから読み取ることを目標とする。

マイクロコードの構成は次のようになっている。
S/D: レジスタやALUとの転送操作を行う。
Typ/a/b/F: 転送以外の操作(ALU操作やアドレスジャンプ)を行う。
つまり、データ転送動作とALU操作(他、操作命令)を同時に行うことができる。

さて、ここまで来たところで実際にマイクロコードを読んでみよう。
読み取る内容はAAA/AAS命令のマイクロコード列である。

 AR  X 7 6 5 4 3 2 1 0 CR S    D      Typ  a    b     F
 ------------------------------------------------------
 AAA 0 0 0 1 1 X 1 1 1 0  A    tempaL  1   XI   tempa
 AAS                   1  ONES tempb   1
                       2  Σ    A       1   DEC  tempb F
                       3               0   XΦ   5
                       4               1   INC  tempb
                       5  X    tempb   0   NCY  7
                       6  Σ    X       4   none RNI
                       7               4   none RNI

うまく表示できないので、等幅のメモ帳に貼り付けるか、US patent 4363091の「TABLE 7」を見てほしい。
テーブルが使えないっぽい。

表のARは外部のROMから読み取られた(ARレジスタに格納された)命令とそのビット列を示している。このARレジスタの値を元にマイクロコードが記述されたアドレスをデコードする。
CRはマイクロコードを進めるたびにインクリメントされるレジスタの値を示している。ジャンプ先の指定などで使用する。結果として相対アドレスに近い感じになっている。

では、いってみよう。

まず最初の命令(CR=0)を読んでみる。S=A, D=tempalとあり、Aレジスタの内容をtempaの下位へコピーする。
次にa=XI, b=tmpaとある。これは、1stオペランドにtmpaを指定したXI操作をALUに指定する。これはType1の指示である。なお、Fig.1bより、ALUの第二オペランドはtempb固定であることがわかる。
(実は、資料の方ではb=temp2と記載があったのだが、temp2なぞここ以外見当たらなかった。リバースエンジニアされた方の資料にはtempaと書かれていたためこちらに差し替えた)

A->tempaL

tempa -> ALU(XI) -> Σ
tempb --/

注意する点として、ALUの操作指示は指示後次のコード読み取りに入ったとしても、別のALU操作指示(TYPE1指示)がくるまではその指示状態が維持されるということがある。これを頭に入れておかないと後のINC/DECで混乱する。

XI命令のALU動作は、Fig.2に示されている。AASの場合のマイナスはどこで指定されるのか記載がなく、実は私の中で疑問が残っているが、とりあえず今回は無視して読み進める。

2つめの命令(CR=1)へ進む。S=ONES, D=tempbとあり、ONESをtempbへコピーする。ONESというのは資料を見た感じでは6のようだ。つまりXI命令の第二オペランドはここで設定される。

ONES(6) -> tempb

tempa -> ALU(XI) -> Σ
tempb --/

3つめの命令(CR=2)へ進む。S=Σ, D=Aとある。これはALU(XI)の演算結果をAレジスタへ格納することを示している。
また、Fのフラグが立っていることが確認できる。これは、ALU(XI)の演算で生じたフラグ変化を記録することを示している。

tempa -> ALU(XI) -> Σ -> A
tempb --/       \-> Σ(F) -> flags

同時に、a=DEC, b=tempbの指示がある。これはtempbのデクリメントを指示する。これによりALUはXIからDECへ切り替わる。

tempb -> ALU(DEC) -> Σ

4つめの命令(CR=3)へ進む。a=XΦ, b=5とある。これはMレジスタの下位ビット---ARレジスタの3ビット目を検査し真であればCR=5まで移動させるというタイプ5の指示である。
3ビット目は一体何かというと、このビットによってAAA/AAS命令のどちらであるかを決定している。

ではまずAAAの場合(XΦの結果が偽であった場合)を考える。

5つめの命令(CR=4)では、a=INC, b=tempbが指定されている。これによりALUはDECからINCへ切り替わる。

tempb -> ALU(INC) -> Σ

6つめの命令(CR=5)では、S=X, D=tempbとある。これは、Xレジスタの内容をtempbの下位へコピーする。

X -> tempb
tempb -> ALU(INC) -> Σ

また同時にキャリーフラグの検査を行う。キャリーフラグは3つめの命令(CR=2)のときに格納したflagsで立つことがある。ざっくり条件を書くと、6を足した(AAAの場合)計算結果が9を超えた場合である。
キャリーフラグが立っていない場合はCR=7まで移動する。CR=7の命令はRNI(Run Next Instruction)となっておりマイクロコードの終了を示す。そうでなければ次の命令へ進む。

7つめの命令(CR=6)では、S=Σ, D=Xとある。これは、これはALU(INC)の演算結果をXレジスタへ格納することを示している。

tempb -> ALU(INC) -> Σ -> X

同時にRNI司令が入り、マイクロコードの実行を終了する。

次に、AASの場合(XΦの結果が真であった場合)を考える。

飛び先の6つめの命令(CR=5)では、S=X, D=tempbとある。これは、Xレジスタの内容をtempbの下位へコピーする。注目する点は、AAAと違いALCがDECの状態が継続していることである。

X -> tempb
tempb -> ALU(DEC) -> Σ

また同時にキャリーフラグの検査を行う。キャリーフラグは3つめの命令(CR=2)のときに格納したflagsで立つことがある。ざっくり条件を書くと、6を引いた(AASの場合)計算結果が9を超えた場合である。
キャリーフラグが立っていない場合はCR=7まで移動する。CR=7の命令はRNI(Run Next Instruction)となっておりマイクロコードの終了を示す。そうでなければ次の命令へ進む。

7つめの命令(CR=6)では、S=Σ, D=Xとある。これは、これはALU(DEC)の演算結果をXレジスタへ格納することを示している。

tempb -> ALU(DEC) -> Σ -> X

同時にRNI司令が入り、マイクロコードの実行を終了する。

以上がAAA/AAS命令のマイクロコードである。他の命令も読めそうな気がしてこない? 読める・・・読めるぞ・・・!

15437636 journal
日記

kitune-sanの日記: SDRAMコントローラをSystemVerilogで書いてみる

日記 by kitune-san

FPGA内部のRAMブロックだけでは今後容量が不足してくると思えるため、DE0-CVに実装されているSDRAM(IS42S16320F-7TL (32Mx16))へアクセスするコントローラを作ることにした。

最初は、CPU側からのアクセスのみを考えていて、シングルモードの読み書きで問題ないと考えていた。
しかし途中でビデオメモリとの共用をしたくなってきた。共用すると速度の問題からVRAM用のキャッシュが必要となり、複数バイトの連続読み出しが必要になった。
出てきた案は、
1. バースト書き込み, バースト読み出しモードを使用する。
2. シングル書き込み, バースト読み出しモードを使用する。
3. シングルの読み書きモードとし、ACK後にREAD/WRITEコマンドを連続して送信する。(毎回バンクとCOLアドレスを指定)

1の案は、バーストの読み出し回数が固定の上、書き込みは1回としたいため、廃案にした。
2の案は、当初最有力であったが、バーストの連続読み出し回数が最大8回であることと、後に3のアクセス方法を見つけたため、廃案とした。
3の案は、読み書き回数が都度指定可能で、さらに8回以上(最大1023回)連続読み出しができるのでこれを採用した。なんかデメリットがあるかもしれないけど、とりあえずこれで進めた。

で、作ったのがこれ
まだ実際にFPGAに書き込んで動作は見ていない。どうやって確認しようか考え中。シュミレータで信号の確認はした。

使い方は次のようにした、
1. アクセスをしたいアドレス(address)、連続アクセス回数(access_num)、(書き込みの場合は)1バイト目の書き込みデータ(data_in)をセットする。
2. 読み書きどちらかの要求フラグ(write_request/read_request)を立てる。

書き込みの場合
3. 書き込み確認フラグ(write_flag)が立ったことを確認したら、要求フラグを下げ、次の書き込みデータをdata_inにセットする。
4. write_flagが下がるまで、次の書き込みデータをdata_inにセットし続ける。

読み取りの場合
3. 読み取り確認フラグ(read_flag)が立ったことを確認したら、要求フラグを下げ、data_outからデータを取得する。
4. read_flagが下がるまで、次の読み取りデータをdata_outからデータを取得する。

注意点として、colアドレス(IS42S16320Fの場合アドレス末尾10バイト)と書き込み回数とを足した結果が、colアドレスのアドレス表現を超える場合には、
書き込み/読み取り途中でアクセス先が折り返される。
また、読み書き処理中に、address, access_numは、変更禁止である。

---

CPU(XTバス)からの読み書き要求とビデオコントローラからの読み取り要求の調停処理は、このコントローラより上のレイヤで作製しようと思う。

15432398 journal
日記

kitune-sanの日記: PC/XTのREADY信号 2

日記 by kitune-san

PC/XTの回路図SystemBord(2/10)は、ざっくり分けると
1. READY信号の生成(nRDY/WAIT, RDYTODMA)
2. DMA要求発生時の信号生成 (HLDA, AENBRD, /AEN, DMAWAIT, /DMAEN)
3. NMI信号生成
4. I/OCHECK信号生成
5. DMA用クロック信号生成(H幅の伸張) (DCLK)
に分かれると思うのだけれど、この内「1. READY信号の生成」がわかりにくくて理解するのに時間がかかってしまったため忘れる前にメモする。というか今でもあれ?となる。

まず、nRDY/WAIT信号は8284のnAEN1に入力される信号で、CPUへ送信するREADY信号を生成するために使用される。nRDY/WAIT=HでREADYはLOW(CPUはT3->Twステート)となる。
nRDY/WAIT信号は一つのフリップフロップから出力される。このFFのトリガはクロックではなく下記のの信号の論理の組み合わせとなっている。
¬/XIOW + ¬/XIOR + (/DACK0BRD ・ ¬/XMEMR ・ AENBRD)
※ AENBRDはLのときアドレスイネーブルとなることに注意
上記の入力がL->Hとなると、nRDY/WAIT=Lとなる。ただし、後述のCLR信号により、CPUクロックの立ち上がりエッジでHにもどる。
FFのPRにはI/OCHRDYが、CLRにはnRDY/WAITを入力としたもう一つのFF(クロック立ち上がりエッジ)の出力/Qが接続されている。
I/OCHRDY信号はバスを通して外部から制御でき、適切なアクセスタイミングでLOWに落とすことで外部のカードからREADY信号を要求することができる。

以上の情報から、nRDY/WAIT信号が発生する条件は以下のタイミングとなる。
1. I/Oアクセス直後 (/XIOWまたは/XIORが、H->Lとなった時)
2. 外部のカードがREADY要求している。
3. DACK0以外のDMAアクセス発生時 (・・・多分)

1,2はわかりやすいと思うのだけれども、3についてはわかりにくいと思う。そもそも、DMAの信号でも、/XIOWか/XIORどちらかがLとなるから(/DACK0BRD ・ ¬/XMEMR ・ AENBRD)いらなくね?と1日中考えていた。
それで、8237のデータシートを見ていたら、8237の書き込み信号は拡張設定をしなければ読み取り信号が出力されるタイミングよりも1クロックずれるということに気がついた。
つまりこの設定がなければ、/XMEMR=L, /XIOW=LのDMA動作の場合に本来8237がほしいタイミングでREADY信号(REDYTODACK)が来ないことになる。これを回避したかったのだろう。…ということで納得することにした。
DACK0を除いたのは、DACK0はDRAMリフレッシュですでに使用されており、不要だったのだろう。

で、これをFPGAで動かせるように実装してみたいと思ったのだが、FFのトリガがクロック以外であることに気が付き困ってしまった。
FPGAを最初に触った時、クロック以外の信号をトリガに入れまくってよくわからなくなったトラウマがあるため避けたい。少なくとも(どっちのエッジでもいいからとりあえず)クロック同期にしたかった。
で、アイディアとして8284内部の立ち上がりエッジのFFを取り出し(イメージ的にはこれをCLR信号のFFと統合して)、オリジナルのnRDY/WAIT信号生成FFを置き換えできないかと考えた。
で、作ったのがこれ。シュミレータで見た感じは思い通りになっている・・・と思う。

15425876 journal
日記

kitune-sanの日記: 8237をSystemVerilogで書いてみる #2 (終)

日記 by kitune-san

前回から、新しく2つのブロックを追加した。
KF8237_Address_And_Count_Registers.sv - アドレスレジスタと現在カウントレジスタの計算を行うブロック。
KF8237_Timing_And_Control.sv - DMA制御のための信号出力を行うブロック。
これらを配線し、KF8237.svを作成した。
実のところ、すべての実装が完了しているわけではなくメモリ間転送については未実装のままとなっている。途中まで忘れていた。現状欲しい機能は実装できているのでとりあえず終了する。

・・・これでPC/XTを構成する主要なチップを、CPUを除いてFPGAで実装することができた。次はラスボス(8088)だ。
mod r/wとかややこしいし、8080からやったほうがいいのかなぁ。

typodupeerror

※ただしPHPを除く -- あるAdmin

読み込み中...