%第1版第6刷 P.297-
5章 汎用入出力インターフェイス
1章でも説明したように、MSXの使用しているPSGは、音声出力の機能とは別にポートAとポートBという2つの8ピット入出力ポートを持っています。MSXはこの2つのポートを汎用入出力インターフェイス(いわゆるジョイスティックポート)に接続して、ジョイスティックやパドルなどの装置とのデータ入出力に利用しています(図5.21)。この汎用入出力インターフェイスに接続される各種の装置は、それぞれ専用のBIOSルーチンがROM内に用意されており、手軽にアクセスすることが可能です。
本章では、各入出力装置の機能とBIOSルーチンによるアクセス法について説明します。
図5.21 汎用入出力インターフェイス
5.1 ポートの機能
PSGの2つの入出力ポートは、図5.22のように利用されています。
図5.22 PSGのポートAとポートBの機能
5.2 ジョイスティックの使用法
ジョイスティックの回路を図5.23に示します。この回路からわかるように、?番端子に“0”を出力し、?〜?、?〜?の端子を読み出せば、スティックとトリガボタンの情報は得られますが、プログラムの移植性などを考慮すると、ジョイスティックのアクセスはやはりBIOSを利用して行う方が無難でしょう。
ジョイスティックをアクセスするためには、以下に示すBIOSルーチンが用意されています。なお、これらのルーチンはBASICのSTICK関数やSTRIG関数とほぼ等しい機能を持っているもので、ジョイスティック以外にカーソルキーやスペースバーの状態をリアルタイムで読み取ることも可能です。
図5.23 ジョイスティック回路図
●GTSTCK(00D5H/MAIN)……………ジョイスティックの読み出し
入力:A←ジョイスティック番号(0=カーソルキー、1〜2=ジョイスティック)
出力:A←ジョイスティックまたはカーソルキーの押された方向
機能:現在のジョイスティックまたはカーソルキーの状態をAレジスタに返す。値はBASICのSTICK関数と同じである。
●GTTRIG(00D8H/MAIN)……………トリガボタンの読み出し
入力:A←トリガボタン番号(0=スペースバー、1〜2=トリガボタン)
出力:A←トリガ・ボタンまたはスペースバーの状態(押す=OFFH、離す=OOH)
機能:現在のトリガボタン、またはスペースバーの状態をAレジスタに返す。この値はトリガが押されていれば0FFH、押されていなければ0となる。
リスト5.7 ジョイスティックの使用法
;============================================================ ; ; List 5.7 Joystick and trigger access ; ;============================================================ ; CHPUT EQU 00A2H BREAKX EQU 00B7H GTSTCK EQU 00D5H GTTRIG EQU 00D8H ORG 0D000H ;-------- program start -------- ジョイスティックの状態を表示する STICK: LD A,1 ;choose joystick 1 CALL GTSTCK ;read joystick status. LD (WK1),A LD A,1 ;choose joystick 1 CALL GTTRIG ;read trigger status OR A JR Z,STCK1 LD HL,WDON ;trigger ON JR STCK2 STCK1: LD HL,WDOFF ;trigger OFF STCK2: CALL PUTSTR LD A,(WK1) OR A JR Z,BRKCH0 ;no use joystick LD C,0 STCK3: DEC A JR Z,STCK4 INC C JR STCK3 STCK4: SLA C ;C := C*16 SLA C SLA C SLA C LD B,0 ;Accounting Strings data address. LD HL,WDSTK ADD HL,BC CALL PUTSTR LD A,0DH ;put carriage return CALL CHPUT ;code := 0DH CALL BREAKX ;break check RET C JR STICK ;----- put strings to screen ----- PUTSTR: LD A,(HL) CP '$' RET Z INC HL CALL CHPUT JR PUTSTR ;----- string data ----- WDON: DB 'Trtgger ON: $' WDOFF: DB 'Trigger OFF: $' WDSTK: DB 'UP only ',0DH,0AH,'$' DB 'Up and Right ',0DH,0AH,'$' DB 'Right only ',0DH,0AH,'$' DB 'Right & Down ',0DH,0AH,'$' DB 'Down only ',0DH,0AH,'$' DB 'Dovn and Left',0DH,0AH,'$' DB 'Left only ',0DH,0AH,'$' DB 'Left and Up ',0DH,0AH,'$' WK1: DW 0 END
5.3 パドルの使用法
パドルの回路は図5.24のとおりです。?端子にパルスを送ると単安定マルチバイブレータは、ある時間幅のパルスを発生します。この幅は可変抵抗の値によって10μs〜3msの範囲で変化しますので、パルス長を測定すれば可変抵抗の値、ひいてはその回転角を知ることができます。
図5.24 パドル回路図
パドルをアクセスするためのBIOSルーチンを次に示します。
●GTPDL(00DEH/MAIN)……………パドル情報の読み出し
入力:A←パドル番号(1〜12)
出力:A←パドルの回転角(O〜255)
機能:Aレジスタで指定したパドルの状態を調べ、結果をAレジスタに返す。
5.4 タッチパネル、ライトペン、マウス、トラックポールの使用法
タッチパネル、ライトペン、マウス、トラックボール(キャット)はすべて同一のBIOSを用いてアクセスすることが可能です。その使い方を以下に説明します。
●GTPAD(00DBH/MAIN)……………各種入出力装置のアクセス
入力:A←装置ID(0〜19)
出力:A←目的の情報
機能:Aレジスタで指定する値によって、表5.5のような各種の情報を得ることができる。これはBASICのPAD関数とまったく同じである。表中“XXX1”は、汎用入出カインターフェイス#1に接続した“XXX”の装置であることを意味する。同様に“XXX2”は汎用入出力インターフェイス#2に接続したものである。
装置ID | 指定される装置 | 返ってくる情報 |
---|---|---|
0 | タッチパネル1 | パネル面に触っていればOFFH、いなければ00H |
1 | X座標(0〜255) | |
2 | Y座標(0〜255) | |
3 | ボタンが押されていれば0FFH、いなければ00H | |
4 | タッチパネル2 | 同上 |
5 | ||
6 | ||
7 | ||
8 | ライトペン | 0FFHであればデータは有効、00Hであれば無効 |
9 | X座標(0〜255) | |
10 | Y座標(0〜255) | |
11 | スイッチが押されていれば0FFH、いなければ00H | |
12 | マウス1、または トラックボール1 | つねに0FFHを返す(入力の要求に使用) |
13 | X座標(0〜255) | |
14 | Y座標(0〜255) | |
15 | つねに00Hを返す(無意味) | |
16 | マウス1、または トラックボール2 | 同上 |
17 | ||
18 | ||
19 |
注1:ライトペンの座標(A=9,1O)とスイッチ(A=11)の情報は、A=8としてBIOSをコールしたとき同時に読み込まれますが、その結果がOFFHの時にのみ、他の値が有効となります。A=8としてBIOSをコールした結果が00Hの場含は、その後に得られる座標値やスイッチの状態は意味を持ちません。
注2:マウスとトラックボールは自動的に判別します。
注3:マウスやトラックボールの座標値を求める場合、まず入力要求のコール(A=12またはA=16)を行い、その後に実際に座標値を求めるコールを実行する、という手順をふみます。このとき2つのコールの時間間隔はできる限り小さくとらなければなりません。入力要求から座標値の入力までに必要以上に時間をかけると、得られたデータは保証されません。
注4:マウスまたはトラックボールについているトリガボタンの状態を得るためには、このGTPADルーチンではなく、GTTRIG(00D8H/MAIN)を使ってください。
表5.5 GTPADのBIOSで得られる情報
リスト5.8 タッチパネルの使用法
;============================================================ ; ; List 5.8 touch pad access ; ;============================================================ ; BREAKX EQU 00B7H GTPAD EQU 00DBH WRTVRM EQU 004DH ORG 0B000H ;-------- program start -------- タッチパッドで指定した位置に"*"を表示する PAD: XOR A ;check sense CALL GTPAD OR A JR NZ,PAD1 LD A,3 CALL GTPAD ;break check OR A RET NZ JR PAD PAD1: LD A,1 ;get X axis CALL GTPAD SRL A ;A := A/8 SRL A SRL A LD (WORK),A ;reserve X axis LD A,2 ;get Y axis CALL GTPAD LD L,A ;HL := Y data(0-255) LD H,0 LD C,A LD B,0 ADD HL,BC ;HL := HL*3 (HL:= 0-767) ADD HL,BC LD A,L AND 11100000B LD L,A LD A,(WORK) ADD A,L LD L,A LD BC.1800H ;VRAM start address. ADD HL,BC LD A,2AH CALL WRTVRM ;write VRAM LD A,3 CALL GTPAD ;break check OR A RET NZ JR PAD ;----- work area ----- WORK: DW 0 ;work END
リスト5.9 マウスとトラックボールの使用法
;============================================================ ; ; List 5.9 mouse and track ball access ; ;============================================================ ; GTPAD EQU 00DBH WRTVRM EQU 004DH RDVRM EQU 004AH BREAKX EQU 00B7H ORG 0D000H ;----- program start ----- マウスまたはトラックボールで指定した位置に"*"を表示する TEST: CALL VADR ;Put old data. LD A,(WKOLD) CALL WRTVRM LD A,12 CALL GTPAD ;Request mouse/track ball data. LD A,13 CALL GTPAD ;Read X val. LD (WKXVAL),A LD A.14 CALL GTPAD ;Read Y val. LD (WKYVAL),A LD A,(WKX) LD B,A LD A,(WKXVAL) ADD A,B CP 245 ;X<0? JR C,TEST01 XOR A ;X=0 JR TEST02 TEST01: CP 32 ;X>31? JR C,TEST02 LD A,31 TEST02: LD (WKX),A LD A,(WKY) LD B,A LD A,(WKYVAL) ADD A,B CP 245 ;Y<0? JR C.TEST03 XOR A ;Y=0 JR TEST04 TEST03: CP 24 ;Y>23 JR C,TEST04 LD A,23 TEST04: LD (WKY),A CALL VADR CALL RDVRM ;Read old data. LD (WKOLD),A CALL VADR LD A,2AH CALL WRTVRM ;Put cursor("*"). CALL BREAKX ;Break check. RET C CALL WAIT JR TEST VADR: LD A,(WKY) ;Make SCREEN Address. LD H,A ; From X,Y axis on WORK AREA LD L,0 ; To HL reg. SRL H RR L SRL H RR L SRL H RR L LD A,(WKX) ADD A,L ; Y*32+X LD L,A LD BC,1800H ; VRAM start address. ADD HL,BC RET WAIT: LD A,0 ;WAIT routine WLP1: INC A LD B,(IX+0) LD B,(IX+0) LD B,(IX+0) JR NZ,WLP1 RET ;----- data ----- WKX: DB 10 ;X axis WKY: DB 10 ;Y axis WKOLD: DB 0 ;Character code on (X,Y) WKXVAL: DB 0 ;X variable. WKYVAL: DB 0 ;Y variable. END