optimizations, fixes, hacks, psp, ...
[picodrive.git] / platform / gp2x / 940ctl.c
index 66a5d2b..917ed29 100644 (file)
 #include "gp2x.h"\r
 #include "emu.h"\r
 #include "menu.h"\r
-#include "asmutils.h"\r
-#include "mp3.h"\r
+#include "../common/mp3.h"\r
+#include "../common/arm_utils.h"\r
+#include "../common/menu.h"\r
+#include "../common/emu.h"\r
 #include "../../Pico/PicoInt.h"\r
+#include "../../Pico/sound/ym2612.h"\r
 #include "../../Pico/sound/mix.h"\r
 \r
 /* we will need some gp2x internals here */\r
@@ -48,23 +51,12 @@ static FILE *loaded_mp3 = 0;
 }\r
 \r
 /* these will be managed locally on our side */\r
-extern int   *ym2612_dacen;\r
-extern INT32 *ym2612_dacout;\r
-extern void  *ym2612_regs;\r
-\r
 static UINT8 *REGS = 0;                /* we will also keep local copy of regs for savestates and such */\r
-static INT32 addr_A1;          /* address line A1      */\r
-static int      dacen;\r
+static INT32 *addr_A1;         /* address line A1      */\r
+\r
+static int   dacen;\r
 static INT32 dacout;\r
 static UINT8 ST_address;       /* address register     */\r
-static UINT8 ST_status;                /* status flag          */\r
-static UINT8 ST_mode;          /* mode  CSM / 3SLOT    */\r
-static int   ST_TA;                    /* timer a              */\r
-static int   ST_TAC;           /* timer a maxval       */\r
-static int   ST_TAT;           /* timer a ticker       */\r
-static UINT8 ST_TB;                    /* timer b              */\r
-static int   ST_TBC;           /* timer b maxval       */\r
-static int   ST_TBT;           /* timer b ticker       */\r
 \r
 static int   writebuff_ptr = 0;\r
 \r
@@ -82,16 +74,16 @@ static int set_timers( int v )
        /* b2 = timer enable a */\r
        /* b1 = load b */\r
        /* b0 = load a */\r
-       change = (ST_mode ^ v) & 0xc0;\r
-       ST_mode = v;\r
+       change = (ym2612_st->mode ^ v) & 0xc0;\r
+       ym2612_st->mode = v;\r
 \r
        /* reset Timer b flag */\r
        if( v & 0x20 )\r
-               ST_status &= ~2;\r
+               ym2612_st->status &= ~2;\r
 \r
        /* reset Timer a flag */\r
        if( v & 0x10 )\r
-               ST_status &= ~1;\r
+               ym2612_st->status &= ~1;\r
 \r
        return change;\r
 }\r
