commit af4315096adec14d0d40a647cac92ddb4135ba75
parent 88bebe70bbf6950b64d83c69c1c86c8c18d21e00
Author: Christos Margiolis <christos@margiolis.net>
Date: Wed, 26 May 2021 18:54:28 +0300
no support for windows
Diffstat:
M | LICENSE | | | 2 | +- |
M | Makefile | | | 41 | ++++++++++++++++++++--------------------- |
M | chip8.1 | | | 2 | +- |
M | chip8.c | | | 150 | ++++++++++++++++++++++++++++--------------------------------------------------- |
M | config.mk | | | 21 | +++++---------------- |
5 files changed, 79 insertions(+), 137 deletions(-)
diff --git a/LICENSE b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-(c) 2020-Present Christos Margiolis <christos@christosmarg.xyz>
+(c) 2020-Present Christos Margiolis <christos@margiolis.net>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the “Software”), to deal in
diff --git a/Makefile b/Makefile
@@ -1,5 +1,5 @@
# See LICENSE file for copyright and license details.
-# chip8 - a minimal CHIP-8 emulator
+# chip8 - CHIP-8 emulator
.POSIX:
include config.mk
@@ -8,47 +8,46 @@ BIN = chip8
DIST = ${BIN}-${VERSION}
MAN1 = ${BIN}.1
-EXT = c
SRC = chip8.c
-OBJ = ${SRC:.${EXT}=.o}
+OBJ = ${SRC:.c=.o}
all: options ${BIN}
options:
@echo ${BIN} build options:
- @echo "CFLAGS = ${CFLAGS}"
- @echo "LDFLAGS = ${LDFLAGS}"
- @echo "CC = ${CC}"
+ @echo "CFLAGS = ${CFLAGS}"
+ @echo "LDFLAGS = ${LDFLAGS}"
+ @echo "CC = ${CC}"
${BIN}: ${OBJ}
${CC} ${LDFLAGS} ${OBJ} -o $@
-.${EXT}.o:
+.c.o:
${CC} -c ${CFLAGS} $<
dist: clean
- ${MKDIR} ${DIST}
- ${CP} -R roms ${MAN1} ${SRC} config.mk LICENSE Makefile README.md ${DIST}
- ${TAR} ${DIST}.tar ${DIST}
- ${GZIP} ${DIST}.tar
- ${RM_DIR} ${DIST}
+ mkdir -p ${DIST}
+ cp -R roms chip8.1 chip8.c config.mk LICENSE Makefile README.md ${DIST}
+ tar -cf ${DIST}.tar ${DIST}
+ gzip ${DIST}.tar
+ rm -rf ${DIST}
run:
./${BIN}
install: all
- ${MKDIR} ${DESTDIR}${BIN_DIR} ${DESTDIR}${MAN_DIR}
- ${CP} ${BIN} ${BIN_DIR}
- ${CP} ${MAN1} ${DESTDIR}${MAN_DIR}
- sed "s/VERSION/${VERSION}/g" < ${MAN1} > ${DESTDIR}${MAN_DIR}/${MAN1}
- chmod 755 ${DESTDIR}${BIN_DIR}/${BIN}
- chmod 644 ${DESTDIR}${MAN_DIR}/${MAN1}
+ mkdir -p ${DESTDIR}${PREFIX}/bin ${DESTDIR}${MANPREFIX}/man1
+ cp -f ${BIN} ${DESTDIR}${PREFIX}/bin
+ cp -f ${MAN1} ${DESTDIR}${MANPREFIX}/man1
+ sed "s/VERSION/${VERSION}/g" < ${MAN1} > ${DESTDIR}${MANPREFIX}/man1/${MAN1}
+ chmod 755 ${DESTDIR}${PREFIX}/bin/${BIN}
+ chmod 644 ${DESTDIR}${MANPREFIX}/man1/${MAN1}
uninstall:
- ${RM} ${DESTDIR}${BIN_DIR}/${BIN}
- ${RM} ${DESTDIR}${MAN_DIR}/${MAN1}
+ rm -f ${DESTDIR}${PREFIX}/bin/${BIN} \
+ ${DESTDIR}${MANPREFIX}/man1/${MAN1}
clean:
- ${RM} ${BIN} ${OBJ} ${DIST}.tar.gz
+ rm -f ${BIN} ${OBJ} ${DIST}.tar.gz *.core
.PHONY: all options clean dist install uninstall run
diff --git a/chip8.1 b/chip8.1
@@ -12,4 +12,4 @@
reads a CHIP\-8 ROM and executes it. It uses the SDL2
library as a rendering API.
.Sh AUTHORS
-.An Christos Margiolis Aq Mt christos@christosmarg.xyz
+.An Christos Margiolis Aq Mt christos@margiolis.net
diff --git a/chip8.c b/chip8.c
@@ -1,22 +1,16 @@
/* See LICENSE file for copyright and license details. */
+#include <sys/types.h>
+
+#include <err.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#include <unistd.h>
#include <SDL2/SDL.h>
-#ifdef _WIN_32
-#include <Windows.h>
-typedef unsigned int u_int32_t
-typedef unsigned short u_int16_t
-typedef unsigned char u_int8_t
-#else /* !_WIN_32 */
-#include <sys/types.h>
-#include <unistd.h>
-#endif /* _WIN_32 */
-
#define VX_MASK(x) ((x & 0x0f00) >> 8)
#define VY_MASK(x) ((x & 0x00f0) >> 4)
#define NN_MASK(x) (x & 0x00ff)
@@ -24,31 +18,29 @@ typedef unsigned char u_int8_t
#define EXECUTE(pc) do { pc += 2; } while (0)
struct chip8 {
- u_int16_t stack[16];
- u_int16_t I;
- u_int16_t opcode;
- u_int16_t pc;
- u_int16_t sp;
- u_int8_t mem[4096];
- u_int8_t gfx[64 * 32];
- u_int8_t V[16];
- u_int8_t keys[16];
- u_int8_t delaytimer;
- u_int8_t soundtimer;
- u_int8_t drawflag;
+ uint16_t stack[16];
+ uint16_t I;
+ uint16_t opcode;
+ uint16_t pc;
+ uint16_t sp;
+ uint8_t mem[4096];
+ uint8_t gfx[64 * 32];
+ uint8_t V[16];
+ uint8_t keys[16];
+ uint8_t delaytimer;
+ uint8_t soundtimer;
+ uint8_t drawflag;
};
static void chip8_init(struct chip8 *);
-static void romload(struct chip8 *, const char *);
+static void rom_load(struct chip8 *, const char *);
static void emulate(struct chip8 *);
static int decode(struct chip8 *);
-static int evhandle(struct chip8 *);
+static int handle_events(struct chip8 *);
static void render(SDL_Renderer *, SDL_Texture *, struct chip8 *);
-static void warn(const char *, ...);
-static void die(const char *, ...);
static char *argv0;
-static const u_int8_t keymap[16] = {
+static const uint8_t keymap[16] = {
SDLK_1, SDLK_2, SDLK_3, SDLK_4,
SDLK_q, SDLK_w, SDLK_e, SDLK_r,
SDLK_a, SDLK_s, SDLK_d, SDLK_f,
@@ -71,7 +63,7 @@ static const u_int8_t keymap[16] = {
static void
chip8_init(struct chip8 *chip8)
{
- u_int8_t fontset[80] = {
+ uint8_t fontset[80] = {
0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
0x20, 0x60, 0x20, 0x20, 0x70, // 1
0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2
@@ -109,30 +101,28 @@ chip8_init(struct chip8 *chip8)
}
static void
-romload(struct chip8 *chip8, const char *fpath)
+rom_load(struct chip8 *chip8, const char *fpath)
{
FILE *rom;
char *buf;
- size_t res, romsize;
+ size_t res, romsiz;
int i;
if ((rom = fopen(fpath, "rb")) == NULL)
- die("fopen: %s", fpath);
+ err(1, "fopen: %s", fpath);
fseek(rom, 0, SEEK_END);
- romsize = ftell(rom);
+ romsiz = ftell(rom);
rewind(rom);
-
- if ((buf = malloc(romsize + 1)) == NULL)
- die("malloc:");
- if ((res = fread(buf, sizeof(char), romsize, rom)) != romsize)
- die("fread:");
- buf[romsize] = '\0';
- if (romsize < (4092 - 512))
- for (i = 0; i < romsize; i++)
+ if ((buf = malloc(romsiz + 1)) == NULL)
+ err(1, "malloc");
+ if ((res = fread(buf, sizeof(char), romsiz, rom)) != romsiz)
+ err(1, "fread");
+ buf[romsiz] = '\0';
+ if (romsiz < (4092 - 512))
+ for (i = 0; i < romsiz; i++)
mem[i + 512] = buf[i];
else
- die("ROM cannot fit into memory");
-
+ errx(1, "ROM cannot fit into memory");
fclose(rom);
free(buf);
}
@@ -156,8 +146,8 @@ static int
decode(struct chip8 *chip8)
{
int yl, xl, i, keypress = 0;
- u_int16_t h, pixel;
- u_int8_t VX, VY;
+ uint16_t h, pixel;
+ uint8_t VX, VY;
switch (opcode & 0xF000) {
case 0x0000: // 00E_
@@ -170,7 +160,7 @@ decode(struct chip8 *chip8)
pc = stack[--sp];
break;
default:
- warn("unknown opcode: %x\n", opcode);
+ warnx("unknown opcode: %x\n", opcode);
return 0;
}
break;
@@ -233,7 +223,7 @@ decode(struct chip8 *chip8)
V[VX_MASK(opcode)] <<= 1;
break;
default:
- warn("unknown opcode: %x\n", opcode);
+ warnx("unknown opcode: %x\n", opcode);
return 0;
}
break;
@@ -279,7 +269,7 @@ decode(struct chip8 *chip8)
EXECUTE(pc);
break;
default:
- warn("unknown opcode: %x\n", opcode);
+ warnx("unknown opcode: %x\n", opcode);
return 0;
}
break;
@@ -327,12 +317,12 @@ decode(struct chip8 *chip8)
I += (VX_MASK(opcode)) + 1;
break;
default:
- warn("unknown opcode: %x\n", opcode);
+ warnx("unknown opcode: %x\n", opcode);
return 0;
}
break;
default:
- warn("unimplemented opcode\n");
+ warnx("unimplemented opcode\n");
return 0;
}
return 1;
@@ -352,7 +342,7 @@ decode(struct chip8 *chip8)
#undef drawflag
static int
-evhandle(struct chip8 *chip8)
+handle_events(struct chip8 *chip8)
{
SDL_Event e;
int i;
@@ -377,7 +367,7 @@ evhandle(struct chip8 *chip8)
static void
render(SDL_Renderer *ren, SDL_Texture *tex, struct chip8 *chip8)
{
- u_int32_t pixels[2048];
+ uint32_t pixels[2048];
int i;
chip8->drawflag = 0;
@@ -389,38 +379,6 @@ render(SDL_Renderer *ren, SDL_Texture *tex, struct chip8 *chip8)
SDL_RenderPresent(ren);
}
-static void
-warn(const char *fmt, ...)
-{
- va_list args;
-
- fprintf(stderr, "%s: ", argv0);
-
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- va_end(args);
-}
-
-static void
-die(const char *fmt, ...)
-{
- va_list args;
-
- fprintf(stderr, "%s: ", argv0);
-
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- va_end(args);
-
- if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
- fputc(' ', stderr);
- perror(NULL);
- } else
- fputc('\n', stderr);
-
- exit(EXIT_FAILURE);
-}
-
int
main(int argc, char *argv[])
{
@@ -433,11 +391,16 @@ main(int argc, char *argv[])
argv0 = *argv;
srand(time(NULL));
if (argc != 2) {
- fprintf(stderr, "usage: %s rom", argv0);
+ fprintf(stderr, "usage: %s rom\n", argv0);
return 1;
}
+ if ((chip8 = malloc(sizeof(struct chip8))) == NULL)
+ err(1, "malloc");
+ chip8_init(chip8);
+ rom_load(chip8, argv[1]);
+
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
- die("SDL_Init: %s", SDL_GetError());
+ errx(1, "SDL_Init: %s", SDL_GetError());
win = SDL_CreateWindow("CHIP-8 Emulator", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, w, h,
@@ -448,24 +411,15 @@ main(int argc, char *argv[])
SDL_TEXTUREACCESS_STREAMING, 64, 32);
if (!win || !ren || !tex)
- die("SDL error: %s", SDL_GetError());
- if ((chip8 = malloc(sizeof(struct chip8))) == NULL)
- die("malloc:");
-
- chip8_init(chip8);
- romload(chip8, argv[1]);
-
+ errx(1, "SDL error: %s", SDL_GetError());
for (;;) {
- if (!evhandle(chip8))
+ if (!handle_events(chip8))
break;
emulate(chip8);
if (chip8->drawflag)
render(ren, tex, chip8);
-#ifdef _WIN_32
- Sleep(1);
-#else /* !_WIN_32 */
+ /* FIXME: VERY slow on some machines */
usleep(1500);
-#endif /* _WIN_32 */
}
free(chip8);
@@ -474,5 +428,5 @@ main(int argc, char *argv[])
SDL_DestroyWindow(win);
SDL_Quit();
- return EXIT_SUCCESS;
+ return 0;
}
diff --git a/config.mk b/config.mk
@@ -1,15 +1,14 @@
# See LICENSE file for copyright and license details.
# chip8 version
-VERSION = 0
+VERSION = 0.1
# paths
PREFIX = /usr/local
-MAN_DIR = ${PREFIX}/share/man/man1
-BIN_DIR = ${PREFIX}/bin
+MANPREFIX = ${PREFIX}/share/man
# includes and libs
-INCS = -Iinclude
-LIBS = -Llib -lSDL2
+INCS = -Iinclude -I${PREFIX}/include
+LIBS = -Llib -L${PREFIX}/lib -lSDL2
# flags
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L \
@@ -17,15 +16,5 @@ CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L \
CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
LDFLAGS = ${LIBS}
-# utils
-CP = cp -f
-RM = rm -f
-RM_DIR = rm -rf
-MV = mv
-MKDIR = mkdir -p
-RM_DIR = rm -rf
-TAR = tar -cf
-GZIP = gzip
-
# compiler
-CC = gcc
+CC = cc