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