arm 2440 linux 应用程序 nes 红白机模拟器 第4篇 linux 手柄驱动支持

小霸王学习机的真实手柄,实测CPU 占用 80%

接线图:

手柄读时序:

joypad.c 驱动: 普通的字符设备驱动。

  1 #include <linux/module.h>
  2 #include <linux/kernel.h>
  3 #include <linux/fs.h>
  4 #include <linux/init.h>
  5 #include <linux/delay.h>
  6 #include <asm/uaccess.h>
  7 #include <asm/irq.h>
  8 #include <asm/io.h>
  9 #include <linux/device.h>
 10
 11 /**
 12  *手柄接线定义
 13  *VCC 3.3 来自 串口
 14  *GND     来自 串口
 15  *CLK   摄像头接口 1P IICSDA GPE15
 16  *LATCH 摄像头接口 2P IICSCL GPE14
 17  *DAT0  摄像头接口 5P CAMCLK GPJ11
 18  */
 19
 20 #define GPE_BASE 0x56000040
 21 #define GPJ_BASE 0x560000d0
 22
 23 //定义一个结构体用来保存 GPIO 信息
 24 typedef struct {
 25     unsigned int con;
 26     unsigned int dat;
 27     unsigned int up;
 28
 29 }T_GPIO_REG, *PT_GPIO_REG;
 30
 31 //禁止编译器优化
 32 static volatile PT_GPIO_REG pt_gpe_reg;
 33 static volatile PT_GPIO_REG pt_gpj_reg;
 34
 35 static struct class *joypad_drv_class;
 36
 37 static ssize_t joypad_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
 38 {
 39     //利用 sszie_t 返回 手柄键值
 40     //buf 是有符号无法保存 8 bit
 41     int i;
 42     ssize_t val = 0;
 43     pt_gpe_reg->dat |= 1<<14;
 44     udelay(2);
 45     pt_gpe_reg->dat &= ~(1<<14);
 46     for(i=0; i<8; i++)
 47     {
 48         udelay(2);
 49         if(! (pt_gpj_reg->dat & 1<<11))
 50         {
 51             val |= 1<<i;
 52         }
 53
 54         pt_gpe_reg->dat |= 1<<15;
 55         udelay(2);
 56         pt_gpe_reg->dat &= ~(1<<15);
 57     }
 58     //最后输出低电平
 59     pt_gpe_reg->dat &= ~(1<<14 | 1<<15);
 60     return val;
 61 }
 62
 63 static struct file_operations joypad_drv_fops = {
 64      .owner  =   THIS_MODULE,
 65     .read   =   joypad_drv_read,
 66 };
 67
 68 int major;
 69 //注册驱动程序
 70 int joypad_drv_init(void)
 71 {
 72     major = register_chrdev(0, "joypad_drv", &joypad_drv_fops);
 73
 74     //自动创建 dev 节点
 75     joypad_drv_class = class_create(THIS_MODULE, "joypad_drv");
 76     device_create(joypad_drv_class, NULL, MKDEV(major, 0), NULL, "joypad");
 77
 78     //ioremap 地址映射
 79     pt_gpe_reg = ioremap(GPE_BASE, sizeof(T_GPIO_REG));
 80     pt_gpj_reg = ioremap(GPJ_BASE, sizeof(T_GPIO_REG));
 81
 82     //配置GPIO
 83      //GPE 14 15 配置为输出引脚
 84     pt_gpe_reg->con &= ~(3<<(2*15));
 85     pt_gpe_reg->con &= ~(3<<(2*14));
 86     pt_gpe_reg->con |=  1<<(2*15);
 87     pt_gpe_reg->con |= 1<<(2*14);
 88
 89     //默认输出低电平
 90     pt_gpe_reg->dat &= ~(1<<14 | 1<<15);
 91
 92     //GPJ 11 配置为输入引脚 禁用内部上拉
 93     pt_gpj_reg->con &= ~(3<<(2*11));
 94     pt_gpj_reg->up |= 1<<11;
 95     return 0;
 96 }
 97
 98 //卸载驱动程序
 99 void joypad_drv_exit(void)
