I have ported my old project “pNesX” game console emulator to the nucleo.

Dependencies:   SDFileSystem mbed

Intro

I have ported my old project “pNesX” to the STM32 Nucleo. The pNesX is a NES emulator for the PlayStation that I have created 16 years ago!

Emulation part was almost without change, the sound part was newly added.

Parts

STM32 Nucleo F446RE
QVGA 2.2 TFT SPI (with the SD card slot)
Audio jack(TS or TRS)
USB Connector
Register 100k, 10k, 4.7k, 100
Capacitor 0.01uF, 2.2uF
Breadboard
Wires
Computer Speakers
USB GamePad

Wiring diagram

/media/uploads/beaglescout007/nucleo_ex06_emu.png

TFT J2Nucleo
VCC3V3
GNDGND
CSPB_5(D4)
ResetPA_10(D2) Pull Up(100k)
D/CPA_8(D7)
MOSIPA_7(D11)
SCKPA_5(D13)
LEDLED-100ohm-3V3
MISOPA_6(D12)
TFT J4Nucleo
SD_CSPA_9
SD_MOSIPB_15
SD_MISOPB_14
SD_SCKPB_13
AudioNucleo
TIPPA_4(A2)
USB con.Nucleo
GNDGND
+PA_12
-PA_11
5V5V

https://youtu.be/jL24IjT6LnI

Limitations

  • Since the rest of the RAM is about 50kbyte, maximum capacity of the game ROM is about 50kbyte.
  • The length of the file name up to 32 characters.
  • The number of files in the folder is up to 100.

Used Library

