-
Notifications
You must be signed in to change notification settings - Fork 100
/
sfc_mapper.c
139 lines (119 loc) · 3.98 KB
/
sfc_mapper.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include "sfc_cpu.h"
#include "sfc_famicom.h"
#include "sfc_mapper_helper.h"
#include <assert.h>
#include <string.h>
// mapper000 - NROM
static inline sfc_ecode sfc_load_mapper_00(sfc_famicom_t* famicom);
// mapper001 - SxROM
extern inline sfc_ecode sfc_load_mapper_01(sfc_famicom_t* famicom);
// mapper002 - UxROM
extern inline sfc_ecode sfc_load_mapper_02(sfc_famicom_t* famicom);
// mapper003 - CNROM
extern inline sfc_ecode sfc_load_mapper_03(sfc_famicom_t* famicom);
// mapper004 - TxROM
extern inline sfc_ecode sfc_load_mapper_04(sfc_famicom_t* famicom);
// mapper074 - MMC3 魔改
extern inline sfc_ecode sfc_load_mapper_4A(sfc_famicom_t* famicom);
#define SFC_CASE_LOAD_MAPPER(id) case 0x##id: return sfc_load_mapper_##id(famicom);
/// <summary>
/// SFCs the mapper hsync defualt.
/// </summary>
/// <param name="famicom">The famicom.</param>
static void sfc_mapper_hsync_defualt(sfc_famicom_t* famicom) {
}
/// <summary>
/// SFCs the mapper WRTS.
/// </summary>
/// <param name="famicom">The famicom.</param>
static void sfc_mapper_wrts_defualt(const sfc_famicom_t* famicom) {
// PRG-RAM 不考虑
// 没有CHR-ROM则表明全是CHR-RAM
if (!famicom->rom_info.count_chrrom_8kb) {
famicom->interfaces.sl_write_stream(
famicom->argument,
famicom->rom_info.data_chrrom,
8 * 1024
);
}
}
/// <summary>
/// SFCs the mapper WRTS.
/// </summary>
/// <param name="famicom">The famicom.</param>
static void sfc_mapper_rrfs_defualt(sfc_famicom_t* famicom) {
// PRG-RAM 不考虑
// 没有CHR-ROM则表明全是CHR-RAM
if (!famicom->rom_info.count_chrrom_8kb) {
famicom->interfaces.sl_read_stream(
famicom->argument,
famicom->rom_info.data_chrrom,
8 * 1024
);
}
}
/// <summary>
/// StepFC: 加载Mapper
/// </summary>
/// <param name="famicom">The famicom.</param>
/// <param name="id">The identifier.</param>
/// <returns></returns>
extern sfc_ecode sfc_load_mapper(sfc_famicom_t* famicom, uint8_t id) {
memset(&famicom->mapper, 0, sizeof(famicom->mapper));
// 载入默认接口
famicom->mapper.hsync = sfc_mapper_hsync_defualt;
famicom->mapper.write_ram_to_stream = sfc_mapper_wrts_defualt;
famicom->mapper.read_ram_from_stream = sfc_mapper_rrfs_defualt;
switch (id)
{
SFC_CASE_LOAD_MAPPER(00);
SFC_CASE_LOAD_MAPPER(01);
SFC_CASE_LOAD_MAPPER(02);
SFC_CASE_LOAD_MAPPER(03);
SFC_CASE_LOAD_MAPPER(04);
SFC_CASE_LOAD_MAPPER(4A);
}
assert(!"NO MAPPER");
return SFC_ERROR_MAPPER_NOT_FOUND;
}
// ------------------------------- MAPPER 000 - NROM
/// <summary>
/// StepFC: MAPPER 000 - NROM 重置
/// </summary>
/// <param name="famicom">The famicom.</param>
/// <returns></returns>
extern sfc_ecode sfc_mapper_00_reset(sfc_famicom_t* famicom) {
assert(famicom->rom_info.count_prgrom16kb && "bad count");
assert(famicom->rom_info.count_prgrom16kb <= 2 && "bad count");
// PRG-ROM
// 16KB -> 载入 $8000-$BFFF, $C000-$FFFF 为镜像
const int id2 = famicom->rom_info.count_prgrom16kb & 2;
// 32KB -> 载入 $8000-$FFFF
sfc_load_prgrom_8k(famicom, 0, 0);
sfc_load_prgrom_8k(famicom, 1, 1);
sfc_load_prgrom_8k(famicom, 2, id2 + 0);
sfc_load_prgrom_8k(famicom, 3, id2 + 1);
// CHR-ROM
for (int i = 0; i != 8; ++i)
sfc_load_chrrom_1k(famicom, i, i);
return SFC_ERROR_OK;
}
/// <summary>
/// SFCs the mapper 00 write high.
/// </summary>
/// <param name="f">The f.</param>
/// <param name="d">The d.</param>
/// <param name="v">The v.</param>
static void sfc_mapper_00_write_high(sfc_famicom_t*f, uint16_t d, uint8_t v) {
assert(!"CANNOT WRITE PRG-ROM");
}
/// <summary>
/// SFCs the load mapper 00.
/// </summary>
/// <param name="famicom">The famicom.</param>
/// <returns></returns>
sfc_ecode sfc_load_mapper_00(sfc_famicom_t* famicom) {
famicom->mapper.reset = sfc_mapper_00_reset;
famicom->mapper.write_high = sfc_mapper_00_write_high;
return SFC_ERROR_OK;
}