Update of /cvsroot/arcem/arcem/gp2x In directory vz-cvs-4.sog:/tmp/cvs-serv17456/arcem/gp2x
Modified Files: DispKbd.c filecalls.c sound.c Log Message: Merge arcem-fast to trunk Index: filecalls.c =================================================================== RCS file: /cvsroot/arcem/arcem/gp2x/filecalls.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- filecalls.c 24 Feb 2006 23:01:24 -0000 1.1 +++ filecalls.c 12 May 2012 17:34:51 -0000 1.2 @@ -23,9 +23,9 @@ * * @param sPath Location of directory to scan * @param hDir Pointer to a Directory struct to fill in - * @returns 1 on success 0 on failure + * @returns true on success false on failure */ -unsigned Directory_Open(const char *sPath, Directory *hDirectory) +bool Directory_Open(const char *sPath, Directory *hDirectory) { assert(sPath); assert(*sPath); @@ -34,9 +34,9 @@ hDirectory->hDir = opendir(sPath); if(NULL == hDirectory->hDir) { - return 0; + return false; } else { - return 1; + return true; } } @@ -81,9 +81,9 @@ * * @param sPath Path to file to check * @param phFileInfo pointer to FileInfo struct to fill in - * @returns 0 on failure 1 on success + * @returns false on failure true on success */ -unsigned char File_GetInfo(const char *sPath, FileInfo *phFileInfo) +bool File_GetInfo(const char *sPath, FileInfo *phFileInfo) { struct stat hEntryInfo; @@ -93,25 +93,25 @@ if (stat(sPath, &hEntryInfo) != 0) { fprintf(stderr, "Warning: could not stat() entry \'%s\': %s\n", sPath, strerror(errno)); - return 0; + return false; } /* Initialise components */ - phFileInfo->bIsRegularFile = 0; - phFileInfo->bIsDirectory = 0; + phFileInfo->bIsRegularFile = false; + phFileInfo->bIsDirectory = false; if (S_ISREG(hEntryInfo.st_mode)) { - phFileInfo->bIsRegularFile = 1; + phFileInfo->bIsRegularFile = true; } if (S_ISDIR(hEntryInfo.st_mode)) { - phFileInfo->bIsDirectory = 1; + phFileInfo->bIsDirectory = true; } /* Fill in Size */ phFileInfo->ulFilesize = hEntryInfo.st_size; /* Success! */ - return 1; + return true; } Index: DispKbd.c =================================================================== RCS file: /cvsroot/arcem/arcem/gp2x/DispKbd.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- DispKbd.c 10 Mar 2006 18:27:56 -0000 1.3 +++ DispKbd.c 12 May 2012 17:34:51 -0000 1.4 @@ -1,16 +1,6 @@ /* (c) David Alan Gilbert 1995-1999 - see Readme file for copying info */ /* Display and keyboard interface for the Arc emulator */ -// #define MOUSEKEY XK_KP_Add - -/*#define DEBUG_VIDCREGS*/ -/* NOTE: Can't use ARMul's refresh function because it has a small - limit on the time delay from posting the event to it executing */ -/* It's actually decremented once every POLLGAP - that is called - with the ARMul scheduler */ - -#define AUTOREFRESHPOLL 2500 - #include <stdio.h> #include <limits.h> @@ -20,6 +10,8 @@ #include "DispKbd.h" #include "archio.h" #include "hdc63463.h" +#include "../armemu.h" +#include "arch/displaydev.h" #include <fcntl.h> #include <linux/fb.h> @@ -28,7 +20,6 @@ #include <sys/ioctl.h> #include <termios.h> -#define ControlHeight 30 #define CURSORCOLBASE 250 #define KEY_PAD_UP (1<<0) @@ -161,14 +152,11 @@ -/* HOSTDISPLAY is too verbose here - but HD could be hard disc somewhere else! */ -/*#define HD HOSTDISPLAY*/ -#define DC DISPLAYCONTROL - static void UpdateCursorPos(ARMul_State *state); static void SelectScreenMode(int x, int y, int bpp); +static void RefreshMouse(ARMul_State *state); -static void set_cursor_palette(unsigned int *pal); +static void set_cursor_palette(uint16_t *pal); static int MonitorWidth; static int MonitorHeight; @@ -199,129 +187,163 @@ MMSP2(0x295A)=mmsp2pal[i]; } -/*-----------------------------------------------------------------------------*/ -/* Configure the colourmap for the standard 1 bpp modes */ -static void DoColourMap_2(ARMul_State *state) { - int c; +/* ------------------------------------------------------------------ */ - if (!(DC.MustRedraw || DC.MustResetPalette)) return; +static void set_cursor_palette(uint16_t *pal) +{ + int c; + for(c = 0; c < 2; c++) /* Should be 0..3 but gp2x h/w cursor is only 2 colour */ + { + MMSP2SETCURSORPAL( c, + (pal[c] & 0xf) * 17, + (pal[c] >> 4 & 0xf) * 17, + (pal[c] >> 8 & 0xf) * 17 + ); + } +} -/* MMSP2 DOES NOT HAVE 1BPP SUPPORT! */ - for(c=0;c<2;c++) - { - MMSP2SETPAL( c, - (VIDC.Palette[c] & 15)*17, - ((VIDC.Palette[c]>>4) & 15)*17, - ((VIDC.Palette[c]>>8) & 15)*17 - ); - }; - mmsp2writepal(); +/* ------------------------------------------------------------------ */ - set_cursor_palette(VIDC.CursorPalette); +/* Palettised display code */ +#define PDD_Name(x) pdd_##x - DC.MustResetPalette=0; -}; /* DoColourMap_2 */ +static int BorderPalEntry; +static int palette_updated = 0; -/*-----------------------------------------------------------------------------*/ -/* Configure the colourmap for the standard 2 bpp modes */ -static void DoColourMap_4(ARMul_State *state) { - int c; +typedef struct { + ARMword *data; + int offset; +} PDD_Row; - if (!(DC.MustRedraw || DC.MustResetPalette)) return; +static void PDD_Name(Host_ChangeMode)(ARMul_State *state,int width,int height,int depth,int hz); -/* MMSP2 DOES NOT HAVE 2BPP SUPPORT! */ - for(c=0;c<4;c++) +static void PDD_Name(Host_SetPaletteEntry)(ARMul_State *state,int i,unsigned int phys) +{ + int r = (phys & 0xf)*0x11; + int g = ((phys>>4) & 0xf)*0x11; + int b = ((phys>>8) & 0xf)*0x11; + MMSP2SETPAL(i,r,g,b); + palette_updated = 1; +} + +static void PDD_Name(Host_SetBorderColour)(ARMul_State *state,unsigned int phys) +{ + /* Set border palette entry */ + if(BorderPalEntry != 256) { - MMSP2SETPAL( c, - (VIDC.Palette[c] & 15)*17, - ((VIDC.Palette[c]>>4) & 15)*17, - ((VIDC.Palette[c]>>8) & 15)*17 - ); - }; + int r = (phys & 0xf)*0x11; + int g = ((phys>>4) & 0xf)*0x11; + int b = ((phys>>8) & 0xf)*0x11; + MMSP2SETPAL(BorderPalEntry,r,g,b); + palette_updated = 1; + } +} - mmsp2writepal(); +static inline PDD_Row PDD_Name(Host_BeginRow)(ARMul_State *state,int row,int offset,int *alignment) +{ + PDD_Row drow; + offset = (MonitorWidth+offset)<<MonitorBpp; + drow.offset = offset & 0x1f; + drow.data = DirectScreenMemory+(offset>>5); + *alignment = drow.offset; + return drow; +} - set_cursor_palette(VIDC.CursorPalette); +static inline void PDD_Name(Host_EndRow)(ARMul_State *state,PDD_Row *row) { /* nothing */ }; - DC.MustResetPalette=0; -}; /* DoColourMap_4 */ +static inline ARMword *PDD_Name(Host_BeginUpdate)(ARMul_State *state,PDD_Row *row,unsigned int count,int *outoffset) +{ + *outoffset = row->offset; + return row->data; +} +static inline void PDD_Name(Host_EndUpdate)(ARMul_State *state,PDD_Row *row) { /* nothing */ }; -/*-----------------------------------------------------------------------------*/ -/* Configure the colourmap for the standard 4 bpp modes */ -static void DoColourMap_16(ARMul_State *state) { - int c; +static inline void PDD_Name(Host_AdvanceRow)(ARMul_State *state,PDD_Row *row,unsigned int count) +{ + row->offset += count; + row->data += count>>5; + row->offset &= 0x1f; +} - if (!(DC.MustRedraw || DC.MustResetPalette)) return; +static void +PDD_Name(Host_PollDisplay)(ARMul_State *state); - for(c=0;c<16;c++) +static void PDD_Name(Host_DrawBorderRect)(ARMul_State *state,int x,int y,int width,int height) +{ + if(BorderPalEntry != 256) { - MMSP2SETPAL( c, - (VIDC.Palette[c] & 15)*17, - ((VIDC.Palette[c]>>4) & 15)*17, - ((VIDC.Palette[c]>>8) & 15)*17 - ); - }; - - mmsp2writepal(); - - set_cursor_palette(VIDC.CursorPalette); - - DC.MustResetPalette=0; -}; /* DoColourMap_16 */ - - -/*-----------------------------------------------------------------------------*/ -/* Configure the colourmap for the 8bpp modes */ -static void DoColourMap_256(ARMul_State *state) { - int c; - int l4; - int l65; - int l7; - unsigned int pal; - int r, g, b; + /* TODO - Fill rect with border colour */ + } +} - if (!(DC.MustRedraw || DC.MustResetPalette)) return; +#include "../arch/paldisplaydev.c" +void PDD_Name(Host_ChangeMode)(ARMul_State *state,int width,int height,int depth,int hz) +{ + SelectScreenMode(width,height,depth); + HD.XScale = 1; + HD.YScale = 1; + HD.Width = MonitorWidth; + HD.Height = MonitorHeight; + + if(MonitorBpp > depth) + { + /* We have enough palette entries to have a border */ + BorderPalEntry = 1<<(1<<depth); + } + else + { + /* Disable border entry */ + BorderPalEntry = 256; + } - for (c = 0; c < 256; c++) + /* Calculate expansion params */ + if((MonitorBpp == depth) && (HD.XScale == 1)) + { + /* No expansion */ + HD.ExpandTable = NULL; + } + else + { + /* Expansion! */ + static ARMword expandtable[256]; + HD.ExpandFactor = 0; + while((1<<HD.ExpandFactor) < HD.XScale) + HD.ExpandFactor++; + HD.ExpandFactor += (MonitorBpp-depth); + HD.ExpandTable = expandtable; + unsigned int mul = 1; + int i; + for(i=0;i<HD.XScale;i++) { - l4 = c >> 1 & 8; - l65 = c >> 3 & 0xc; - l7 = c >> 4 & 8; - - pal = VIDC.Palette[c & 0xf]; - r = l4 | (pal & 7); - g = l65 | (pal >> 4 & 3); - b = l7 | (pal >> 8 & 7); - - MMSP2SETPAL( c, r*17, g*17, b*17 ); + mul |= 1<<(i*(1<<MonitorBpp)); } + GenExpandTable(HD.ExpandTable,1<<depth,HD.ExpandFactor,mul); + } - mmsp2writepal(); - - set_cursor_palette(VIDC.CursorPalette); + /* Screen is expected to be cleared */ + PDD_Name(Host_DrawBorderRect)(state,0,0,HD.Width,HD.Height); +} - DC.MustResetPalette=0; -}; /* DoColourMap_Standard */ +static void +PDD_Name(Host_PollDisplay)(ARMul_State *state) +{ + /* TODO - Surely there's a way of updating one palette entry at a time? */ + if(palette_updated) + { + palette_updated = 0; + mmsp2writepal(); + } -/* ------------------------------------------------------------------ */ + set_cursor_palette(VIDC.CursorPalette); -static void set_cursor_palette(unsigned int *pal) -{ - int c; - for(c = 0; c < 2; c++) /* Should be 0..3 but gp2x h/w cursor is only 2 colour */ - { - MMSP2SETCURSORPAL( c, - (pal[c] & 0xf) * 17, - (pal[c] >> 4 & 0xf) * 17, - (pal[c] >> 8 & 0xf) * 17 - ); - } + RefreshMouse(state); } + /* ------------------------------------------------------------------ */ /* Refresh the mouse's image */ @@ -370,46 +392,6 @@ -void -RefreshDisplay(ARMul_State *state) -{ - DC.AutoRefresh=AUTOREFRESHPOLL; - ioc.IRQStatus|=8; /* VSync */ - ioc.IRQStatus |= 0x20; /* Sound - just an experiment */ - IO_UpdateNirq(); - - DC.miny=MonitorHeight-1; - DC.maxy=0; - -static int hackdelay = 1; - - if ( --hackdelay ) - return; - hackdelay = 20; - - RefreshMouse(state); - - /* Figure out number of BPP */ - switch ((VIDC.ControlReg & 0xc)>>2) - { - case 0: - DoColourMap_2(state); - break; - case 1: - DoColourMap_4(state); - break; - case 2: - DoColourMap_16(state); - break; - case 3: - DoColourMap_256(state); - break; - } - - /*fprintf(stderr,"RefreshDisplay: Refreshed %d-%d\n",DC.miny,DC.maxy); */ - -}; /* RefreshDisplay */ - void readJoypad(void) { int ret=0; @@ -444,8 +426,8 @@ } /*-----------------------------------------------------------------------------*/ -void -DisplayKbd_InitHost(ARMul_State *state) +int +DisplayDev_Init(ARMul_State *state) { struct termios term; @@ -462,7 +444,11 @@ SelectScreenMode(320, 240, 3); openJoypad(); -} /* DisplayKbd_InitHost */ + + DisplayDev_FrameSkip = 4; /* TODO - Tweak */ + + return DisplayDev_Set(state,&PDD_DisplayDev); +} /* DisplayDev_Init */ /*-----------------------------------------------------------------------------*/ static void ProcessKey(ARMul_State *state, int key, int transition) { @@ -473,8 +459,7 @@ /* Move the Control pane window */ static void UpdateCursorPos(ARMul_State *state) { int x, y; - x=VIDC.Horiz_CursorStart-(VIDC.Horiz_DisplayStart * 2 ); - y=VIDC.Vert_CursorStart-VIDC.Vert_DisplayStart; + DisplayDev_GetCursorPos(state,&x,&y); MMSP2(0x2920)=20+((x*320)/MonitorWidth); MMSP2(0x2922)=(y*240)/MonitorHeight; @@ -521,7 +506,7 @@ /*----------------------------------------------------------------------------*/ int -DisplayKbd_PollHost(ARMul_State *state) +Kbd_PollHostKbd(ARMul_State *state) { int run=0; int MouseX=0, MouseY=0; @@ -606,240 +591,8 @@ } } return run; -} /* DisplayKbd_PollHost */ - - -static void UpdateGp2xScreenFromVIDC(void) -{ - SelectScreenMode((VIDC.Horiz_DisplayEnd - VIDC.Horiz_DisplayStart) * 2, - VIDC.Vert_DisplayEnd - VIDC.Vert_DisplayStart, - (VIDC.ControlReg & 0xc) >> 2); -} - - -/*-----------------------------------------------------------------------------*/ -void VIDC_PutVal(ARMul_State *state,ARMword address, ARMword data,int bNw) { - unsigned int addr, val; - - addr=(data>>24) & 255; - val=data & 0xffffff; - - if (!(addr & 0xc0)) { - int Log, Sup,Red,Green,Blue; - - /* This lot presumes it's not 8bpp mode! */ - Log=(addr>>2) & 15; - Sup=(val >> 12) & 1; - Blue=(val >> 8) & 15; - Green=(val >> 4) & 15; - Red=val & 15; -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC Palette write: Logical=%d Physical=(%d,%d,%d,%d)\n", - Log,Sup,Red,Green,Blue); -#endif - VideoRelUpdateAndForce(DC.MustResetPalette,VIDC.Palette[Log],(val & 0x1fff)); - return; - }; - - addr&=~3; - switch (addr) { - case 0x40: /* Border col */ -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC border colour write val=0x%x\n",val); -#endif - VideoRelUpdateAndForce(DC.MustResetPalette,VIDC.BorderCol,(val & 0x1fff)); - break; - - case 0x44: /* Cursor palette log col 1 */ -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC cursor log col 1 write val=0x%x\n",val); -#endif - VideoRelUpdateAndForce(DC.MustResetPalette,VIDC.CursorPalette[0],(val & 0x1fff)); - break; - - case 0x48: /* Cursor palette log col 2 */ -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC cursor log col 2 write val=0x%x\n",val); -#endif - VideoRelUpdateAndForce(DC.MustResetPalette,VIDC.CursorPalette[1],(val & 0x1fff)); - break; - - case 0x4c: /* Cursor palette log col 3 */ -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC cursor log col 3 write val=0x%x\n",val); -#endif - VideoRelUpdateAndForce(DC.MustResetPalette,VIDC.CursorPalette[2],(val & 0x1fff)); - break; - - case 0x60: /* Stereo image reg 7 */ - case 0x64: /* Stereo image reg 0 */ - case 0x68: /* Stereo image reg 1 */ - case 0x6c: /* Stereo image reg 2 */ - case 0x70: /* Stereo image reg 3 */ - case 0x74: /* Stereo image reg 4 */ - case 0x78: /* Stereo image reg 5 */ - case 0x7c: /* Stereo image reg 6 */ -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC stereo image reg write val=0x%x\n",val); -#endif - VIDC.StereoImageReg[(addr==0x60)?7:((addr-0x64)/4)]=val & 7; - break; - - case 0x80: -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC Horiz cycle register val=%d\n",val>>14); -#endif - VideoRelUpdateAndForce(DC.MustRedraw,VIDC.Horiz_Cycle,(val>>14) & 0x3ff); - break; - - case 0x84: -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC Horiz sync width register val=%d\n",val>>14); -#endif - VideoRelUpdateAndForce(DC.MustRedraw,VIDC.Horiz_SyncWidth,(val>>14) & 0x3ff); - break; - - case 0x88: -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC Horiz border start register val=%d\n",val>>14); -#endif - VideoRelUpdateAndForce(DC.MustRedraw,VIDC.Horiz_BorderStart,(val>>14) & 0x3ff); - break; - - case 0x8c: -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC Horiz display start register val=%d\n",val>>14); -#endif - VideoRelUpdateAndForce(DC.MustRedraw,VIDC.Horiz_DisplayStart,(val>>14) & 0x3ff); -#ifdef DIRECT_DISPLAY - //if (DC.MustRedraw) - UpdateGp2xScreenFromVIDC(); -#endif - break; - - case 0x90: -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC Horiz display end register val=%d\n",val>>14); -#endif - VideoRelUpdateAndForce(DC.MustRedraw,VIDC.Horiz_DisplayEnd,(val>>14) & 0x3ff); -#ifdef DIRECT_DISPLAY - //if (DC.MustRedraw) - UpdateGp2xScreenFromVIDC(); -#endif - break; - - case 0x94: -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC horizontal border end register val=%d\n",val>>14); -#endif - VideoRelUpdateAndForce(DC.MustRedraw,VIDC.Horiz_BorderEnd,(val>>14) & 0x3ff); - break; - - case 0x98: -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC horiz cursor start register val=%d\n",val>>13); -#endif - VIDC.Horiz_CursorStart=(val>>13) & 0x7ff; - UpdateCursorPos(state); - break; - - case 0x9c: -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC horiz interlace register val=%d\n",val>>14); -#endif - VideoRelUpdateAndForce(DC.MustRedraw,VIDC.Horiz_Interlace,(val>>14) & 0x3ff); - break; - - case 0xa0: -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC Vert cycle register val=%d\n",val>>14); -#endif - VideoRelUpdateAndForce(DC.MustRedraw,VIDC.Vert_Cycle,(val>>14) & 0x3ff); - break; - - case 0xa4: -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC Vert sync width register val=%d\n",val>>14); -#endif - VideoRelUpdateAndForce(DC.MustRedraw,VIDC.Vert_SyncWidth,(val>>14) & 0x3ff); - break; - - case 0xa8: -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC Vert border start register val=%d\n",val>>14); -#endif - VideoRelUpdateAndForce(DC.MustRedraw,VIDC.Vert_BorderStart,(val>>14) & 0x3ff); - break; - - case 0xac: -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC Vert disp start register val=%d\n",val>>14); -#endif - VideoRelUpdateAndForce(DC.MustRedraw,VIDC.Vert_DisplayStart,((val>>14) & 0x3ff)); -#ifdef DIRECT_DISPLAY - //if (DC.MustRedraw) - UpdateGp2xScreenFromVIDC(); -#endif - break; - - case 0xb0: -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC Vert disp end register val=%d\n",val>>14); -#endif - VideoRelUpdateAndForce(DC.MustRedraw,VIDC.Vert_DisplayEnd,(val>>14) & 0x3ff); -#ifdef DIRECT_DISPLAY - //if (DC.MustRedraw) - UpdateGp2xScreenFromVIDC(); -#endif - break; - - case 0xb4: -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC Vert Border end register val=%d\n",val>>14); -#endif - VideoRelUpdateAndForce(DC.MustRedraw,VIDC.Vert_BorderEnd,(val>>14) & 0x3ff); - break; - - case 0xb8: -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC Vert cursor start register val=%d\n",val>>14); -#endif - VIDC.Vert_CursorStart=(val>>14) & 0x3ff; - UpdateCursorPos(state); - break; - - case 0xbc: -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC Vert cursor end register val=%d\n",val>>14); -#endif - VIDC.Vert_CursorEnd=(val>>14) & 0x3ff; - UpdateCursorPos(state); - break; - - case 0xc0: -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC Sound freq register val=%d\n",val); -#endif - VIDC.SoundFreq=val & 0xff; - break; - - case 0xe0: -#ifdef DEBUG_VIDCREGS - fprintf(stderr,"VIDC Control register val=0x%x\n",val); -#endif - VideoRelUpdateAndForce(DC.MustRedraw,VIDC.ControlReg,val & 0xffff); -#ifdef DIRECT_DISPLAY - //if (DC.MustRedraw) - UpdateGp2xScreenFromVIDC(); -#endif - break; - - default: - fprintf(stderr,"Write to unknown VIDC register reg=0x%x val=0x%x\n",addr,val); - break; +} /* Kbd_PollHostKbd */ - }; /* Register switch */ -}; /* PutValVIDC */ void gp2xScreenOffset(int offset) { @@ -853,8 +606,14 @@ { // printf("request set screen mode to %dx%d at %d bpp\n",x, y, 1<<bpp); + if(bpp<2) + bpp = 2; /* MMSP2 doesn't support 1bpp or 2bpp */ + if (x<=0 || x>1024 || y<=0 || y>768 || bpp<=0 || bpp>3) - return; + { + fprintf(stderr,"Bad mode\n"); + exit(EXIT_FAILURE); + } if (x==MonitorWidth && y==MonitorHeight && bpp==MonitorBpp) return; @@ -871,7 +630,7 @@ if ( screenfd < 0 ) { fprintf(stderr,"Unable to open mmsp2 device\n"); - return; + exit(EXIT_FAILURE); } mmsp2 = (unsigned short *) mmap( NULL, @@ -885,8 +644,7 @@ if ( mmsp2 == (unsigned short *)-1 ) { fprintf(stderr,"Unable to memory map the mmsp2 hardware\n"); - close( screenfd ); - return; + exit(EXIT_FAILURE); } DirectScreenExtent = 512*1024; @@ -902,13 +660,18 @@ if ( DirectScreenMemory == (int *)-1 ) { fprintf(stderr,"Unable to memory map the screen memory\n"); - close( screenfd ); - return; + exit(EXIT_FAILURE); } memset( DirectScreenMemory, 0, DirectScreenExtent ); } + if(x*y<<bpp > DirectScreenExtent<<3) + { + fprintf(stderr,"Mode too big\n"); + exit(EXIT_FAILURE); + } + bpp=1<<bpp; MMSP2(0x28da) = (((bpp+1)/8)<<9) | 0xab; /* bpp, enables */ MMSP2(0x290c) = x*((bpp+1)/8); /* line length, bytes */ Index: sound.c =================================================================== RCS file: /cvsroot/arcem/arcem/gp2x/sound.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- sound.c 24 Feb 2006 23:01:24 -0000 1.1 +++ sound.c 12 May 2012 17:34:51 -0000 1.2 @@ -11,93 +11,174 @@ #include "../armdefs.h" #include "../arch/sound.h" +#include "../arch/displaydev.h" +#include "../armemu.h" -static unsigned long format = AFMT_S16_LE; -static unsigned long channels = 2; -/*static unsigned long bits = 16;*/ -static unsigned long sampleRate = 0; - -static unsigned long bufferSize = 0; - -/*static unsigned long numberGot = 0;*/ - -static unsigned long bufferRead = 0; -static unsigned long bufferWrite = 0; - -/* This is how many 16 byte blocks to get before leaving - * sound_poll to return to the emulator */ -static unsigned long blocksAtATime = 1; -/* This is how many 16 byte blocks should be collected before - * calling write(), so this controls the size of the buffer. */ -static unsigned long numberOfFills = 100; - -/* This is the size of the gap between sound_poll doing something. */ -static unsigned long delayTotal = 100; -static unsigned long delayProgress = 0; +static uint32_t format = AFMT_S16_LE; +static uint32_t channels = 2; +static uint32_t sampleRate = 44100; static int soundDevice; -static SoundData *buffer = NULL; +/* Threading currently doesn't work very well - no priority control is in place, so the sound thread hardly ever gets any CPU time */ +//#define SOUND_THREAD + +#ifdef SOUND_THREAD static pthread_t thread; static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; -void -sound_poll(void) +#define BUFFER_SAMPLES (16384) /* 8K stereo pairs */ + +SoundData sound_buffer[BUFFER_SAMPLES]; +volatile int32_t sound_buffer_in=BUFFER_SAMPLES; /* Number of samples we've placed in the buffer */ +volatile int32_t sound_buffer_out=0; /* Number of samples read out by the sound thread */ +static const int32_t sound_buff_mask=BUFFER_SAMPLES-1; +#else +SoundData sound_buffer[256*2]; /* Must be >= 2*Sound_BatchSize! */ +#endif + +SoundData *Sound_GetHostBuffer(int32_t *destavail) { - static unsigned long localBufferWrite = 0; +#ifdef SOUND_THREAD + /* Work out how much space is available until next wrap point, or we start overwriting data */ + pthread_mutex_lock(&mut); + int32_t local_buffer_in = sound_buffer_in; + int32_t used = local_buffer_in-sound_buffer_out; + pthread_mutex_unlock(&mut); + int32_t ofs = local_buffer_in & sound_buff_mask; + int32_t buffree = BUFFER_SAMPLES-MAX(ofs,used); + *destavail = buffree>>1; + return sound_buffer + ofs; +#else + /* Just assume we always have enough space for the max batch size */ + *destavail = sizeof(sound_buffer)/(sizeof(SoundData)*2); + return sound_buffer; +#endif +} - delayProgress++; - if (delayProgress >= delayTotal) { - int i; +void Sound_HostBuffered(SoundData *buffer,int32_t numSamples) +{ + numSamples <<= 1; +#ifdef SOUND_THREAD + pthread_mutex_lock(&mut); + int32_t local_buffer_in = sound_buffer_in; + int32_t used = local_buffer_in-sound_buffer_out; + pthread_mutex_unlock(&mut); + int32_t ofs = local_buffer_in & sound_buff_mask; - /*bufferWrite = (numberGot + i) * 16 * 2);*/ + local_buffer_in += numSamples; + + if(buffree == numSamples) + { + fprintf(stderr,"*** sound overflow! ***\n"); + if(Sound_FudgeRate < -10) + Sound_FudgeRate = Sound_FudgeRate/2; + else + Sound_FudgeRate+=10; + } + else if(!used) + { + fprintf(stderr,"*** sound underflow! ***\n"); + if(Sound_FudgeRate > 10) + Sound_FudgeRate = Sound_FudgeRate/2; + else + Sound_FudgeRate-=10; + } + else if(used < BUFFER_SAMPLES/4) + { + Sound_FudgeRate--; + } + else if(buffree < BUFFER_SAMPLES/4) + { + Sound_FudgeRate++; + } + else if(Sound_FudgeRate) + { + /* Bring the fudge value back towards 0 until we go out of the comfort zone */ + Sound_FudgeRate += (Sound_FudgeRate>0?-1:1); + } - for (i = 0; i < blocksAtATime; i++) { - /* *Important*, you must respect whether sound dma - * is enabled or not at all times otherwise sound - * will come out wrong. - */ - /*if( SoundDMAFetch(buffer + ((numberGot + i) * 16 * 2)) == 1 ) return; */ - if (SoundDMAFetch(buffer + localBufferWrite) == 1) { - return; - } - } + pthread_mutex_lock(&mut); + sound_buffer_in = local_buffer_in; + pthread_mutex_unlock(&mut); + pthread_cond_broadcast(&cond); - localBufferWrite += (blocksAtATime * 16 * 2); - if (localBufferWrite >= (bufferSize / sizeof(SoundData))) { - localBufferWrite = 0; + pthread_yield(); +#else + audio_buf_info buf; + if (ioctl(soundDevice, SOUND_PCM_GETOSPACE, &buf) != -1) { + /* Adjust fudge rate based around how much buffer space is available + We aim for the buffer to be somewhere between 1/4 and 3/4 full, but don't + explicitly set the buffer size, so we're at the mercy of the sound system + in terms of how much lag there'll be */ + int32_t bufsize = buf.fragsize*buf.fragstotal; + int32_t buffree = buf.bytes/sizeof(SoundData); + int32_t used = (bufsize-buf.bytes)/sizeof(SoundData); + int32_t stepsize = Sound_DMARate>>2; + bufsize /= sizeof(SoundData); + if(numSamples > buffree) + { + fprintf(stderr,"*** sound overflow! %d %d %d %d ***\n",numSamples-buffree,ARMul_EmuRate,Sound_FudgeRate,Sound_DMARate); + numSamples = buffree; /* We could block until space is available, but I'm woried we'd get stuck blocking forever because the FudgeRate increase wouldn't compensate for the ARMul cycles lost due to blocking */ + if(Sound_FudgeRate < -stepsize) + Sound_FudgeRate = Sound_FudgeRate/2; + else + Sound_FudgeRate+=stepsize; } - - if (pthread_mutex_trylock(&mut) == 0) { - bufferWrite = localBufferWrite; - pthread_mutex_unlock(&mut); - pthread_cond_broadcast(&cond); + else if(!used) + { + fprintf(stderr,"*** sound underflow! %d %d %d ***\n",ARMul_EmuRate,Sound_FudgeRate,Sound_DMARate); + if(Sound_FudgeRate > stepsize) + Sound_FudgeRate = Sound_FudgeRate/2; + else + Sound_FudgeRate-=stepsize; + } + else if(used < bufsize/4) + { + Sound_FudgeRate-=stepsize>>4; + } + else if(buffree < bufsize/4) + { + Sound_FudgeRate+=stepsize>>4; + } + else if(Sound_FudgeRate) + { + /* Bring the fudge value back towards 0 until we go out of the comfort zone */ + Sound_FudgeRate += (Sound_FudgeRate>0?-1:1); } - delayProgress = 0; } + + write(soundDevice,buffer,numSamples*sizeof(SoundData)); +#endif } +#ifdef SOUND_THREAD static void * sound_writeThread(void *arg) { + int32_t local_buffer_out = sound_buffer_out; for (;;) { - int y; + int32_t avail; pthread_mutex_lock(&mut); - y = bufferWrite; + sound_buffer_out = local_buffer_out; + avail = sound_buffer_in-local_buffer_out; pthread_mutex_unlock(&mut); - if (bufferRead != y) { - if (y < bufferRead) { - y = bufferSize / sizeof(SoundData); - } - write(soundDevice, buffer + bufferRead, - (y - bufferRead) * sizeof(SoundData)); - bufferRead = y; - if (bufferRead >= (bufferSize / sizeof(SoundData))) { - bufferRead = 0; + printf("%d\n",avail); + if (avail) { + int32_t ofs = local_buffer_out & sound_buff_mask; + + if(ofs + avail > BUFFER_SAMPLES) { + /* We're about to wrap */ + avail = BUFFER_SAMPLES-ofs; } + + write(soundDevice, sound_buffer + ofs, + avail * sizeof(SoundData)); + + local_buffer_out += avail; } else { pthread_mutex_lock(&mut); pthread_cond_wait(&cond, &mut); @@ -107,11 +188,12 @@ return NULL; } +#endif int -sound_init(void) +Sound_InitHost(ARMul_State *state) { - if ((soundDevice = open("/dev/dsp", O_CREAT | O_WRONLY )) < 0) { + if ((soundDevice = open("/dev/dsp", O_WRONLY )) < 0) { fprintf(stderr, "Could not open audio device /dev/dsp\n"); return -1; } @@ -137,42 +219,33 @@ } if (ioctl(soundDevice, SOUND_PCM_WRITE_RATE, &sampleRate) == -1) { - fprintf(stderr, "Could not set initial sample rate\n"); + fprintf(stderr, "Could not set sample rate\n"); return -1; } - bufferSize = numberOfFills * 16 * 2 * sizeof(SoundData); - buffer = malloc(bufferSize); - if (!buffer) { - fprintf(stderr, "sound_init(): Out of memory\n"); - exit(EXIT_FAILURE); + if (ioctl(soundDevice, SOUND_PCM_READ_RATE, &sampleRate) == -1) { + fprintf(stderr, "Could not read sample rate\n"); + return -1; } - pthread_create(&thread, NULL, sound_writeThread, 0); + /* Check that GETOSPACE is supported */ + audio_buf_info buf; + if (ioctl(soundDevice, SOUND_PCM_GETOSPACE, &buf) == -1) { + fprintf(stderr,"Could not read output space\n"); + return -1; + } + fprintf(stderr,"Sound buffer params: frags %d total %d size %d bytes %d\n",buf.fragments,buf.fragstotal,buf.fragsize,buf.bytes); - return 0; -} + eSound_StereoSense = Stereo_LeftRight; -/** - * sound_setSampleRate - * - * Set the sample rate of sound, using - * the period specified in microseconds. - * - * @param period period of sample in microseconds - */ -void -sound_setSampleRate(unsigned long period) -{ - /* freq = 1 / (period * 10^-6) */ - if (period != 0) { - sampleRate = 1000000 / period; - } else { - sampleRate = 44100; - } + /* Use a decent batch size */ + Sound_BatchSize = 256; - printf("asked to set sample rate to %lu\n", sampleRate); - ioctl(soundDevice, SOUND_PCM_WRITE_RATE, &sampleRate); - ioctl(soundDevice, SOUND_PCM_READ_RATE, &sampleRate); - printf("set sample rate to %lu\n", sampleRate); + Sound_HostRate = sampleRate<<10; + +#ifdef SOUND_THREAD + pthread_create(&thread, NULL, sound_writeThread, 0); +#endif + + return 0; } ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ -- arcem-cvs mailing list arcem-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/arcem-cvs