-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathmake_perf_rom.c
98 lines (86 loc) · 2.28 KB
/
make_perf_rom.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <assert.h>
#include <err.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "defs_6502.h"
#include "emit_6502.h"
#include "util.h"
static const size_t k_rom_size = 16384;
int
main(int argc, const char* argv[]) {
int fd;
int arg;
ssize_t write_ret;
int fast = 0;
size_t bytes = 0;
uint8_t* p_mem = malloc(k_rom_size);
struct util_buffer* p_buf = util_buffer_create();
if (p_mem == NULL) {
errx(1, "couldn't allocate ROM buffer");
}
(void) memset(p_mem, '\xf2', k_rom_size);
util_buffer_setup(p_buf, p_mem, k_rom_size);
/* Reset vector: jump to 0xC000, start of OS ROM. */
p_mem[0x3FFC] = 0x00;
p_mem[0x3FFD] = 0xC0;
/* Some statically placed values that can be useful. */
p_mem[0x3F00] = 0x60; /* aka. RTS */
/* Copy ROM to RAM. */
util_buffer_set_pos(p_buf, 0x0000);
emit_LDX(p_buf, k_imm, 0x00);
emit_LDA(p_buf, k_abx, 0xC100);
emit_STA(p_buf, k_abx, 0x1000);
emit_DEX(p_buf);
emit_BNE(p_buf, -9);
emit_JMP(p_buf, k_abs, 0x1000);
util_buffer_set_pos(p_buf, 0x0100);
emit_LDA(p_buf, k_imm, 0x20);
emit_STA(p_buf, k_zpg, 0x01);
emit_LDA(p_buf, k_imm, 0x00);
emit_STA(p_buf, k_zpg, 0x00);
emit_TAX(p_buf);
emit_TAY(p_buf);
emit_STA(p_buf, k_zpg, 0x30);
emit_STA(p_buf, k_zpg, 0x31);
for (arg = 1; arg < argc; ++arg) {
int i;
if (!strcmp(argv[arg], "-f")) {
/* "Fast", does 2^24 iterations instead of 2^32. */
fast = 1;
} else if (sscanf(argv[arg], "%x", &i) == 1) {
util_buffer_add_1b(p_buf, i);
bytes++;
}
}
emit_INX(p_buf);
emit_BNE(p_buf, (0xfd - bytes));
emit_INY(p_buf);
emit_BNE(p_buf, (0xfa - bytes));
emit_INC(p_buf, k_zpg, 0x30);
emit_BNE(p_buf, (0xf6 - bytes));
if (!fast) {
emit_INC(p_buf, k_zpg, 0x31);
emit_BNE(p_buf, (0xf2 - bytes));
}
emit_EXIT(p_buf);
fd = open("perf.rom", O_CREAT | O_WRONLY, 0600);
if (fd < 0) {
errx(1, "can't open output rom");
}
write_ret = write(fd, p_mem, k_rom_size);
if (write_ret < 0) {
errx(1, "can't write output rom");
}
if ((size_t) write_ret != k_rom_size) {
errx(1, "can't write output rom");
}
if (close(fd) != 0) {
errx(1, "can't close output file descriptor for rom");
}
return 0;
}