@@ -112,19 +104,19 @@ int YM2612Write_940(unsigned int a, unsigned int v)
 \r
        switch( a ) {\r
        case 0: /* address port 0 */\r
-               if (!addr_A1 && ST_address == v)\r
+               if (!*addr_A1 && ST_address == v)\r
                        return 0;       /* address already selected, don't send this command to 940 */\r
                ST_address = v;\r
                /* don't send DAC or timer related address changes to 940 */\r
-               if (!addr_A1 && (v & 0xf0) == 0x20 &&\r
+               if (!*addr_A1 && (v & 0xf0) == 0x20 &&\r
                        (v == 0x24 || v == 0x25 || v == 0x26 || v == 0x2a))\r
                                return 0;\r
-               addr_A1 = 0;\r
+               *addr_A1 = 0;\r
                upd = 0;\r
                break;\r
 \r
        case 1: /* data port 0    */\r
-               if (addr_A1 != 0) {\r
+               if (*addr_A1 != 0) {\r
                        return 0;       /* verified on real YM2608 */\r
                }\r
 \r
@@ -137,30 +129,30 @@ int YM2612Write_940(unsigned int a, unsigned int v)
                        switch( addr )\r
                        {\r
                        case 0x24: { // timer A High 8\r
-                                       int TAnew = (ST_TA & 0x03)|(((int)v)<<2);\r
-                                       if(ST_TA != TAnew) {\r
+                                       int TAnew = (ym2612_st->TA & 0x03)|(((int)v)<<2);\r
+                                       if (ym2612_st->TA != TAnew) {\r
                                                // we should reset ticker only if new value is written. Outrun requires this.\r
-                                               ST_TA = TAnew;\r
-                                               ST_TAC = (1024-TAnew)*18;\r
-                                               ST_TAT = 0;\r
+                                               ym2612_st->TA = TAnew;\r
+                                               ym2612_st->TAC = (1024-TAnew)*18;\r
+                                               ym2612_st->TAT = 0;\r
                                        }\r
                                        return 0;\r
                                }\r
                        case 0x25: { // timer A Low 2\r
-                                       int TAnew = (ST_TA & 0x3fc)|(v&3);\r
-                                       if(ST_TA != TAnew) {\r
-                                               ST_TA = TAnew;\r
-                                               ST_TAC = (1024-TAnew)*18;\r
-                                               ST_TAT = 0;\r
+                                       int TAnew = (ym2612_st->TA & 0x3fc)|(v&3);\r
+                                       if (ym2612_st->TA != TAnew) {\r
+                                               ym2612_st->TA = TAnew;\r
+                                               ym2612_st->TAC = (1024-TAnew)*18;\r
+                                               ym2612_st->TAT = 0;\r
                                        }\r
                                        return 0;\r
                                }\r
                        case 0x26: // timer B\r
-                               if(ST_TB != v) {\r
-                                       ST_TB = v;\r
-                                       ST_TBC  = (256-v)<<4;\r
-                                       ST_TBC *= 18;\r
-                                       ST_TBT  = 0;\r
+                               if (ym2612_st->TB != v) {\r
+                                       ym2612_st->TB = v;\r
+                                       ym2612_st->TBC  = (256-v)<<4;\r
+                                       ym2612_st->TBC *= 18;\r
+                                       ym2612_st->TBT  = 0;\r
                                }\r
                                return 0;\r
                        case 0x27:      /* mode, timer control */\r
@@ -183,15 +175,15 @@ int YM2612Write_940(unsigned int a, unsigned int v)
                break;\r
 \r
        case 2: /* address port 1 */\r
-               if (addr_A1 && ST_address == v)\r
+               if (*addr_A1 && ST_address == v)\r
                        return 0;\r
                ST_address = v;\r
-               addr_A1 = 1;\r
+               *addr_A1 = 1;\r
                upd = 0;\r
                break;\r
 \r
        case 3: /* data port 1    */\r
-               if (addr_A1 != 1) {\r
+               if (*addr_A1 != 1) {\r
                        return 0;       /* verified on real YM2608 */\r
                }\r
 \r
@@ -227,38 +219,6 @@ int YM2612Write_940(unsigned int a, unsigned int v)
        return 0; // cause the engine to do updates once per frame only\r
 }\r
 \r
-UINT8 YM2612Read_940(void)\r
-{\r
-       return ST_status;\r
-}\r
-\r
-\r
-int YM2612PicoTick_940(int n)\r
-{\r
-       //int ret = 0;\r
-\r
-       // timer A\r
-       if(ST_mode & 0x01 && (ST_TAT+=64*n) >= ST_TAC) {\r
-               ST_TAT -= ST_TAC;\r
-               if(ST_mode & 0x04) ST_status |= 1;\r
-               // CSM mode total level latch and auto key on\r
-/*             FIXME\r
-               if(ST_mode & 0x80) {\r
-                       CSMKeyControll( &(ym2612_940->CH[2]) ); // Vectorman2, etc.\r
-                       ret = 1;\r
-               }\r
-*/\r
-       }\r
-\r
-       // timer B\r
-       if(ST_mode & 0x02 && (ST_TBT+=64*n) >= ST_TBC) {\r
-               ST_TBT -= ST_TBC;\r
-               if(ST_mode & 0x08) ST_status |= 2;\r
-       }\r
-\r
-       return 0;\r
-}\r
-\r
 \r
 #define CHECK_BUSY(job) \\r
        (gp2x_memregs[0x3b46>>1] & (1<<(job-1)))\r
@@ -312,7 +272,7 @@ static void add_job_940(int job)
 \r
 void YM2612PicoStateLoad_940(void)\r
 {\r
-       int i, old_A1 = addr_A1;\r
+       int i, old_A1 = *addr_A1;\r
 \r
        /* make sure JOB940_PICOSTATELOAD gets done before next JOB940_YM2612UPDATEONE */\r
        add_job_940(JOB940_PICOSTATELOAD);\r
@@ -330,20 +290,24 @@ void YM2612PicoStateLoad_940(void)
                YM2612Write_940(3, REGS[i|0x100]);\r
        }\r
 \r
-       addr_A1 = old_A1;\r
+       *addr_A1 = old_A1;\r
 }\r
 \r
 \r
 static void internal_reset(void)\r
 {\r
        writebuff_ptr = 0;\r
-       ST_mode   = 0;\r
-       ST_status = 0;  /* normal mode */\r
-       ST_TA     = 0;\r
-       ST_TAC    = 0;\r
-       ST_TB     = 0;\r
-       ST_TBC    = 0;\r
-       dacen = 0;\r
+       ym2612_st->mode   = 0;\r
+       ym2612_st->status = 0;  /* normal mode */\r
+       ym2612_st->TA     = 0;\r
+       ym2612_st->TAC    = 0;\r
+       ym2612_st->TAT    = 0;\r
+       ym2612_st->TB     = 0;\r
+       ym2612_st->TBC    = 0;\r
+       ym2612_st->TBT    = 0;\r
+       dacen     = 0;\r
+       dacout    = 0;\r
+       ST_address= 0;\r
 }\r
 \r
 \r
@@ -438,7 +402,11 @@ void YM2612Init_940(int baseclock, int rate)
        memset(shared_data, 0, sizeof(*shared_data));\r
        memset(shared_ctl,  0, sizeof(*shared_ctl));\r
 \r
+       /* cause local ym2612 to init REGS */\r
+       YM2612Init_(baseclock, rate);\r
+\r
        REGS = YM2612GetRegs();\r
+       addr_A1 = (INT32 *) (REGS + 0x200);\r
 \r
        ym2612_dacen  = &dacen;\r
        ym2612_dacout = &dacout;\r
@@ -525,9 +493,8 @@ void mp3_update(int *buffer, int length, int stereo)
        int length_mp3;\r
        int cdda_on;\r
 \r
-       // not data track, CDC is reading, playback was started, track not ended\r
-       cdda_on = !(Pico_mcd->s68k_regs[0x36] & 1) && (Pico_mcd->scd.Status_CDC & 1) &&\r
-                       loaded_mp3 && shared_ctl->mp3_offs < shared_ctl->mp3_len;\r
+       // playback was started, track not ended\r
+       cdda_on = loaded_mp3 && shared_ctl->mp3_offs < shared_ctl->mp3_len;\r
 \r
        if (!cdda_on) return;\r
 \r
@@ -641,7 +608,7 @@ void mp3_start_play(FILE *f, int pos) // pos is 0-1023
 \r
 int mp3_get_offset(void)\r
 {\r
-       int offs1024 = 0;\r
+       unsigned int offs1024 = 0;\r
        int cdda_on;\r
 \r
        cdda_on = (PicoMCD & 1) && (PicoOpt&0x800) && !(Pico_mcd->s68k_regs[0x36] & 1) &&\r
@@ -649,10 +616,9 @@ int mp3_get_offset(void)
 \r
        if (cdda_on) {\r
                offs1024  = shared_ctl->mp3_offs << 7;\r
-               offs1024 /= shared_ctl->mp3_len;\r
-               offs1024 <<= 3;\r
+               offs1024 /= shared_ctl->mp3_len  >> 3;\r
        }\r
-       printf("offs1024=%i (%i/%i)\n", offs1024, shared_ctl->mp3_offs, shared_ctl->mp3_len);\r
+       printf("offs1024=%u (%i/%i)\n", offs1024, shared_ctl->mp3_offs, shared_ctl->mp3_len);\r
 \r
        return offs1024;\r
 }\r