commit d804131ea9e814054e08ce16e90009b87b199522
Author: Naveen Narayanan <nan@sysgo.com>
Date: Sun, 6 Mar 2022 16:00:17 +0100
Initial commit
Diffstat:
A | 8.c | | | 299 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | Makefile | | | 8 | ++++++++ |
A | README | | | 6 | ++++++ |
3 files changed, 313 insertions(+), 0 deletions(-)
diff --git a/8.c b/8.c
@@ -0,0 +1,299 @@
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define BUFSZ 256
+
+unsigned short opcode;
+unsigned char mem[4096];
+unsigned char V[16];
+unsigned short I;
+unsigned short pc;
+unsigned char gfx[64 * 32];
+unsigned char delaytmr;
+unsigned char soundtmr;
+unsigned short stack[16];
+unsigned short* sp;
+unsigned char keys[16];
+unsigned char buf[BUFSZ];
+
+unsigned char fnt[80] =
+{
+ 0xF0, 0x90, 0x90, 0x90, 0xF0, //0
+ 0x20, 0x60, 0x20, 0x20, 0x70, //1
+ 0xF0, 0x10, 0xF0, 0x80, 0xF0, //2
+ 0xF0, 0x10, 0xF0, 0x10, 0xF0, //3
+ 0x90, 0x90, 0xF0, 0x10, 0x10, //4
+ 0xF0, 0x80, 0xF0, 0x10, 0xF0, //5
+ 0xF0, 0x80, 0xF0, 0x90, 0xF0, //6
+ 0xF0, 0x10, 0x20, 0x40, 0x40, //7
+ 0xF0, 0x90, 0xF0, 0x90, 0xF0, //8
+ 0xF0, 0x90, 0xF0, 0x10, 0xF0, //9
+ 0xF0, 0x90, 0xF0, 0x90, 0x90, //A
+ 0xE0, 0x90, 0xE0, 0x90, 0xE0, //B
+ 0xF0, 0x80, 0x80, 0x80, 0xF0, //C
+ 0xE0, 0x90, 0x90, 0x90, 0xE0, //D
+ 0xF0, 0x80, 0xF0, 0x80, 0xF0, //E
+ 0xF0, 0x80, 0xF0, 0x80, 0x80 //F
+};
+
+static void
+init()
+{
+ pc = 0x200;
+ opcode = 0;
+ I = 0;
+ sp = stack;
+
+ for (int i = 0; i < 80; ++i)
+ mem[i] = fnt[i];
+
+ for (int i = 0; i < BUFSZ; ++i)
+ mem[i + 512] = buf[i];
+}
+
+static void
+clrscr()
+{
+}
+
+static short
+sprite()
+{
+ /* return address of sprite */
+ return 0;
+}
+
+static void
+draw()
+{
+}
+
+static int
+key()
+{
+ /* return pressed key */
+ return 0;
+}
+
+static int
+waitkey()
+{
+ /* block until keypress and return it */
+ return 0;
+}
+
+static void
+bcd()
+{
+}
+
+static void
+execute()
+{
+ int x, y, c;
+
+ switch (opcode & 0xF000) {
+ case 0x0000:
+ switch (opcode) {
+ case 0x00E0:
+ clrscr();
+ pc += 2;
+ case 0x00EE:
+ if (sp > stack) {
+ pc = *sp;
+ --sp;
+ }
+ return;
+ default:
+ fprintf(stderr, "machine code routine\n");
+ pc += 2;
+ return;
+ }
+ case 0x1000:
+ pc = opcode & 0x0FFF;
+ return;
+ case 0x2000:
+ *sp = pc;
+ ++sp;
+ pc = opcode & 0x0FFF;
+ return;
+ case 0x3000:
+ x = (opcode & 0x0F00) >> 8;
+ c = opcode & 0x00FF;
+ if (V[x] == c)
+ pc += 4;
+ return;
+ case 0x4000:
+ x = (opcode & 0x0F00) >> 8;
+ c = opcode & 0x00FF;
+ if (V[x] != c)
+ pc += 4;
+ return;
+ case 0x5000:
+ x = (opcode & 0x0F00) >> 8;
+ y = (opcode & 0x00F0) >> 4;
+ if (V[x] == V[y])
+ pc += 4;
+ return;
+ case 0x6000:
+ x = (opcode & 0x0F00) >> 8;
+ c = opcode & 0x00FF;
+ V[x] = c;
+ pc += 2;
+ return;
+ case 0x7000:
+ x = (opcode & 0x0F00) >> 8;
+ c = opcode & 0x00FF;
+ V[x] += c;
+ pc += 2;
+ return;
+ case 0x8000:
+ x = (opcode & 0x0F00) >> 8;
+ y = (opcode & 0x00F0) >> 4;
+ pc += 2;
+ switch(opcode & 0x000F) {
+ case 0x0000:
+ V[x] = V[y];
+ return;
+ case 0x0001:
+ V[x] |= V[y];
+ return;
+ case 0x0002:
+ V[x] &= V[y];
+ return;
+ case 0x0003:
+ V[x] ^= V[y];
+ return;
+ case 0x0004:
+ V[0xF] = 0;
+ if (V[y] > CHAR_MAX - V[x])
+ V[0xF] = 1;
+ V[x] += V[y];
+ return;
+ case 0x0005:
+ V[0xF] = 0;
+ if (V[y] > V[x])
+ V[0xF] = 1;
+ V[x] -= V[y];
+ return;
+ case 0x0006:
+ V[0xF] = V[x] & 0x01;
+ V[x] >>= 1;
+ return;
+ case 0x0007:
+ V[0xF] = 1;
+ if (V[x] > V[y])
+ V[0xF] = 0;
+ V[x] = V[y] - V[x];
+ return;
+ case 0x000E:
+ V[0xF] = V[x] & 0x80;
+ V[x] <<= 1;
+ return;
+ default:
+ goto err;
+ }
+ case 0x9000:
+ x = (opcode & 0x0F00) >> 8;
+ y = (opcode & 0x00F0) >> 4;
+ if (V[x] != V[y])
+ pc += 4;
+ pc += 2;
+ return;
+ case 0xA000:
+ I = opcode & 0x0FFF;
+ pc += 2;
+ return;
+ case 0xB000:
+ pc = V[0] + (opcode & 0x0FFF);
+ return;
+ case 0xC000:
+ x = (opcode & 0x0F00) >> 8;
+ c = (opcode & 0x00FF);
+ V[x] = (rand() % 256) & c;
+ pc += 2;
+ return;
+ case 0xD000:
+ x = (opcode & 0x0F00) >> 8;
+ y = (opcode & 0x00F0) >> 4;
+ c = opcode & 0x000F;
+ draw(V[x], V[y], c);
+ pc += 2;
+ return;
+ case 0xE000:
+ x = (opcode & 0x0F00) >> 8;
+ pc += 2;
+ switch (opcode & 0x00FF) {
+ case 0x009E:
+ if (key() == V[x])
+ pc += 4;
+ return;
+ case 0x00A1:
+ if (key() != V[x])
+ pc += 4;
+ return;
+ default:
+ goto err;
+ }
+ case 0xF000:
+ x = (opcode & 0x0F00) >> 8;
+ pc += 2;
+ switch (opcode & 0x00FF) {
+ case 0x0007:
+ V[x] = delaytmr;
+ return;
+ case 0x000A:
+ V[x] = waitkey();
+ return;
+ case 0x0015:
+ delaytmr = V[x];
+ return;
+ case 0x0018:
+ soundtmr = V[x];
+ return;
+ case 0x001E:
+ I += V[x];
+ return;
+ case 0x0029:
+ I = sprite(V[x]);
+ return;
+ case 0x0033:
+ bcd(x);
+ return;
+ case 0x0055:
+ for (int i = 0; i < 16; ++i)
+ mem[I + 1 + i] = V[i]; /* mem[I] shouldn't be modified */
+ return;
+ case 0x0065:
+ for (int i = 0; i < 16; ++i)
+ V[i] = mem[I + 1 + i]; /* mem[I] shouldn't be modified */
+ return;
+ default:
+ goto err;
+ }
+ default:
+ goto err;
+ }
+err:
+ fprintf(stderr, "Unknown opcode: 0x%X\n", opcode);
+}
+
+static void
+cycle()
+{
+ opcode = mem[pc] << 8 | mem[pc+1];
+ execute();
+ if (delaytmr > 0)
+ --delaytmr;
+ if (soundtmr > 0) {
+ printf("BEEP\n");
+ --soundtmr;
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ printf("Welcome to 8\n");
+}
diff --git a/Makefile b/Makefile
@@ -0,0 +1,8 @@
+BIN = 8
+
+all: ${BIN}
+
+.PHONY: clean
+
+clean:
+ -rm -f ${BIN}
diff --git a/README b/README
@@ -0,0 +1,6 @@
+8
+---
+a CHIP-8 emulator
+
+love,
+zer