2014年7月26日土曜日

Joystickアダプタ

次は、ジョイスティックアダプタをつけてみる。

SDカードスロットと一緒に、別基板に配置。
SDカードスロットはピン向きが逆になったので、クロスして配線。
あと本体側との接続ピンと干渉したため、基板をちょっとカット。

合体させると、このように。
上下がぶつからないように、コネクタの長さを調整してネジ止め。

ジョイスティックアダプタの場合、I/Oポートは以下
I/Oポート
アドレス
リード/ライト内容CAD1CAD0
19hリードジョイスティックアダプタ入力ポートALowHigh
1Ahリードジョイスティックアダプタ入力ポートBHighLow

リードするデータ内容は、デフォルト0xFFで、各ボタンが押されると、以下のビットがLowになる。
bit7bit6bit5bit4bit3bit2bit1bit0
--トリガーBトリガーA右ボタン左ボタン下ボタン上ボタン

初代パソピアに装着して、ジョイスティックを接続する

ジョイスティックのテストプログラム
100 OUT &H1B,1
110 A=PEEK(0):IF A=195 GOTO 130
120 PRINT HEX$(INP(&H1A));" ";HEX$(INP(&H19)):GOTO 120
130 PRINT STICK(1);STRIG(1);"(";HEX$(INP(&H1A));") ";
140 PRINT STICK(2);STRIG(2);"(";HEX$(INP(&H19));")":GOTO 130

パソピア7に装着して、テストプログラムを走らせる

STICK命令とSTRIG命令は、両方とも動いている。
STRIG命令は、トリガーAのみ有効だが、IN命令で読み込むとトリガーBのビットも生きていることがわかる

2014年7月25日金曜日

SDカード対応

DO夢で32GBのSDカードを購入。
2,000円以下で32GBが買えるとは、良い時代になった。。

MRAMが64KB×2なので、より大容量のデータが扱えるようにSDカード対応を考える。
使ったのは秋月のSDカードスロットDIP化モジュール
10kΩのプルアップ抵抗と3.3Vレギュレータが付いているので便利

電源はMRAMを使うときに用意した3.3Vをそのまま使うことにする。
AVRの近くにソケットを用意して、SDカードスロットDIP化モジュールを接続できるようにしておく

SDカードの読み書きは、ぷちFatFsを使わせてもらう
ディレクトリの操作(_USE_DIR)と、ファイル書き込み(_USE_WRITE)を有効にしたので、バイナリサイズが大きくなってしまった。。

SDカードのファイル内容をMRAMに保存したり、MRAMのデータをSDカードに書き込めるようにする。
ATmega1284のSRAMは16KBあるので、4KBをバッファエリアとしてSDカードの読み書きを高速化する。
バッファ領域はスロット7に割り当て(OUT &H1B, 7)、PASOPIA側からコマンドを入力できるようにする。

コマンドは、以下の4種類を用意
sv [slot] [file name] : MRAMのメモリ内容をSDカードのファイルへセーブ
 [slot] : コピー元
  5 : RAMPAC1: SLOT4: デフォルト装置番号5
  6 : RAMPAC2: SLOT3: デフォルト装置番号6
  7 : BUFFER: SLOT7
 [file name] : SDカードコピー先ファイル名
  "/"から始まった場合、絶対パス
 [戻り値]
  Ok : セーブが成功した場合
  (エラー文字列) : エラーが発生した場合
ld [slot] [file name] : SDカードのファイルをMRAMへロード
 [slot] : コピー先
  5 : RAMPAC1: SLOT4: デフォルト装置番号5
  6 : RAMPAC2: SLOT3: デフォルト装置番号6
  7 : BUFFER: SLOT7
 [file name] : SDカードコピー元ファイル名
  "/"から始まった場合、絶対パス
 [戻り値]
  Ok : ロードが成功した場合
  (エラー文字列) : エラーが発生した場合
ls [path] : フォルダとファイルのリストを表示
 [path] : 読込元のSDカードのパスとファイル名
 [戻り値]
  (ファイル名 or フォルダ名)の一覧 : フォルダの場合は名称の最後に"/"が付く
  (エラー文字列) : エラーが発生した場合
cd [path] : カレントディレクトリの変更
 [path] : パス名 [戻り値]
 [戻り値]
  (フォルダ名) : カレントフォルダ
  (エラー文字列) : エラーが発生した場合
SDカードの処理が終わったら、バッファ領域に[戻り値]が書き込まれる。

