Index: pacbox.c =================================================================== --- pacbox.c (revision 15844) +++ pacbox.c (working copy) @@ -28,9 +28,14 @@ #include "pacbox_lcd.h" #include "lib/configfile.h" #include "lib/oldmenuapi.h" +#ifdef PACBOX_AUDIO_ENABLED +#include "lib/playback_control.h" +#endif PLUGIN_HEADER +#ifndef PACBOX_AUDIO_ENABLED PLUGIN_IRAM_DECLARE +#endif struct plugin_api* rb; @@ -109,8 +114,10 @@ /* A buffer to render Pacman's 244x288 screen into */ static unsigned char video_buffer[ScreenWidth*ScreenHeight] __attribute__ ((aligned (16))); -static long start_time; +static long start_time, end_time; static long video_frames = 0; +static bool volatile game_menu = false; +static bool volatile do_exit = false; static int dipDifficulty[] = { DipDifficulty_Normal, DipDifficulty_Hard }; static int dipLives[] = { DipLives_1, DipLives_2, DipLives_3, DipLives_5 }; @@ -170,6 +177,9 @@ }; static const struct menu_item items[] = { +#ifdef PACBOX_AUDIO_ENABLED + { "Audio Playback", NULL }, +#endif { "Difficulty", NULL }, { "Pacmen Per Game", NULL }, { "Bonus Life", NULL }, @@ -179,6 +189,19 @@ { "Quit", NULL }, }; + enum menu_item_id { +#ifdef PACBOX_AUDIO_ENABLED + MRES_AUDIO, +#endif + MRES_DIFFICULTY, + MRES_PACMEN_PER_GAME, + MRES_BONUS_LIFE, + MRES_GHOST_NAMES, + MRES_DISPLAY_FPS, + MRES_RESTART, + MRES_QUIT + }; + m = menu_init(rb, items, sizeof(items) / sizeof(*items), NULL, NULL, NULL, NULL); @@ -189,7 +212,12 @@ switch(result) { - case 0: +#ifdef PACBOX_AUDIO_ENABLED + case MRES_AUDIO: + playback_control(rb); + break; +#endif + case MRES_DIFFICULTY: new_setting=settings.difficulty; rb->set_option("Difficulty", &new_setting, INT, difficulty_options , 2, NULL); @@ -198,7 +226,7 @@ need_restart=true; } break; - case 1: + case MRES_PACMEN_PER_GAME: new_setting=settings.numlives; rb->set_option("Pacmen Per Game", &new_setting, INT, numlives_options , 4, NULL); @@ -207,7 +235,7 @@ need_restart=true; } break; - case 2: + case MRES_BONUS_LIFE: new_setting=settings.bonus; rb->set_option("Bonus Life", &new_setting, INT, bonus_options , 4, NULL); @@ -216,7 +244,7 @@ need_restart=true; } break; - case 3: + case MRES_GHOST_NAMES: new_setting=settings.ghostnames; rb->set_option("Ghost Names", &new_setting, INT, ghostname_options , 2, NULL); @@ -225,11 +253,11 @@ need_restart=true; } break; - case 4: /* Show FPS */ + case MRES_DISPLAY_FPS: rb->set_option("Display FPS",&settings.showfps,INT, noyes, 2, NULL); break; - case 5: /* Restart */ + case MRES_RESTART: need_restart=true; menu_quit=1; break; @@ -250,23 +278,21 @@ restart game usb connected */ - return (result==6); + return (result==MRES_QUIT); } /* Runs the game engine for one frame. */ -static int gameProc( void ) +static void gameProc( void ) { - int x; int fps; char str[80]; int status; - long end_time; int frame_counter = 0; int yield_counter = 0; - + while (1) { /* Run the machine for one frame (1/60th second) */ @@ -288,14 +314,8 @@ #endif ) { end_time = *rb->current_tick; - x = pacbox_menu(); - rb->lcd_clear_display(); -#ifdef HAVE_REMOTE_LCD - rb->lcd_remote_clear_display(); - rb->lcd_remote_update(); -#endif - if (x == 1) { return 1; } - start_time += *rb->current_tick-end_time; + game_menu = true; + return; } #ifdef PACMAN_HAS_REMOTE @@ -358,14 +378,23 @@ } } } - return 0; + + do_exit = true; + return; } +#ifdef PACBOX_ON_COP +static unsigned char pacbox_stack[ 2048 ]; +static size_t pacbox_stack_size = 2048; +#endif + enum plugin_status plugin_start(struct plugin_api* api, void* parameter) { (void)parameter; +#ifndef PACBOX_AUDIO_ENABLED PLUGIN_IRAM_INIT(api) +#endif rb = api; #ifdef HAVE_ADJUSTABLE_CPU_FREQ @@ -406,11 +435,48 @@ init_PacmanMachine(settings_to_dip(settings)); /* Load the romset */ - if (loadROMS()) { + if (loadROMS()) + { start_time = *rb->current_tick-1; - - gameProc(); - + + do { +#ifdef PACBOX_ON_COP + struct thread_entry* pacbox_thread_id; + + if ((pacbox_thread_id = rb->create_thread( gameProc, + (uint8_t*)pacbox_stack, pacbox_stack_size, 0, "pacbox_game" + IF_PRIO(,PRIORITY_PLAYBACK) IF_COP(, COP))) == NULL) + { + rb->splash(HZ*2, "Couldn't create PacBox thread" ); + do_exit = true; + } + else + { + /* Wait for game to end */ + rb->thread_wait(pacbox_thread_id); +#else + { + gameProc(); +#endif + + if( game_menu ) + { + rb->yield(); + int x = pacbox_menu(); + rb->lcd_clear_display(); +#ifdef HAVE_REMOTE_LCD + rb->lcd_remote_clear_display(); + rb->lcd_remote_update(); +#endif + if (x == 1) + do_exit = true; + + game_menu = false; + start_time += *rb->current_tick-1 - end_time; + }; + } + } while (!do_exit); + /* Save the user settings if they have changed */ if (rb->memcmp(&settings,&old_settings,sizeof(settings))!=0) { rb->splash(0, "Saving settings..."); Index: pacbox.h =================================================================== --- pacbox.h (revision 15844) +++ pacbox.h (working copy) @@ -167,4 +167,27 @@ #define FPS 20 #endif +/* Can we run the emulator on a separate thread on cop? + The only advantage of doing so is to enable audio codecs to run on the + main cpu. Note that doing so requires turning off the iram usage + of pacbox, since codecs use iram, so may not be appropriate to turn + on for all dual core targets */ +#if defined(IPOD_VIDEO) +#define PACBOX_ON_COP #endif + +#if defined (PACBOX_ON_COP) || defined (TOSHIBA_GIGABEAT_F) +#define PACBOX_AUDIO_ENABLED +#endif + +#ifdef PACBOX_ON_COP +#define PACBOX_IBSS +#define PACBOX_IDATA +#define PACBOX_ICODE .text +#else +#define PACBOX_IBSS IBSS_ATTR +#define PACBOX_IDATA IDATA_ATTR +#define PACBOX_ICODE .icode +#endif + +#endif Index: z80.c =================================================================== --- z80.c (revision 15844) +++ z80.c (working copy) @@ -26,9 +26,10 @@ #include "hardware.h" #include "z80.h" #include "z80_internal.h" +#include "pacbox.h" // Table with parity, sign and zero flags precomputed for each byte value -unsigned char PSZ_[256] IDATA_ATTR = { +unsigned char PSZ_[256] PACBOX_IDATA = { Zero|Parity, 0, 0, Parity, 0, Parity, Parity, 0, 0, Parity, Parity, 0, Parity, 0, 0, Parity, 0, Parity, Parity, 0, Parity, 0, 0, Parity, Parity, 0, 0, Parity, 0, Parity, Parity, 0, 0, Parity, Parity, 0, Parity, 0, 0, Parity, Parity, 0, 0, Parity, 0, Parity, Parity, 0, @@ -76,33 +77,33 @@ /** */ unsigned do_opcode_xycb( unsigned xy ); -unsigned iflags_ IBSS_ATTR; // Interrupt mode (bits 0 and 1) and flags -unsigned cycles_ IBSS_ATTR; // Number of CPU cycles elapsed so far +unsigned iflags_ PACBOX_IBSS ; // Interrupt mode (bits 0 and 1) and flags +unsigned cycles_ PACBOX_IBSS ; // Number of CPU cycles elapsed so far // Registers -unsigned char B IBSS_ATTR; //@- B register -unsigned char C IBSS_ATTR; //@- C register -unsigned char D IBSS_ATTR; //@- D register -unsigned char E IBSS_ATTR; //@- E register -unsigned char H IBSS_ATTR; //@- H register -unsigned char L IBSS_ATTR; //@- L register -unsigned char A IBSS_ATTR; //@- A register (accumulator) -unsigned char F IBSS_ATTR; //@- Flags register -unsigned char B1 IBSS_ATTR; //@- Alternate B register (B') -unsigned char C1 IBSS_ATTR; //@- Alternate C register (C') -unsigned char D1 IBSS_ATTR; //@- Alternate D register (D') -unsigned char E1 IBSS_ATTR; //@- Alternate E register (E') -unsigned char H1 IBSS_ATTR; //@- Alternate H register (H') -unsigned char L1 IBSS_ATTR; //@- Alternate L register (L') -unsigned char A1 IBSS_ATTR; //@- Alternate A register (A') -unsigned char F1 IBSS_ATTR; //@- Alternate flags register (F') -unsigned IX IBSS_ATTR; //@- Index register X -unsigned IY IBSS_ATTR; //@- Index register Y -unsigned PC IBSS_ATTR; //@- Program counter -unsigned SP IBSS_ATTR; //@- Stack pointer -unsigned char I IBSS_ATTR; //@- Interrupt register -unsigned char R IBSS_ATTR; //@- Refresh register +unsigned char B PACBOX_IBSS ; //@- B register +unsigned char C PACBOX_IBSS ; //@- C register +unsigned char D PACBOX_IBSS ; //@- D register +unsigned char E PACBOX_IBSS ; //@- E register +unsigned char H PACBOX_IBSS ; //@- H register +unsigned char L PACBOX_IBSS ; //@- L register +unsigned char A PACBOX_IBSS ; //@- A register (accumulator) +unsigned char F PACBOX_IBSS ; //@- Flags register +unsigned char B1 PACBOX_IBSS ; //@- Alternate B register (B') +unsigned char C1 PACBOX_IBSS ; //@- Alternate C register (C') +unsigned char D1 PACBOX_IBSS ; //@- Alternate D register (D') +unsigned char E1 PACBOX_IBSS ; //@- Alternate E register (E') +unsigned char H1 PACBOX_IBSS ; //@- Alternate H register (H') +unsigned char L1 PACBOX_IBSS ; //@- Alternate L register (L') +unsigned char A1 PACBOX_IBSS ; //@- Alternate A register (A') +unsigned char F1 PACBOX_IBSS ; //@- Alternate flags register (F') +unsigned IX PACBOX_IBSS ; //@- Index register X +unsigned IY PACBOX_IBSS ; //@- Index register Y +unsigned PC PACBOX_IBSS ; //@- Program counter +unsigned SP PACBOX_IBSS ; //@- Stack pointer +unsigned char I PACBOX_IBSS ; //@- Interrupt register +unsigned char R PACBOX_IBSS ; //@- Refresh register /** Returns the 16 bit register BC. */ Index: pacbox_arm.S =================================================================== --- pacbox_arm.S (revision 15844) +++ pacbox_arm.S (working copy) @@ -19,7 +19,7 @@ #include "pacbox.h" - .section .icode,"ax",%progbits + .section PACBOX_ICODE,"ax",%progbits .global blit_display /* void blit_display(fb_data* lcd_framebuffer, unsigned char* vbuf) Index: hardware.c =================================================================== --- hardware.c (revision 15844) +++ hardware.c (working copy) @@ -24,25 +24,26 @@ #include "plugin.h" #include "hardware.h" +#include "pacbox.h" extern struct plugin_api* rb; /* The main data for Pacman */ -unsigned char ram_[20*1024] IBSS_ATTR; // ROM (16K) and RAM (4K) -unsigned char charset_rom_[4*1024] IBSS_ATTR; // Character set ROM (4K) -unsigned char spriteset_rom_[4*1024] IBSS_ATTR; // Sprite set ROM (4K) -unsigned char dirty_[1024] IBSS_ATTR; -unsigned char video_mem_[1024] IBSS_ATTR; // Video memory (1K) -unsigned char color_mem_[1024] IBSS_ATTR; // Color memory (1K) -unsigned char charmap_[256*8*8] IBSS_ATTR; /* Character data for 256 8x8 characters */ +unsigned char ram_[20*1024] PACBOX_IBSS ; // ROM (16K) and RAM (4K) +unsigned char charset_rom_[4*1024] PACBOX_IBSS ; // Character set ROM (4K) +unsigned char spriteset_rom_[4*1024] PACBOX_IBSS ; // Sprite set ROM (4K) +unsigned char dirty_[1024] PACBOX_IBSS ; +unsigned char video_mem_[1024] PACBOX_IBSS ; // Video memory (1K) +unsigned char color_mem_[1024] PACBOX_IBSS ; // Color memory (1K) +unsigned char charmap_[256*8*8] PACBOX_IBSS ; /* Character data for 256 8x8 characters */ unsigned char spritemap_[64*16*16]; /* Sprite data for 64 16x16 sprites */ -unsigned char output_devices_ IBSS_ATTR; /* Output flip-flops set by the game program */ -unsigned char interrupt_vector_ IBSS_ATTR; -unsigned coin_counter_ IBSS_ATTR; -unsigned char port1_ IBSS_ATTR; -unsigned char port2_ IBSS_ATTR; -unsigned char dip_switches_ IBSS_ATTR; +unsigned char output_devices_ PACBOX_IBSS ; /* Output flip-flops set by the game program */ +unsigned char interrupt_vector_ PACBOX_IBSS ; +unsigned coin_counter_ PACBOX_IBSS ; +unsigned char port1_ PACBOX_IBSS ; +unsigned char port2_ PACBOX_IBSS ; +unsigned char dip_switches_ PACBOX_IBSS ; /* Internal tables and structures for faster access to data */ struct PacmanSprite sprites_[8]; /* Sprites */