Committer:
beaglescout007
Date:
Sun Apr 03 07:45:29 2016 +0000
Revision:
0:3dac1f1bc9e0
Release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
beaglescout007 0:3dac1f1bc9e0 1 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 2 /* */
beaglescout007 0:3dac1f1bc9e0 3 /* pNesX_System_Nucleo.cpp : The function which depends on a system */
beaglescout007 0:3dac1f1bc9e0 4 /* (for Nucleo F446RE) */
beaglescout007 0:3dac1f1bc9e0 5 /* */
beaglescout007 0:3dac1f1bc9e0 6 /* 2016/1/20 Racoon */
beaglescout007 0:3dac1f1bc9e0 7 /* */
beaglescout007 0:3dac1f1bc9e0 8 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 9
beaglescout007 0:3dac1f1bc9e0 10 /*-------------------------------------------------------------------*/
beaglescout007 0:3dac1f1bc9e0 11 /* Include files */
beaglescout007 0:3dac1f1bc9e0 12 /*-------------------------------------------------------------------*/
beaglescout007 0:3dac1f1bc9e0 13
beaglescout007 0:3dac1f1bc9e0 14 #include "mbed.h"
beaglescout007 0:3dac1f1bc9e0 15 #include "SDFileSystem.h"
beaglescout007 0:3dac1f1bc9e0 16 #include "tft.h"
beaglescout007 0:3dac1f1bc9e0 17
beaglescout007 0:3dac1f1bc9e0 18 //#define PS_GAMEPAD
beaglescout007 0:3dac1f1bc9e0 19
beaglescout007 0:3dac1f1bc9e0 20 #if !defined(PS_GAMEPAD)
beaglescout007 0:3dac1f1bc9e0 21 #include "USBHostGamepad.h"
beaglescout007 0:3dac1f1bc9e0 22 USBHostGamepad *pad;
beaglescout007 0:3dac1f1bc9e0 23 #else
beaglescout007 0:3dac1f1bc9e0 24 #include "pspad.h"
beaglescout007 0:3dac1f1bc9e0 25 #endif
beaglescout007 0:3dac1f1bc9e0 26
beaglescout007 0:3dac1f1bc9e0 27 #include "pNesX.h"
beaglescout007 0:3dac1f1bc9e0 28 #include "pNesX_System.h"
beaglescout007 0:3dac1f1bc9e0 29
beaglescout007 0:3dac1f1bc9e0 30 extern int pNesX_Filer();
beaglescout007 0:3dac1f1bc9e0 31 extern void ApuMute(bool mute);
beaglescout007 0:3dac1f1bc9e0 32
beaglescout007 0:3dac1f1bc9e0 33 SDFileSystem *sd; //(PB_15, PB_14, PB_13, PA_9, "sd", NC, SDFileSystem::SWITCH_NONE, 20000000);
beaglescout007 0:3dac1f1bc9e0 34
beaglescout007 0:3dac1f1bc9e0 35 DigitalIn userbutton(USER_BUTTON);
beaglescout007 0:3dac1f1bc9e0 36
beaglescout007 0:3dac1f1bc9e0 37 extern WORD LineData[][256];
beaglescout007 0:3dac1f1bc9e0 38 extern WORD *pDrawData;
beaglescout007 0:3dac1f1bc9e0 39
beaglescout007 0:3dac1f1bc9e0 40 //#define SHOW_FPS
beaglescout007 0:3dac1f1bc9e0 41
beaglescout007 0:3dac1f1bc9e0 42 #if defined(SHOW_FPS)
beaglescout007 0:3dac1f1bc9e0 43 Timer timer;
beaglescout007 0:3dac1f1bc9e0 44 int fps = 0;
beaglescout007 0:3dac1f1bc9e0 45 int dmawait;
beaglescout007 0:3dac1f1bc9e0 46 #endif
beaglescout007 0:3dac1f1bc9e0 47
beaglescout007 0:3dac1f1bc9e0 48 /*-------------------------------------------------------------------*/
beaglescout007 0:3dac1f1bc9e0 49 /* ROM image file information */
beaglescout007 0:3dac1f1bc9e0 50 /*-------------------------------------------------------------------*/
beaglescout007 0:3dac1f1bc9e0 51
beaglescout007 0:3dac1f1bc9e0 52 extern char szRomFolder[];
beaglescout007 0:3dac1f1bc9e0 53 extern char szRomFilename[];
beaglescout007 0:3dac1f1bc9e0 54 extern char szRomPath[];
beaglescout007 0:3dac1f1bc9e0 55
beaglescout007 0:3dac1f1bc9e0 56 char szRomName[ 256 ];
beaglescout007 0:3dac1f1bc9e0 57 char szSaveName[ 256 ];
beaglescout007 0:3dac1f1bc9e0 58 int nSRAM_SaveFlag;
beaglescout007 0:3dac1f1bc9e0 59
beaglescout007 0:3dac1f1bc9e0 60 // Palette data
beaglescout007 0:3dac1f1bc9e0 61 const WORD NesPalette[ 64 ] =
beaglescout007 0:3dac1f1bc9e0 62 {
beaglescout007 0:3dac1f1bc9e0 63 0xef7b,0x1f00,0x1700,0x5741,0x1090,0x04a8,0x80a8,0xa088,0x8051,0xc003,0x4003,0xc002,0x0b02,0x0000,0x0000,0x0000,
beaglescout007 0:3dac1f1bc9e0 64 0xf7bd,0xdf03,0xdf02,0x3f6a,0x19d8,0x0be0,0xc0f9,0xe2e2,0xe0ab,0xc005,0x4005,0x4805,0x5104,0x0000,0x0000,0x0000,
beaglescout007 0:3dac1f1bc9e0 65 0xdfff,0xff3d,0x5f6c,0xdf9b,0xdffb,0xd3fa,0xcbfb,0x08fd,0xc0fd,0xc3bf,0xca5e,0xd35f,0x5b07,0xcf7b,0x0000,0x0000,
beaglescout007 0:3dac1f1bc9e0 66 0xffff,0x3fa7,0xdfbd,0xdfdd,0xdffd,0x38fd,0x96f6,0x15ff,0xcffe,0xcfdf,0xd7bf,0xdbbf,0xff07,0xdffe,0x0000,0x0000
beaglescout007 0:3dac1f1bc9e0 67 };
beaglescout007 0:3dac1f1bc9e0 68
beaglescout007 0:3dac1f1bc9e0 69 /*-------------------------------------------------------------------*/
beaglescout007 0:3dac1f1bc9e0 70 /* Function prototypes */
beaglescout007 0:3dac1f1bc9e0 71 /*-------------------------------------------------------------------*/
beaglescout007 0:3dac1f1bc9e0 72
beaglescout007 0:3dac1f1bc9e0 73 int LoadSRAM();
beaglescout007 0:3dac1f1bc9e0 74 int SaveSRAM();
beaglescout007 0:3dac1f1bc9e0 75
beaglescout007 0:3dac1f1bc9e0 76 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 77 /* */
beaglescout007 0:3dac1f1bc9e0 78 /* LoadSRAM() : Load a SRAM */
beaglescout007 0:3dac1f1bc9e0 79 /* */
beaglescout007 0:3dac1f1bc9e0 80 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 81 int LoadSRAM()
beaglescout007 0:3dac1f1bc9e0 82 {
beaglescout007 0:3dac1f1bc9e0 83 /*
beaglescout007 0:3dac1f1bc9e0 84 * Load a SRAM
beaglescout007 0:3dac1f1bc9e0 85 *
beaglescout007 0:3dac1f1bc9e0 86 * Return values
beaglescout007 0:3dac1f1bc9e0 87 * 0 : Normally
beaglescout007 0:3dac1f1bc9e0 88 * -1 : SRAM data couldn't be read
beaglescout007 0:3dac1f1bc9e0 89 */
beaglescout007 0:3dac1f1bc9e0 90
beaglescout007 0:3dac1f1bc9e0 91 return 0;
beaglescout007 0:3dac1f1bc9e0 92 }
beaglescout007 0:3dac1f1bc9e0 93
beaglescout007 0:3dac1f1bc9e0 94 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 95 /* */
beaglescout007 0:3dac1f1bc9e0 96 /* SaveSRAM() : Save a SRAM */
beaglescout007 0:3dac1f1bc9e0 97 /* */
beaglescout007 0:3dac1f1bc9e0 98 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 99 int SaveSRAM()
beaglescout007 0:3dac1f1bc9e0 100 {
beaglescout007 0:3dac1f1bc9e0 101 /*
beaglescout007 0:3dac1f1bc9e0 102 * Save a SRAM
beaglescout007 0:3dac1f1bc9e0 103 *
beaglescout007 0:3dac1f1bc9e0 104 * Return values
beaglescout007 0:3dac1f1bc9e0 105 * 0 : Normally
beaglescout007 0:3dac1f1bc9e0 106 * -1 : SRAM data couldn't be written
beaglescout007 0:3dac1f1bc9e0 107 */
beaglescout007 0:3dac1f1bc9e0 108
beaglescout007 0:3dac1f1bc9e0 109
beaglescout007 0:3dac1f1bc9e0 110 // Successful
beaglescout007 0:3dac1f1bc9e0 111 return 0;
beaglescout007 0:3dac1f1bc9e0 112 }
beaglescout007 0:3dac1f1bc9e0 113
beaglescout007 0:3dac1f1bc9e0 114 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 115 /* */
beaglescout007 0:3dac1f1bc9e0 116 /* pNesX_Menu() : Menu screen */
beaglescout007 0:3dac1f1bc9e0 117 /* */
beaglescout007 0:3dac1f1bc9e0 118 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 119 int pNesX_Menu()
beaglescout007 0:3dac1f1bc9e0 120 {
beaglescout007 0:3dac1f1bc9e0 121 /*
beaglescout007 0:3dac1f1bc9e0 122 * Menu screen
beaglescout007 0:3dac1f1bc9e0 123 *
beaglescout007 0:3dac1f1bc9e0 124 * Return values
beaglescout007 0:3dac1f1bc9e0 125 * 0 : Normally
beaglescout007 0:3dac1f1bc9e0 126 * -1 : Exit pNesX
beaglescout007 0:3dac1f1bc9e0 127 */
beaglescout007 0:3dac1f1bc9e0 128
beaglescout007 0:3dac1f1bc9e0 129 #if defined(SHOW_FPS)
beaglescout007 0:3dac1f1bc9e0 130 timer.stop();
beaglescout007 0:3dac1f1bc9e0 131 #endif
beaglescout007 0:3dac1f1bc9e0 132
beaglescout007 0:3dac1f1bc9e0 133 ApuMute(true);
beaglescout007 0:3dac1f1bc9e0 134
beaglescout007 0:3dac1f1bc9e0 135 switch (pNesX_Filer())
beaglescout007 0:3dac1f1bc9e0 136 {
beaglescout007 0:3dac1f1bc9e0 137 case 0: // Selected a file
beaglescout007 0:3dac1f1bc9e0 138 if ( pNesX_Load( szRomPath ) == 0 )
beaglescout007 0:3dac1f1bc9e0 139 {
beaglescout007 0:3dac1f1bc9e0 140 // Set a ROM image name
beaglescout007 0:3dac1f1bc9e0 141 strcpy( szRomName, szRomFilename );
beaglescout007 0:3dac1f1bc9e0 142
beaglescout007 0:3dac1f1bc9e0 143 // Load SRAM
beaglescout007 0:3dac1f1bc9e0 144 LoadSRAM();
beaglescout007 0:3dac1f1bc9e0 145 }
beaglescout007 0:3dac1f1bc9e0 146 break;
beaglescout007 0:3dac1f1bc9e0 147
beaglescout007 0:3dac1f1bc9e0 148 case 1: // Return to Emu
beaglescout007 0:3dac1f1bc9e0 149 break;
beaglescout007 0:3dac1f1bc9e0 150
beaglescout007 0:3dac1f1bc9e0 151 case 2: // Reset
beaglescout007 0:3dac1f1bc9e0 152 if ( szRomName[ 0 ] != 0 )
beaglescout007 0:3dac1f1bc9e0 153 {
beaglescout007 0:3dac1f1bc9e0 154 // Reset pNesX
beaglescout007 0:3dac1f1bc9e0 155 pNesX_Reset();
beaglescout007 0:3dac1f1bc9e0 156 }
beaglescout007 0:3dac1f1bc9e0 157
beaglescout007 0:3dac1f1bc9e0 158 break;
beaglescout007 0:3dac1f1bc9e0 159
beaglescout007 0:3dac1f1bc9e0 160 case -1: // Error
beaglescout007 0:3dac1f1bc9e0 161 printf("Filer Error\r\n");
beaglescout007 0:3dac1f1bc9e0 162 while(1);
beaglescout007 0:3dac1f1bc9e0 163 }
beaglescout007 0:3dac1f1bc9e0 164
beaglescout007 0:3dac1f1bc9e0 165 tft_clear(TFT_BLACK);
beaglescout007 0:3dac1f1bc9e0 166 tft_set_window(32, 8, NES_DISP_WIDTH + 32 - 1, NES_DISP_HEIGHT + 8 - 1);
beaglescout007 0:3dac1f1bc9e0 167
beaglescout007 0:3dac1f1bc9e0 168 ApuMute(false);
beaglescout007 0:3dac1f1bc9e0 169
beaglescout007 0:3dac1f1bc9e0 170 #if defined(SHOW_FPS)
beaglescout007 0:3dac1f1bc9e0 171 timer.start();
beaglescout007 0:3dac1f1bc9e0 172 #endif
beaglescout007 0:3dac1f1bc9e0 173
beaglescout007 0:3dac1f1bc9e0 174 return 0;
beaglescout007 0:3dac1f1bc9e0 175 }
beaglescout007 0:3dac1f1bc9e0 176
beaglescout007 0:3dac1f1bc9e0 177 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 178 /* */
beaglescout007 0:3dac1f1bc9e0 179 /* pNesX_ReadRom() : Read ROM image file */
beaglescout007 0:3dac1f1bc9e0 180 /* */
beaglescout007 0:3dac1f1bc9e0 181 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 182 int pNesX_ReadRom( const char *pszFileName )
beaglescout007 0:3dac1f1bc9e0 183 {
beaglescout007 0:3dac1f1bc9e0 184 /*
beaglescout007 0:3dac1f1bc9e0 185 * Read ROM image file
beaglescout007 0:3dac1f1bc9e0 186 *
beaglescout007 0:3dac1f1bc9e0 187 * Parameters
beaglescout007 0:3dac1f1bc9e0 188 * const char *pszFileName (Read)
beaglescout007 0:3dac1f1bc9e0 189 *
beaglescout007 0:3dac1f1bc9e0 190 * Return values
beaglescout007 0:3dac1f1bc9e0 191 * 0 : Normally
beaglescout007 0:3dac1f1bc9e0 192 * -1 : Error
beaglescout007 0:3dac1f1bc9e0 193 */
beaglescout007 0:3dac1f1bc9e0 194 FileHandle* file;
beaglescout007 0:3dac1f1bc9e0 195
beaglescout007 0:3dac1f1bc9e0 196 /* Open ROM file */
beaglescout007 0:3dac1f1bc9e0 197 file = sd->open(pszFileName, O_RDONLY);
beaglescout007 0:3dac1f1bc9e0 198 if ( file == NULL )
beaglescout007 0:3dac1f1bc9e0 199 {
beaglescout007 0:3dac1f1bc9e0 200 printf("open error\r\n");
beaglescout007 0:3dac1f1bc9e0 201 return -1;
beaglescout007 0:3dac1f1bc9e0 202 }
beaglescout007 0:3dac1f1bc9e0 203
beaglescout007 0:3dac1f1bc9e0 204 /* Read ROM Header */
beaglescout007 0:3dac1f1bc9e0 205 file->read( &NesHeader, sizeof NesHeader);
beaglescout007 0:3dac1f1bc9e0 206 if ( memcmp( NesHeader.byID, "NES\x1a", 4 ) != 0 )
beaglescout007 0:3dac1f1bc9e0 207 {
beaglescout007 0:3dac1f1bc9e0 208 /* not .nes file */
beaglescout007 0:3dac1f1bc9e0 209 file->close();
beaglescout007 0:3dac1f1bc9e0 210 return -1;
beaglescout007 0:3dac1f1bc9e0 211 }
beaglescout007 0:3dac1f1bc9e0 212
beaglescout007 0:3dac1f1bc9e0 213 /* Clear SRAM */
beaglescout007 0:3dac1f1bc9e0 214 memset( SRAM, 0, SRAM_SIZE );
beaglescout007 0:3dac1f1bc9e0 215
beaglescout007 0:3dac1f1bc9e0 216 /* If trainer presents Read Triner at 0x7000-0x71ff */
beaglescout007 0:3dac1f1bc9e0 217 if ( NesHeader.byInfo1 & 4 )
beaglescout007 0:3dac1f1bc9e0 218 {
beaglescout007 0:3dac1f1bc9e0 219 printf("Read Trainer\r\n");
beaglescout007 0:3dac1f1bc9e0 220 file->read( &SRAM[ 0x1000 ], 512 );
beaglescout007 0:3dac1f1bc9e0 221 }
beaglescout007 0:3dac1f1bc9e0 222
beaglescout007 0:3dac1f1bc9e0 223 printf("RomSize: %d\r\n", NesHeader.byRomSize);
beaglescout007 0:3dac1f1bc9e0 224 /* Allocate Memory for ROM Image */
beaglescout007 0:3dac1f1bc9e0 225 ROM = (BYTE *)malloc( NesHeader.byRomSize * 0x4000 );
beaglescout007 0:3dac1f1bc9e0 226 printf("ROM addr:%x\r\n", ROM);
beaglescout007 0:3dac1f1bc9e0 227
beaglescout007 0:3dac1f1bc9e0 228 /* Read ROM Image */
beaglescout007 0:3dac1f1bc9e0 229 file->read( ROM, 0x4000 * NesHeader.byRomSize );
beaglescout007 0:3dac1f1bc9e0 230
beaglescout007 0:3dac1f1bc9e0 231 if ( NesHeader.byVRomSize > 0 )
beaglescout007 0:3dac1f1bc9e0 232 {
beaglescout007 0:3dac1f1bc9e0 233 /* Allocate Memory for VROM Image */
beaglescout007 0:3dac1f1bc9e0 234 VROM = (BYTE *)malloc( NesHeader.byVRomSize * 0x2000 );
beaglescout007 0:3dac1f1bc9e0 235 printf("VROM addr:%x\r\n", VROM);
beaglescout007 0:3dac1f1bc9e0 236
beaglescout007 0:3dac1f1bc9e0 237 /* Read VROM Image */
beaglescout007 0:3dac1f1bc9e0 238 file->read( VROM, 0x2000 * NesHeader.byVRomSize );
beaglescout007 0:3dac1f1bc9e0 239 }
beaglescout007 0:3dac1f1bc9e0 240
beaglescout007 0:3dac1f1bc9e0 241 /* File close */
beaglescout007 0:3dac1f1bc9e0 242 file->close();
beaglescout007 0:3dac1f1bc9e0 243
beaglescout007 0:3dac1f1bc9e0 244 /* Successful */
beaglescout007 0:3dac1f1bc9e0 245 return 0;
beaglescout007 0:3dac1f1bc9e0 246 }
beaglescout007 0:3dac1f1bc9e0 247
beaglescout007 0:3dac1f1bc9e0 248 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 249 /* */
beaglescout007 0:3dac1f1bc9e0 250 /* pNesX_ReleaseRom() : Release a memory for ROM */
beaglescout007 0:3dac1f1bc9e0 251 /* */
beaglescout007 0:3dac1f1bc9e0 252 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 253 void pNesX_ReleaseRom()
beaglescout007 0:3dac1f1bc9e0 254 {
beaglescout007 0:3dac1f1bc9e0 255 /*
beaglescout007 0:3dac1f1bc9e0 256 * Release a memory for ROM
beaglescout007 0:3dac1f1bc9e0 257 *
beaglescout007 0:3dac1f1bc9e0 258 */
beaglescout007 0:3dac1f1bc9e0 259 if ( ROM )
beaglescout007 0:3dac1f1bc9e0 260 {
beaglescout007 0:3dac1f1bc9e0 261 free( ROM );
beaglescout007 0:3dac1f1bc9e0 262 ROM = NULL;
beaglescout007 0:3dac1f1bc9e0 263 }
beaglescout007 0:3dac1f1bc9e0 264
beaglescout007 0:3dac1f1bc9e0 265 if ( VROM )
beaglescout007 0:3dac1f1bc9e0 266 {
beaglescout007 0:3dac1f1bc9e0 267 free( VROM );
beaglescout007 0:3dac1f1bc9e0 268 VROM = NULL;
beaglescout007 0:3dac1f1bc9e0 269 }
beaglescout007 0:3dac1f1bc9e0 270 }
beaglescout007 0:3dac1f1bc9e0 271
beaglescout007 0:3dac1f1bc9e0 272 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 273 /* */
beaglescout007 0:3dac1f1bc9e0 274 /* pNesX_LoadFrame() : */
beaglescout007 0:3dac1f1bc9e0 275 /* Transfer the contents of work frame on the screen */
beaglescout007 0:3dac1f1bc9e0 276 /* */
beaglescout007 0:3dac1f1bc9e0 277 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 278 void pNesX_LoadFrame()
beaglescout007 0:3dac1f1bc9e0 279 {
beaglescout007 0:3dac1f1bc9e0 280 /*
beaglescout007 0:3dac1f1bc9e0 281 * Transfer the contents of work frame on the screen
beaglescout007 0:3dac1f1bc9e0 282 *
beaglescout007 0:3dac1f1bc9e0 283 */
beaglescout007 0:3dac1f1bc9e0 284 #if defined(SHOW_FPS)
beaglescout007 0:3dac1f1bc9e0 285 fps++;
beaglescout007 0:3dac1f1bc9e0 286
beaglescout007 0:3dac1f1bc9e0 287 if (timer.read_ms() >= 1000)
beaglescout007 0:3dac1f1bc9e0 288 {
beaglescout007 0:3dac1f1bc9e0 289 timer.stop();
beaglescout007 0:3dac1f1bc9e0 290 printf("%d %d %d\r\n", fps, timer.read_ms(), dmawait);
beaglescout007 0:3dac1f1bc9e0 291 fps = 0;
beaglescout007 0:3dac1f1bc9e0 292 timer.reset();
beaglescout007 0:3dac1f1bc9e0 293 timer.start();
beaglescout007 0:3dac1f1bc9e0 294 }
beaglescout007 0:3dac1f1bc9e0 295 dmawait = 0;
beaglescout007 0:3dac1f1bc9e0 296 #endif
beaglescout007 0:3dac1f1bc9e0 297 }
beaglescout007 0:3dac1f1bc9e0 298
beaglescout007 0:3dac1f1bc9e0 299 void pNesX_TransmitLinedata()
beaglescout007 0:3dac1f1bc9e0 300 {
beaglescout007 0:3dac1f1bc9e0 301 while (SpiHandle.State != HAL_SPI_STATE_READY)
beaglescout007 0:3dac1f1bc9e0 302 {
beaglescout007 0:3dac1f1bc9e0 303 #if defined(SHOW_FPS)
beaglescout007 0:3dac1f1bc9e0 304 dmawait++;
beaglescout007 0:3dac1f1bc9e0 305 #endif
beaglescout007 0:3dac1f1bc9e0 306 }
beaglescout007 0:3dac1f1bc9e0 307 HAL_SPI_Transmit_DMA(&SpiHandle, (uint8_t *)pDrawData, 256 * 2);
beaglescout007 0:3dac1f1bc9e0 308 }
beaglescout007 0:3dac1f1bc9e0 309
beaglescout007 0:3dac1f1bc9e0 310 #if !defined(PS_GAMEPAD)
beaglescout007 0:3dac1f1bc9e0 311 const BYTE UsbPadTable[] = {0x10, 0x90, 0x80, 0xa0, 0x20, 0x60, 0x40, 0x50};
beaglescout007 0:3dac1f1bc9e0 312 #endif
beaglescout007 0:3dac1f1bc9e0 313
beaglescout007 0:3dac1f1bc9e0 314 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 315 /* */
beaglescout007 0:3dac1f1bc9e0 316 /* pNesX_PadState() : Get a joypad state */
beaglescout007 0:3dac1f1bc9e0 317 /* */
beaglescout007 0:3dac1f1bc9e0 318 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 319 void pNesX_PadState( DWORD *pdwPad1, DWORD *pdwPad2, DWORD *pdwSystem )
beaglescout007 0:3dac1f1bc9e0 320 {
beaglescout007 0:3dac1f1bc9e0 321 /*
beaglescout007 0:3dac1f1bc9e0 322 * Get a joypad state
beaglescout007 0:3dac1f1bc9e0 323 *
beaglescout007 0:3dac1f1bc9e0 324 * Parameters
beaglescout007 0:3dac1f1bc9e0 325 * DWORD *pdwPad1 (Write)
beaglescout007 0:3dac1f1bc9e0 326 * Joypad 1 State R L D U St Se B A
beaglescout007 0:3dac1f1bc9e0 327 *
beaglescout007 0:3dac1f1bc9e0 328 * DWORD *pdwPad2 (Write)
beaglescout007 0:3dac1f1bc9e0 329 * Joypad 2 State
beaglescout007 0:3dac1f1bc9e0 330 *
beaglescout007 0:3dac1f1bc9e0 331 * DWORD *pdwSystem (Write)
beaglescout007 0:3dac1f1bc9e0 332 * Input for pNesX
beaglescout007 0:3dac1f1bc9e0 333 *
beaglescout007 0:3dac1f1bc9e0 334 */
beaglescout007 0:3dac1f1bc9e0 335
beaglescout007 0:3dac1f1bc9e0 336 #if !defined(PS_GAMEPAD)
beaglescout007 0:3dac1f1bc9e0 337 *pdwPad1 = ((pad->report[4] & 0x20) >> 5) |
beaglescout007 0:3dac1f1bc9e0 338 ((pad->report[4] & 0x10) >> 3) |
beaglescout007 0:3dac1f1bc9e0 339 ((pad->report[5] & 0x30) >> 2);
beaglescout007 0:3dac1f1bc9e0 340
beaglescout007 0:3dac1f1bc9e0 341 if (!(pad->report[4] & 8))
beaglescout007 0:3dac1f1bc9e0 342 {
beaglescout007 0:3dac1f1bc9e0 343 *pdwPad1 |= UsbPadTable[pad->report[4] & 7];
beaglescout007 0:3dac1f1bc9e0 344 }
beaglescout007 0:3dac1f1bc9e0 345
beaglescout007 0:3dac1f1bc9e0 346 *pdwPad1 = *pdwPad1 | ( *pdwPad1 << 8 );
beaglescout007 0:3dac1f1bc9e0 347
beaglescout007 0:3dac1f1bc9e0 348 *pdwPad2 = 0;
beaglescout007 0:3dac1f1bc9e0 349 *pdwSystem = ((pad->report[5] & 0x4) >> 2) |
beaglescout007 0:3dac1f1bc9e0 350 (((pad->report[5] & 0xa) == 0xa) << 1);
beaglescout007 0:3dac1f1bc9e0 351
beaglescout007 0:3dac1f1bc9e0 352 USBHost::poll();
beaglescout007 0:3dac1f1bc9e0 353 #else
beaglescout007 0:3dac1f1bc9e0 354
beaglescout007 0:3dac1f1bc9e0 355 unsigned short pad1, pad2;
beaglescout007 0:3dac1f1bc9e0 356 pspad_read(&pad1, &pad2);
beaglescout007 0:3dac1f1bc9e0 357 // R L D U St Se B A
beaglescout007 0:3dac1f1bc9e0 358
beaglescout007 0:3dac1f1bc9e0 359 // SE -- -- ST U R D L L2 R2 L1 R1 TR O X SQ
beaglescout007 0:3dac1f1bc9e0 360 *pdwPad1 = ((pad1 & 0x0400) >> 3) |
beaglescout007 0:3dac1f1bc9e0 361 ((pad1 & 0x0100) >> 2) |
beaglescout007 0:3dac1f1bc9e0 362 ((pad1 & 0x0200) >> 4) |
beaglescout007 0:3dac1f1bc9e0 363 ((pad1 & 0x0800) >> 7) |
beaglescout007 0:3dac1f1bc9e0 364 ((pad1 & 0x1000) >> 9) |
beaglescout007 0:3dac1f1bc9e0 365 ((pad1 & 0x8000) >> 13) |
beaglescout007 0:3dac1f1bc9e0 366 ((pad1 & 1) << 1) |
beaglescout007 0:3dac1f1bc9e0 367 ((pad1 & 2) >> 1);
beaglescout007 0:3dac1f1bc9e0 368
beaglescout007 0:3dac1f1bc9e0 369 *pdwPad1 = *pdwPad1 | ( *pdwPad1 << 8 );
beaglescout007 0:3dac1f1bc9e0 370
beaglescout007 0:3dac1f1bc9e0 371 *pdwPad2 = 0;
beaglescout007 0:3dac1f1bc9e0 372
beaglescout007 0:3dac1f1bc9e0 373 *pdwSystem = ((pad1 & 0x80) >> 7) |
beaglescout007 0:3dac1f1bc9e0 374 (((pad1 & 0x50) == 0x50) << 1);
beaglescout007 0:3dac1f1bc9e0 375
beaglescout007 0:3dac1f1bc9e0 376 #endif
beaglescout007 0:3dac1f1bc9e0 377
beaglescout007 0:3dac1f1bc9e0 378 }
beaglescout007 0:3dac1f1bc9e0 379
beaglescout007 0:3dac1f1bc9e0 380 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 381 /* */
beaglescout007 0:3dac1f1bc9e0 382 /* pNesX_MemoryCopy() : memcpy */
beaglescout007 0:3dac1f1bc9e0 383 /* */
beaglescout007 0:3dac1f1bc9e0 384 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 385 void *pNesX_MemoryCopy( void *dest, const void *src, int count )
beaglescout007 0:3dac1f1bc9e0 386 {
beaglescout007 0:3dac1f1bc9e0 387 /*
beaglescout007 0:3dac1f1bc9e0 388 * memcpy
beaglescout007 0:3dac1f1bc9e0 389 *
beaglescout007 0:3dac1f1bc9e0 390 * Parameters
beaglescout007 0:3dac1f1bc9e0 391 * void *dest (Write)
beaglescout007 0:3dac1f1bc9e0 392 * Points to the starting address of the copied block to destination
beaglescout007 0:3dac1f1bc9e0 393 *
beaglescout007 0:3dac1f1bc9e0 394 * const void *src (Read)
beaglescout007 0:3dac1f1bc9e0 395 * Points to the starting address of the block of memory to copy
beaglescout007 0:3dac1f1bc9e0 396 *
beaglescout007 0:3dac1f1bc9e0 397 * int count (Read)
beaglescout007 0:3dac1f1bc9e0 398 * Specifies the size, in bytes, of the block of memory to copy
beaglescout007 0:3dac1f1bc9e0 399 *
beaglescout007 0:3dac1f1bc9e0 400 * Return values
beaglescout007 0:3dac1f1bc9e0 401 * Pointer of destination
beaglescout007 0:3dac1f1bc9e0 402 */
beaglescout007 0:3dac1f1bc9e0 403
beaglescout007 0:3dac1f1bc9e0 404 memcpy(dest, src, count );
beaglescout007 0:3dac1f1bc9e0 405 return dest;
beaglescout007 0:3dac1f1bc9e0 406 }
beaglescout007 0:3dac1f1bc9e0 407
beaglescout007 0:3dac1f1bc9e0 408 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 409 /* */
beaglescout007 0:3dac1f1bc9e0 410 /* pNesX_MemorySet() : */
beaglescout007 0:3dac1f1bc9e0 411 /* */
beaglescout007 0:3dac1f1bc9e0 412 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 413 void *pNesX_MemorySet( void *dest, int c, int count )
beaglescout007 0:3dac1f1bc9e0 414 {
beaglescout007 0:3dac1f1bc9e0 415 /*
beaglescout007 0:3dac1f1bc9e0 416 * memset
beaglescout007 0:3dac1f1bc9e0 417 *
beaglescout007 0:3dac1f1bc9e0 418 * Parameters
beaglescout007 0:3dac1f1bc9e0 419 * void *dest (Write)
beaglescout007 0:3dac1f1bc9e0 420 * Points to the starting address of the block of memory to fill
beaglescout007 0:3dac1f1bc9e0 421 *
beaglescout007 0:3dac1f1bc9e0 422 * int c (Read)
beaglescout007 0:3dac1f1bc9e0 423 * Specifies the byte value with which to fill the memory block
beaglescout007 0:3dac1f1bc9e0 424 *
beaglescout007 0:3dac1f1bc9e0 425 * int count (Read)
beaglescout007 0:3dac1f1bc9e0 426 * Specifies the size, in bytes, of the block of memory to fill
beaglescout007 0:3dac1f1bc9e0 427 *
beaglescout007 0:3dac1f1bc9e0 428 * Return values
beaglescout007 0:3dac1f1bc9e0 429 * Pointer of destination
beaglescout007 0:3dac1f1bc9e0 430 */
beaglescout007 0:3dac1f1bc9e0 431
beaglescout007 0:3dac1f1bc9e0 432 memset(dest, c, count);
beaglescout007 0:3dac1f1bc9e0 433 return dest;
beaglescout007 0:3dac1f1bc9e0 434 }
beaglescout007 0:3dac1f1bc9e0 435
beaglescout007 0:3dac1f1bc9e0 436 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 437 /* */
beaglescout007 0:3dac1f1bc9e0 438 /* DebugPrint() : Print debug message */
beaglescout007 0:3dac1f1bc9e0 439 /* */
beaglescout007 0:3dac1f1bc9e0 440 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 441 void pNesX_DebugPrint( char *pszMsg )
beaglescout007 0:3dac1f1bc9e0 442 {
beaglescout007 0:3dac1f1bc9e0 443 }
beaglescout007 0:3dac1f1bc9e0 444
beaglescout007 0:3dac1f1bc9e0 445 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 446 /* */
beaglescout007 0:3dac1f1bc9e0 447 /* pNesX Initialise */
beaglescout007 0:3dac1f1bc9e0 448 /* */
beaglescout007 0:3dac1f1bc9e0 449 /*===================================================================*/
beaglescout007 0:3dac1f1bc9e0 450 int main()
beaglescout007 0:3dac1f1bc9e0 451 {
beaglescout007 0:3dac1f1bc9e0 452 // TFT initialize
beaglescout007 0:3dac1f1bc9e0 453 tft_init();
beaglescout007 0:3dac1f1bc9e0 454 tft_clear(TFT_BLACK);
beaglescout007 0:3dac1f1bc9e0 455 tft_set_window(32, 8, NES_DISP_WIDTH + 32 - 1, NES_DISP_HEIGHT + 8 - 1);
beaglescout007 0:3dac1f1bc9e0 456
beaglescout007 0:3dac1f1bc9e0 457 // SD card Initialize
beaglescout007 0:3dac1f1bc9e0 458 sd = new SDFileSystem(PB_15, PB_14, PB_13, PA_9, "sd", NC, SDFileSystem::SWITCH_NONE, 20000000);
beaglescout007 0:3dac1f1bc9e0 459 sd->crc(true);
beaglescout007 0:3dac1f1bc9e0 460 sd->large_frames(true);
beaglescout007 0:3dac1f1bc9e0 461 sd->write_validation(true);
beaglescout007 0:3dac1f1bc9e0 462
beaglescout007 0:3dac1f1bc9e0 463 strcpy(szRomFolder, "/sd");
beaglescout007 0:3dac1f1bc9e0 464
beaglescout007 0:3dac1f1bc9e0 465 #if !defined(PS_GAMEPAD)
beaglescout007 0:3dac1f1bc9e0 466 // USB Gmaepad Initialize
beaglescout007 0:3dac1f1bc9e0 467 pad = new USBHostGamepad();
beaglescout007 0:3dac1f1bc9e0 468 pad->connect();
beaglescout007 0:3dac1f1bc9e0 469 #else
beaglescout007 0:3dac1f1bc9e0 470 pspad_init();
beaglescout007 0:3dac1f1bc9e0 471 #endif
beaglescout007 0:3dac1f1bc9e0 472
beaglescout007 0:3dac1f1bc9e0 473 // Apu Initialize
beaglescout007 0:3dac1f1bc9e0 474 ApuInit();
beaglescout007 0:3dac1f1bc9e0 475
beaglescout007 0:3dac1f1bc9e0 476 /*-------------------------------------------------------------------*/
beaglescout007 0:3dac1f1bc9e0 477 /* Start pNesX */
beaglescout007 0:3dac1f1bc9e0 478 /*-------------------------------------------------------------------*/
beaglescout007 0:3dac1f1bc9e0 479
beaglescout007 0:3dac1f1bc9e0 480 pNesX_Main();
beaglescout007 0:3dac1f1bc9e0 481 }
beaglescout007 0:3dac1f1bc9e0 482
beaglescout007 0:3dac1f1bc9e0 483