細切れなアップデートが続きます、、、
nicobas20081028.zip
Video出力のプログラムをアセンブラで書き直して(videodot.S)高速化させてみました。
2倍くらい速くなるかなと思ったんですが、
実際に増えたwidth方向のドット数は18ドット→23ドットでした。ちょっとだけマシになりました。
これ以上はもうスピードアップはできないみたいですが、beep処理を削ったらもっとドット数が増やせると思います。
NicoKeyboardはスイッチの同時読みに対応しているかどうかについて、お問い合わせがあったので、ココに書いておきます。
まず、ハードの説明から、、
NicoKeyboardの回路図の一部です。8x8のキーマトリックスです。
ic側の出力は8行のうち、どれか1行がLowになります。
個々のスイッチにダイオードが入っていないので、3つ以上スイッチのを
「特殊な組み合わせ」で同時に押すと誤動作します。
たとえば、↑のような状態。
Q、A、Sを同時押しすると赤い部分がLowになり、押してないはずのDが押されてしまいます。
こういうのが「特殊な組み合わせ」です。
ただし、行や列がバラバラの場合には、3つ以上同時に押しても問題ありません。
たとえば、1列全部押すとか、1行を全部押すのは問題ありません。
ここまではハードの話で、今度はソフトの話。
NicoKeyboardのソフトはちょっと機能を節約してまして、
alt、ctrl、shiftの3つだけが同時押しに対応しています。
現時点のver.7のソースの一部、スイッチの読み取り部分です。
swnum=SWNUM_NONE; sw2num=SWNUM_NONE; for(rownum=0; rownum<8; rownum++) { if(mode==MODE_PS2) ps2_recvbyte(); //1行〜8行のうち1つをLow if(rownum==0){ PORTD &= ~ID_DAT; //(74HC164)DAT }else{ PORTD |= ID_DAT; //(74HC164)DAT } timer_wait(TCNT_50US); //50uSec PORTD |= IC_CLK; //(74HC164)CLK PORTD &= ~IC_CLK; //(74HC164)CLK timer_wait(TCNT_50US); //50uSec for(colnum=0; colnum<8; colnum++){ if(((0x80 >> colnum)& PINB)==0){ //Lowを検出した場合、スイッチが押された PORTD |= MASK_LED; //LED swnum = colnum+(rownum *8); if(swnum <= SWNUM_SHIFT){ //Alt/Shift/Ctrlは同時押し用変数に格納 sw2num = swnum; swnum = SWNUM_NONE; } PORTD &= ~MASK_LED; //LED } } }
sw2numとswnumにスイッチ番号が入ります。
sw2numがAlt/Shift/Ctrl同時押し用です。
それ以外はスイッチ番号の大きいほうを優先して、swnumに上書きします。
たとえば、dとsを同時に押したらsしか検出しません。
これがイヤな場合は、swnumを64個全部のスイッチ分用意すれば解決できます。
8bitx8行、8バイトのバッファがあればいいだけです。
ソースはサイトで公開していますので、改造してみてください。
あと、チャタリング除去も簡単にできるので、よかったらやってみてください。