User | Revision | Line number | New contents of line |
beaglescout007 |
0:3dac1f1bc9e0
|
1
|
/*===================================================================*/
|
beaglescout007 |
0:3dac1f1bc9e0
|
2
|
/* */
|
beaglescout007 |
0:3dac1f1bc9e0
|
3
|
/* K6502_RW.h : 6502 Reading/Writing Operation for NES */
|
beaglescout007 |
0:3dac1f1bc9e0
|
4
|
/* This file is included in K6502.cpp */
|
beaglescout007 |
0:3dac1f1bc9e0
|
5
|
/* */
|
beaglescout007 |
0:3dac1f1bc9e0
|
6
|
/* 1999/11/03 Racoon New preparation */
|
beaglescout007 |
0:3dac1f1bc9e0
|
7
|
/* */
|
beaglescout007 |
0:3dac1f1bc9e0
|
8
|
/*===================================================================*/
|
beaglescout007 |
0:3dac1f1bc9e0
|
9
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
10
|
#ifndef K6502_RW_H_INCLUDED
|
beaglescout007 |
0:3dac1f1bc9e0
|
11
|
#define K6502_RW_H_INCLUDED
|
beaglescout007 |
0:3dac1f1bc9e0
|
12
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
13
|
/*-------------------------------------------------------------------*/
|
beaglescout007 |
0:3dac1f1bc9e0
|
14
|
/* Include files */
|
beaglescout007 |
0:3dac1f1bc9e0
|
15
|
/*-------------------------------------------------------------------*/
|
beaglescout007 |
0:3dac1f1bc9e0
|
16
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
17
|
#include "pNesX.h"
|
beaglescout007 |
0:3dac1f1bc9e0
|
18
|
#include "pNesX_System.h"
|
beaglescout007 |
0:3dac1f1bc9e0
|
19
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
20
|
/*===================================================================*/
|
beaglescout007 |
0:3dac1f1bc9e0
|
21
|
/* */
|
beaglescout007 |
0:3dac1f1bc9e0
|
22
|
/* K6502_ReadZp() : Reading from the zero page */
|
beaglescout007 |
0:3dac1f1bc9e0
|
23
|
/* */
|
beaglescout007 |
0:3dac1f1bc9e0
|
24
|
/*===================================================================*/
|
beaglescout007 |
0:3dac1f1bc9e0
|
25
|
static inline BYTE K6502_ReadZp( BYTE byAddr )
|
beaglescout007 |
0:3dac1f1bc9e0
|
26
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
27
|
/*
|
beaglescout007 |
0:3dac1f1bc9e0
|
28
|
* Reading from the zero page
|
beaglescout007 |
0:3dac1f1bc9e0
|
29
|
*
|
beaglescout007 |
0:3dac1f1bc9e0
|
30
|
* Parameters
|
beaglescout007 |
0:3dac1f1bc9e0
|
31
|
* BYTE byAddr (Read)
|
beaglescout007 |
0:3dac1f1bc9e0
|
32
|
* An address inside the zero page
|
beaglescout007 |
0:3dac1f1bc9e0
|
33
|
*
|
beaglescout007 |
0:3dac1f1bc9e0
|
34
|
* Return values
|
beaglescout007 |
0:3dac1f1bc9e0
|
35
|
* Read Data
|
beaglescout007 |
0:3dac1f1bc9e0
|
36
|
*/
|
beaglescout007 |
0:3dac1f1bc9e0
|
37
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
38
|
return RAM[ byAddr ];
|
beaglescout007 |
0:3dac1f1bc9e0
|
39
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
40
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
41
|
/*===================================================================*/
|
beaglescout007 |
0:3dac1f1bc9e0
|
42
|
/* */
|
beaglescout007 |
0:3dac1f1bc9e0
|
43
|
/* K6502_Read() : Reading operation */
|
beaglescout007 |
0:3dac1f1bc9e0
|
44
|
/* */
|
beaglescout007 |
0:3dac1f1bc9e0
|
45
|
/*===================================================================*/
|
beaglescout007 |
0:3dac1f1bc9e0
|
46
|
static inline BYTE K6502_Read( WORD wAddr )
|
beaglescout007 |
0:3dac1f1bc9e0
|
47
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
48
|
/*
|
beaglescout007 |
0:3dac1f1bc9e0
|
49
|
* Reading operation
|
beaglescout007 |
0:3dac1f1bc9e0
|
50
|
*
|
beaglescout007 |
0:3dac1f1bc9e0
|
51
|
* Parameters
|
beaglescout007 |
0:3dac1f1bc9e0
|
52
|
* WORD wAddr (Read)
|
beaglescout007 |
0:3dac1f1bc9e0
|
53
|
* Address to read
|
beaglescout007 |
0:3dac1f1bc9e0
|
54
|
*
|
beaglescout007 |
0:3dac1f1bc9e0
|
55
|
* Return values
|
beaglescout007 |
0:3dac1f1bc9e0
|
56
|
* Read data
|
beaglescout007 |
0:3dac1f1bc9e0
|
57
|
*
|
beaglescout007 |
0:3dac1f1bc9e0
|
58
|
* Remarks
|
beaglescout007 |
0:3dac1f1bc9e0
|
59
|
* 0x0000 - 0x1fff RAM ( 0x800 - 0x1fff is mirror of 0x0 - 0x7ff )
|
beaglescout007 |
0:3dac1f1bc9e0
|
60
|
* 0x2000 - 0x3fff PPU
|
beaglescout007 |
0:3dac1f1bc9e0
|
61
|
* 0x4000 - 0x5fff Sound
|
beaglescout007 |
0:3dac1f1bc9e0
|
62
|
* 0x6000 - 0x7fff SRAM ( Battery Backed )
|
beaglescout007 |
0:3dac1f1bc9e0
|
63
|
* 0x8000 - 0xffff ROM
|
beaglescout007 |
0:3dac1f1bc9e0
|
64
|
*
|
beaglescout007 |
0:3dac1f1bc9e0
|
65
|
*/
|
beaglescout007 |
0:3dac1f1bc9e0
|
66
|
BYTE byRet;
|
beaglescout007 |
0:3dac1f1bc9e0
|
67
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
68
|
switch ( wAddr & 0xe000 )
|
beaglescout007 |
0:3dac1f1bc9e0
|
69
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
70
|
case 0x0000: /* RAM */
|
beaglescout007 |
0:3dac1f1bc9e0
|
71
|
return RAM[ wAddr & 0x7ff ];
|
beaglescout007 |
0:3dac1f1bc9e0
|
72
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
73
|
case 0x2000: /* PPU */
|
beaglescout007 |
0:3dac1f1bc9e0
|
74
|
if ( wAddr <= 0x2006 ) /* PPU Status */
|
beaglescout007 |
0:3dac1f1bc9e0
|
75
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
76
|
// Set return value
|
beaglescout007 |
0:3dac1f1bc9e0
|
77
|
byRet = PPU_R2;
|
beaglescout007 |
0:3dac1f1bc9e0
|
78
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
79
|
// Reset a V-Blank flag
|
beaglescout007 |
0:3dac1f1bc9e0
|
80
|
PPU_R2 &= ~R2_IN_VBLANK;
|
beaglescout007 |
0:3dac1f1bc9e0
|
81
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
82
|
// Reset address latch
|
beaglescout007 |
0:3dac1f1bc9e0
|
83
|
PPU_Latch_Flag = 0;
|
beaglescout007 |
0:3dac1f1bc9e0
|
84
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
85
|
// Make a Nametable 0 in V-Blank
|
beaglescout007 |
0:3dac1f1bc9e0
|
86
|
if ( PPU_Scanline >= SCAN_VBLANK_START && !( PPU_R0 & R0_NMI_VB ) )
|
beaglescout007 |
0:3dac1f1bc9e0
|
87
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
88
|
PPU_R0 &= ~R0_NAME_ADDR;
|
beaglescout007 |
0:3dac1f1bc9e0
|
89
|
PPU_NameTableBank = NAME_TABLE0;
|
beaglescout007 |
0:3dac1f1bc9e0
|
90
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
91
|
return byRet;
|
beaglescout007 |
0:3dac1f1bc9e0
|
92
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
93
|
else
|
beaglescout007 |
0:3dac1f1bc9e0
|
94
|
if ( wAddr == 0x2007 ) /* PPU Memory */
|
beaglescout007 |
0:3dac1f1bc9e0
|
95
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
96
|
// Set return value;
|
beaglescout007 |
0:3dac1f1bc9e0
|
97
|
byRet = PPU_R7;
|
beaglescout007 |
0:3dac1f1bc9e0
|
98
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
99
|
// Read PPU Memory
|
beaglescout007 |
0:3dac1f1bc9e0
|
100
|
PPU_R7 = PPUBANK[ PPU_Addr >> 10 ][ PPU_Addr & 0x3ff ];
|
beaglescout007 |
0:3dac1f1bc9e0
|
101
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
102
|
// Increment PPU Address
|
beaglescout007 |
0:3dac1f1bc9e0
|
103
|
PPU_Addr += PPU_Increment;
|
beaglescout007 |
0:3dac1f1bc9e0
|
104
|
PPU_Addr &= 0x3fff;
|
beaglescout007 |
0:3dac1f1bc9e0
|
105
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
106
|
return byRet;
|
beaglescout007 |
0:3dac1f1bc9e0
|
107
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
108
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
109
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
110
|
case 0x4000: /* Sound */
|
beaglescout007 |
0:3dac1f1bc9e0
|
111
|
if ( wAddr < 0x4016 )
|
beaglescout007 |
0:3dac1f1bc9e0
|
112
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
113
|
// Return APU Register
|
beaglescout007 |
0:3dac1f1bc9e0
|
114
|
//return APU_Reg[ wAddr & 0x1f ];
|
beaglescout007 |
0:3dac1f1bc9e0
|
115
|
return ApuRead( wAddr & 0x1f );
|
beaglescout007 |
0:3dac1f1bc9e0
|
116
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
117
|
else
|
beaglescout007 |
0:3dac1f1bc9e0
|
118
|
if ( wAddr == 0x4016 )
|
beaglescout007 |
0:3dac1f1bc9e0
|
119
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
120
|
// Set Joypad1 data
|
beaglescout007 |
0:3dac1f1bc9e0
|
121
|
byRet = (BYTE)( ( PAD1_Latch >> PAD1_Bit ) & 1 ) | 0x40;
|
beaglescout007 |
0:3dac1f1bc9e0
|
122
|
PAD1_Bit = ( PAD1_Bit == 23 ) ? 0 : ( PAD1_Bit + 1 );
|
beaglescout007 |
0:3dac1f1bc9e0
|
123
|
return byRet;
|
beaglescout007 |
0:3dac1f1bc9e0
|
124
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
125
|
else
|
beaglescout007 |
0:3dac1f1bc9e0
|
126
|
if ( wAddr == 0x4017 )
|
beaglescout007 |
0:3dac1f1bc9e0
|
127
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
128
|
// Set Joypad2 data
|
beaglescout007 |
0:3dac1f1bc9e0
|
129
|
byRet = (BYTE)( ( PAD2_Latch >> PAD2_Bit ) & 1 ) | 0x40;
|
beaglescout007 |
0:3dac1f1bc9e0
|
130
|
PAD2_Bit = ( PAD2_Bit == 23 ) ? 0 : ( PAD2_Bit + 1 );
|
beaglescout007 |
0:3dac1f1bc9e0
|
131
|
return byRet;
|
beaglescout007 |
0:3dac1f1bc9e0
|
132
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
133
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
134
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
135
|
case 0x6000: /* SRAM */
|
beaglescout007 |
0:3dac1f1bc9e0
|
136
|
return SRAM[ wAddr & 0x1fff ];
|
beaglescout007 |
0:3dac1f1bc9e0
|
137
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
138
|
case 0x8000: /* ROM BANK 0 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
139
|
return ROMBANK0[ wAddr & 0x1fff ];
|
beaglescout007 |
0:3dac1f1bc9e0
|
140
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
141
|
case 0xa000: /* ROM BANK 1 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
142
|
return ROMBANK1[ wAddr & 0x1fff ];
|
beaglescout007 |
0:3dac1f1bc9e0
|
143
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
144
|
case 0xc000: /* ROM BANK 2 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
145
|
return ROMBANK2[ wAddr & 0x1fff ];
|
beaglescout007 |
0:3dac1f1bc9e0
|
146
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
147
|
case 0xe000: /* ROM BANK 3 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
148
|
return ROMBANK3[ wAddr & 0x1fff ];
|
beaglescout007 |
0:3dac1f1bc9e0
|
149
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
150
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
151
|
return 0;
|
beaglescout007 |
0:3dac1f1bc9e0
|
152
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
153
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
154
|
/*===================================================================*/
|
beaglescout007 |
0:3dac1f1bc9e0
|
155
|
/* */
|
beaglescout007 |
0:3dac1f1bc9e0
|
156
|
/* K6502_Write() : Writing operation */
|
beaglescout007 |
0:3dac1f1bc9e0
|
157
|
/* */
|
beaglescout007 |
0:3dac1f1bc9e0
|
158
|
/*===================================================================*/
|
beaglescout007 |
0:3dac1f1bc9e0
|
159
|
static inline void K6502_Write( WORD wAddr, BYTE byData )
|
beaglescout007 |
0:3dac1f1bc9e0
|
160
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
161
|
/*
|
beaglescout007 |
0:3dac1f1bc9e0
|
162
|
* Writing operation
|
beaglescout007 |
0:3dac1f1bc9e0
|
163
|
*
|
beaglescout007 |
0:3dac1f1bc9e0
|
164
|
* Parameters
|
beaglescout007 |
0:3dac1f1bc9e0
|
165
|
* WORD wAddr (Read)
|
beaglescout007 |
0:3dac1f1bc9e0
|
166
|
* Address to write
|
beaglescout007 |
0:3dac1f1bc9e0
|
167
|
*
|
beaglescout007 |
0:3dac1f1bc9e0
|
168
|
* BYTE byData (Read)
|
beaglescout007 |
0:3dac1f1bc9e0
|
169
|
* Data to write
|
beaglescout007 |
0:3dac1f1bc9e0
|
170
|
*
|
beaglescout007 |
0:3dac1f1bc9e0
|
171
|
* Remarks
|
beaglescout007 |
0:3dac1f1bc9e0
|
172
|
* 0x0000 - 0x1fff RAM ( 0x800 - 0x1fff is mirror of 0x0 - 0x7ff )
|
beaglescout007 |
0:3dac1f1bc9e0
|
173
|
* 0x2000 - 0x3fff PPU
|
beaglescout007 |
0:3dac1f1bc9e0
|
174
|
* 0x4000 - 0x5fff Sound
|
beaglescout007 |
0:3dac1f1bc9e0
|
175
|
* 0x6000 - 0x7fff SRAM ( Battery Backed )
|
beaglescout007 |
0:3dac1f1bc9e0
|
176
|
* 0x8000 - 0xffff ROM
|
beaglescout007 |
0:3dac1f1bc9e0
|
177
|
*
|
beaglescout007 |
0:3dac1f1bc9e0
|
178
|
*/
|
beaglescout007 |
0:3dac1f1bc9e0
|
179
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
180
|
switch ( wAddr & 0xe000 )
|
beaglescout007 |
0:3dac1f1bc9e0
|
181
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
182
|
case 0x0000: /* RAM */
|
beaglescout007 |
0:3dac1f1bc9e0
|
183
|
RAM[ wAddr & 0x7ff ] = byData;
|
beaglescout007 |
0:3dac1f1bc9e0
|
184
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
185
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
186
|
case 0x2000: /* PPU */
|
beaglescout007 |
0:3dac1f1bc9e0
|
187
|
switch ( wAddr & 0x7 )
|
beaglescout007 |
0:3dac1f1bc9e0
|
188
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
189
|
case 0: /* 0x2000 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
190
|
PPU_R0 = byData;
|
beaglescout007 |
0:3dac1f1bc9e0
|
191
|
PPU_Increment = ( PPU_R0 & R0_INC_ADDR ) ? 32 : 1;
|
beaglescout007 |
0:3dac1f1bc9e0
|
192
|
PPU_NameTableBank = NAME_TABLE0 + ( PPU_R0 & R0_NAME_ADDR );
|
beaglescout007 |
0:3dac1f1bc9e0
|
193
|
PPU_BG_Base = ( PPU_R0 & R0_BG_ADDR ) ? ChrBuf + 256 * 64 : ChrBuf;
|
beaglescout007 |
0:3dac1f1bc9e0
|
194
|
PPU_SP_Base = ( PPU_R0 & R0_SP_ADDR ) ? ChrBuf + 256 * 64 : ChrBuf;
|
beaglescout007 |
0:3dac1f1bc9e0
|
195
|
PPU_SP_Height = ( PPU_R0 & R0_SP_SIZE ) ? 16 : 8;
|
beaglescout007 |
0:3dac1f1bc9e0
|
196
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
197
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
198
|
case 1: /* 0x2001 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
199
|
PPU_R1 = byData;
|
beaglescout007 |
0:3dac1f1bc9e0
|
200
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
201
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
202
|
case 2: /* 0x2002 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
203
|
PPU_R2 = byData;
|
beaglescout007 |
0:3dac1f1bc9e0
|
204
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
205
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
206
|
case 3: /* 0x2003 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
207
|
// Sprite RAM Address
|
beaglescout007 |
0:3dac1f1bc9e0
|
208
|
PPU_R3 = byData;
|
beaglescout007 |
0:3dac1f1bc9e0
|
209
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
210
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
211
|
case 4: /* 0x2004 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
212
|
// Write data to Sprite RAM
|
beaglescout007 |
0:3dac1f1bc9e0
|
213
|
SPRRAM[ PPU_R3++ ] = byData;
|
beaglescout007 |
0:3dac1f1bc9e0
|
214
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
215
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
216
|
case 5: /* 0x2005 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
217
|
// Set Scroll Register
|
beaglescout007 |
0:3dac1f1bc9e0
|
218
|
if ( PPU_Latch_Flag )
|
beaglescout007 |
0:3dac1f1bc9e0
|
219
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
220
|
// V-Scroll Register
|
beaglescout007 |
0:3dac1f1bc9e0
|
221
|
PPU_Scr_V_Next = ( byData > 239 ) ? 0 : byData;
|
beaglescout007 |
0:3dac1f1bc9e0
|
222
|
PPU_Scr_V_Byte_Next = PPU_Scr_V_Next >> 3;
|
beaglescout007 |
0:3dac1f1bc9e0
|
223
|
PPU_Scr_V_Bit_Next = PPU_Scr_V_Next & 7;
|
beaglescout007 |
0:3dac1f1bc9e0
|
224
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
225
|
else
|
beaglescout007 |
0:3dac1f1bc9e0
|
226
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
227
|
// H-Scroll Register
|
beaglescout007 |
0:3dac1f1bc9e0
|
228
|
PPU_Scr_H_Next = byData;
|
beaglescout007 |
0:3dac1f1bc9e0
|
229
|
PPU_Scr_H_Byte_Next = PPU_Scr_H_Next >> 3;
|
beaglescout007 |
0:3dac1f1bc9e0
|
230
|
PPU_Scr_H_Bit_Next = PPU_Scr_H_Next & 7;
|
beaglescout007 |
0:3dac1f1bc9e0
|
231
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
232
|
PPU_Latch_Flag ^= 1;
|
beaglescout007 |
0:3dac1f1bc9e0
|
233
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
234
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
235
|
case 6: /* 0x2006 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
236
|
// Set PPU Address
|
beaglescout007 |
0:3dac1f1bc9e0
|
237
|
if ( PPU_Latch_Flag )
|
beaglescout007 |
0:3dac1f1bc9e0
|
238
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
239
|
// Low
|
beaglescout007 |
0:3dac1f1bc9e0
|
240
|
PPU_Addr |= byData;
|
beaglescout007 |
0:3dac1f1bc9e0
|
241
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
242
|
else
|
beaglescout007 |
0:3dac1f1bc9e0
|
243
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
244
|
// High
|
beaglescout007 |
0:3dac1f1bc9e0
|
245
|
PPU_Addr = ( byData & 0x3f ) << 8;
|
beaglescout007 |
0:3dac1f1bc9e0
|
246
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
247
|
PPU_Latch_Flag ^= 1;
|
beaglescout007 |
0:3dac1f1bc9e0
|
248
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
249
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
250
|
case 7: /* 0x2007 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
251
|
// Write to PPU Memory
|
beaglescout007 |
0:3dac1f1bc9e0
|
252
|
if ( PPU_Addr < 0x2000 && NesHeader.byVRomSize == 0 )
|
beaglescout007 |
0:3dac1f1bc9e0
|
253
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
254
|
// Pattern Data
|
beaglescout007 |
0:3dac1f1bc9e0
|
255
|
ChrBufUpdate |= ( 1 << ( PPU_Addr >> 10 ) );
|
beaglescout007 |
0:3dac1f1bc9e0
|
256
|
PPURAM[ PPU_Addr ] = byData;
|
beaglescout007 |
0:3dac1f1bc9e0
|
257
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
258
|
else
|
beaglescout007 |
0:3dac1f1bc9e0
|
259
|
if ( PPU_Addr < 0x3f00 ) /* 0x2000 - 0x3eff */
|
beaglescout007 |
0:3dac1f1bc9e0
|
260
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
261
|
// Name Table
|
beaglescout007 |
0:3dac1f1bc9e0
|
262
|
PPUBANK[ PPU_Addr >> 10 ][ PPU_Addr & 0x3ff ] = byData;
|
beaglescout007 |
0:3dac1f1bc9e0
|
263
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
264
|
else
|
beaglescout007 |
0:3dac1f1bc9e0
|
265
|
if ( !( PPU_Addr & 0xf ) ) /* 0x3f00 or 0x3f10 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
266
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
267
|
// Palette mirror
|
beaglescout007 |
0:3dac1f1bc9e0
|
268
|
PPURAM[ 0x3f10 ] = PPURAM[ 0x3f14 ] = PPURAM[ 0x3f18 ] = PPURAM[ 0x3f1c ] =
|
beaglescout007 |
0:3dac1f1bc9e0
|
269
|
PPURAM[ 0x3f00 ] = PPURAM[ 0x3f04 ] = PPURAM[ 0x3f08 ] = PPURAM[ 0x3f0c ] = byData;
|
beaglescout007 |
0:3dac1f1bc9e0
|
270
|
PalTable[ 0x00 ] = PalTable[ 0x04 ] = PalTable[ 0x08 ] = PalTable[ 0x0c ] =
|
beaglescout007 |
0:3dac1f1bc9e0
|
271
|
PalTable[ 0x10 ] = PalTable[ 0x14 ] = PalTable[ 0x18 ] = PalTable[ 0x1c ] = NesPalette[ byData ]; // | 0x8000;
|
beaglescout007 |
0:3dac1f1bc9e0
|
272
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
273
|
else
|
beaglescout007 |
0:3dac1f1bc9e0
|
274
|
if ( PPU_Addr & 3 )
|
beaglescout007 |
0:3dac1f1bc9e0
|
275
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
276
|
// Palette
|
beaglescout007 |
0:3dac1f1bc9e0
|
277
|
PPURAM[ PPU_Addr ] = byData;
|
beaglescout007 |
0:3dac1f1bc9e0
|
278
|
PalTable[ PPU_Addr & 0x1f ] = NesPalette[ byData ];
|
beaglescout007 |
0:3dac1f1bc9e0
|
279
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
280
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
281
|
// Increment PPU Address
|
beaglescout007 |
0:3dac1f1bc9e0
|
282
|
PPU_Addr += PPU_Increment;
|
beaglescout007 |
0:3dac1f1bc9e0
|
283
|
PPU_Addr &= 0x3fff;
|
beaglescout007 |
0:3dac1f1bc9e0
|
284
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
285
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
286
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
287
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
288
|
case 0x4000: /* Sound */
|
beaglescout007 |
0:3dac1f1bc9e0
|
289
|
switch ( wAddr & 0x1f )
|
beaglescout007 |
0:3dac1f1bc9e0
|
290
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
291
|
case 0x14: /* 0x4014 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
292
|
// Sprite DMA
|
beaglescout007 |
0:3dac1f1bc9e0
|
293
|
switch ( byData >> 5 )
|
beaglescout007 |
0:3dac1f1bc9e0
|
294
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
295
|
case 0x0: /* RAM */
|
beaglescout007 |
0:3dac1f1bc9e0
|
296
|
pNesX_MemoryCopy( SPRRAM, &RAM[ ( (WORD)byData << 8 ) & 0x7ff ], SPRRAM_SIZE );
|
beaglescout007 |
0:3dac1f1bc9e0
|
297
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
298
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
299
|
case 0x3: /* SRAM */
|
beaglescout007 |
0:3dac1f1bc9e0
|
300
|
pNesX_MemoryCopy( SPRRAM, &SRAM[ ( (WORD)byData << 8 ) & 0x1fff ], SPRRAM_SIZE );
|
beaglescout007 |
0:3dac1f1bc9e0
|
301
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
302
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
303
|
case 0x4: /* ROM BANK 0 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
304
|
pNesX_MemoryCopy( SPRRAM, &ROMBANK0[ ( (WORD)byData << 8 ) & 0x1fff ], SPRRAM_SIZE );
|
beaglescout007 |
0:3dac1f1bc9e0
|
305
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
306
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
307
|
case 0x5: /* ROM BANK 1 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
308
|
pNesX_MemoryCopy( SPRRAM, &ROMBANK1[ ( (WORD)byData << 8 ) & 0x1fff ], SPRRAM_SIZE );
|
beaglescout007 |
0:3dac1f1bc9e0
|
309
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
310
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
311
|
case 0x6: /* ROM BANK 2 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
312
|
pNesX_MemoryCopy( SPRRAM, &ROMBANK2[ ( (WORD)byData << 8 ) & 0x1fff ], SPRRAM_SIZE );
|
beaglescout007 |
0:3dac1f1bc9e0
|
313
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
314
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
315
|
case 0x7: /* ROM BANK 3 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
316
|
pNesX_MemoryCopy( SPRRAM, &ROMBANK3[ ( (WORD)byData << 8 ) & 0x1fff ], SPRRAM_SIZE );
|
beaglescout007 |
0:3dac1f1bc9e0
|
317
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
318
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
319
|
APU_Reg[ 0x14 ] = byData;
|
beaglescout007 |
0:3dac1f1bc9e0
|
320
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
321
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
322
|
case 0x16: /* 0x4016 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
323
|
// Reset joypad
|
beaglescout007 |
0:3dac1f1bc9e0
|
324
|
if ( !( APU_Reg[ 0x16 ] & 1 ) && ( byData & 1 ) )
|
beaglescout007 |
0:3dac1f1bc9e0
|
325
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
326
|
PAD1_Bit = 0;
|
beaglescout007 |
0:3dac1f1bc9e0
|
327
|
PAD2_Bit = 0;
|
beaglescout007 |
0:3dac1f1bc9e0
|
328
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
329
|
APU_Reg[ 0x16 ] = byData;
|
beaglescout007 |
0:3dac1f1bc9e0
|
330
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
331
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
332
|
default:
|
beaglescout007 |
0:3dac1f1bc9e0
|
333
|
if ( wAddr <= 0x4017 )
|
beaglescout007 |
0:3dac1f1bc9e0
|
334
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
335
|
// Write to APU Register
|
beaglescout007 |
0:3dac1f1bc9e0
|
336
|
ApuWrite( wAddr & 0x1f, byData );
|
beaglescout007 |
0:3dac1f1bc9e0
|
337
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
338
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
339
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
340
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
341
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
342
|
case 0x6000: /* SRAM */
|
beaglescout007 |
0:3dac1f1bc9e0
|
343
|
SRAM[ wAddr & 0x1fff ] = byData;
|
beaglescout007 |
0:3dac1f1bc9e0
|
344
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
345
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
346
|
case 0x8000: /* ROM BANK 0 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
347
|
case 0xa000: /* ROM BANK 1 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
348
|
case 0xc000: /* ROM BANK 2 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
349
|
case 0xe000: /* ROM BANK 3 */
|
beaglescout007 |
0:3dac1f1bc9e0
|
350
|
// Write to Mapper
|
beaglescout007 |
0:3dac1f1bc9e0
|
351
|
MapperWrite( wAddr, byData );
|
beaglescout007 |
0:3dac1f1bc9e0
|
352
|
break;
|
beaglescout007 |
0:3dac1f1bc9e0
|
353
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
354
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
355
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
356
|
// Reading/Writing operation (WORD version)
|
beaglescout007 |
0:3dac1f1bc9e0
|
357
|
static inline WORD K6502_ReadW( WORD wAddr ){ return K6502_Read( wAddr ) | (WORD)K6502_Read( wAddr + 1 ) << 8; };
|
beaglescout007 |
0:3dac1f1bc9e0
|
358
|
static inline void K6502_WriteW( WORD wAddr, WORD wData ){ K6502_Write( wAddr, wData & 0xff ); K6502_Write( wAddr + 1, wData >> 8 ); };
|
beaglescout007 |
0:3dac1f1bc9e0
|
359
|
static inline WORD K6502_ReadZpW( BYTE byAddr ){ return K6502_ReadZp( byAddr ) | ( K6502_ReadZp( byAddr + 1 ) << 8 ); };
|
beaglescout007 |
0:3dac1f1bc9e0
|
360
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
361
|
#endif /* !K6502_RW_H_INCLUDED */
|
beaglescout007 |
0:3dac1f1bc9e0
|
362
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
363
|
|