100 {
101     //取消 地址映射
102     iounmap(pt_gpe_reg);
103     iounmap(pt_gpj_reg);
104
105     unregister_chrdev(major, "joypad_drv");
106     device_destroy(joypad_drv_class, MKDEV(major, 0));
107     class_destroy(joypad_drv_class);
108 }
109
110 module_init(joypad_drv_init);
111 module_exit(joypad_drv_exit);
112 MODULE_LICENSE("GPL");

InfoNES  InfoNES_System_Linux.cpp:

  1 /*===================================================================*/
  2 /*                                                                   */
  3 /*  InfoNES_System_Linux.cpp : Linux specific File                   */
  4 /*                                                                   */
  5 /*  2001/05/18  InfoNES Project ( Sound is based on DarcNES )        */
  6 /*                                                                   */
  7 /*===================================================================*/
  8
  9 /*-------------------------------------------------------------------*/
 10 /*  Include files                                                    */
 11 /*-------------------------------------------------------------------*/
 12
 13 #include <stdio.h>
 14 #include <stdlib.h>
 15 #include <string.h>
 16 #include <pthread.h>
 17
 18 #include <sys/types.h>
 19 #include <sys/stat.h>
 20 #include <fcntl.h>
 21 #include <sys/ioctl.h>
 22 #include <unistd.h>
 23 #include <sys/soundcard.h>
 24
 25 #include "../InfoNES.h"
 26 #include "../InfoNES_System.h"
 27 #include "../InfoNES_pAPU.h"
 28
 29 //bool define
 30 #define TRUE 1
 31 #define FALSE 0
 32
 33 /* lcd 操作相关 头文件 */
 34 #include <sys/types.h>
 35 #include <sys/stat.h>
 36 #include <fcntl.h>
 37 #include <linux/fb.h>
 38 #include <sys/ioctl.h>
 39 #include <unistd.h>
 40 #include <string.h>
 41 #include <sys/mman.h>
 42 #include <termios.h>
 43
 44 #include <fcntl.h>
 45
 46 #define JOYPAD_DEV "/dev/joypad"
 47 static int joypad_fd;
 48
 49 static int fb_fd;
 50 static unsigned char *fb_mem;
 51 static int px_width;
 52 static int line_width;
 53 static int screen_width;
 54 static struct fb_var_screeninfo var;
 55
 56 static int init_joypad()
 57 {
 58     joypad_fd = open(JOYPAD_DEV, O_RDONLY);
 59     if(-1 == joypad_fd)
 60     {
 61         printf("joypad dev not found \r\n");
 62         return -1;
 63     }
 64     return 0;
 65 }
 66
 67 static int lcd_fb_display_px(WORD color, int x, int y)
 68 {
 69     unsigned char  *pen8;
 70     unsigned short *pen16;
 71
 72     pen8 = (unsigned char *)(fb_mem + y*line_width + x*px_width);
 73     pen16 = (unsigned short *)pen8;
 74     *pen16 = color;
 75
 76     return 0;
 77 }
 78
 79 static int lcd_fb_init()
 80 {
 81     //如果使用 mmap 打开方式 必须是 读定方式
 82     fb_fd = open("/dev/fb0", O_RDWR);
 83     if(-1 == fb_fd)
 84     {
 85         printf("cat‘t open /dev/fb0 \n");
 86         return -1;
 87     }
 88     //获取屏幕参数
 89     if(-1 == ioctl(fb_fd, FBIOGET_VSCREENINFO, &var))
 90     {
 91         close(fb_fd);
 92         printf("cat‘t ioctl /dev/fb0 \n");
 93         return -1;
 94     }
 95
 96     //计算参数
 97     px_width = var.bits_per_pixel / 8;
 98     line_width = var.xres * px_width;
 99     screen_width = var.yres * line_width;
100
101     fb_mem = (unsigned char *)mmap(NULL, screen_width, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);
102     if(fb_mem == (void *)-1)
103     {
104         close(fb_fd);
105         printf("cat‘t mmap /dev/fb0 \n");
106         return -1;
107     }
108     //清屏
109     memset(fb_mem, 0 , screen_width);
110     return 0;
111 }
112
113 /*-------------------------------------------------------------------*/
114 /*  ROM image file information                                       */
115 /*-------------------------------------------------------------------*/
116
117 char    szRomName[256];
118 char    szSaveName[256];
119 int    nSRAM_SaveFlag;
120
121 /*-------------------------------------------------------------------*/
122 /*  Constants ( Linux specific )                                     */
123 /*-------------------------------------------------------------------*/
124
125 #define VBOX_SIZE    7
126 #define SOUND_DEVICE    "/dev/dsp"
127 #define VERSION        "InfoNES v0.91J"
128
129 /*-------------------------------------------------------------------*/
130 /*  Global Variables ( Linux specific )                              */
131 /*-------------------------------------------------------------------*/
132
133 /* Emulation thread */
134 pthread_t  emulation_tid;
135 int bThread;
136
137 /* Pad state */
138 DWORD    dwKeyPad1;
139 DWORD    dwKeyPad2;
140 DWORD    dwKeySystem;
141
142 /* For Sound Emulation */
143 BYTE    final_wave[2048];
144 int    waveptr;
145 int    wavflag;
146 int    sound_fd;
147
148 /*-------------------------------------------------------------------*/
149 /*  Function prototypes ( Linux specific )                           */
150 /*-------------------------------------------------------------------*/
151
152 void *emulation_thread( void *args );
153
154
155 void start_application( char *filename );
156
157
158 int LoadSRAM();
159
160
161 int SaveSRAM();
162
163
164 /* Palette data */
165 WORD NesPalette[64] =
166 {
167     0x39ce, 0x1071, 0x0015, 0x2013, 0x440e, 0x5402, 0x5000, 0x3c20,
168     0x20a0, 0x0100, 0x0140, 0x00e2, 0x0ceb, 0x0000, 0x0000, 0x0000,
169     0x5ef7, 0x01dd, 0x10fd, 0x401e, 0x5c17, 0x700b, 0x6ca0, 0x6521,
170     0x45c0, 0x0240, 0x02a0, 0x0247, 0x0211, 0x0000, 0x0000, 0x0000,
171     0x7fff, 0x1eff, 0x2e5f, 0x223f, 0x79ff, 0x7dd6, 0x7dcc, 0x7e67,
172     0x7ae7, 0x4342, 0x2769, 0x2ff3, 0x03bb, 0x0000, 0x0000, 0x0000,
173     0x7fff, 0x579f, 0x635f, 0x6b3f, 0x7f1f, 0x7f1b, 0x7ef6, 0x7f75,
174     0x7f94, 0x73f4, 0x57d7, 0x5bf9, 0x4ffe, 0x0000, 0x0000, 0x0000
175 };
176
177 /*===================================================================*/
178 /*                                                                   */
179 /*                main() : Application main                          */
180 /*                                                                   */
181 /*===================================================================*/
182
183 /* Application main */
184 int main( int argc, char **argv )
185 {
186     char cmd;
187
188     /*-------------------------------------------------------------------*/
189     /*  Pad Control                                                      */
190     /*-------------------------------------------------------------------*/
191
192     /* Initialize a pad state */
193     dwKeyPad1    = 0;
194     dwKeyPad2    = 0;
195     dwKeySystem = 0;
196
197     /*-------------------------------------------------------------------*/
198     /*  Load Cassette & Create Thread                                    */
199     /*-------------------------------------------------------------------*/
200
201     /* Initialize thread state */
202     bThread = FALSE;
203
204     /* If a rom name specified, start it */
205     if ( argc == 2 )
206     {
207         start_application( argv[1] );
208     }
209
210     lcd_fb_init();
211     init_joypad();
212
213     //主循环中处理输入事件
214     while(1)
215     {
216         dwKeyPad1 = read(joypad_fd, 0, 0);
217     }
218     return(0);
219 }
220
221
222 /*===================================================================*/
223 /*                                                                   */
224 /*           emulation_thread() : Thread Hooking Routine             */
225 /*                                                                   */
226 /*===================================================================*/
227
228 void *emulation_thread( void *args )
229 {
230     InfoNES_Main();
231 }
232
233
234 /*===================================================================*/
235 /*                                                                   */
236 /*     start_application() : Start NES Hardware                      */
237 /*                                                                   */
238 /*===================================================================*/
239 void start_application( char *filename )
240 {
241     /* Set a ROM image name */
242     strcpy( szRomName, filename );
243
244     /* Load cassette */
245     if ( InfoNES_Load( szRomName ) == 0 )
246     {
247         /* Load SRAM */
248         LoadSRAM();
249
250         /* Create Emulation Thread */
251         bThread = TRUE;
252         pthread_create( &emulation_tid, NULL, emulation_thread, NULL );
253     }
254 }
255
256
257 /*===================================================================*/
258 /*                                                                   */
259 /*           LoadSRAM() : Load a SRAM                                */
260 /*                                                                   */
261 /*===================================================================*/
262 int LoadSRAM()
263 {
264 /*
265  *  Load a SRAM
266  *
267  *  Return values
268  *     0 : Normally
269  *    -1 : SRAM data couldn‘t be read
270  */
271
272     FILE        *fp;
273     unsigned char    pSrcBuf[SRAM_SIZE];
274     unsigned char    chData;
275     unsigned char    chTag;
276     int        nRunLen;
277     int        nDecoded;
278     int        nDecLen;
279     int        nIdx;
280
281     /* It doesn‘t need to save it */
282     nSRAM_SaveFlag = 0;
283
284     /* It is finished if the ROM doesn‘t have SRAM */
285     if ( !ROM_SRAM )
286         return(0);
287
288     /* There is necessity to save it */
289     nSRAM_SaveFlag = 1;
290
291     /* The preparation of the SRAM file name */
292     strcpy( szSaveName, szRomName );
293     strcpy( strrchr( szSaveName, ‘.‘ ) + 1, "srm" );
294
295     /*-------------------------------------------------------------------*/
296     /*  Read a SRAM data                                                 */
297     /*-------------------------------------------------------------------*/
298
299     /* Open SRAM file */
300     fp = fopen( szSaveName, "rb" );
301     if ( fp == NULL )
302         return(-1);
303
304     /* Read SRAM data */
305     fread( pSrcBuf, SRAM_SIZE, 1, fp );
306
307     /* Close SRAM file */
308     fclose( fp );
309
310     /*-------------------------------------------------------------------*/
311     /*  Extract a SRAM data                                              */
312     /*-------------------------------------------------------------------*/
313
314     nDecoded    = 0;
315     nDecLen        = 0;
316
317     chTag = pSrcBuf[nDecoded++];
318
319     while ( nDecLen < 8192 )
320     {
321         chData = pSrcBuf[nDecoded++];
322
323         if ( chData == chTag )
324         {
325             chData    = pSrcBuf[nDecoded++];
326             nRunLen = pSrcBuf[nDecoded++];
327             for ( nIdx = 0; nIdx < nRunLen + 1; ++nIdx )
328             {
329                 SRAM[nDecLen++] = chData;
330             }
331         }else  {
332             SRAM[nDecLen++] = chData;
333         }
334     }
335
336     /* Successful */
337     return(0);
338 }
339
340
341 /*===================================================================*/
342 /*                                                                   */
343 /*           SaveSRAM() : Save a SRAM                                */
344 /*                                                                   */
345 /*===================================================================*/
346 int SaveSRAM()
347 {
348 /*
349  *  Save a SRAM
350  *
351  *  Return values
352  *     0 : Normally
353  *    -1 : SRAM data couldn‘t be written
354  */
355
356     FILE        *fp;
357     int        nUsedTable[256];
358     unsigned char    chData;
359     unsigned char    chPrevData;
360     unsigned char    chTag;
361     int        nIdx;
362     int        nEncoded;
363     int        nEncLen;
364     int        nRunLen;
365     unsigned char    pDstBuf[SRAM_SIZE];
366
367     if ( !nSRAM_SaveFlag )
368         return(0);  /* It doesn‘t need to save it */
369
370     /*-------------------------------------------------------------------*/
371     /*  Compress a SRAM data                                             */
372     /*-------------------------------------------------------------------*/
373
374     memset( nUsedTable, 0, sizeof nUsedTable );
375
376     for ( nIdx = 0; nIdx < SRAM_SIZE; ++nIdx )
377     {
378         ++nUsedTable[SRAM[nIdx++]];
379     }
380     for ( nIdx = 1, chTag = 0; nIdx < 256; ++nIdx )
381     {
382         if ( nUsedTable[nIdx] < nUsedTable[chTag] )
383             chTag = nIdx;
384     }
385
386     nEncoded    = 0;
387     nEncLen        = 0;
388     nRunLen        = 1;
389
390     pDstBuf[nEncLen++] = chTag;
391
392     chPrevData = SRAM[nEncoded++];
393
394     while ( nEncoded < SRAM_SIZE && nEncLen < SRAM_SIZE - 133 )
395     {
396         chData = SRAM[nEncoded++];
397
398         if ( chPrevData == chData && nRunLen < 256 )
399             ++nRunLen;
400         else{
401             if ( nRunLen >= 4 || chPrevData == chTag )
402             {
403                 pDstBuf[nEncLen++]    = chTag;
404                 pDstBuf[nEncLen++]    = chPrevData;
405                 pDstBuf[nEncLen++]    = nRunLen - 1;
406             }else  {
407                 for ( nIdx = 0; nIdx < nRunLen; ++nIdx )
408                     pDstBuf[nEncLen++] = chPrevData;
409             }
410
411             chPrevData    = chData;
412             nRunLen        = 1;
413         }
414     }
415     if ( nRunLen >= 4 || chPrevData == chTag )
416     {
417         pDstBuf[nEncLen++]    = chTag;
418         pDstBuf[nEncLen++]    = chPrevData;
419         pDstBuf[nEncLen++]    = nRunLen - 1;
420     }else  {
421         for ( nIdx = 0; nIdx < nRunLen; ++nIdx )
422             pDstBuf[nEncLen++] = chPrevData;
423     }
424
425     /*-------------------------------------------------------------------*/
426     /*  Write a SRAM data                                                */
427     /*-------------------------------------------------------------------*/
428
429     /* Open SRAM file */
430     fp = fopen( szSaveName, "wb" );
431     if ( fp == NULL )
432         return(-1);
433
434     /* Write SRAM data */
435     fwrite( pDstBuf, nEncLen, 1, fp );
436
437     /* Close SRAM file */
438     fclose( fp );
439
440     /* Successful */
441     return(0);
442 }
443
444
445 /*===================================================================*/
446 /*                                                                   */
447 /*                  InfoNES_Menu() : Menu screen                     */
448 /*                                                                   */
449 /*===================================================================*/
450 int InfoNES_Menu()
451 {
452 /*
453  *  Menu screen
454  *
455  *  Return values
456  *     0 : Normally
457  *    -1 : Exit InfoNES
458  */
459
460     /* If terminated */
461     if ( bThread == FALSE )
462     {
463         return(-1);
464     }
465
466     /* Nothing to do here */
467     return(0);
468 }
469
470
471 /*===================================================================*/
472 /*                                                                   */
473 /*               InfoNES_ReadRom() : Read ROM image file             */
474 /*                                                                   */
475 /*===================================================================*/
476 int InfoNES_ReadRom( const char *pszFileName )
477 {
478 /*
479  *  Read ROM image file
480  *
481  *  Parameters
482  *    const char *pszFileName          (Read)
483  *
484  *  Return values
485  *     0 : Normally
486  *    -1 : Error
487  */
488
489     FILE *fp;
490
491     /* Open ROM file */
492     fp = fopen( pszFileName, "rb" );
493     if ( fp == NULL )
494         return(-1);
495
496     /* Read ROM Header */
497     fread( &NesHeader, sizeof NesHeader, 1, fp );
498     if ( memcmp( NesHeader.byID, "NES\x1a", 4 ) != 0 )
499     {
500         /* not .nes file */
501         fclose( fp );
502         return(-1);
503     }
504
505     /* Clear SRAM */
506     memset( SRAM, 0, SRAM_SIZE );
507
508     /* If trainer presents Read Triner at 0x7000-0x71ff */
509     if ( NesHeader.byInfo1 & 4 )
510     {
511         fread( &SRAM[0x1000], 512, 1, fp );
512     }
513
514     /* Allocate Memory for ROM Image */
515     ROM = (BYTE *) malloc( NesHeader.byRomSize * 0x4000 );
516
517     /* Read ROM Image */
518     fread( ROM, 0x4000, NesHeader.byRomSize, fp );
519
520     if ( NesHeader.byVRomSize > 0 )
521     {
522         /* Allocate Memory for VROM Image */
523         VROM = (BYTE *) malloc( NesHeader.byVRomSize * 0x2000 );
524
525         /* Read VROM Image */
526         fread( VROM, 0x2000, NesHeader.byVRomSize, fp );
527     }
528
529     /* File close */
530     fclose( fp );
531
532     /* Successful */
533     return(0);
534 }
535
536
537 /*===================================================================*/
538 /*                                                                   */
539 /*           InfoNES_ReleaseRom() : Release a memory for ROM         */
540 /*                                                                   */
541 /*===================================================================*/
542 void InfoNES_ReleaseRom()
543 {
544 /*
545  *  Release a memory for ROM
546  *
547  */
548
549     if ( ROM )
550     {
551         free( ROM );
552         ROM = NULL;
553     }
554
555     if ( VROM )
556     {
557         free( VROM );
558         VROM = NULL;
559     }
560 }
561
562
563 /*===================================================================*/
564 /*                                                                   */
565 /*             InfoNES_MemoryCopy() : memcpy                         */
566 /*                                                                   */
567 /*===================================================================*/
568 void *InfoNES_MemoryCopy( void *dest, const void *src, int count )
569 {
570 /*
571  *  memcpy
572  *
573  *  Parameters
574  *    void *dest                       (Write)
575  *      Points to the starting address of the copied block‘s destination
576  *
577  *    const void *src                  (Read)
578  *      Points to the starting address of the block of memory to copy
579  *
580  *    int count                        (Read)
581  *      Specifies the size, in bytes, of the block of memory to copy
582  *
583  *  Return values
584  *    Pointer of destination
585  */
586
587     memcpy( dest, src, count );
588     return(dest);
589 }
590
591
592 /*===================================================================*/
593 /*                                                                   */
594 /*             InfoNES_MemorySet() : memset                          */
595 /*                                                                   */
596 /*===================================================================*/
597 void *InfoNES_MemorySet( void *dest, int c, int count )
598 {
599 /*
600  *  memset
601  *
602  *  Parameters
603  *    void *dest                       (Write)
604  *      Points to the starting address of the block of memory to fill
605  *
606  *    int c                            (Read)
607  *      Specifies the byte value with which to fill the memory block
608  *
609  *    int count                        (Read)
610  *      Specifies the size, in bytes, of the block of memory to fill
611  *
612  *  Return values
613  *    Pointer of destination
614  */
615
616     memset( dest, c, count );
617     return(dest);
618 }
619
620
621 /*===================================================================*/
622 /*                                                                   */
623 /*      InfoNES_LoadFrame() :                                        */
624 /*           Transfer the contents of work frame on the screen       */
625 /*                                                                   */
626 /*===================================================================*/
627 void InfoNES_LoadFrame()
628 {
629     int x,y;
630     WORD wColor;
631     for (y = 0; y < NES_DISP_HEIGHT; y++ )
632     {
633         for (x = 0; x < NES_DISP_WIDTH; x++ )
634         {
635             wColor = WorkFrame[y * NES_DISP_WIDTH  + x ];
636             lcd_fb_display_px(wColor, x, y);
637         }
638     }
639 }
640
641
642 /*===================================================================*/
643 /*                                                                   */
644 /*             InfoNES_PadState() : Get a joypad state               */
645 /*                                                                   */
646 /*===================================================================*/
647 void InfoNES_PadState( DWORD *pdwPad1, DWORD *pdwPad2, DWORD *pdwSystem )
648 {
649 /*
650  *  Get a joypad state
651  *
652  *  Parameters
653  *    DWORD *pdwPad1                   (Write)
654  *      Joypad 1 State
655  *
656  *    DWORD *pdwPad2                   (Write)
657  *      Joypad 2 State
658  *
659  *    DWORD *pdwSystem                 (Write)
660  *      Input for InfoNES
661  *
662  */
663
664     /* Transfer joypad state */
665     *pdwPad1    = dwKeyPad1;
666     *pdwPad2    = dwKeyPad2;
667     *pdwSystem    = dwKeySystem;
668
669     dwKeyPad1 = 0;
670 }
671
672
673 /*===================================================================*/
674 /*                                                                   */
675 /*        InfoNES_SoundInit() : Sound Emulation Initialize           */
676 /*                                                                   */
677 /*===================================================================*/
678 void InfoNES_SoundInit( void )
679 {
680     sound_fd = 0;
681 }
682
683
684 /*===================================================================*/
685 /*                                                                   */
686 /*        InfoNES_SoundOpen() : Sound Open                           */
687 /*                                                                   */
688 /*===================================================================*/
689 int InfoNES_SoundOpen( int samples_per_sync, int sample_rate )
690 {
691     return 1;
692 }
693
694
695 /*===================================================================*/
696 /*                                                                   */
697 /*        InfoNES_SoundClose() : Sound Close                         */
698 /*                                                                   */
699 /*===================================================================*/
700 void InfoNES_SoundClose( void )
701 {
702     if ( sound_fd )
703     {
704         close( sound_fd );
705     }
706 }
707
708
709 /*===================================================================*/
710 /*                                                                   */
711 /*            InfoNES_SoundOutput() : Sound Output 5 Waves           */
712 /*                                                                   */
713 /*===================================================================*/
714 void InfoNES_SoundOutput( int samples, BYTE *wave1, BYTE *wave2, BYTE *wave3, BYTE *wave4, BYTE *wave5 )
715 {
716
717 }
718
719
720 /*===================================================================*/
721 /*                                                                   */
722 /*            InfoNES_Wait() : Wait Emulation if required            */
723 /*                                                                   */
724 /*===================================================================*/
725 void InfoNES_Wait()
726 {
727 }
728
729
730 /*===================================================================*/
731 /*                                                                   */
732 /*            InfoNES_MessageBox() : Print System Message            */
733 /*                                                                   */
734 /*===================================================================*/
735 void InfoNES_MessageBox( char *pszMsg, ... )
736 {
737     printf( "MessageBox: %s \n", pszMsg );
738 }
739
740
741 /*
742  * End of InfoNES_System_Linux.cpp
743  */
时间: 2024-10-10 21:20:51

