sdccでmsx その４

#概要
sdccでmsxのスプライトをやってみた。
#写真
![sprite.jpg](https://qiita-image-store.s3.amazonaws.com/0/18104/ef7fbf97-d316-c06f-1e2b-8dca9df90994.jpeg)
#開発環境
SDCC : ver2.8.1
ruMSX : ver0.41
#MakeFile
```
All : vdp.rom
vdp.rom : vdp.ihx
	hex2rom vdp.ihx vdp.rom
vdp.ihx : VDP_SPRITE_MSX.o VDP_TMS9918_MSX.o vdp.o
	sdcc -V -mz80 --no-std-crt0 --code-loc 0x4010 --data-loc 0x8000 vdp.o VDP_SPRITE_MSX.o VDP_TMS9918_MSX.o 
vdp.o : vdp.c
	sdcc -V -mz80 -c vdp.c
VDP_SPRITE_MSX.o : VDP_SPRITE_MSX.c
	sdcc -V -mz80 -c VDP_SPRITE_MSX.c
VDP_TMS9918_MSX.o : VDP_TMS9918_MSX.s
	as-z80 -plogff VDP_TMS9918_MSX.o VDP_TMS9918_MSX.s
```
#サンプルコード
```
#include "newTypes.h"
#include "VDP_TMS9918.h"
#include "VDP_SPRITE.h"

#define HALT 			__asm halt __endasm
#define _CHKRAM 		0x0000
#define _CALSLT 		0x001C
#define _CHGET			0x009F
#define _GTSTCK 		0x00D5
#define _GTTRIG 		0x00D8
#define _SNSMAT 		0x0141
#define _KILBUF 		0x0156
void setSpritesPatterns();
void showSprites(byte offset);
void testSCREEN1();
void testSPRITES();
void testSpritePosition();
void testSpriteColor();
void testSpritePattern();
void testSpriteVisible();
void testFill();
void testColor();
void testVpeekVpoke();
void fillOrdered();
void vpoke_block(uint address, char * block, uint size);
void WAIT(uint cicles);
byte inkey();
void print0(byte column, byte line, char * text);
void print(byte column, byte line, char * text);
void vprint(uint vaddr, char * text);
const unsigned char TILESET_B0[] = {
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x0C,0x0C,0x00,0x0C,0x00,
	0x00,0x14,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x3E,0x14,0x3E,0x14,0x00,0x00,
	0x08,0x3E,0x68,0x3E,0x0B,0x3E,0x08,0x00,0x00,0x33,0x36,0x0C,0x1B,0x33,0x00,0x00,
	0x00,0x38,0x6C,0x3D,0x66,0x3D,0x00,0x00,0x00,0x18,0x30,0x00,0x00,0x00,0x00,0x00,
	0x06,0x0C,0x0C,0x0C,0x0C,0x0C,0x06,0x00,0x30,0x18,0x18,0x18,0x18,0x18,0x30,0x00,
	0x00,0x5A,0x3C,0x7E,0x3C,0x5A,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,
	0x00,0x00,0x00,0x00,0x18,0x18,0x10,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,
	0x00,0x3E,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x18,0x38,0x18,0x18,0x3C,0x00,0x00,
	0x00,0x7E,0x03,0x3E,0x60,0x7F,0x00,0x00,0x00,0x7E,0x03,0x1E,0x03,0x7E,0x00,0x00,
	0x00,0x63,0x63,0x7F,0x03,0x03,0x00,0x00,0x00,0x7F,0x60,0x7E,0x03,0x7E,0x00,0x00,
	0x00,0x3E,0x60,0x7E,0x63,0x3E,0x00,0x00,0x00,0x7F,0x03,0x06,0x0C,0x0C,0x00,0x00,
	0x00,0x3E,0x63,0x3E,0x63,0x3E,0x00,0x00,0x00,0x3E,0x63,0x3F,0x03,0x3E,0x00,0x00,
	0x00,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x10,0x00,
	0x00,0x0C,0x18,0x30,0x18,0x0C,0x00,0x00,0x00,0x00,0x3C,0x00,0x3C,0x00,0x00,0x00,
	0x00,0x30,0x18,0x0C,0x18,0x30,0x00,0x00,0x00,0x1E,0x33,0x06,0x0C,0x00,0x0C,0x00,
	0x3E,0x41,0x5D,0x55,0x5F,0x40,0x3E,0x00,0x00,0x3E,0x63,0x7F,0x63,0x63,0x00,0x00,
	0x00,0x7E,0x63,0x7E,0x63,0x7E,0x00,0x00,0x00,0x3F,0x60,0x60,0x60,0x3F,0x00,0x00,
	0x00,0x7E,0x63,0x63,0x63,0x7E,0x00,0x00,0x00,0x7F,0x60,0x7C,0x60,0x7F,0x00,0x00,
	0x00,0x7F,0x60,0x7C,0x60,0x60,0x00,0x00,0x00,0x3F,0x60,0x67,0x63,0x3F,0x00,0x00,
	0x00,0x63,0x63,0x7F,0x63,0x63,0x00,0x00,0x00,0x1E,0x0C,0x0C,0x0C,0x1E,0x00,0x00,
	0x00,0x1E,0x0C,0x0C,0x6C,0x38,0x00,0x00,0x00,0x63,0x66,0x7C,0x66,0x63,0x00,0x00,
	0x00,0x60,0x60,0x60,0x60,0x7F,0x00,0x00,0x00,0x63,0x77,0x7F,0x6B,0x63,0x00,0x00,
	0x00,0x63,0x73,0x7B,0x6F,0x67,0x00,0x00,0x00,0x3E,0x63,0x63,0x63,0x3E,0x00,0x00,
	0x00,0x7E,0x63,0x63,0x7E,0x60,0x00,0x00,0x00,0x3E,0x63,0x6B,0x66,0x3D,0x00,0x00,
	0x00,0x7E,0x63,0x63,0x7E,0x63,0x00,0x00,0x00,0x3F,0x60,0x3E,0x03,0x7E,0x00,0x00,
	0x00,0x7E,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,
	0x00,0x63,0x63,0x63,0x36,0x1C,0x00,0x00,0x00,0x63,0x6B,0x7F,0x77,0x63,0x00,0x00,
	0x00,0x63,0x36,0x1C,0x36,0x63,0x00,0x00,0x00,0x66,0x66,0x3C,0x18,0x18,0x00,0x00,
	0x00,0x7E,0x0C,0x18,0x30,0x7E,0x00,0x00,0x0E,0x0C,0x0C,0x0C,0x0C,0x0C,0x0E,0x00,
	0x00,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x38,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55
};
const char sprcol[8] = {
	12,2,3,14,6,8,9,15
};
const byte SPRITE_DATA[] = {
	60,66,165,129,165,153,66,60,
	60,126,219,255,255,219,102,60,
	108,254,254,254,124,56,16,0,
	16,56,124,254,124,56,16,0,
	16,56,84,254,84,16,56,0,
	16,56,124,254,254,16,56,0,
	0,0,0,24,24,0,0,0,
	255,255,255,231,231,255,255,255,
	15,31,61,63,123,124,191,191,159,239,111,31,15,5,5,29,
	192,224,96,192,64,128,128,132,134,222,192,192,128,0,0,192,
	5,7,26,46,111,91,92,91,95,88,111,45,22,2,2,6,
	64,192,184,212,212,106,234,106,234,106,212,212,248,64,64,96,
	3,7,79,207,77,79,44,30,63,63,63,63,31,2,2,6,
	192,226,230,226,162,244,56,124,254,254,254,252,248,64,64,96,
	5,30,63,111,87,110,63,0,7,5,7,4,6,3,2,6,
	96,248,244,234,118,190,124,0,224,96,224,32,96,192,64,96,
	5,7,31,63,127,127,127,125,127,127,120,63,31,4,4,12,
	64,192,240,248,252,252,252,124,252,252,60,248,240,64,64,96,
	7,31,63,63,127,113,127,127,127,126,62,63,31,7,2,6,
	224,248,252,252,254,142,254,254,254,126,124,252,248,224,64,96,
	0,7,31,63,127,113,255,255,123,124,63,31,7,2,2,6,
	0,224,248,252,254,142,255,255,222,62,252,248,224,64,64,96,
	5,30,63,111,87,110,63,0,7,5,7,4,6,3,2,6,
	96,248,244,234,118,190,124,0,224,96,224,32,96,192,64,96,
	0,63,96,62,3,126,0,0,0,0,0,0,0,0,0,0,
	0,63,96,96,96,63,0,0,0,0,0,0,0,0,0,0,
	0,126,99,99,126,99,0,0,0,0,0,0,0,0,0,0,
	0,127,96,124,96,127,0,0,0,0,0,0,0,0,0,0,
	0,127,96,124,96,127,0,0,0,0,0,0,0,0,0,0,
	0,99,115,123,111,103,0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	0,126,3,30,3,126,0,0,0,0,0,0,0,0,0,0
};
void main(void)
{
	screen(1);
	color(15, 4, 4);
	HALT;
	print(3, 9, "TEST VDP TMS9918 SDCC LIB");
	print(3, 10, "v1 (11/FEB/2014)");
	WAIT(50);
	//testColor();
	testSCREEN1();
	WAIT(50);
	return;
}
byte inkey()
{
__asm
	 call	_CHGET
	 ld 	l,a
__endasm;
}
void WAIT(uint cicles)
{
	uint i;
	for (i = 0; i < cicles; i++) HALT;
	return;
}
void testSCREEN1()
{
	color(15, 5, 1);
	screen(1);
	print(23, 23, " SCREEN 1");
	WAIT(50);
	fillOrdered();
	WAIT(50);
	copyToVRAM((uint) TILESET_B0, BASE12 + (32 * 8), 64 * 8);
	fillVRAM(BASE6, 32, 0x75);
	WAIT(50);
	testFill();
	testSPRITES();
	return;
}
void testSPRITES()
{
	setSpritesSize(0);
	setSpritesZoom(false);
	setSpritesPatterns();
	showSprites(0);
	WAIT(50);
	setSpritesSize(1);
	showSprites(2);
	WAIT(50);
	setSpritesZoom(true);
	WAIT(50);
	clearSprites();
	WAIT(50);
	setSpritesPatterns();
	showSprites(2);
	WAIT(50);
	testSpriteVisible();
	testSpritePattern();
	testSpriteColor();
	testSpritePosition();
	return;
}
void fillOrdered()
{
	byte i;
	for (i = 0; i < 255; i++) vpoke(BASE5 + i, i);
	return;
}
void testColor()
{
	char i;
	char inkcol = 15;
	screen(0);
	color(15, 0, 4);
	print0(15, 10, "TEST color");
	WAIT(100);
	for (i = 0; i < 16; i++)
	{
		color(inkcol--, i, i);
		WAIT(15);
	}
	return;
}
void testVpeekVpoke()
{
	uint vaddr = BASE0;
	byte i;
	byte value;
	print0(0, 9, "TEST VPEEK & VPOKE:");
	for (i = 0; i < 255; i++)
	{
		HALT;
		value = vpeek(vaddr);
		vpoke(vaddr + 440, value);
		vaddr++;
	}
	return;
}
void testFill()
{
	byte i;
	for (i = 32; i < 95; i++)
	{
		HALT;
		fillVRAM(BASE10, 760, i);
		HALT;
		HALT;
		HALT;
	}
	return;
}
void setSpritesPatterns()
{
	HALT;
	copyToVRAM((uint) SPRITE_DATA, BASE14, 32 * 14);
	return;
}
void showSprites(byte offset)
{
	byte N = 8;
	byte X = 0, Y = 0;
	byte i = 0;
	for (i = 0; i < N; i++)
	{
		putSprite(i, X * 32, Y * 32, sprcol[i], i + offset);
		X++;
		if (X == 4)
		{
			X = 0;
			Y++;
		}
	}
	return;
}
void testSpriteVisible()
{
	byte i, o;
	for (i = 0; i < 8; i++)
	{
		for (o = 0; o < 8; o++)
		{
			if (o == i)
			{
				setSpriteVisible(o, true);
			}
			else
			{
				setSpriteVisible(o, false);
			}
		}
		WAIT(25);
	}
	return;
}
void testSpritePattern()
{
	byte i;
	for (i = 2; i < 10; i++)
	{
		setSpritePattern(7, i);
		WAIT(25);
	}
	return;
}
void testSpriteColor()
{
	byte i;
	for (i = 0; i < 16; i++)
	{
		setSpriteColor(7, i);
		WAIT(25);
	}
	return;
}
void testSpritePosition()
{
	uint i = 0;
	uint posT = 168;
	byte o = 0;
	unsigned char posX[] = {
	0xAA,0xAA,0xAA,0xAA,0xAA,0xA9,0xA9,0xA9,0xA9,0xA8,0xA8,0xA7,0xA7,0xA6,0xA6,0xA5,
	0xA4,0xA4,0xA3,0xA2,0xA1,0xA0,0x9F,0x9E,0x9D,0x9C,0x9B,0x9A,0x99,0x98,0x96,0x95,
	0x94,0x93,0x91,0x90,0x8E,0x8D,0x8B,0x8A,0x88,0x87,0x85,0x84,0x82,0x80,0x7F,0x7D,
	0x7B,0x7A,0x78,0x76,0x74,0x73,0x71,0x6F,0x6D,0x6B,0x6A,0x68,0x66,0x64,0x62,0x60,
	0x5F,0x5D,0x5B,0x59,0x57,0x55,0x53,0x52,0x50,0x4E,0x4C,0x4A,0x49,0x47,0x45,0x43,
	0x42,0x40,0x3E,0x3D,0x3B,0x3A,0x38,0x36,0x35,0x33,0x32,0x30,0x2F,0x2E,0x2C,0x2B,
	0x29,0x28,0x27,0x26,0x25,0x23,0x22,0x21,0x20,0x1F,0x1E,0x1D,0x1C,0x1C,0x1B,0x1A,
	0x19,0x19,0x18,0x18,0x17,0x16,0x16,0x16,0x15,0x15,0x15,0x14,0x14,0x14,0x14,0x14,
	0x14,0x14,0x14,0x14,0x14,0x15,0x15,0x15,0x16,0x16,0x16,0x17,0x18,0x18,0x19,0x19,
	0x1A,0x1B,0x1C,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0x25,0x26,0x27,0x28,0x29,
	0x2B,0x2C,0x2E,0x2F,0x30,0x32,0x33,0x35,0x36,0x38,0x39,0x3B,0x3D,0x3E,0x40,0x42,
	0x43,0x45,0x47,0x49,0x4A,0x4C,0x4E,0x50,0x52,0x53,0x55,0x57,0x59,0x5B,0x5D,0x5F,
	0x60,0x62,0x64,0x66,0x68,0x6A,0x6B,0x6D,0x6F,0x71,0x73,0x74,0x76,0x78,0x7A,0x7B,
	0x7D,0x7F,0x80,0x82,0x84,0x85,0x87,0x88,0x8A,0x8B,0x8D,0x8E,0x90,0x91,0x93,0x94,
	0x95,0x96,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xA0,0xA1,0xA2,0xA3,0xA4,0xA4,
	0xA5,0xA6,0xA6,0xA7,0xA7,0xA8,0xA8,0xA9,0xA9,0xA9,0xA9,0xAA,0xAA,0xAA,0xAA,0xAA
	};
	unsigned char posY[] = {
	0x5F,0x61,0x63,0x65,0x66,0x68,0x6A,0x6C,0x6E,0x6F,0x71,0x73,0x75,0x77,0x78,0x7A,
	0x7C,0x7E,0x7F,0x81,0x82,0x84,0x86,0x87,0x89,0x8A,0x8C,0x8D,0x8F,0x90,0x92,0x93,
	0x94,0x95,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9E,0x9F,0x9F,0xA0,0xA1,0xA2,0xA3,0xA4,
	0xA4,0xA5,0xA6,0xA6,0xA7,0xA7,0xA8,0xA8,0xA9,0xA9,0xA9,0xA9,0xAA,0xAA,0xAA,0xAA,
	0xAA,0xAA,0xAA,0xAA,0xAA,0xA9,0xA9,0xA9,0xA8,0xA8,0xA8,0xA7,0xA7,0xA6,0xA5,0xA5,
	0xA4,0xA3,0xA3,0xA2,0xA1,0xA0,0x9F,0x9E,0x9D,0x9C,0x9B,0x9A,0x99,0x97,0x96,0x95,
	0x94,0x92,0x91,0x8F,0x8E,0x8D,0x8B,0x8A,0x88,0x86,0x85,0x83,0x82,0x80,0x7E,0x7D,
	0x7B,0x79,0x77,0x76,0x74,0x72,0x70,0x6F,0x6D,0x6B,0x69,0x67,0x65,0x64,0x62,0x60,
	0x5E,0x5C,0x5A,0x59,0x57,0x55,0x53,0x51,0x4F,0x4E,0x4C,0x4A,0x48,0x47,0x45,0x43,
	0x41,0x40,0x3E,0x3C,0x3B,0x39,0x38,0x36,0x34,0x33,0x31,0x30,0x2F,0x2D,0x2C,0x2A,
	0x29,0x28,0x27,0x25,0x24,0x23,0x22,0x21,0x20,0x1F,0x1E,0x1D,0x1C,0x1B,0x1B,0x1A,
	0x19,0x19,0x18,0x17,0x17,0x16,0x16,0x16,0x15,0x15,0x15,0x14,0x14,0x14,0x14,0x14,
	0x14,0x14,0x14,0x14,0x15,0x15,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x1A,
	0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x1F,0x20,0x22,0x23,0x24,0x25,0x26,0x27,0x29,0x2A,
	0x2B,0x2C,0x2E,0x2F,0x31,0x32,0x34,0x35,0x37,0x38,0x3A,0x3C,0x3D,0x3F,0x40,0x42,
	0x44,0x46,0x47,0x49,0x4B,0x4D,0x4F,0x50,0x52,0x54,0x56,0x58,0x59,0x5B,0x5D,0x5F
	};
	for (o = 0; o < 2; o++)
	{
		for (i = 0; i < 256; i++)
		{
			HALT;
			setSpritePosition(7, posX[posT] + 42, posY[posT]);
			posT++;
			if (posT > 255) posT = 0;
		}
	}
	return;
}
void print0(byte column, byte line, char * text)
{
	uint vaddr = BASE0 + (line * 40) + column; 
	vprint(vaddr, text);
}
void print(byte column, byte line, char * text)
{
	uint vaddr = BASE10 + (line * 32) + column; 
	vprint(vaddr, text);
}
void vprint(uint vaddr, char * text)
{
	while (* (text)) vpoke(vaddr++, * (text++));
}
void vpoke_block(uint address, char * block, uint size)
{
	while (size-->0)
	{ 
		vpoke(address++, * (block++));
	}
}

```