バッファへのコマンド入出力をBASICのINPUT命令で組んでみた。
100 INPUT A$
110 B$=LEFT$(A$,1)
120 IF B$="e" OR B$="E" THEN OUT &H1B,4:END
130 OUT &H1B,7:OUT &H19,0
140 FOR I=0 TO &HFF
150   OUT &H18,I
160   B$=MID$(A$,I+1,1)
170   IF B$="" GOTO 200
180   OUT &H1A,ASC(B$)
190 NEXT I
200 OUT &H1A,0:OUT &H18,0:OUT &H1B,15
210 C=INP(&H1A):IF C>=254 GOTO 210
220 FOR I=1 TO &HFF
230   OUT &H18,I:D=INP(&H1A)
240   IF C=0 AND D=0 GOTO 280
250   IF C=0 THEN PRINT CHR$(13);CHR$(10); ELSE PRINT CHR$(C);
260   C=D
270 NEXT I
280 PRINT"":GOTO 100

こんな感じで、SDカードのファイルからMRAMにデータを読み込む

MRAMは64KB単位で読み書きするようにしたため、SDカードには65,536 bytesのファイルを置いておく必要がある。(スロット7の場合は、4,096 bytes)
セーブ命令も、既にあるファイルに上書きする。

これで、以前エミュレータで作成したRAM PACイメージを、MRAMに保存できるようになった。

2014年7月20日日曜日

初代Pasopiaで動かない

MRAMのRAM PAC2を初代パソピアで試したところ、読み書きが失敗する。
ロジアナで、波形を確認してみる。


OUTとIN命令を続けて実行すると、以下のようになった。
上が初代パソピア、下がパソピア7

初代パソピアの方は、CSEL2がLowになってから、CWRもしくはCRDがLowになるまで、約230ns程度の遅延がある。

ポーリング中のアルゴリズムを見直した。
RAMPAC_PORT_SET:
  out _SFR_IO_ADDR(PORTA), r25 ; r25の返答値をセット         ; clock=1
RAMPAC_SCAN_POLLING:
  sbis _SFR_IO_ADDR(PIND), PD4 ; PD4=1(CWR=High)でスキップ     ; clock=1/2,3
  rjmp RAMPAC_NOT_READ_DATA ; RAMPAC_NOT_READ_DATAへ   ; clock=2
  sbic _SFR_IO_ADDR(PIND), PD3 ; PD3=0(CRD=Low)でスキップ     ; clock=1/2,3
  rjmp RAMPAC_SCAN_POLLING ; RAMPAC_SCAN_POLLINGへ    ; clock=2

RAMPAC_READ_DATA:
  sbic _SFR_IO_ADDR(PIND), PD2 ; PD2=0(CSEL2=Low)でスキップ    ; clock=1/2,3
  rjmp RAMPAC_SCAN_POLLING ; RAMPAC_SCAN_POLLINGへ戻る  ; clock=2
  ;PD2=0(CSEL2=Low)でPD3=0(CRD=Low)の場合 = PasopiaのIN命令
  out _SFR_IO_ADDR(DDRA), r19 ; PA0-PA7 : Output(0xFF)        ; clock=1
RAMPAC_WAIT_READ_DATA:
  sbis _SFR_IO_ADDR(PIND), PD2 ; PD2=0(CSEL2=High)でスキップ    ; clock=1/2,3
  rjmp RAMPAC_WAIT_READ_DATA ; RAMPAC_WAIT_READ_DATAへ戻る ; clock=2
  ; CSEL2=Highになったら、PinAをInputに戻す
  out _SFR_IO_ADDR(PORTA), r19 ; PA0-PA7 : Enable pull-up        ; clock=1
  out _SFR_IO_ADDR(DDRA), r18 ; PA0-PA7 : Input(0x00)          ; clock=1
  rjmp RAMPAC_SCAN_POLLING ; RAMPAC_SCAN_POLLINGへ戻る   ; clock=2

RAMPAC_NOT_READ_DATA:
  ;PD2=0(CSEL2=Low)でPD4=0(CWR=Low)の場合 = PasopiaのOUT命令
  in r23, _SFR_IO_ADDR(PIND)                                                        ; clock=1
  in r24, _SFR_IO_ADDR(PINA) ; PinAから入力                                   ; clock=1
  andi r23, 0b00011111                                                                  ; clock=1
  cpi r23, 0b00001011                                                                    ; clock=1
  breq RAMPAC_PIO_CONTROL ; OUT &H1B -> PIO_CONTROLへ        ; clock=1/2
  cpi r23, 0b00001000                                                                    ; clock=1
  breq RAMPAC_SET_LOW_ADDRESS ; OUT &H18 -> SET_LOW_ADDRESSへ ; clock=1/2
    cpi r23, 0b00001010                                                      ; clock=1
    breq RAMPAC_SET_HIGH_ADDRESS ; OUT &H19 -> SET_HIGH_ADDRESSへ ; clock=1/2
    cpi r23, 0b00001001                                                     ; clock=1
    breq RAMPAC_WRITE_DATA ; OUT &H1A -> WRITE_DATAへ            ; clock=1/2
    rjmp RAMPAC_SCAN_POLLING                                             ; clock=2