arm 2440 linux 应用程序 nes 红白机模拟器 第4篇 linux 手柄驱动支持的相关文章

arm 2440 linux 应用程序 nes 红白机模拟器 第2篇 InfoNES

InfoNES 支持 map ,声音,代码比较少,方便 移值. 在上个 LiteNES  的基础上,其实不到半小时就移值好了这个,但问题是,一直是黑屏.InfoNES_LoadFrame ()  WorkFrame 中一直是 0 . 解决的过程很漫长,最终看到 说是 ADS 中 有符号 无符号的问题,但是 这里用的是 makefile 不是 ADS ,试着改了 makefile 加上 CCFLAGS =  -O2 -fsigned-char . 终于有输出了,性能还算不错. InfoNES 源码

arm linux 应用程序 nes 红白机模拟器 第1篇

对比了很多种,开源的 NES 模拟器 VirtuaNES , nestopia , FakeNES , FCEUX , InfoNES , LiteNES 最后决定使用 LiteNES 进行移值,它是由 mynes 移值而来.LiteNES 对 mynes 代码进行整理兼容了 C99 标准,编译时无警告. https://github.com/NJUOS/LiteNES https://github.com/yaglo/mynes LiteNES , mynes  基于 Allegro ,All

nes 红白机模拟器 第7篇 编译使用方法

