2018年11月08日

キー入力について

  P6のキー入力についてまとめておきます。


1.キー入力は、全てサブCPUが管理している。
  メインCPUからは、8255を通して通信を行ってデータを取得する事になります。
  また、サブCPUとの通信は、通常は割り込みを使用します。

  割り込みを使用しない方法も無くはないのですが、SR以降の挙動が変わるんじゃなかと思います。

  以降、割り込みを使っているという前提で記載します。


2.キー入力の種類は4種類ある。

 1)通常キー入力(割り込みベクタ0x02)
  キー入力があった時点にサブCPUから割り込みが発生し、値を返してきます。
  逆に、キー入力がないと、全く割り込みが発生しません。
  そのため、キーが押下された事はわかりますが、キーを離した事はわかりません。

  キーをずっと押下している場合は、サブCPU側でキーリピートの処理を行って、その都度割り込みが発生します。
  キーリピートの間隔などの変更などもできず、何故か機種によって間隔も違うようです。

  また、SHIFT/CTRL/GRPH/かな入力、ひらがな<->カタカナ切換(SHIFT+PAGE)もサブCPUの方で行っており、返ってくる値もそのコードになります。

  ややこしいんですが、CAPSを押した時の処理はサブCPUで行っておらず、CAPSは普通の特殊キーの一つになっています。


 2)特殊キー入力(割り込みベクタ0x14)
  これに該当するキーは以下の通りです。右に返ってくる値を併記します。

  グラフィックキー(GRPH+1〜9など):グラフィックコード(0x01〜0x1f)
  ファンクションキー(F1〜F5):0xf0〜0xf4
  SHIFT +F1〜F5       :0xf5〜0xf9
  STOP            :0xfa
  CAPSキー          :0xfb
  SHIFT+PAGE         :0xfc
  MODEキー          :0xfd
  かなキー          :0xfe


  動作としては、1)通常キー入力と同じです。
  押された時に、値を返してきて、ずっと押下している場合は、キーリピートされて、その都度割り込みが発生します。


 3)ゲームキー入力(割り込みベクタ0x16)
  1)2)とは違い、メインCPUからゲームキー調査のコマンドを発行します(サブCPUに対して0x06を出力)。
  しばらくすると、サブCPUから割り込みが発生して、ゲームキーの状態を返してきます。

  返ってくる値は以下の通り。

  bit7-0:[SPC] ["L"] [←] [→] [↓] [↑] [STOP] [SHIFT] の押下状態(押している時"1"、離している時"0")


  このゲームキー入力を使う事で、キーが押されているか、押されていないかがリアルタイムに分かります。
  逆にここで検出できる SPACE/カーソル/STOP/SHIFT 以外は、リアルタイムで押下されているかどうかがわかりません。


 4)CMT入出力時のSTOPキー入力(割り込みベクタ0x0e/0x10)
  押された時点でサブCPUから割り込みが発生します。値は返してきません。


3.サブCPUとの通信について

  BASICのROM内通信を使うのが一番手っ取り早いんですが、自前で全部作ると以下のようになります。
  (下記は、拙作Meltdown for p6mk2から、一部抜き出して変更したもの)



;
; 割り込み関連
;
org $8400

INT_TABLE:
dw INTDT0 ; 0x00
dw INTKEYIN ; 0x02(通常キー入力)
dw INTDT0 ; 0x04(RS-232C)
dw INTTIMER ; 0x06(TIMER)
dw INTDT1 ; 0x08(CMT READ)
dw INTDT0 ; 0x0A
dw INTDT0 ; 0x0C
dw INTDT0 ; 0x0E(CMT使用時STOP入力)
dw INTDT0 ; 0x10(CMT使用時STOP入力)
dw INTDT0 ; 0x12(CMT ERROR)
dw INTKEYIN2 ; 0x14(特殊キー入力)
dw INTGAMEKEY ; 0x16(ゲームキー入力)


;
; サブCPUから1バイトデータを受信する
;
; RET:Areg=受信データ
;
GETSUBCPU:
ld a,$0c
out ($93),a
.wait:
in a,($92)
and $20
jr z,.wait
ld a,$0d
out ($93),a
in a,($90)
ret

;
; サブCPUへ1バイトデータを送信する
;
; Areg=送信データ
;
SETSUBCPU:
push af
ld a,$08
out ($93),a
.wait:
in a,($92)
and $80
jr z,.wait
ld a,$09
out ($93),a
pop af
out ($90),a
ret

;
; 割り込み終端(データ1バイト受信+何もしない)
;
INTDT1:
push af
call GETSUBCPU
pop af
;
; 割り込み終端(何もしない)
;
INTDT0:
ei
ret

;
; キー入力割り込み
; 通常キーは、ASCIIコード
;
INTKEYIN:
push af
call GETSUBCPU
ld (KEYDATA),a
pop af
ei
ret

;
; キー入力割り込み
; GRAPH+キーの場合は、そのASCIIコード
; ファンクションキーの場合は、0xf0〜0xf9
; STOPキーの場合は、0xfa
; CAPSキーの場合は、0xfb
; MODEキーの場合は、0xfd
;
INTKEYIN2:
push af
call GETSUBCPU
ld (KEYDATA2),a
pop af
ei
ret

;
; タイマ割り込み
;
INTTIMER:
push af

ld a,(TIMERCNT)
inc a
and $03
ld (TIMERCNT),a
jr nz,.next1

ld a,$06
call SETSUBCPU ; ゲームキー呼び出し

.next1:
pop hl←不要でした
	pop	af
ei
ret

;
; ゲームキー割り込み
;
INTGAMEKEY:
push af
push bc

call GETSUBCPU

;
; サブCPUからのゲームキーをJOYSTICKの並びに変更する
; SPC "0" 左右下上 STOP SFT
; ↓
; "0" STOP SFT SPC 右左下上

ld b,a
xor a
bit 2,b
jr z,.lp1
or $01
.lp1: bit 3,b
jr z,.lp2
or $02
.lp2: bit 5,b
jr z,.lp3
or $04
.lp3: bit 4,b
jr z,.lp4
or $08
.lp4: bit 7,b
jr z,.lp5
or $10
.lp5: bit 0,b
jr z,.lp6
or $20
.lp6: bit 1,b
jr z,.lp7
or $40
.lp7:
ld b,a

;
; ジョイスティックポートにアクセスする
;
ld a,$0f
out ($a0),a
ld a,$c0
out ($a1),a
ld a,$0e
out ($a0),a
in a,($a2)
cpl
and $3f
;
; Areg:"0" "0" TRG2 TRG1 右左下上

or b
ld (GAMEDATA),a

pop bc
pop af
ei
ret



posted by えすび at 23:54| Comment(0) | P6解析:サブCPUと8255 | このブログの読者になる | 更新情報をチェックする