1 /*
2  * gbsplay is a Gameboy sound player
3  *
4  * 2015 (C) by Tobias Diedrich <ranma+gbsplay@tdiedrich.de>
5  *
6  * Licensed under GNU GPL v1 or, at your option, any later version.
7  */
8 
9 #include "common.h"
10 
11 #include <stdint.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 
16 #include "plugout.h"
17 
18 static FILE *file;
19 static long cycles_prev = 0;
20 
iodumper_open(enum plugout_endian endian,long rate)21 static long regparm iodumper_open(enum plugout_endian endian, long rate)
22 {
23 	/*
24 	 * clone and close STDOUT_FILENO
25 	 * to make sure nobody else can write to stdout
26 	 */
27 	int fd = dup(STDOUT_FILENO);
28 	if (fd == -1) return -1;
29 	(void)close(STDOUT_FILENO);
30 	file = fdopen(fd, "w");
31 
32 	return 0;
33 }
34 
iodumper_skip(int subsong)35 static int regparm iodumper_skip(int subsong)
36 {
37 	fprintf(file, "\nsubsong %d\n", subsong);
38 	fprintf(stderr, "dumping subsong %d\n", subsong);
39 
40 	return 0;
41 }
42 
iodumper_io(long cycles,uint32_t addr,uint8_t val)43 static int regparm iodumper_io(long cycles, uint32_t addr, uint8_t val)
44 {
45 	long cycle_diff = cycles - cycles_prev;
46 
47 	fprintf(file, "%08lx %04x=%02x\n", cycle_diff, addr, val);
48 	cycles_prev = cycles;
49 
50 	return 0;
51 }
52 
iodumper_close(void)53 static void regparm iodumper_close(void)
54 {
55 	fflush(file);
56 	fclose(file);
57 }
58 
59 const struct output_plugin plugout_iodumper = {
60 	.name = "iodumper",
61 	.description = "STDOUT io dumper",
62 	.open = iodumper_open,
63 	.skip = iodumper_skip,
64 	.io = iodumper_io,
65 	.close = iodumper_close,
66 	.flags = PLUGOUT_USES_STDOUT,
67 };
68