bug fixes in drc, audio, display
authorkub <derkub@gmail.com>
Tue, 14 Jan 2020 21:49:03 +0000 (22:49 +0100)
committerkub <derkub@gmail.com>
Tue, 14 Jan 2020 21:49:03 +0000 (22:49 +0100)
14 files changed:
cpu/sh2/compiler.c
cpu/sh2/compiler.h
pico/32x/32x.c
pico/32x/sh2soc.c
pico/draw2.c
pico/draw2_arm.S
pico/pico.h
pico/sound/mix_arm.S
pico/sound/sound.c
pico/sound/ym2612.c
pico/sound/ym2612.h
pico/sound/ym2612_arm.S
platform/common/dismips.c
platform/linux/emu.c

index bd3e5b4..0432042 100644 (file)
@@ -703,8 +703,8 @@ static void add_to_hashlist(struct block_entry *be, int tcache_id)
 
 #if (DRC_DEBUG & 2)
   if (be->next != NULL) {
-    printf(" %08x: entry hash collision with %08x\n",
-      be->pc, be->next->pc);
+    printf(" %08x@%p: entry hash collision with %08x@%p\n",
+      be->pc, be->tcache_ptr, be->next->pc, be->next->tcache_ptr);
     hash_collisions++;
   }
 #endif
@@ -5323,7 +5323,7 @@ int sh2_execute_drc(SH2 *sh2c, int cycles)
   // TODO: irq cycles
   ret_cycles = (int32_t)sh2c->sr >> 12;
   if (ret_cycles > 0)
-    dbg(1, "warning: drc returned with cycles: %d", ret_cycles);
+    dbg(1, "warning: drc returned with cycles: %d, pc %08x", ret_cycles, sh2c->pc);
 
   sh2c->sr &= 0x3f3;
   return ret_cycles;
@@ -5506,10 +5506,6 @@ void sh2_drc_mem_setup(SH2 *sh2)
   sh2->p_drcblk_ram = Pico32xMem->drcblk_ram;
 }
 
