2018年11月10日

画面がちらつく事について

  P6でキャラ描画時にちらつく問題ですが...

  普通はキャラ描画時には、

 キャラを消す(背景を描く)
 ↓
 新しいキャラクタを描く

  を1画面内で行うため、描画タイミングによっては、キャラが消えている瞬間と、キャラが描画されている瞬間の両方が表示されるために、キャラがちらつくという現象が発生すると思います。

  P6の場合、この現象を抑えるために2画面を使用している事が多いです。

 画面1を表示する
 ↓
 画面2内で、キャラを消し、新しいキャラクタを描く
 ↓
 画面2を表示する
 ↓
 画面1内で、キャラを消し、新しいキャラクタを描く
 ↓
 画面1を表示する(最初に戻る)


  この時、画面1→画面2に表示を切り替えるのを、垂直帰線期間で切り替えるのがベストですが、描画中でもそこまで画面がちらつく事はありません。

  と思うのですが、どうでしょうか?


posted by えすび at 14:32| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

2018年11月09日

同期信号検出について

  P6の垂直同期信号検出についてまとめました。
  いろいろ飛び交っているようなので(^^;)

1.初代機

  垂直同期は普通では検出不可です。
  ブログの前の記事では、サブCPUを使って無理やり検出してますが、実際にプログラムで使用するのにはちょっと難しいです。


2.mk2/66

  垂直同期、水平同期は、PSGのジョイスティックポートから読み出す事が出来ます。
  MODE1〜5のどのモードでも読み出せます。


; ジョイスティックポートにアクセスする
;

: レジスタ0x07(ミキサ)の上位2ビットを設定する(B:出力、A:入力)
; BASICではA、Bとも入力になっているため変更が必要
ld a,$07
out ($a0),a
ld a,$bf
out ($a1),a

; レジスタ0x0fに0xc0を出力(ジョイスティック1、8ピンに"L"を出力)
ld a,$0f
out ($a0),a
ld a,$c0
out ($a1),a

; レジスタ0x0eからジョイスティックポートを読み出す
ld a,$0e
out ($a0),a
in a,($a2)


  この状態で、Aregには、

  Areg[7-0]:垂直同期 水平同期 TRG2 TRG1 右 左 下 上

  が返ってきます。


  ただし...

  検出できる垂直同期は、垂直帰線期間の始まりとかではなく、どちらかというと単なるタイミング信号です。

  具体的には、画面走査線のカウンタ値で示すと以下の通りです。


  画面走査線カウンタ(0〜261)

   0〜 2:垂直同期="L"
   3〜261:垂直同期="H"
  37〜228:画面描画範囲


  帰線期間のちょうど真ん中辺りのタイミングのため、ちょっと使いづらいです。

  また、水平同期に関してはパルス幅が14MHzで64クロックしかなく、CPUからまともに検出する事が難しいです。


3.mk2SR/66SR

  mk2/66と同じ手順で垂直同期、水平同期は、PSGのジョイスティックポートから読み出す事が出来ます。
  MODE1〜6のどのモードでも読み出せます。

  さらに垂直同期をトリガにした割り込みが使用できます。

  ただし、あくまでも垂直同期で、垂直帰線期間の始まりとかではありません。


posted by えすび at 23:38| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

RGBコンバータ使用時の注意

  今更ですが、RGBコンバータについての注意です。

  端子形状から他の機種でも使用できそうですが、P6以外の使用はしないで下さい。

  PC-8001mk2、PC-98、FM-7などで使用した場合、最悪は壊れる可能性があります。
 (1ピンに+12Vが出力されているため)

posted by えすび at 21:09| Comment(0) | HW:その他 | このブログの読者になる | 更新情報をチェックする

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 | このブログの読者になる | 更新情報をチェックする