Future Driver

DMA

DMAはVDPに搭載された機能で、下記のメモリ間転送を行います。

  1. 68000のメモリ(RAMかROM)から、VDPのメモリ(VRAMかCRAMかVSRAM)へ転送
  2. VRAMからVRAMへ転送
  3. VRAMを指定値で埋める(VDPデータレジスタからVRAMへ転送)

DMA転送手順

  1. DMA有効フラグを1にします。 (VDPレジスタ1で設定)
  2. 自動アドレス加算値を指定します。 (VDPレジスタ15で設定)
  3. 転送サイズを指定します。 (VDPレジスタ19〜20で設定)
  4. 転送モードと転送元アドレスを指定します。 (VDPレジスタ21〜23で設定)
  5. VDP CTRL (アドレス 0xC00004) で転送先アドレスを指定します。
  6. VDP DATA (アドレス 0xC00000) に埋める値を設定します。

転送モードが 「VRAMを指定値で埋める」 の場合は6番目が終わると自動で転送が始まります。
それ以外の転送モードでは5番目が終わると自動で転送が始まり、6番目は不要です。
転送中は68000は停止しています。

転送モードによる設定内容の違い

転送モード 自動アドレス加算値 転送サイズ 転送元アドレス
のアラインメント
転送先アドレス
のアラインメント
68000のメモリからVDPのメモリへ転送 WORD単位 WORD単位 WORD単位 BYTE単位
VRAMからVRAMへ転送 BYTE単位 BYTE単位 BYTE単位 BYTE単位
VRAMを指定値で埋める BYTE単位 BYTE単位 - WORD単位

68000のメモリはワード(16bit)単位、VRAMはバイト(8bit)単位、VDP DATAはワード(16bit)単位 でアクセスすると覚えておけば良いでしょう。

68000のRAMかROMから、VRAMかCRAMかVSRAMへ転送

ワード単位で転送します。
自動アドレス加算値と転送元アドレスに奇数を指定すると正常に動作しません。 つまり自動アドレス加算値も転送元アドレスも偶数になります。
転送サイズには、例えば4bytes転送したいなら転送サイズに 2 を指定します。

VRAMからVRAMへ転送

バイト単位で転送します。

VRAMを指定値で埋める(VDPデータレジスタからVRAMへ転送)

ワード単位で転送します。
転送先アドレスに奇数を指定すると正常に動作しません。

転送モードと状況による転送容量の違い

転送種別 横解像度
(Pixel)
HBlank期間中
(Byte)
VBlank期間中
1ライン当り
(Byte)
VBlank期間中
NTSC
(Byte)
VBlank期間中
PAL(224Lines)
(Byte)
VBlank期間中
PAL(240Lines)
(Byte)
68000のメモリからVDPのメモリ(VRAM)へ転送 320 18 205 7380 17835 14555
68000のメモリからVDPのメモリ(VRAM)へ転送 256 16 167 6012 14529 11857
VRAMからVRAMへ転送 320 17 204 7344 17748 14484
VRAMからVRAMへ転送 256 15 166 5976 14442 11786
VRAMを指定値で埋める 320 9 102 3672 8874 7242
VRAMを指定値で埋める 256 8 83 2988 7221 5893

コード例

68000のRAMかROMから、VRAMへのDMA転送

/* sourceAddress から destinationAddress へ autoIncSize 分アドレス加算しながら transfersLength バイト転送する */
void dma()
uint autoIncSize;		/* 自動加算サイズ */
uint transfersLength;		/* 転送サイズ */
ulong sourceAddress;		/* 転送元アドレス */
uint destinationAddress;	/* 転送先アドレス */
{
	register ulong *ctrl32;
	register uint *ctrl16;

	ctrl16 = (uint *)VDP_CONTROL_ADDRESS;
	ctrl32 = (ulong *)VDP_CONTROL_ADDRESS;

	*ctrl16 = REGISTER_WRITE(1) + ((0 << R_9918) | (1 << R_DISP) | (1 << R_IE0) | (1 << R_M1) | (0 << R_M2) | (1 << R_SMS));	/* R_M1 = 1 = DMA有効 */
	*ctrl16 = REGISTER_WRITE(15) + (autoIncSize);			/* 自動アドレス加算値(2bytes単位) */
	*ctrl16 = REGISTER_WRITE(19) + (transfersLength & 0x00FF);	/* 転送サイズ(2bytes単位) */
	*ctrl16 = REGISTER_WRITE(20) + (transfersLength >> 8 & 0x00FF);
	*ctrl16 = REGISTER_WRITE(21) + (uchar)((ulong)sourceAddress >> 1 & 0x000000FF);	 /* 68000の転送元アドレス(2bytes単位) */
	*ctrl16 = REGISTER_WRITE(22) + (uchar)((ulong)sourceAddress >> 9 & 0x000000FF);
	*ctrl16 = REGISTER_WRITE(23) + (uchar)((ulong)sourceAddress >> 17 & 0x000000FF);
	*ctrl32 = VRAM_WRITE(destinationAddress) + 0x00000080;		/* VRAMの指定アドレスへDMA転送開始 */
}


inserted by FC2 system