summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/includes/nes.h
blob: c395c2142493f9729fe181958ff46dfad6af09c3 (plain) (blame)
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
/*****************************************************************************
 *
 * includes/nes.h
 *
 * Nintendo Entertainment System (Famicom)
 *
 ****************************************************************************/

#ifndef NES_H_
#define NES_H_


/***************************************************************************
    CONSTANTS
***************************************************************************/

#define NTSC_CLOCK           N2A03_DEFAULTCLOCK     /* 1.789772 MHz */
#define PAL_CLOCK	           (26601712.0/16)        /* 1.662607 MHz */

#define NES_BATTERY_SIZE 0x2000


/***************************************************************************
    TYPE DEFINITIONS
***************************************************************************/

struct nes_input
{
	UINT32 shift;
	UINT32 i0, i1, i2;
};

/*PPU fast banking constants and structures */

#define CHRROM 0
#define CHRRAM 1

typedef struct
{
	int source;	//defines source of base pointer
	int origin; //defines offset of 0x400 byte segment at base pointer
	UINT8* access;	//source translated + origin -> valid pointer!
} chr_bank;

/*PPU nametable fast banking constants and structures */

#define CIRAM 0
#define ROM 1
#define EXRAM 2
#define MMC5FILL 3
#define CART_NTRAM 4

#define NES_BATTERY 0
#define NES_WRAM 1

typedef struct
{
	int source;		/* defines source of base pointer */
	int origin;		/* defines offset of 0x400 byte segment at base pointer */
	int writable;	/* ExRAM, at least, can be write-protected AND used as nametable */
	UINT8* access;	/* direct access when possible */
} name_table;

typedef void (*nes_prg_callback)(running_machine &machine, int start, int bank);
typedef void (*nes_chr_callback)(running_machine &machine, int start, int bank, int source);

class nes_state : public driver_device
{
public:
	nes_state(const machine_config &mconfig, device_type type, const char *tag)
		: driver_device(mconfig, type, tag) { }

	/* input_related - this part has to be cleaned up (e.g. in_2 and in_3 are not really necessary here...) */
	nes_input m_in_0, m_in_1, m_in_2, m_in_3;
	UINT8 m_fck_scan, m_fck_mode;

	int           m_prg_bank[5];
	chr_bank      m_chr_map[8];  //quick banking structure, because some of this changes multiple times per scanline!
	name_table    m_nt_page[4];  //quick banking structure for a maximum of 4K of RAM/ROM/ExRAM

	int m_chr_open_bus;
	int m_prgram_bank5_start, m_battery_bank5_start, m_empty_bank5_start;

	UINT8 m_ce_mask, m_ce_state;
	UINT8 m_vrc_ls_prg_a, m_vrc_ls_prg_b, m_vrc_ls_chr;

	int m_MMC5_floodtile;
	int m_MMC5_floodattr;
	int m_mmc5_vram_control;
	UINT8 m_mmc5_high_chr;
	UINT8 m_mmc5_split_scr;
	UINT8 *m_extended_ntram;

	UINT8 m_mmc5_last_chr_a;
	UINT16 m_mmc5_vrom_regA[8];
	UINT16 m_mmc5_vrom_regB[4];
	UINT8 m_mmc5_prg_regs[4];
	UINT8 m_mmc5_bank_security;
	UINT8 m_mmc5_prg_mode;
	UINT8 m_mmc5_chr_mode;
	UINT8 m_mmc5_chr_high;
	UINT8 m_mmc5_split_ctrl;
	UINT8 m_mmc5_split_yst;
	UINT8 m_mmc5_split_bank;

	/* video-related */
	int m_nes_vram_sprite[8]; /* Used only by mmc5 for now */
	int m_last_frame_flip;

	/* misc */
	write8_space_func   m_mmc_write_low;
	const char  		*m_mmc_write_low_name;
	write8_space_func   m_mmc_write_mid;
	const char  		*m_mmc_write_mid_name;
	write8_space_func   m_mmc_write;
	const char  		*m_mmc_write_name;
	read8_space_func    m_mmc_read_low;
	const char  		*m_mmc_read_low_name;
	read8_space_func    m_mmc_read_mid;
	const char  		*m_mmc_read_mid_name;
	read8_space_func    m_mmc_read;
	const char  		*m_mmc_read_name;
	emu_timer	        *m_irq_timer;

	nes_prg_callback    m_mmc3_prg_cb;	// these are used to simplify a lot emulation of some MMC3 pirate clones
	nes_chr_callback    m_mmc3_chr_cb;

	/* devices */
	device_t      *m_maincpu;
	ppu2c0x_device      *m_ppu;
	device_t      *m_sound;
	device_t      *m_cart;

	/* misc region to be allocated at init */
	// variables which don't change at run-time
	UINT8      *m_rom;
	UINT8      *m_prg;
	UINT8      *m_vrom;
	UINT8      *m_vram;
	UINT8      *m_wram;
	UINT8      *m_ciram; //PPU nametable RAM - external to PPU!
	UINT8      *m_battery_ram;
	UINT8      *m_mapper_ram;
	UINT8      *m_mapper_bram;

	/***** Mapper-related variables *****/

	// common ones
	int        m_IRQ_enable, m_IRQ_enable_latch;
	UINT16     m_IRQ_count, m_IRQ_count_latch;
	UINT8      m_IRQ_toggle;
	UINT8      m_IRQ_reset;
	UINT8      m_IRQ_status;
	UINT8      m_IRQ_mode;
	UINT8      m_IRQ_clear;
	int        m_mult1, m_mult2;

