#define SAMPLES_PER_UPDATE 500
#if PACMAN
-// define pacman I/O addresses here
+#define INT_VECTOR 0
+
+#define TILE_RAM 0x4000
+#define PALETTE_RAM 0x4400
#else // APPLE
#define IO_PAGE 0xe000
#define HW_KBD 0xe000 // R last key pressed + 128
#endif
#define TRACE 0
-#define IO_TRACE 1
-#define MEM_TRACE 1
+#define IO_TRACE 0
+#define MEM_TRACE 0
extern char **environ;
// see palette.py
uint32_t palette[0x10] = {
+#if PACMAN
+ // see https://www.lomont.org/software/games/pacman/PacmanEmulation.pdf
+ 0xff000000,
+ 0xffff0000,
+ 0xffde9751,
+ 0xffffb8ff,
+ 0xff000000,
+ 0xff00ffff,
+ 0xff47b8ff,
+ 0xffffb851,
+ 0xff000000,
+ 0xffffff00,
+ 0xff000000,
+ 0xff2121ff,
+ 0xff00ff00,
+ 0xff47b8ae,
+ 0xffffb8ae,
+ 0xffdedeff,
+#else // APPLE
0xff000000,
0xffbc0089,
0xff0000bc,
0xffffffbc,
0xffbcffe1,
0xffffffff,
+#endif
};
// can make this green or amber to be more realistic
int usleep_count, exit_flag;
#if PACMAN
-// define pacman I/O state here
+uint8_t int_vector;
// just for now until we have pacman audio
#define C0X0_SOFT_SWITCH_TAPEOUT 4
#endif
switch (port) {
+#if PACMAN
+ case INT_VECTOR:
+ int_vector = val;
+ break;
+#endif
case STDOUT_DATA:
if (write(fd_out, &val, 1) == -1) {
perror("write()");
fd_out = fd_master;
}
+// not sure why this was needed
+// keyboard input should be via SDL2
+// HRCG input should be via a pty master (not slave)
+#if 0
if (isatty(fd_in)) {
if (tcgetattr(fd_in, &termios_attr) == -1) {
perror("tcgetattr()");
exit(EXIT_FAILURE);
}
}
+#endif
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0) {
fprintf(stderr, "SDL_Init(): %s\n\n", SDL_GetError());
SDL_RenderClear(renderer);
#if PACMAN
- // define pacman video update here
+ // send z80 a vertical refresh interrupt
+ cpu.int_pending = true;
+ cpu.int_data = int_vector;
+
+ for (int i = 0; i < 36; ++i)
+ for (int j = 0; j < 28; ++j) {
+ int offset =
+ i < 2 ?
+ 0x3dd + (i << 5) - j :
+ i < 34 ?
+ 0x3a0 - 2 + i - (j << 5) :
+ 0x1d - (34 << 5) + (i << 5) - j;
+ int tile_base =
+ ROM_PACMAN_5E_ADDR | (mem[TILE_RAM | offset] << 4) | 0xf;
+ int palette_base =
+ ROM_82S126_4A_ADDR | ((mem[PALETTE_RAM | offset] & 0x3f) << 2);
+ for (int k = 0; k < 8; ++k) {
+ int y = ((i << 3) | k) * WINDOW_Y_SCALE;
+ for (int l = 0; l < 8; ++l) {
+ int data = mem[tile_base ^ ((k & 4) << 1) ^ l] << (k & 3);
+ uint32_t rgb = palette[
+ mem[
+ palette_base | ((data & 8) >> 3) | ((data & 0x80) >> 6)
+ ] & 0xf
+ ];
+ int x = ((j << 3) | l) * WINDOW_X_SCALE;
+ for (int m = 0; m < WINDOW_Y_SCALE; ++m)
+ for (int n = 0; n < WINDOW_X_SCALE; ++n)
+ frame[y + m][x + n] = rgb;
+ }
+ }
+ }
#else // APPLE
struct timespec timeval;
clock_gettime(CLOCK_MONOTONIC, &timeval);