【MSX】VDP操作によるVRAMアクセスについて
初版 2026/01/27
改訂 2026/01/28
概要
- VRAMは、CPUからI/O経由でVDP経由でアクセスする。そのため、I/O操作命令(OUT/IN)を使用する。
- なお、MSXでは互換性の保証のため、周辺ハードウェアへのアクセスはBIOS経由を推奨しているが、VRAMへのアクセスについては直接I/O経由でのアクセスが認められている。
- VDPは大きく「コマンド発行」「コマンド実行」の2つの手順が必要。
- VDPのレジスタ操作は最低12ステート、読み書きは最低21ステートの間隔を開けること。ただし、
OUT (C), rの場合は連続して書いても問題ない。12 - I/O操作中は割り込みがかからないようにすること。3
VRAM1バイト読み込み
; ---- SET READ ----
DI
LD A, (0x0006) ; get read port #0 address
LD C, A
INC C ; port #1 address
LD A, L ; HL = read addr.
OUT (C), A
LD A, H
OUT (C), A
; ---- READ ----
DEC C ; port #1 address
IN A, (C) ; A = data
EI
VRAM1バイト書き込み
- 書き込みをする際は、ポート#1に送るアドレスのビット7をONにする。
; ---- SET WRITE ----
DI
LD A, (0x0007) ; get write port #0 address
INC A
LD C, A ; port #1 address
LD A, E ; DE = dist addr.
OUT (C), A
LD A, D
OR 0x40 ; write mode
OUT (C), A
; ---- WRITE ----
LD A, (HL) ; HL = data addr.
DEC C ; port #0 address
OUT (C), A
EI
VRAM連続書き込み
OUTIを実行すると、データのアドレス(HL)は自動的にインクリメント、カウンタ(B)はデクリメントされ、カウンタがゼロになった時にゼロフラグが立つ。- 書き込み先のVRAMアドレスは、VDPにより自動的にインクリメントされる。これを利用して、メモリにある連続したデータを高速にVRAMに送ることができる。
; ---- SET WRITE ----
DI
LD HL, _data ; HL = data addr.
LD DE, 0x1800 ; DE = dist addr.
_loop:
; ---- SET WRITE ----
LD A, (0x0007) ; get write port #0 address
LD C, A
INC C ; port #1 address
LD A, E ; set dist addr
OUT (C), A
LD A, D
OR 0x40 ; write mode
OUT (C), A
; ---- WRITE ----
DEC C ; port #0 address
LD B, 10 ; col num
_loop_1:
OUTI
JP NZ, _loop_1
EI
RET
_data:
DB 0x41 ; A
DB 0x42 ; B
DB 0x43 ; C
DB 0x44 ; D
DB 0x45 ; E
DB 0x46 ; F
DB 0x47 ; G
DB 0x48 ; H
DB 0x49 ; I
DB 0x4A ; J