	UINT8 m_mmc_chr_source;			// This is set at init to CHRROM or CHRRAM. a few mappers can swap between
									// the two (this is done in the specific handlers).

	UINT8 m_mmc_cmd1, m_mmc_cmd2;		// These represent registers where the mapper writes important values
	UINT8 m_mmc_count;				// This is used as counter in mappers like 1 and 45

	int m_mmc_prg_base, m_mmc_prg_mask;	// MMC3 based multigame carts select a block of banks by using these (and then act like normal MMC3),
	int m_mmc_chr_base, m_mmc_chr_mask;	// while MMC3 and clones (mapper 118 & 119) simply set them as 0 and 0xff resp.

	UINT8 m_mmc_prg_bank[6];				// Many mappers writes only some bits of the selected bank (for both PRG and CHR),
	UINT8 m_mmc_vrom_bank[16];			// hence these are handy to latch bank values.

	UINT16 m_MMC5_vrom_bank[12];			// MMC5 has 10bit wide VROM regs!
	UINT8 m_mmc_extra_bank[16];			// some MMC3 clone have 2 series of PRG/CHR banks...
										// we collect them all here: first 4 elements PRG banks, then 6/8 CHR banks

	UINT8 m_mmc_latch1, m_mmc_latch2;
	UINT8 m_mmc_reg[16];

	UINT8 m_mmc_dipsetting;

	// misc mapper related variables which should be merged with the above one, where possible
	int m_mmc1_reg_write_enable;
	int m_mmc1_latch;
	int m_mmc1_count;

	int m_mmc3_latch;
	int m_mmc3_wram_protect;
	int m_mmc3_alt_irq;

	int m_MMC5_rom_bank_mode;
	int m_MMC5_vrom_bank_mode;
	int m_MMC5_vram_protect;
	int m_MMC5_scanline;
	int m_vrom_page_a;
	int m_vrom_page_b;
	// int vrom_next[4];

	UINT8 m_mmc6_reg;

	// these might be unified in single mmc_reg[] array, together with state->m_mmc_cmd1 & state->m_mmc_cmd2
	// but be careful that MMC3 clones often use state->m_mmc_cmd1/state->m_mmc_cmd2 (from base MMC3) AND additional regs below!
	UINT8 m_mapper83_reg[10];
	UINT8 m_mapper83_low_reg[4];
	UINT8 m_txc_reg[4];	// used by mappers 132, 172 & 173
	UINT8 m_subor_reg[4];	// used by mappers 166 & 167
	UINT8 m_sachen_reg[8];	// used by mappers 137, 138, 139 & 141
	UINT8 m_map52_reg_written;
	UINT8 m_map114_reg, m_map114_reg_enabled;

	/***** NES-cart related *****/

	/* load-time cart variables which remain constant */
	UINT16 m_prg_chunks;		// iNES 2.0 allows for more chunks (a recently dumped multigame cart has 256 chunks of both PRG & CHR!)
	UINT16 m_chr_chunks;
	UINT16 m_vram_chunks;
	UINT8 m_trainer;
	UINT8 m_battery;			// if there is PRG RAM with battery backup
	UINT32 m_battery_size;
	UINT8 m_prg_ram;			// if there is PRG RAM with no backup
	UINT32 m_wram_size;
	UINT32 m_mapper_ram_size;
	UINT32 m_mapper_bram_size;

	/* system variables which don't change at run-time */
	UINT16 m_mapper;		// for iNES
	UINT16 m_pcb_id;		// for UNIF & xml
	UINT8 m_four_screen_vram;
	UINT8 m_hard_mirroring;
	UINT8 m_crc_hack;	// this is needed to detect different boards sharing the same Mappers (shame on .nes format)
	UINT8 m_ines20;

	/***** FDS-floppy related *****/

	int     m_disk_expansion;

	UINT8   m_fds_sides;
	UINT8   *m_fds_data;	// here, we store a copy of the disk
	UINT8   *m_fds_ram;	// here, we emulate the RAM adapter

	/* Variables which can change */
	UINT8   m_fds_motor_on;
	UINT8   m_fds_door_closed;
	UINT8   m_fds_current_side;
	UINT32  m_fds_head_position;
	UINT8   m_fds_status0;
	UINT8   m_fds_read_mode;
	UINT8   m_fds_write_reg;

	/* these are used in the mapper 20 handlers */
	int     m_fds_last_side;
	int     m_fds_count;
	DECLARE_READ8_MEMBER(nes_IN0_r);
	DECLARE_READ8_MEMBER(nes_IN1_r);
	DECLARE_WRITE8_MEMBER(nes_IN0_w);
	DECLARE_WRITE8_MEMBER(nes_IN1_w);
	DECLARE_READ8_MEMBER(nes_fds_r);
	DECLARE_WRITE8_MEMBER(nes_fds_w);
	DECLARE_WRITE8_MEMBER(nes_vh_sprite_dma_w);
	DECLARE_DRIVER_INIT(famicom);
};


/*----------- defined in machine/nes.c -----------*/


/* protos */

DEVICE_IMAGE_LOAD(nes_cart);
DEVICE_START(nes_disk);
DEVICE_IMAGE_LOAD(nes_disk);
DEVICE_IMAGE_UNLOAD(nes_disk);

MACHINE_START( nes );
MACHINE_RESET( nes );



int nes_ppu_vidaccess( device_t *device, int address, int data );

void nes_partialhash(hash_collection &dest, const unsigned char *data, unsigned long length, const char *functions);

/*----------- defined in video/nes.c -----------*/

PALETTE_INIT( nes );
VIDEO_START( nes );
SCREEN_UPDATE_IND16( nes );


#endif /* NES_H_ */