arduinoでchip8　その２

#概要

arduinoでchip8やってみた。
メモリー足りないので、tftに直接描いた。
なので、軌跡が残る。

#写真

![CIMG2820.JPG](https://qiita-image-store.s3.amazonaws.com/0/18104/22ba0e68-b25a-6dd2-76d1-a0c18a513fe2.jpeg)


#サンプルコード


```
#include <Adafruit_GFX.h>
#include "Adafruit_TFTLCD.h"
#include "TouchScreen.h"

#define XP 				8
#define YP 				A3
#define XM 				A2
#define YM 				9
#define TS_MINX 		150 - 40
#define TS_MAXX 		920 - 40
#define TS_MINY 		120 - 40
#define TS_MAXY 		940 - 40
#define LCD_CS 			A3
#define LCD_CD 			A2
#define LCD_WR 			A1
#define LCD_RD 			A0
#define LCD_RESET 		A4
#define BLACK			0x0000
#define BLUE			0x001F
#define RED				0xF800
#define GREEN			0x07E0
#define CYAN			0x07FF
#define MAGENTA 		0xF81F
#define YELLOW			0xFFE0
#define WHITE			0xFFFF
#define MINPRESSURE 	10
#define MAXPRESSURE 	1000

TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
const char rom[] PROGMEM = {
	240, 144, 144, 144, 240, 32, 96, 32, 32, 112, 240, 16, 240, 128, 240, 240, 16, 240, 16, 240, 144, 144, 240, 16, 16, 240, 128, 240, 16,
	240, 240, 128, 240, 144, 240, 240, 16, 32, 64, 64, 240, 144, 240, 144, 240, 240, 144, 240, 16, 240, 240, 144, 240, 144, 144, 224, 144,
	224, 144, 224, 240, 128, 128, 128, 240, 224, 144, 144, 144, 224, 240, 128, 240, 128, 240, 240, 128, 240, 128, 128, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
	106, 2, 107, 12, 108, 63, 109, 12, 162, 234, 218, 182, 220, 214, 110, 0, 34, 212, 102, 3, 104, 2, 96, 96, 240, 21, 240, 7, 48, 0, 18, 26,
	199, 23, 119, 8, 105, 255, 162, 240, 214, 113, 162, 234, 218, 182, 220, 214, 96, 1, 224, 161, 123, 254, 96, 4, 224, 161, 123, 2, 96, 31,
	139, 2, 218, 182, 96, 12, 224, 161, 125, 254, 96, 13, 224, 161, 125, 2, 96, 31, 141, 2, 220, 214, 162, 240, 214, 113, 134, 132, 135, 148,
	96, 63, 134, 2, 97, 31, 135, 18, 70, 2, 18, 120, 70, 63, 18, 130, 71, 31, 105, 255, 71, 0, 105, 1, 214, 113, 18, 42, 104, 2, 99, 1, 128,
	112, 128, 181, 18, 138, 104, 254, 99, 10, 128, 112, 128, 213, 63, 1, 18, 162, 97, 2, 128, 21, 63, 1, 18, 186, 128, 21, 63, 1, 18, 200, 128,
	21, 63, 1, 18, 194, 96, 32, 240, 24, 34, 212, 142, 52, 34, 212, 102, 62, 51, 1, 102, 3, 104, 254, 51, 1, 104, 2, 18, 22, 121, 255, 73, 254,
	105, 255, 18, 200, 121, 1, 73, 2, 105, 1, 96, 4, 240, 24, 118, 1, 70, 64, 118, 254, 18, 108, 162, 242, 254, 51, 242, 101, 241, 41, 100, 20,
	101, 0, 212, 85, 116, 21, 242, 41, 212, 85, 0, 238, 128, 128, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#define PC_START 			0x200;
int opcode[1] = {0};
int V[16] = {0};
int pc[1] = {0};
int I[1] = {0};
int delay_timer[1] = {0};
int sound_timer[1] = {0};
int stack[16] = {0};
int sp[1] = {0};
int keypad[16] = {0};
int memory[3] = {0};
int NNN(int op)
{
	return (op & 0x0fff);
};
int NN(int op)
{
	return (op & 0x00ff);
}
int N(int op)
{
	return (op & 0x000f);
};
int X(int op)
{
	return ((op & 0x0F00) >> 8);
};
int Y(int op)
{
	return ((op & 0x00F0) >> 4);
};
int L(int op)
{
	return (op & 0xf000);
};
void disp_clear()
{
	int i,
		j;
	for (i = 0; i < 64; i++)
	{
		for (j = 0; j < 32; j++)
		{
			gfx(i, j, 1);
		}
	}
};
int rand()
{
	return random(11);
};
void gfx(int x, int y, int c)
{
	if (c > 0)
	{
		tft.drawPixel(x * 3, y * 3, BLACK);
		tft.drawPixel(x * 3, y * 3 + 1, BLACK);
		tft.drawPixel(x * 3, y * 3 + 2, BLACK);
		tft.drawPixel(x * 3 + 1, y * 3, BLACK);
		tft.drawPixel(x * 3 + 1, y * 3 + 1, BLACK);
		tft.drawPixel(x * 3 + 1, y * 3 + 2, BLACK);
		tft.drawPixel(x * 3 + 2, y * 3, BLACK);
		tft.drawPixel(x * 3 + 2, y * 3 + 1, BLACK);
		tft.drawPixel(x * 3 + 2, y * 3 + 2, BLACK);
	}
	else
	{
		tft.drawPixel(x * 3, y * 3, WHITE);
		tft.drawPixel(x * 3, y * 3 + 1, WHITE);
		tft.drawPixel(x * 3, y * 3 + 2, WHITE);
		tft.drawPixel(x * 3 + 1, y * 3, WHITE);
		tft.drawPixel(x * 3 + 1, y * 3 + 1, WHITE);
		tft.drawPixel(x * 3 + 1, y * 3 + 2, WHITE);
		tft.drawPixel(x * 3 + 2, y * 3, WHITE);
		tft.drawPixel(x * 3 + 2, y * 3 + 1, WHITE);
		tft.drawPixel(x * 3 + 2, y * 3 + 2, WHITE);
	}
}
void setup(void)
{
	int i;
	int j;
	Serial.begin(115200);
	Serial.println("start");
	tft.reset();
	uint16_t identifier = 0x9341;
	tft.begin(identifier);
	tft.fillScreen(WHITE);
	tft.fillRect(0, 0, 192, 96, BLACK);
	for (i = 0; i < 4; i++)
	{
		for (j = 0; j < 4; j++)
		{
			for (int yline = 0; yline < 5; yline++)
			{
				int font = (i * 4 + j) * 5;
				int line = (int) pgm_read_byte_near(rom + font + yline);
				for (int xline = 0; xline < 4; xline++)
				{
					if ((line & (0x80 >> xline)) != 0)
					{
						int x = j * 15 + 10;
						int y = i * 15 + 50;
						gfx(x + xline, y + yline, 1);
					}
				}
			}
		}
	}
	pc[0] = PC_START;
}
void loop()
{
	int n;
	int i;
	Point p = ts.getPoint();
	pinMode(XM, OUTPUT);
	pinMode(YP, OUTPUT);
	uint8_t m0 = pgm_read_byte_near(rom + pc[0]);
	uint8_t m1 = pgm_read_byte_near(rom + pc[0] + 1);
	int opcode = (int) (m0 << 8) | m1;
	switch (L(opcode))
	{
	case 0x0000:
		switch (opcode & 0x00FF)
		{
		case 0x00E0:
			disp_clear();
			pc[0] += 2;
		break;
		case 0x00EE:
			sp[0] -= 1;
			pc[0] = stack[sp[0]];
			pc[0] += 2;
		break;
		case 0x0000:
			pc[0] += 2;
		break;
		default:
		break;
		}
	break;
	case 0x1000:
		pc[0] = NNN(opcode);
	break;
	case 0x2000:
		stack[sp[0]] = pc[0];
		sp[0] += 1;
		pc[0] = NNN(opcode);
	break;
	case 0x3000:
		pc[0] += (V[X(opcode)] == NN(opcode)) ? 4 : 2;
	break;
	case 0x4000:
		pc[0] += (V[X(opcode)] != NN(opcode)) ? 4 : 2;
	break;
	case 0x5000:
		pc[0] += (V[X(opcode)] == V[Y(opcode)]) ? 4 : 2;
	break;
	case 0x6000:
		V[X(opcode)] = NN(opcode);
		pc[0] += 2;
	break;
	case 0x7000:
		V[X(opcode)] += NN(opcode);
		pc[0] += 2;
	break;
	case 0x8000:
		switch (N(opcode))
		{
		case 0x0000:
			V[X(opcode)] = V[Y(opcode)];
		break;
		case 0x0001:
			V[X(opcode)] |= V[Y(opcode)];
			V[0xF] = 0;
		break;
		case 0x0002:
			V[X(opcode)] &= V[Y(opcode)];
			V[0xF] = 0;
		break;
		case 0x0003:
			V[X(opcode)] ^= V[Y(opcode)];
			V[0xF] = 0;
		break;
		case 0x0004:
			V[0xF] = V[Y(opcode)] > (0xFF - V[X(opcode)]) ? 1 : 0;
			V[X(opcode)] += V[Y(opcode)];
		break;
		case 0x0005:
			V[0xF] = V[Y(opcode)] > V[X(opcode)] ? 0 : 1;
			V[X(opcode)] -= V[Y(opcode)];
		break;
		case 0x0006:
			V[0xF] = V[X(opcode)] & 0x1;
			V[X(opcode)] >>= 0x01;
		break;
		case 0x0007:
			V[0xF] = V[Y(opcode)] < V[X(opcode)] ? 0 : 1;
			V[X(opcode)] = V[Y(opcode)] - V[X(opcode)];
		break;
		case 0x000E:
			V[0xF] = V[X(opcode)] >> 0x7;
			V[X(opcode)] <<= 0x01;
		break;
		default:
		break;
		}
		pc[0] += 2;
	break;
	case 0x9000:
		pc[0] += V[X(opcode)] != V[Y(opcode)] ? 4 : 2;
	break;
	case 0xA000:
		I[0] = NNN(opcode);
		pc[0] += 2;
	break;
	case 0xB000:
		pc[0] = V[0] + NNN(opcode);
	break;
	case 0xC000:
		V[X(opcode)] = NN(rand()) & NN(opcode);
		pc[0] += 2;
	break;
	case 0xD000:
	{
		int x = V[X(opcode)];
		int y = V[Y(opcode)];
		int h = N(opcode);
		V[0xF] = 0;
		for (int yline = 0; yline < h; yline++)
		{
			int line = (int) pgm_read_byte_near(rom + I[0] + yline);
			for (int xline = 0; xline < 4; xline++)
			{
				if ((line & (0x80 >> xline)) != 0)
				{
					gfx(x + xline, y + yline, 0);
				}
			}
		}
		V[0xF] = 1;
		pc[0] += 2;
	}
	break;
	case 0xE000:
		switch (NN(opcode))
		{
		case 0x009E:
			pc[0] += keypad[V[X(opcode)]] != 0 ? 4 : 2;
		break;
		case 0x00A1:
			pc[0] += keypad[V[X(opcode)]] == 0 ? 4 : 2;
		break;
		default:
		break;
		}
	break;
	case 0xF000:
		switch (NN(opcode))
		{
		case 0x0007:
			V[X(opcode)] = delay_timer[0];
			pc[0] += 2;
		break;
		case 0x000A:
		{
			bool keyPressed0 = false;
			for (int i = 0; i < 16; i++)
			{
				if (keypad[i] != 0)
				{
					V[X(opcode)] = i;
					keyPressed0 = true;
				}
			}
			if (keyPressed0) pc[0] += 2;
		}
		break;
		case 0x0015:
			delay_timer[0] = V[X(opcode)];
			pc[0] += 2;
		break;
		case 0x0018:
			sound_timer[0] = V[X(opcode)];
			pc[0] += 2;
		break;
		case 0x001E:
			V[0xF] = ((I[0] + V[X(opcode)]) > 0xFFF) ? 1 : 0;
			I[0] += V[X(opcode)];
			pc[0] += 2;
		break;
		case 0x0029:
			I[0] = V[X(opcode)] * 0x5;
			pc[0] += 2;
		break;
		case 0x0033:
		{
			memory[0] = V[X(opcode)] / 100;
			memory[1] = (V[X(opcode)] / 10) % 10;
			memory[2] = (V[X(opcode)] % 100) % 10;
			pc[0] += 2;
		}
		break;
		case 0x0055:
		{
			memory[0] = V[0];
			memory[1] = V[1];
			memory[2] = V[2];
			I[0] = I[0] + (X(opcode)) + 1;
			pc[0] += 2;
		}
		break;
		case 0x0065:
		{
			tft.fillRect(0, 0, 192, 96, BLACK);
			V[0] = memory[0];
			V[1] = memory[1];
			V[2] = memory[2];
			I[0] = I[0] + (X(opcode)) + 1;
			pc[0] += 2;
		}
		break;
		default:
		break;
		}
	break;
	default:
	break;
	}
	if (delay_timer[0] > 0) delay_timer[0]--;
	if (sound_timer[0] > 0) sound_timer[0]--;
	if (p.z > MINPRESSURE && p.z < MAXPRESSURE)
	{
		p.x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);
		p.y = map(p.y, TS_MINY, TS_MAXY, tft.height(), 0);
		n = p.x / 45 + p.y / 45 * 5;
		tft.fillRect(0, 120, 60, 30, WHITE);
		tft.setCursor(0, 120);
		tft.setTextColor(RED);
		tft.setTextSize(2);
		tft.println(n);
		if (n == 15) keypad[0] = 1;
		if (n == 16) keypad[1] = 1;
		if (n == 17) keypad[2] = 1;
		if (n == 18) keypad[3] = 1;
		if (n == 20) keypad[4] = 1;
		if (n == 21) keypad[5] = 1;
		if (n == 22) keypad[6] = 1;
		if (n == 23) keypad[7] = 1;
		if (n == 25) keypad[8] = 1;
		if (n == 26) keypad[9] = 1;
		if (n == 27) keypad[10] = 1;
		if (n == 28) keypad[11] = 1;
		if (n == 30) keypad[12] = 1;
		if (n == 31) keypad[13] = 1;
		if (n == 32) keypad[14] = 1;
		if (n == 33) keypad[15] = 1;
	}
	else
	{
		keypad[0] = 0;
		keypad[1] = 0;
		keypad[2] = 0;
		keypad[3] = 0;
		keypad[4] = 0;
		keypad[5] = 0;
		keypad[6] = 0;
		keypad[7] = 0;
		keypad[8] = 0;
		keypad[9] = 0;
		keypad[10] = 0;
		keypad[11] = 0;
		keypad[12] = 0;
		keypad[13] = 0;
		keypad[14] = 0;
		keypad[15] = 0;
	}
}

```

以上。