BDS C で X1 turbo の DMA を使ってみる
>BDS C の使い方 - 目次
BDS C の使い方 - SHARP X1 で使ってみる で作った IO16.CRL の out16 関数を使っています。
test.c
dma.c
コンパイル・リンク
Z80 DMA のハンドブックを読んでも、いまいちよくわからなかったんですが、決まりきった手順なのでこのように一度 DMA にコマンドを発行してみると、そんなに面倒でもなかったです。
>BDS C の使い方 - 目次
BDS C の使い方 - SHARP X1 で使ってみる で作った IO16.CRL の out16 関数を使っています。
test.c
/*
BDS C で SHARP X1 の DMA を使うテスト
2014年9月20日作成
X1 G-RAM はI/O空間
0x2000 - 0x27FF テキストアトリビュート
0x3000 - 0x37FF テキスト
0x4000 - 0x7FFF B
0x8000 - 0xBFFF R
0xC000 - 0xFFFF G
*/
void main()
{
/* グラフィックパレット初期化 */
out16(0x1000,0xAA); /* 1010 1010 */
out16(0x1100,0xCC); /* 1100 1100 */
out16(0x1200,0xF0); /* 1111 0000 */
/* GRAMクリア */
dma_rset();
dma_vfil(0x4000, 0xC000, 0xAA);
dma_enbl();
puts("hit key\n");
pause();
dma_vfil(0x4000, 0xC000, 0xFF);
dma_enbl();
puts("hit key\n");
pause();
dma_vfil(0x4000, 0xC000, 0x55);
dma_enbl();
puts("hit key\n");
pause();
dma_vfil(0x4000, 0xC000, 0x00);
dma_enbl();
puts("hit key\n");
pause();
/* GRAM Bプレーン適当書き込み*/
dma_m2v(0x0000, 0x4000, 0x4000);
dma_enbl();
dma_rset();
puts("hit key\n");
pause();
dma_vfil(0x4000, 0x4000, 0xAA);
dma_enbl();
}
dma.c
/*
DMA.C
2014年9月20日作成
*/
#define DMA_ADDR 0x1F80
/* DMA RESET */
dma_rset()
{
char a;
for(a=6; 0!=a; a--)
{
out16(DMA_ADDR, 0xC0);
}
}
/* ENABLE DMA */
dma_enbl()
{
out16(DMA_ADDR,0x87);
}
dma_set(cmd, size)
char cmd[];
char size;
{
char count;
for(count=0; count!=size; count++)
{
out16(DMA_ADDR, cmd[count]);
}
}
/* VRAM FILL
VRAM の addr から size を data で埋める */
dma_vfil(addr, size, data)
short addr,size;
char data;
{
char cmd[13];
/*initb(cmd, "0x00,0x00,0x00,0x00,0x00");*/
size--; /* DMAの都合により -1 */
out16(addr,data); /* 最初のアドレスにデータを書く。このデータをソースにDMAで転送する */
/* ソースを変数へのポインタで指定しようとしたらうまく行かなかった */
cmd[ 0]=0x79; /* 0111 1001 WR0 */
/* +----- 0:B->A 1:A->B */
cmd[ 1]=addr; /* PORT A アドレスL */
cmd[ 2]=addr>>8; /* PORT A アドレスH */
cmd[ 3]=size; /* ブロックレングスL */
cmd[ 4]=size>>8; /* ブロックレングスH */
cmd[ 5]=0x1C; /* 0001 1100 WR1 PORT A */
/* || +------ 0:メモリー 1:I/O */
/* ++-------- 00:-- 01:++ 10/11:固定 */
cmd[ 6]=0xCD; /* 1100 1101 WR4 */
/* ++--------- 00:バイト 01:コンティニュアス 10:バースト */
cmd[ 7]=addr; /* PORT B アドレスL */
cmd[ 8]=addr>>8; /* PORT B アドレスH */
cmd[ 9]=0x38; /* 0011 1000 WR2 PORT B */
/* || +------ 0:メモリー 1:I/O */
/* ++-------- 00:-- 01:++ 10/11:固定 */
cmd[10]=0x9A; /* 1001 1010 WR5 */
/* | +------ 0:READY L 1:READY H */
/* +-------- 0:CE 1:CE/WAIT */
cmd[11]=0xCF; /* WR6 LOAD */
cmd[12]=0xB3; /* WR6 FORCE READY */
dma_set(cmd,13);
}
/* MEMORY -> VRAM */
dma_m2v(src, dst ,size)
short src, dst, size;
{
char cmd[13];
size--;
cmd[ 0]=0x7D; /* 0111 1101 WR0 */
/* +----- 0:B->A 1:A->B */
cmd[ 1]=src; /* PORT A アドレスL */
cmd[ 2]=src>>8; /* PORT A アドレスH */
cmd[ 3]=size; /* ブロックレングスL */
cmd[ 4]=size>>8; /* ブロックレングスH */
cmd[ 5]=0x14; /* 0001 0100 WR1 PORT A */
/* || +------ 0:メモリー 1:I/O */
/* ++-------- 00:-- 01:++ 10/11:固定 */
cmd[ 6]=0xCD; /* 1100 1101 WR4 */
/* ++--------- 00:バイト 01:コンティニュアス 10:バースト */
cmd[ 7]=dst; /* PORT B アドレスL */
cmd[ 8]=dst>>8; /* PORT B アドレスH */
cmd[ 9]=0x18; /* 0001 1000 WR2 PORT B */
/* || +------ 0:メモリー 1:I/O */
/* ++-------- 00:-- 01:++ 10/11:固定 */
cmd[10]=0x9A; /* 1001 1010 WR5 READYはH有効 */
/* | +------ 0:READY L 1:READY H */
/* +-------- 0:CE 1:CE/WAIT */
cmd[11]=0xCF; /* WR6 LOAD */
cmd[12]=0xB3; /* WR6 FORCE READY */
dma_set(cmd,13);
}
コンパイル・リンク
>cpm cc dma\dma
BD Software C Compiler v1.60 (part I)
42K elbowroom
BD Software C Compiler v1.60 (part II)
39K to spare
>cpm cc dma\test
BD Software C Compiler v1.60 (part I)
43K elbowroom
BD Software C Compiler v1.60 (part II)
40K to spare
>cpm clink dma\test c:dma c:io16
BD Software C Linker v1.60
Last code address: 0C4E
Externals start at 0C4F, occupy 0000 bytes, last byte at 0C4F
Top of memory: FDFF
Stack space: F1B1
Writing output...
52K link space remaining
>
Z80 DMA のハンドブックを読んでも、いまいちよくわからなかったんですが、決まりきった手順なのでこのように一度 DMA にコマンドを発行してみると、そんなに面倒でもなかったです。
>BDS C の使い方 - 目次