blob: 51d22a2bfd271e4f719880c228d86e26594bf5d9 (
plain)
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
__attribute__((section(".mapper_001_0")))
static uint8_t mapper_001_0_prg_rom_read(struct nes_state *state, uint32_t addr) {
struct mapper_001_0 *mapper = &state->mapper_data.m001_0;
if(addr >= 0x8000) {
if(addr < 0xc000) {
return mapper->prg_rom_0[addr & 0x3fff];
} else {
return mapper->prg_rom_1[addr & 0x3fff];
}
}
return 0;
}
__attribute__((section(".mapper_001_0")))
static void mapper_001_0_prg_rom_write(struct nes_state *state, uint32_t addr, uint8_t value) {
struct mapper_001_0 *mapper = &state->mapper_data.m001_0;
if(addr < 0x8000) return;
if(value & 0x80) {
mapper->shift = 0;
mapper->shift_count = 0;
mapper->control |= 0x0c;
return;
}
mapper->shift |= (value & 1) << mapper->shift_count;
mapper->shift_count++;
if(mapper->shift_count == 5) {
uint32_t bank;
uint8_t reg = (addr >> 13) & 0x03;
switch(reg) {
case 0: {// Control
mapper->control = mapper->shift;
} break;
case 1: { // CHR bank 0
mapper->chr_bank0 = mapper->shift;
mapper->chr_bank_0 = state->chr_rom + (mapper->chr_bank0 * 0x1000);
} break;
case 2: { // CHR bank 1
mapper->chr_bank1 = mapper->shift;
mapper->chr_bank_1 = state->chr_rom + (mapper->chr_bank1 * 0x1000);
} break;
case 3: { // PRG bank
mapper->prg_bank = mapper->shift & 0x0f;
if(mapper->control & 0x08) {
// 16KB bank switching
if(mapper->control & 0x04) {
mapper->prg_rom_0 = state->prg_rom + 0x4000 * 0;
mapper->prg_rom_1 = state->prg_rom + 0x4000 * mapper->prg_bank;
} else {
mapper->prg_rom_0 = state->prg_rom + 0x4000 * mapper->prg_bank;
mapper->prg_rom_1 = state->prg_rom + 0x4000 * (state->ines.prg_size / 0x4000 - 1);
}
} else {
// 32KB mode
bank = (mapper->prg_bank & 0x0e) * 0x4000;
mapper->prg_rom_0 = state->prg_rom + bank;
mapper->prg_rom_1 = state->prg_rom + bank + 0x4000;
}
} break;
}
mapper->shift = 0;
mapper->shift_count = 0;
}
}
__attribute__((section(".mapper_001_0")))
static uint8_t mapper_001_0_chr_read(struct nes_state *state, uint32_t addr) {
struct mapper_001_0 *mapper = &state->mapper_data.m001_0;
if(mapper->control & 0x10) {
// 4KB mode
if(addr < 0x1000) {
return mapper->chr_bank_0[addr];
} else {
return mapper->chr_bank_1[addr - 0x1000];
}
} else {
// 8KB mode
return mapper->chr_bank_0[addr];
}
}
__attribute__((section(".mapper_001_0")))
static void mapper_001_0_chr_write(struct nes_state *state, uint32_t addr, uint8_t value) {
// CHR RAM write (if present)
state->chr_ram[addr] = value;
}
__attribute__((section(".mapper_001_0")))
static uint8_t mapper_001_0_ciram_read(struct nes_state *state, uint32_t addr) {
return state->ciram[addr & 0x3ff];
}
__attribute__((section(".mapper_001_0")))
static void mapper_001_0_ciram_write(struct nes_state *state, uint32_t addr, uint8_t value) {
state->ciram[addr & 0x3ff] = value;
}
__attribute__((section(".mapper_001_0")))
static void mapper_001_0_init(struct nes_state *state) {
struct mapper_001_0 *mapper = &state->mapper_data.m001_0;
mapper->control = 0x0c;
mapper->prg_rom_0 = state->prg_rom;
mapper->prg_rom_1 = state->prg_rom + (state->ines.prg_size - 0x4000);
mapper->chr_bank_0 = state->chr_rom;
mapper->chr_bank_1 = state->chr_rom + 0x1000;
state->mapper_function.prg_rom_read = mapper_001_0_prg_rom_read;
state->mapper_function.prg_rom_write = mapper_001_0_prg_rom_write;
state->mapper_function.chr_read = mapper_001_0_chr_read;
state->mapper_function.chr_write = mapper_001_0_chr_write;
state->mapper_function.ciram_read = mapper_001_0_ciram_read;
state->mapper_function.ciram_write = mapper_001_0_ciram_write;
}
|