当サイトの一部ページには、アフィリエイト・アドセンス・アソシエイト・プロモーション広告を掲載しています。

Amazonのアソシエイトとして、Security Akademeiaは適格販売により収入を得ています。

広告配信等の詳細については、プライバシーポリシーページに掲載しています。

消費者庁が、2023年10月1日から施行する景品表示法の規制対象(通称:ステマ規制)にならないよう、配慮して記事を作成しています。もし問題の表現がありましたら、問い合わせページよりご連絡ください。

参考:令和5年10月1日からステルスマーケティングは景品表示法違反となります。 | 消費者庁

Network【NandGame編】

Networkレベル

Networkレベルのゴールは、ネットワーク経由で他のコンピューターからデータを受信して、モニターに表示することです。

ネットワークのワイヤーはアドレス0x6001にメモリーマップされています。

ネットワークのデータは1つあたり16ビット幅になります。16ビット同時に届くのではなく、1ビットずつ届きます。そのため、メモリーマップされたアドレスにセットされるデータのうち、次の2ビットが重要な存在となります。

桁(右から0スタート)接続端子名役目
0ビット目dataワイヤーを介して送信されてきたデータの現在のビット。
1ビット目sync新しいビットが到着したことを示すためのビット。同期に使う。

ネットワークプロトコルの仕様

使用されるネットワークプロトコルの詳細は、レベルヘルプに載っています。

ネットワークは情報をビット列として伝送します。

ネットワークワイヤーが銅線であれば、レベル以上の電流を1、電流がない(or ある閾値以下の電流)を0として扱います。

光ファイバーであれば、光が存在すれば1、なければ0を意味します。

同期(Synchronization)

あるビットが終わり、新しいビットが始まるタイミングをどうやって知るのかという問題があります。2つの1が連続することと、1つの1が長く続いていることを区別できません。よって、ネットワークプロトコルには、ビットがいつ終了するかを決定するタイミングメカニズムが必要です。

一般的な解決策は、全パーティーが共有する、合意されたネットワーククロックを使うことです。ただし、高精度が要求されます。なぜなら、あるパーティーがほんの少し同期がずれただけで、すべてのデータがスクランブルされてしまうからです。

別の方法としては、ネットワーク自体に同期信号を伝送する同期ネットワークを含むことです。これはより多くの帯域幅を必要としますが、実装はより簡単になります。

本レベルでは、2本のワイヤーによって同期された通信を実現します。DataワイヤーとSyncワイヤーがあります。Dataワイヤーはデータ伝送用、Syncワイヤーは同期信号用です。同期信号が(0から1、または1から0に)変化するたびに、Dataワイヤーから新しい新しいビットを読み取ります。この通信方式は2倍の帯域幅を必要としますが、実装は簡単になります。

メッセージの書式(Message format)

次の問題は、データ伝送の開始と終了をどうやって判断するのかということです。0の信号が無信号と同じであれば、相手側が0を送信したのか、送信を終了したのかを識別できません。

よって、本レベルのネットワークプロトコルでは、送信は常に1ビットで始まり、16ビットのデータが続き、制御ビットが続くものとします。制御ビットが0の場合に、送信を終了したとして判断します。一方、制御ビットが1の場合、16ビットのデータが続き、再び制御ビットが続きます。

帯域幅(Bandwitdh)

ネットワークの人レートは、プロセッサーが書くビットを受信して処理できる程度に遅くなければなりません。現実世界では、ネットワークのビットレートはプロセッサーの処理速度よりもはるかに遅いはずです。

本レベルのシミュレーションでは、ネットワークのビットレートはプロセッサーのクロックレートの100倍遅いものとします。

Networkレベルを解く

1:プログラムの設計方針を決定する

ディスプレイはアドレス0x4000から0x6000にメモリーマップされていました[1]詳細はDisplayレベルを参照してください。

ネットワークワイヤーはアドレス0x6001にメモリーマップされています。

2:プログラムを実装する

次のサイトのプログラムを少し修正したものです。

# Assembler code 
DEFINE sync 0x2
DEFINE addr 0x3fff
DEFINE net 0x6001
#Init screen address
A = addr
*A = A + 1
#Wait for sync
MAIN:
A = net
D = *A
A = sync
D = D + *A
D & A ; JEQ
#Update sync & set data to D
D = D - *A
*A = D & A
D = D - *A
#Fetch screen pointer and update screen
A = addr
A = *A
D = D + *A ; JEQ
*A = D + *A
#If row not done, wait for sync
A = MAIN
D ; JGE
#Else change row and wait for sync
A = 0x20
D = A
A = addr
*A = D + *A
A = MAIN
JMP

プログラムのロジックを完全に追い切れていません。
まだスタックを使えないので、条件分岐の前に加算、後に減算するアプローチでDレジスターを擬似的に保管しています。

3:テストする

かなりのデータをやりとりするので、クロック周波数をMaxにしてます。

プログラムが正常であれば、最終的にディスプレイに小さいハートマークが描画されます。

最後に[Check solution]ボタンを押して、本レベルをクリアします。

以上でSoftwareのLow levelを全クリアにしたことになります。

スタック操作を用いる【別解】

レベルヘルプには、スタック操作マクロを実装してからこの課題に戻った方がよいと書かれています。

★後日更新予定。

References

References
1 詳細はDisplayレベルを参照してください。