模拟器,基于 InfoNES ,作者添加修改以下功能: 1, joypad 真实手柄驱动程序(字符型设备驱动) 2,原始图像只有256*240 ,添加 图像放大算法,这里实现了2种,a, 最近邻插值 b, 双线性插值 (因为2440 速度太慢,采用双线性插值时,大概要3秒算一帧,等以后用 4412 在测试实际效果,本文还会更新) 3,声音支持,原 InfoNES 中,使用 oss 播放声音,添加 使用 alsa 播放支持, 4,LCD显示支持,原 InfoNES 中,使用 Gtk进行显示,作者添

nes 红白机模拟器 第6篇 声音支持

InfoNES 源码中并没有包含 linux 的声音支持. 但提供 wince 和 win 的工程,文件,通过分析,win 的 DirectSound 发声,在使用 linux ALSA 实现. 先使用 DirectSound 模仿写一个 播放 wav 的程序. 为了简单,我这里使用  vc++ 6.0 (vs2015 实在太大了,电脑装上太卡). 新建一个 mfc exe 项目,基于对话框.放一个按钮,双击添加事件. 添加头文件引用#include <mmsystem.h>#pragma c

nes 红白机模拟器 第3篇 游戏手柄测试 51 STM32

手柄使用的是 CD4021 ,datasheet 上说支持 3V - 15V . 因为手柄是 5V 供电,2440 开发板上是GPIO 3.3V 电平,STM32 GPIO 也是 3.3V (也兼容5V)电平. 所以先在 STM32 上测试能用后,在接到 2440 开发板上. 正好是 8个键值,用来点 8个 LED .按下一个键,就会亮一个灯. c51 : 1 #include <reg52.h> 2 3 sbit CLK = P2 ^ 2; 4 sbit LATCH = P2 ^ 1; 5