-void sh2_drc_frame(void)
-{
-}
-
 int sh2_drc_init(SH2 *sh2)
 {
   int i;
@@ -5716,8 +5712,6 @@ u16 scan_block(u32 base_pc, int is_slave, u8 *op_flags, u32 *end_pc_out,
     else if ((lowest_mova && lowest_mova <= pc) ||
               (lowest_literal && lowest_literal <= pc))
       break; // text area collides with data area
-    else if ((op_flags[i] & OF_BTARGET) && dr_get_entry(pc, is_slave, &i_end))
-      break; // branch target already compiled
 
     op = FETCH_OP(pc);
     switch ((op & 0xf000) >> 12)
@@ -6497,9 +6491,6 @@ end:
   last_btarget = 0;
   op = 0; // delay/poll insns counter
   for (i = 0, pc = base_pc; i < i_end; i++, pc += 2) {
-    int null;
-    if ((op_flags[i] & OF_BTARGET) && dr_get_entry(pc, is_slave, &null))
-      break; // branch target already compiled
     opd = &ops[i];
     crc += FETCH_OP(pc);
 
index dd37d47..00a8707 100644 (file)
@@ -6,7 +6,6 @@ void sh2_drc_wcheck_da(uint32_t a, unsigned len, SH2 *sh2);
 #ifdef DRC_SH2
 void sh2_drc_mem_setup(SH2 *sh2);
 void sh2_drc_flush_all(void);
-void sh2_drc_frame(void);
 #else
 #define sh2_drc_mem_setup(x)
 #define sh2_drc_flush_all()
index 896b5aa..aa45ba7 100644 (file)
@@ -580,7 +580,6 @@ void PicoFrame32x(void)
 
   PicoFrameStart();
   PicoFrameHints();
-  sh2_drc_frame();
 
   elprintf(EL_32X, "poll: %02x %02x %02x",
     Pico32x.emu_flags & 3, msh2.state, ssh2.state);
index dd834bf..cf11666 100644 (file)
@@ -137,11 +137,15 @@ static void dmac_memcpy(struct dma_chan *chan, SH2 *sh2)
 
   if (!up || chan->tcr < 4)
     return;
-  // XXX Mars Check Program fills a 64K buffer, then copies 32K longwords from
-  // DRAM to SDRAM in 4-longword mode, which is 128K. This overwrites a comm
-  // area in SDRAM, which is why the check fails.
-  // Is this a buswidth mismatch problem? As a kludge, usw 16-bit width xfers
-  if (size == 3 && (chan->sar & 0xdf000000) == 0x04000000) size = 1;
+#if MARS_CHECK_HACK
+  // XXX Mars Check Program copies 32K longwords (128KB) from a 64KB buffer in
+  // ROM or DRAM to SDRAM in 4-longword mode, overwriting an SDRAM comm area in
+  // turn, which crashes the test on emulators without CPU cache emulation.
+  // This may be a bug in Mars Check. As a kludge limit the transfer to 64KB,
+  // which is what the check program test uses for checking the result.
+  // A better way would clearly be to have a mechanism to patch the ROM...
+  if (size == 3 && chan->tcr == 32768 && chan->dar == 0x06020000) size = 1;
+#endif
   if (size == 3) size = 2;  // 4-word xfer mode still counts in words
   // XXX check TCR being a multiple of 4 in 4-word xfer mode?
   // XXX check alignment of sar/dar, generating a bus error if unaligned?
index f0e0518..38a90ef 100644 (file)
@@ -157,6 +157,8 @@ static void DrawWindowFull(int start, int end, int prio, struct PicoEState *est)
        {\r
                nametab=(pvid->reg[3]&0x3e)<<9; // 32-cell mode\r
                nametab_step = 1<<5;\r
+               if (!(PicoIn.opt&POPT_DIS_32C_BORDER))\r
+                       scrpos += 32;\r
        }\r
        nametab += nametab_step*start;\r
 \r
@@ -240,6 +242,8 @@ static void DrawLayerFull(int plane, int *hcache, int planestart, int planeend,
        else          nametab=(pvid->reg[4]&0x07)<<12; // B\r
 \r
        scrpos = est->Draw2FB;\r
+       if (!(pvid->reg[12]&1) && !(PicoIn.opt&POPT_DIS_32C_BORDER))\r
+               scrpos += 32;\r
        scrpos+=8*LINE_WIDTH*(planestart-START_ROW);\r
 \r
        // Get vertical scroll value:\r
@@ -315,6 +319,8 @@ static void DrawTilesFromCacheF(int *hc, struct PicoEState *est)
        short blank=-1; // The tile we know is blank\r
        unsigned char *scrpos = est->Draw2FB, *pd = 0;\r
 \r
+       if (!(Pico.video.reg[12]&1) && !(PicoIn.opt&POPT_DIS_32C_BORDER))\r
+               scrpos += 32;\r
        // *hcache++ = code|(dx<<16)|(trow<<27); // cache it\r
        scrpos+=(*hc++)*LINE_WIDTH - START_ROW*LINE_WIDTH*8;\r
 \r
@@ -377,6 +383,8 @@ static void DrawSpriteFull(unsigned int *sprite, struct PicoEState *est)
        while(sy <= START_ROW*8) { sy+=8; tile+=tdeltay; height--; }\r
 \r
        scrpos = est->Draw2FB;\r
+       if (!(Pico.video.reg[12]&1) && !(PicoIn.opt&POPT_DIS_32C_BORDER))\r
+               scrpos += 32;\r
        scrpos+=(sy-START_ROW*8)*LINE_WIDTH;\r
 \r
        for (; height > 0; height--, sy+=8, tile+=tdeltay)\r
@@ -502,6 +510,11 @@ static void DrawDisplayFull(void)
                maxw = 264; maxcolc = 32;\r
        }\r
 \r
+       // 32C border for centering? (for asm)\r
+       est->rendstatus &= ~PDRAW_BORDER_32;\r
+       if ((est->rendstatus&PDRAW_32_COLS) && !(PicoIn.opt&POPT_DIS_32C_BORDER))\r
+               est->rendstatus |= PDRAW_BORDER_32;\r
+\r
        // horizontal window?\r
        if ((win=pvid->reg[0x12]))\r
        {\r
index 6b09449..ded0d5a 100644 (file)
@@ -414,7 +414,10 @@ DrawLayerFull:
 \r
     ldr     r11,[sp, #9*4]        @ est\r
     sub     r4, r9, #(START_ROW<<24)\r
+    ldr     r7, [r11, #OFS_EST_rendstatus]\r
     ldr     r11, [r11, #OFS_EST_Draw2FB]\r
+    tst     r7, #0x100            @ H32 border mode?\r
+    addne   r11, r11, #32\r
     mov     r4, r4, asr #24\r
     mov     r7, #328*8\r
     mla     r11, r4, r7, r11      @ scrpos+=8*328*(planestart-START_ROW);\r
@@ -590,8 +593,11 @@ DrawTilesFromCacheF:
     mov     r9, #0xff000000 @ r9=prevcode=-1\r
     mvn     r6, #0          @ r6=prevy=-1\r
 \r
+    ldr     r7, [r1, #OFS_EST_rendstatus]\r
     ldr     r4, [r1, #OFS_EST_Draw2FB]\r
     ldr     r2, [r0], #4    @ read y offset\r
+    tst     r7, #0x100      @ H32 border mode?\r
+    addne   r4, r4, #32\r
     mov     r7, #328\r
     mla     r2, r7, r2, r4\r
     sub     r12, r2, #(328*8*START_ROW) @ r12=scrpos\r
@@ -688,13 +694,18 @@ DrawWindowFull:
 \r
     ldr     r4, [r11, #OFS_Pico_video_reg+12]\r
     mov     r5, #1                @ nametab_step\r
+    ldr     r11, [r3, #OFS_EST_Draw2FB]\r
     tst     r4, #1                @ 40 cell mode?\r
     andne   r12, r12, #0xf000     @ 0x3c<<10\r
-    andeq   r12, r12, #0xf800\r
     movne   r5, r5, lsl #7\r
-    moveq   r5, r5, lsl #6        @ nametab_step\r
-\r
-    and     r4, r0, #0xff\r
+    bne     0f\r
+    ldr     r7, [r3, #OFS_EST_rendstatus]\r
+    and     r12, r12, #0xf800\r
+    mov     r5, r5, lsl #6        @ nametab_step\r
+    tst     r7, #0x100\r
+    addne   r11, r11, #32         @ center screen in H32 mode\r
+\r
+0:  and     r4, r0, #0xff\r
     mla     r12, r5, r4, r12      @ nametab += nametab_step*start;\r
 \r
     ldr     r10, [r3, #OFS_EST_PicoMem_vram]\r
@@ -715,7 +726,6 @@ DrawWindowFull:
 \r
     mov     r9, #0xff000000       @ r9=prevcode=-1\r
 \r
-    ldr     r11, [r3, #OFS_EST_Draw2FB]\r
     and     r4, r0, #0xff\r
     add     r11, r11, #328*8\r
     sub     r4, r4, #START_ROW\r
@@ -915,8 +925,11 @@ DrawSpriteFull:
     and     r3, lr, #0x6000\r
     mov     r3, r3, lsr #9  @ r3=pal=((code>>9)&0x30);\r
 \r
+    ldr     r0, [r1,  #OFS_EST_rendstatus]\r
     ldr     r11, [r1, #OFS_EST_Draw2FB]\r
     ldr     r10, [r1, #OFS_EST_PicoMem_vram]\r
+    tst     r0, #0x100      @ H32 border mode?\r
+    addne   r11, r11, #32\r
     sub     r1, r12, #(START_ROW*8)\r
     mov     r0, #328\r
     mla     r11, r1, r0, r11      @ scrpos+=(sy-START_ROW*8)*328;\r
index daf5dfd..1a60ce3 100644 (file)
@@ -204,6 +204,7 @@ void PicoDoHighPal555(int sh, int line, struct PicoEState *est);
 #define PDRAW_PLANE_HI_PRIO (1<<6) // have layer with all hi prio tiles (mk3)\r
 #define PDRAW_SHHI_DONE     (1<<7) // layer sh/hi already processed\r
 #define PDRAW_32_COLS       (1<<8) // 32 column mode\r
+#define PDRAW_BORDER_32     (1<<9) // center H32 in buffer (32 px border)\r
 extern int rendstatus_old;\r
 extern int rendlines;\r
 \r
index 104b306..a1558d7 100644 (file)
@@ -176,10 +176,10 @@ m16_32_s2_no_unal2:
 @ filter out DC offset
 @ in=int_sample (max 20 bit), y=filter memory, r3=tmp
 .macro DCfilt in y
-    rsb     r3, \y, \in, asl #12               @ fixpoint 20.12
+    rsb     r3, \y, \in, lsl #12               @ fixpoint 20.12
     add     \y, \y, r3, asr #13
-    sub     \in, \in, \y, asr #12
-    sub     \in, \in, \in, asr #2              @ reduce audio lvl some
+    sub     r3, r3, r3, asr #2                 @ reduce audio lvl some
+    asr     \in, r3, #12
 .endm
 
 @ mix 32bit audio (with 16bits really used, upper bits indicate overflow) with normal 16 bit audio with left channel only
index f4cd424..74fb6fc 100644 (file)
@@ -38,7 +38,7 @@ static void dac_recalculate(void)
 \r
   for(i = 0; i <= lines; i++)\r
   {\r
-    dac_info[i] = ((pos+(1<<15)) >> 16); // round to nearest\r
+    dac_info[i] = ((pos+0x8000) >> 16); // round to nearest\r
     pos += Pico.snd.fm_mult;\r
   }\r
   for (i = lines+1; i < sizeof(dac_info) / sizeof(dac_info[0]); i++)\r
@@ -85,10 +85,10 @@ void PsndRerate(int preserve_state)
   // calculate Pico.snd.len\r
   Pico.snd.len = PicoIn.sndRate / target_fps;\r
   Pico.snd.len_e_add = ((PicoIn.sndRate - Pico.snd.len * target_fps) << 16) / target_fps;\r
-  Pico.snd.len_e_cnt = 0;\r
+  Pico.snd.len_e_cnt = 0; // Q16\r
 \r
-  // samples per line\r
-  Pico.snd.fm_mult = 65536.0 * PicoIn.sndRate / (target_fps*target_lines);\r
+  // samples per line (Q16)\r
+  Pico.snd.fm_mult = 65536LL * PicoIn.sndRate / (target_fps*target_lines);\r
 \r
   // recalculate dac info\r
   dac_recalculate();\r
@@ -176,7 +176,7 @@ PICO_INTERNAL void PsndDoFM(int line_to)
   int pos, len;\r
   int stereo = 0;\r
 \r
-  // Q16, number of samples to fill in buffer\r
+  // Q16, number of samples since last call\r
   len = ((line_to-1) * Pico.snd.fm_mult) - Pico.snd.fm_pos;\r
 \r
   // don't do this too often (no more than 256 per sec)\r
@@ -184,9 +184,9 @@ PICO_INTERNAL void PsndDoFM(int line_to)
     return;\r
 \r
   // update position and calculate buffer offset and length\r
-  pos = Pico.snd.fm_pos >> 16;\r
+  pos = (Pico.snd.fm_pos+0x8000) >> 16;\r
   Pico.snd.fm_pos += len;\r
-  len = (Pico.snd.fm_pos >> 16) - pos;\r
+  len = ((Pico.snd.fm_pos+0x8000) >> 16) - pos;\r
 \r
   // fill buffer\r
   if (PicoIn.opt & POPT_EN_STEREO) {\r
@@ -195,8 +195,6 @@ PICO_INTERNAL void PsndDoFM(int line_to)
   }\r
   if (PicoIn.opt & POPT_EN_FM)\r
     YM2612UpdateOne(PsndBuffer + pos, len, stereo, 1);\r
-  else\r
-    memset32(PsndBuffer + pos, 0, len<<stereo);\r
 }\r
 \r
 // cdda\r
@@ -258,6 +256,8 @@ PICO_INTERNAL void PsndClear(void)
     memset32((int *) out, 0, len/2);\r
     if (len & 1) out[len-1] = 0;\r
   }\r
+  if (!(PicoIn.opt & POPT_EN_FM))\r
+    memset32(PsndBuffer, 0, PicoIn.opt & POPT_EN_STEREO ? len*2 : len);\r
 }\r
 \r
 \r
@@ -265,7 +265,7 @@ static int PsndRender(int offset, int length)
 {\r
   int *buf32;\r
   int stereo = (PicoIn.opt & 8) >> 3;\r
-  int fmlen = (Pico.snd.fm_pos >> 16) - offset;\r
+  int fmlen = ((Pico.snd.fm_pos+0x8000) >> 16) - offset;\r
 \r
   offset <<= stereo;\r
   buf32 = PsndBuffer+offset;\r
@@ -282,15 +282,11 @@ static int PsndRender(int offset, int length)
     int *fmbuf = buf32 + (fmlen << stereo);\r
     if (PicoIn.opt & POPT_EN_FM)\r
       YM2612UpdateOne(fmbuf, length-fmlen, stereo, 1);\r
-    else\r
-      memset32(fmbuf, 0, (length-fmlen)<<stereo);\r
-    Pico.snd.fm_pos += (length-fmlen)<<16;\r
   }\r
 \r
   // CD: PCM sound\r
   if (PicoIn.AHW & PAHW_MCD) {\r
     pcd_pcm_update(buf32, length, stereo);\r
-    //buf32_updated = 1;\r
   }\r
 \r
   // CD: CDDA audio\r
index 23f106d..af381fb 100644 (file)
@@ -564,7 +564,7 @@ INLINE void FM_KEYON(int c , int s )
                SLOT->ssg ^= SLOT->ssgn;\r
                SLOT->ssgn = 0;\r
                SLOT->state = (SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC;\r
-               if (SLOT->ar + SLOT->ksr < 32+62) {\r
+               if (SLOT->ar_ksr < 32+62) {\r
                        if (SLOT->volume > MIN_ATT_INDEX) SLOT->state = EG_ATT;\r
                } else {\r
                        SLOT->volume = MIN_ATT_INDEX;\r
@@ -619,6 +619,7 @@ INLINE void set_ar_ksr(FM_CH *CH, FM_SLOT *SLOT, int v)
        int eg_sh_ar, eg_sel_ar;\r
 \r
        SLOT->ar = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;\r
+       SLOT->ar_ksr = SLOT->ar + SLOT->ksr;\r
 \r
        SLOT->KSR = 3-(v>>6);\r
        if (SLOT->KSR != old_KSR)\r
@@ -627,10 +628,10 @@ INLINE void set_ar_ksr(FM_CH *CH, FM_SLOT *SLOT, int v)
        }\r
 \r
        /* refresh Attack rate */\r
-       if ((SLOT->ar + SLOT->ksr) < 32+62)\r
+       if ((SLOT->ar_ksr) < 32+62)\r
        {\r
-               eg_sh_ar  = eg_rate_shift [SLOT->ar  + SLOT->ksr ];\r
-               eg_sel_ar = eg_rate_select[SLOT->ar  + SLOT->ksr ];\r
+               eg_sh_ar  = eg_rate_shift [SLOT->ar_ksr];\r
+               eg_sel_ar = eg_rate_select[SLOT->ar_ksr];\r
        }\r
        else\r
        {\r
@@ -872,7 +873,7 @@ INLINE void update_ssg_eg_phase(FM_SLOT *SLOT)
 \r
                if (SLOT->state != EG_ATT) {\r
                        SLOT->state = (SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC;\r
-                       if (SLOT->ar + SLOT->ksr < 32+62) {\r
+                       if (SLOT->ar_ksr < 32+62) {\r
                                if (SLOT->volume > MIN_ATT_INDEX) SLOT->state = EG_ATT;\r
                        } else {\r
                                SLOT->volume = MIN_ATT_INDEX;\r
@@ -972,7 +973,7 @@ static void chan_render_loop(chan_rend_context *ct, int *buffer, int length)
                ct->vol_out3 = (SLOT->vol_ipol*ifrac1 + SLOT->vol_out*ifrac0) >> EG_SH;\r
                SLOT = &ct->CH->SLOT[SLOT4];\r
                ct->vol_out4 = (SLOT->vol_ipol*ifrac1 + SLOT->vol_out*ifrac0) >> EG_SH;\r
-#else\r
+#elif 1\r
                switch (ct->eg_timer >> EG_SH)\r
                {\r
                        case 0:\r
@@ -997,6 +998,23 @@ static void chan_render_loop(chan_rend_context *ct, int *buffer, int length)
                                ct->vol_out4 =  (ct->CH->SLOT[SLOT4].vol_ipol +\r
                                        ct->CH->SLOT[SLOT4].vol_out) >> 1;\r
                }\r
+#elif 0\r
+               if (ct->eg_timer >> (EG_SH-1) < EG_TIMER_OVERFLOW >> EG_SH) {\r
+                       ct->vol_out1 =  ct->CH->SLOT[SLOT1].vol_ipol;\r
+                       ct->vol_out2 =  ct->CH->SLOT[SLOT2].vol_ipol;\r
+                       ct->vol_out3 =  ct->CH->SLOT[SLOT3].vol_ipol;\r
+                       ct->vol_out4 =  ct->CH->SLOT[SLOT4].vol_ipol;\r
+               } else {\r
+                       ct->vol_out1 =  ct->CH->SLOT[SLOT1].vol_out;\r
+                       ct->vol_out2 =  ct->CH->SLOT[SLOT2].vol_out;\r
+                       ct->vol_out3 =  ct->CH->SLOT[SLOT3].vol_out;\r
+                       ct->vol_out4 =  ct->CH->SLOT[SLOT4].vol_out;\r
+               }\r
+#else\r
+               ct->vol_out1 =  ct->CH->SLOT[SLOT1].vol_out;\r
+               ct->vol_out2 =  ct->CH->SLOT[SLOT2].vol_out;\r
+               ct->vol_out3 =  ct->CH->SLOT[SLOT3].vol_out;\r
+               ct->vol_out4 =  ct->CH->SLOT[SLOT4].vol_out;\r
 #endif\r
 \r
                if (ct->pack & 4) continue; /* output disabled */\r
@@ -1335,12 +1353,13 @@ INLINE void refresh_fc_eg_slot(FM_SLOT *SLOT, int fc, int kc)
        {\r
                int eg_sh, eg_sel;\r
                SLOT->ksr = ksr;\r
+               SLOT->ar_ksr = SLOT->ar + ksr;\r
 \r
                /* calculate envelope generator rates */\r
-               if ((SLOT->ar + ksr) < 32+62)\r
+               if ((SLOT->ar_ksr) < 32+62)\r
                {\r
-                       eg_sh  = eg_rate_shift [SLOT->ar  + ksr ];\r
-                       eg_sel = eg_rate_select[SLOT->ar  + ksr ];\r
+                       eg_sh  = eg_rate_shift [SLOT->ar_ksr];\r
+                       eg_sel = eg_rate_select[SLOT->ar_ksr];\r
                }\r
                else\r
                {\r
index 3a1ea7a..73e693f 100644 (file)
@@ -56,8 +56,9 @@ typedef struct
 \r
        UINT8   ssg;            /* 0x30 SSG-EG waveform */\r
        UINT8   ssgn;\r
-       UINT16  vol_out;        /* 0x32 current output from EG (without LFO) */\r
-       UINT16  vol_ipol;       /* 0x34 interpolator memory */\r
+       UINT16  ar_ksr;         /* 0x32 ar+ksr */\r
+       UINT16  vol_out;        /* 0x34 current output from EG (without LFO) */\r
+       UINT16  vol_ipol;       /* 0x36 interpolator memory */\r
 } FM_SLOT;\r
 \r
 \r
index 86e5f1c..4cb9285 100644 (file)
 @ r5=slot, r1=eg_cnt, trashes: r0,r2,r3
 @ writes output to routp, but only if vol_out changes
 .macro update_eg_phase_slot slot
-    ldrh    r0, [r5,#0x32]       @ vol_out
+    ldrh    r0, [r5,#0x34]       @ vol_out
     ldrb    r2, [r5,#0x17]       @ state
     add     r3, r5, #0x1c
-    strh    r0, [r5,#0x34]       @ vol_ipol
+    strh    r0, [r5,#0x36]       @ vol_ipol
     tst     r2, r2
     beq     0f                   @ EG_OFF
 
 11:
     ldrh    r3, [r5,#0x18]       @ tl
     add     r0, r0, r3           @ volume += tl
-    strh    r0, [r5,#0x32]       @ vol_out
+    strh    r0, [r5,#0x34]       @ vol_out
 .if     \slot == SLOT1
     mov     r6, r6, lsr #16
     orr     r6, r0, r6, lsl #16
     ldrh    r0, [r5,#0x30]                @ ssg+ssgn
     ldrb    r2, [r5,#0x17]                @ state
     ldrh    r3, [r5,#0x1a]                @ volume
-    tst     r0, #0x08                     @ ssg enabled?
-    beq     9f
-    cmp     r2, #EG_REL                   @ state > EG_REL?
-    ble     9f
-    cmp     r3, #0x200                    @ volume >= 0x200?
+    cmp     r0, #0x08                     @ ssg enabled &&
+    cmpge   r2, #EG_REL+1                 @   state > EG_REL &&
+    cmpge   r3, #0x200                    @   volume >= 0x200?
     blt     9f
 
     tst     r0, #0x01
     eor     r0, r0, #0x4                  @ if ( !(ssg&0x04 )
     tst     r0, #0x4
     cmpne   r2, #EG_ATT                   @ if ( state != EG_ATT )
-    movne   r0, #0x400
-    subne   r0, r0, #1
-    strneh  r0, [r5,#0x1a]                @ volume = MAX_ATT
+    movne   r3, #0x400
+    subne   r3, r3, #1
+    strneh  r3, [r5,#0x1a]                @ volume = MAX_ATT
     b       9f
 
 1:  tst     r0, #0x02
     eorne   r0, r0, #0x4                  @ ssg ^= 4
     eorne   r0, r0, #0x400                @ ssgn ^= 4
     strneh  r0, [r5,#0x30]
-    moveq   r3, #0
-    streq   r3, [r5,#0x0c]                @ phase = 0
+    moveq   r0, #0
+    streq   r0, [r5,#0x0c]                @ phase = 0
 
     cmp     r2, #EG_ATT                   @ if ( state != EG_ATT )
     beq     9f
 
-    ldr     r3, [r5,#0x1c]                @ sl
+    ldr     r0, [r5,#0x1c]                @ sl
     mov     r2, #EG_SUS                   @ state = sl==MIN_ATT ? EG_SUS:EG_DEC
-    cmp     r3, #0
+    cmp     r0, #0
 
-    ldr     r0, [r5,#0x04]                @ ar
-    ldr     r3, [r5,#0x14]                @ ksr
+    ldrh    r0, [r5,#0x32]                @ ar+ksr
     movne   r2, #EG_DEC
-    add     r0, r0, r3
     cmp     r0, #32+62                    @ if ( ar+ksr >= 32+62 )
-    ldrlt   r0, [r5,#0x1a]
-    movge   r0, #0
-    strgeh  r0, [r5,#0x1a]                @ volume = MIN_ATT
+    movge   r3, #0
+    strgeh  r3, [r5,#0x1a]                @ volume = MIN_ATT
+    bge     9f
 
-    cmp     r0, #0
+    cmp     r3, #0
     movgt   r2, #EG_ATT
     strb    r2, [r5,#0x17]                @ state
 9:
@@ -673,10 +669,10 @@ chan_render_loop:
     ldr     r10, [lr, #0x54]     @ op1_out
 @   ldmia   lr,  {r6,r7}         @ load volumes
     ldr     r5, [lr, #0x40]      @ CH
-    ldrh    r6, [r5, #0x32]      @ vol_out values for all slots
-    ldrh    r2, [r5, #0x32+SLOT_STRUCT_SIZE*2]
-    ldrh    r7, [r5, #0x32+SLOT_STRUCT_SIZE]
-    ldrh    r3, [r5, #0x32+SLOT_STRUCT_SIZE*3]
+    ldrh    r6, [r5, #0x34]      @ vol_out values for all slots
+    ldrh    r2, [r5, #0x34+SLOT_STRUCT_SIZE*2]
+    ldrh    r7, [r5, #0x34+SLOT_STRUCT_SIZE]
+    ldrh    r3, [r5, #0x34+SLOT_STRUCT_SIZE*3]
     orr     r6, r6, r2, lsl #16
     orr     r7, r7, r3, lsl #16
 
@@ -756,28 +752,28 @@ eg_done:
     cmp     r3, #(EG_TIMER_OVERFLOW>>EG_SH)/2
     bgt     0f                      @ mix is vol_out
 
-    ldrh    r0, [r5,#0x34]          @ SLOT1 vol_ipol
+    ldrh    r0, [r5,#0x36]          @ SLOT1 vol_ipol
     lsleq   r2, r6, #16
     addeq   r0, r0, r2, lsr #16
     lsreq   r0, r0, #1
     mov     r6, r6, lsr #16
     orr     r6, r0, r6, lsl #16
 
-    ldrh    r0, [r5,#0x34+SLOT_STRUCT_SIZE*2] @ SLOT2 vol_ipol
+    ldrh    r0, [r5,#0x36+SLOT_STRUCT_SIZE*2] @ SLOT2 vol_ipol
     addeq   r0, r0, r6, lsr #16
     lsreq   r0, r0, #1
     mov     r6, r6, lsl #16
     orr     r6, r6, r0
     ror     r6, r6, #16
 
-    ldrh    r0, [r5,#0x34+SLOT_STRUCT_SIZE]   @ SLOT3 vol_ipol
+    ldrh    r0, [r5,#0x36+SLOT_STRUCT_SIZE]   @ SLOT3 vol_ipol
     lsleq   r2, r7, #16
     addeq   r0, r0, r2, lsr #16
     lsreq   r0, r0, #1
     mov     r7, r7, lsr #16
     orr     r7, r0, r7, lsl #16
 
-    ldrh    r0, [r5,#0x34+SLOT_STRUCT_SIZE*3] @ SLOT4 vol_ipol
+    ldrh    r0, [r5,#0x36+SLOT_STRUCT_SIZE*3] @ SLOT4 vol_ipol
     addeq   r0, r0, r7, lsr #16
     lsreq   r0, r0, #1
     mov     r7, r7, lsl #16
@@ -787,22 +783,22 @@ eg_done:
     @ super-basic... just take value closest to sample point
     mov     r3, r8, lsr #EG_SH-1    @ eg_timer, [0..3<<EG_SH) after loop
     cmp     r3, #(EG_TIMER_OVERFLOW>>EG_SH)
-    bgt     0f                      @ mix is vol_out
+    bge     0f                      @ mix is vol_out
 
-    ldrh    r0, [r5,#0x34]          @ SLOT1 vol_ipol
+    ldrh    r0, [r5,#0x36]          @ SLOT1 vol_ipol
     mov     r6, r6, lsr #16
     orr     r6, r0, r6, lsl #16
 
-    ldrh    r0, [r5,#0x34+SLOT_STRUCT_SIZE*2] @ SLOT2 vol_ipol
+    ldrh    r0, [r5,#0x36+SLOT_STRUCT_SIZE*2] @ SLOT2 vol_ipol
     mov     r6, r6, lsl #16
     orr     r6, r6, r0
     ror     r6, r6, #16
 
-    ldrh    r0, [r5,#0x34+SLOT_STRUCT_SIZE]   @ SLOT3 vol_ipol
+    ldrh    r0, [r5,#0x36+SLOT_STRUCT_SIZE]   @ SLOT3 vol_ipol
     mov     r7, r7, lsr #16
     orr     r7, r0, r7, lsl #16
 
-    ldrh    r0, [r5,#0x34+SLOT_STRUCT_SIZE*3] @ SLOT4 vol_ipol
+    ldrh    r0, [r5,#0x36+SLOT_STRUCT_SIZE*3] @ SLOT4 vol_ipol
     mov     r7, r7, lsl #16
     orr     r7, r7, r0
     ror     r7, r7, #16
index dc06ce8..d855ad6 100644 (file)
@@ -368,10 +368,12 @@ int dismips(uintptr_t pc, uint32_t insn, char *buf, size_t buflen, unsigned long
                else
                        snprintf(buf, buflen, "%s %s, %s, %d", pi->name, rd, rt, sa);
                break;
+       //dext: pos,size-1      dextm: pos,size-33      dextu: pos-32,size-1
+       //dins: pos,pos+size-1  dinsm: pos,pos+size-33  dinsu: pos-32,pos+size-33
        case F_IMM_TS:
-               if (insn & 0x01)        sb+=32;
-               if (insn & 0x02)        sa+=32;
-               if (insn & 0x04)        sb-=sa;
+               if (insn & 0x01)        sb+=32; // ...m
+               if (insn & 0x02)        sa+=32; // ...u
+               if (insn & 0x04)        sb-=sa; // ins
                snprintf(buf, buflen, "%s %s, %s, %d, %d", pi->name, rt, rs, sa, sb+1);
                break;
        case B_IMM_S:
index 9366526..5e4dd72 100644 (file)
@@ -176,7 +176,10 @@ void plat_debug_cat(char *str)
 void emu_video_mode_change(int start_line, int line_count, int is_32cols)\r
 {\r
        // clear whole screen in all buffers\r
-       memset32(g_screen_ptr, 0, g_screen_ppitch * g_screen_height * 2 / 4);\r
+       if (currentConfig.renderer != RT_16BIT && !(PicoIn.AHW & PAHW_32X))\r
+               memset32(Pico.est.Draw2FB, 0, (320+8) * (8+240+8) / 4);\r
+       else\r
+               memset32(g_screen_ptr, 0, g_screen_ppitch * g_screen_height * 2 / 4);\r
 }\r
 \r
 void pemu_loop_prep(void)\r