おかしいのはset_7219()関数の中で16回目のループ;i=15の時です。
このときの入力データのビット状態を見るマスク:
msk=(1<<(15-i));
が怪しいということになります。
1<<0=???
1のゼロ回左シフトっていくつなんでしょうか。
そこで左シフト<<の挙動をみるプログラムをささっと書いてみます。
文字列入出力やsprintf系関数は既にこっそりライブラリ化してあってここら辺は楽になってます。
それはさておき、このプログラムをコンパイル、DLL、実行させると
あー、やっちまってます
1<<0=0
ですと。普通はやっぱり
1<<0=1
でしょう。これの中間アセンブラファイルを見てみると理由がわかりました。
左シフト<<はマシンコードでSLA(Shift Left Arithmetic)に展開されているのですが
マニュアルにはSLAの動作はこう書かれています。
シフト量をWR0で与えるときその値が1~15であればその数シフトしますが、WR=0に限っては16回シフトであると。