nes 红白机模拟器 第5篇 全屏显示

先看一下效果图,全屏是全了,但是效果非常很一般(差) 放大的原理是使用最初级的算法,直接取对应像素法. 1 /** 2 * 生成zoom 缩放表 3 */ 4 int make_zoom_tab() 5 { 6 int i; 7 zoom_x_tab = (int *)malloc(sizeof(int) * NES_DISP_WIDTH); 8 if(NULL == zoom_x_tab) 9 { 10 printf("make zoom_x_tab error\n"); 11 re

当年击败红白机的奇葩怪招 后来玩山寨的都在学

百合一.千合一,是山寨者往往第一时间想到的法子,无限集成近乎全套功能于一身,甭管好坏.但这往往也就忽悠下好奇的围观群众. 文/张书乐    原载于<人民邮电报>2015年10月23日<乐游记>专栏 红白机被以小霸王为首的中国"山寨"游戏机们击溃,一个关键原因就在于竞争对手的终端产品都能够毫无阻碍地运行红白机的游戏卡带.短短3年的"山寨"之路,让小霸王成功突破年产值10亿元大关.当时,面对正在变成世界工厂.劳动力成本极为低廉的中国对手,且在知识

童年红白机?FC经典游戏600合集for mac

曾经的"小霸王"游戏机,让我们许多80年后.90后度过了一个欢乐愉快的童年,虽然如今这类游戏机和卡带几乎已经退出游戏市场,但经典永远留在了我们这一代人心中.今天给大家分享的小霸王FC经典游戏600合集,带你回顾童年,重温经典!希望大家喜欢! 霸王FC经典游戏600合集之部分游戏介绍 1.<超级马里奥兄弟><超级马里奥兄弟>,是任天堂公司开发并于1985年出品的著名横版过关游戏,是游戏奠基之作,这是一款任天堂针对FC主机全力度身订造的游戏.这个游戏被赞誉为电子游戏

5. Linux应用程序地址布局

程序构成: 在学习Linux应用程序开发时,经常会遇到如下概念:代码段.数据段.BSS段(Block Started by Symbol,又名:未初始化数据段) .堆(heap)和栈(stack).而这些部分也是构成Linux应用程序的重要组成部分. 内存布局: 当Linux应用程序在内存中运行的时候,以上组成部分在内存中布局: 从低地址到高地址分别为:代码段.数据段.BSS段.堆.栈. 堆向高内存地址生长. 栈向低内存地址生长. 下面测试下面的程序: 查看系统的线程: 下面我们看这代码的地址分