・・・

今までは、CSEL2がLowになるまでポーリングして待っていたが、今回はCWRかCRDがLowになるまでポーリングで待つようにした。

IN命令の応答は、前回でもぎりぎりのタイミングだったが、今回ポーリング間隔が広くなってしまったので、応答が間に合うように、ロジックを工夫。
ポーリングに入る前に、PortAの出力値を事前にセットしておき、1clock分を節約するとか。

これで、初代パソピアでも動くようになった。

2014年7月19日土曜日

鎌力SFX買った

以前紹介した98ケースはCPU上にATX電源があり、排熱に問題があった。

今回は一回り小さい、SFX電源を購入。
Scytheの「鎌力GOLD SFX PLUG-IN (SPKRG-S500P)」

マザーボードの横に設置する。
但しこの電源、奥行きが130mmと少し長いので、HDDスロットと干渉したため、HDDスロットを削った

これで縦に収まるようになった。

今までATX電源があった部分には、8cmファンを設置する。
アルミ板を削って、ファン固定のプレートを作成

ファンをつけるとこんなかんじ

マザーボードは、今まで通りAsusのP5N-D

CPUクーラーは、CoolerMaster Hyper48。
ファンがうるさかったので、X-FANのRDL9025S-PWMに交換。
相変わらずファイルスロットととのクリアランスは無いが、以前に比べてCPU上のスペースは余裕ができた。

カバーをつけて完成
外見は以前と変わらないが、CPU(X3350)は冷えるようになった。

2014年7月6日日曜日

64KB RAM PAC2

無いと思っていた64KBのRAM PAC2を、オクで入手。
探してみると、あるもんだ。。
但し付属品はなく、本体のみ。

Pasopia700にセット。

MRAMと同じように、Pasopia7のフォーマッタでフォーマットする。
64K bytesと認識されているが、save命令はやはり?DF Errorが出てしまった。

付属品を持っていないので推測になるが、64KBのRAM PAC2には専用のフォーマッターが付いていたのではないだろうか。。このままだと使えない。。
BASICのパッチが付属していた可能性もあるが、まずはフォーマッターを疑ってみる。

64KB RAM PAC2の場合、トラック数は32KBと同じ1Fh(31)になり、セクタ数が倍の8になり、クラスタ数は2となる。はず。
もしトラック数を3Fh(63)にすると、クラスタ数の最大がFFh(255)となるが、FATのNEXTクラスタ番号では、C1h~C4hが最終クラスタと定義されているので、問題が出そう。
なので、フォーマット結果が示すように、トラック数そのまま、セクタ数・クラスタ数が倍になる。はず。
では、FAT領域側に問題があると考え、08h~0Bhの設定を32KBと同じにした。
000102030405060708090A0B0C0D0E0F
64KBAA1F0800048000020404010310000000
64KB (?DF Error)AA1F0800048000020708020610000000
32KBAA1F0400048000010404010308000000
16KBAA0F0400044000010404010308000000
8KBAA070400042000010404010308000000
4KBAA030400041000010404010308000000

この設定で64KB RAM PAC2に書き込みしてみると、、、書けた!

 RAM PAC2の先頭256バイトをダンプすると、こんなかんじ。

MRAMでも、このフォーマットでBASICファイルの読み書きができることを確認した。
全てをチェックしたわけではないので問題が残っている可能性もあるか、64KB x 2のMRAMは、以下のフォーマットで使おうことにする。
アドレス000102030405060708090A0B0C0D0E0F
0000-000Fヘッダ001F0800048000020404010310000000
0010-001F00000000000000000000000000000000
0020-021FディレクトリFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
0220-02FF属性00000000000000000000000000000000
0300-030FFATFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF
0310-03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
0400-FFFFデータ領域00000000000000000000000000000000

絶妙なタイミングだったが、64KBのRAM PAC2が入手できたおかけで、MRAMの容量を最大限利用できるようになった。