s3k_ss, s3d_dd kinda works midi
authornotaz <notasas@gmail.com>
Sat, 1 Mar 2025 21:22:52 +0000 (23:22 +0200)
committernotaz <notasas@gmail.com>
Sat, 1 Mar 2025 21:22:52 +0000 (23:22 +0200)
.gitmodules
mkbd_s3d_dd.sh [new file with mode: 0755]
mkbd_s3k_ss.sh [new file with mode: 0755]
pico/pico.c
pico/sound/mkbd.h [new file with mode: 0644]
pico/sound/sn76496.c
pico/sound/sound.c
pico/sound/ym2612.c
platform/common/emu.c
platform/common/main.c
platform/libpicofe

index 5d28012..568b0fc 100644 (file)
@@ -1,6 +1,6 @@
 [submodule "platform/libpicofe"]
        path = platform/libpicofe
-       url = https://github.com/irixxxx/libpicofe.git
+       url = https://github.com/notaz/libpicofe.git
 [submodule "cpu/cyclone"]
        path = cpu/cyclone
        url = https://github.com/irixxxx/cyclone68000.git
diff --git a/mkbd_s3d_dd.sh b/mkbd_s3d_dd.sh
new file mode 100755 (executable)
index 0000000..548c9a0
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+exec ./picodrive -load 3 -mk_c 0 -mk_ce 4 -mk_transpose -12 -mk_ar_min 62 \
+  -mk_echo_on 11 -mk_echo_off 12 "$@"
diff --git a/mkbd_s3k_ss.sh b/mkbd_s3k_ss.sh
new file mode 100755 (executable)
index 0000000..bd6b1c7
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec ./picodrive -load 2 -mk_c 4 -mk_ce 3 -mk_echo_on 13 -mk_echo_off 21 "$@"
index 1d93d60..2b2f267 100644 (file)
@@ -250,6 +250,7 @@ void PicoLoopPrepare(void)
 }\r
 \r
 #include "pico_cmn.c"\r
+#include "sound/mkbd.h"\r
 \r
 /* sync z80 to 68k */\r
 PICO_INTERNAL void PicoSyncZ80(unsigned int m68k_cycles_done)\r
@@ -259,6 +260,8 @@ PICO_INTERNAL void PicoSyncZ80(unsigned int m68k_cycles_done)
 \r
   m68k_cnt = m68k_cycles_done - Pico.t.m68c_frame_start;\r
   Pico.t.z80c_aim = cycles_68k_to_z80(m68k_cnt);\r
+  if (mkbd_stop_z80)\r
+    Pico.t.z80c_cnt = Pico.t.z80c_aim;\r
   cnt = Pico.t.z80c_aim - Pico.t.z80c_cnt;\r
 \r
   pprof_start(z80);\r
diff --git a/pico/sound/mkbd.h b/pico/sound/mkbd.h
new file mode 100644 (file)
index 0000000..57de899
--- /dev/null
@@ -0,0 +1,19 @@
+
+extern int mkbd_stolen_channels;
+extern int mkbd_kbd_channel;
+extern int mkbd_kbd_echo_channel;
+extern int mkbd_echo_delay_on;
+extern int mkbd_echo_delay_off;
+extern int mkbd_transpose;
+extern int mkbd_ar_min;
+extern int mkbd_stop_z80;
+
+void mkbd_steal_toggle(int c, int shift);
+void mkbd_snd_inject(int c, unsigned int octave, unsigned int key, int is_on,
+       int echo_c, int echo_frames);
+void mkbd_snd_adj_start(int c, int step);
+void mkbd_snd_do_frame(void);
+
+void sn76496h_steal(int c, int is_stolen);
+
+void mkbd_tempo_kdown(int tempo_increase, int is_kdown);
index 1624d13..2c3cee8 100644 (file)
@@ -21,6 +21,7 @@
 #endif\r
 \r
 #include "sn76496.h"\r
+#include "mkbd.h"\r
 \r
 #define MAX_OUTPUT 0x4800 // was 0x7fff\r
 \r
@@ -57,6 +58,8 @@ struct SN76496
        int Count[4];\r
        int Output[4];\r
        int Panning;\r
+       int mkbd_bk_Volume[4];\r
+       char mkbd_stolen[4];\r
 };\r
 \r
 static struct SN76496 ono_sn; // one and only SN76496\r
@@ -103,6 +106,9 @@ void SN76496Write(int data)
                case 5: /* tone 2 : volume */\r
                case 7: /* noise  : volume */\r
                        R->Volume[c] = R->VolTable[data & 0x0f];\r
+                       R->mkbd_bk_Volume[c] = R->Volume[c];\r
+                       if (R->mkbd_stolen[c])\r
+                               R->Volume[c] = 0;\r
                        break;\r
                case 6: /* noise  : frequency, mode */\r
                        n = data;\r
@@ -322,3 +328,13 @@ int SN76496_init(int clock,int sample_rate)
        return 0;\r
 }\r
 \r
+#undef NDEBUG\r
+#include <assert.h>\r
+\r
+void sn76496h_steal(int c, int is_stolen)\r
+{\r
+       assert((unsigned)c < 4u);\r
+       ono_sn.mkbd_stolen[c] = is_stolen;\r
+       ono_sn.Volume[c] = is_stolen ? 0 : ono_sn.mkbd_bk_Volume[c];\r
+}\r
+\r
index 447d9dd..d8bbe18 100644 (file)
@@ -291,6 +291,9 @@ PICO_INTERNAL void PsndDoDAC(int cyc_to)
   if (len <= 0)\r
     return;\r
 \r
+  if (mkbd_stolen_channels & (1u << 5))\r
+    ;\r
+  else\r
   // fill buffer, applying a rather weak order 1 bessel IIR on the way\r
   // y[n] = (x[n] + x[n-1])*(1/2) (3dB cutoff at 11025 Hz, no gain)\r
   // 1 sample delay for correct IIR filtering over audio frame boundaries\r
@@ -502,6 +505,61 @@ PICO_INTERNAL void PsndClear(void)
     memset32(PsndBuffer, 0, PicoIn.opt & POPT_EN_STEREO ? len*2 : len);\r
 }\r
 \r
+static int g_tempo_kdown;\r
+static int g_tempo_increase;\r
+\r
+static int is_rom(const char *name)\r
+{\r
+  const char *rn = (const char *)Pico.rom + 0x150;\r
+  int i;\r
+  for (i = 0; name[i]; i++)\r
+    if (rn[i^1] != name[i])\r
+      return 0;\r
+  return 1;\r
+}\r
+\r
+static void smps_set_init_tempo(u32 base, u8 val)\r
+{\r
+  Pico.rom[(base + 5)^1] = val;\r
+}\r
+\r
+static void do_tempo_adj(void)\r
+{\r
+  static int step;\r
+  //u8 *mem = &Pico.rom[Pico.m.z80_bank68k << 15];\r
+  //u8 *mem = &Pico.rom[0x0EBE80];\r
+  //mem[5^1]--;\r
+  if (!g_tempo_kdown)\r
+    return;\r
+  if (step++ < 2)\r
+    return;\r
+  step = 0;\r
+  if (g_tempo_increase)\r
+    PicoMem.zram[0x1c24]--;\r
+  else\r
+    PicoMem.zram[0x1c24]++;\r
+  //printf("tempo %02x\n", PicoMem.zram[0x1c24]);\r
+  if (is_rom("SONIC & KNUCKLES")) {\r
+    smps_set_init_tempo(0x0EBE80, PicoMem.zram[0x1c24]); // ssz\r
+  }\r
+  else if (is_rom("SONIC 3D FLICKIES")) {\r
+    smps_set_init_tempo(0x0C7091, PicoMem.zram[0x1c24]); // diamond dust1\r
+  }\r
+}\r
+\r
+void mkbd_tempo_kdown(int tempo_up, int is_kdown)\r
+{\r
+  g_tempo_kdown = is_kdown;\r
+  g_tempo_increase = tempo_up;\r
+  //u16 mp = PicoMem.zram[0x1618] | (PicoMem.zram[0x1619] << 8);\r
+#if 0\r
+  int i;\r
+  for (i = 0; i < 0x2000-1; i++)\r
+    if (PicoMem.zram[i] == 0x80 && PicoMem.zram[i+1] == 0xbe)\r
+      printf("%04x\n", i);\r
+#endif\r
+}\r
+\r
 #include <stdint.h>\r
 #include <fcntl.h>\r
 #include <poll.h>\r
@@ -541,22 +599,26 @@ static int midi_init(void)
 \r
 static void do_note(uint8_t note, int is_down)\r
 {\r
-  static uint32_t state[96/8/4];\r
+  static uint32_t state[128/8/4];\r
   int i, v = 0, release_all = 0;\r
-  if (note >= 96)\r
+  note += mkbd_transpose;\r
+  if (note >= 128u)\r
     return;\r
   if (is_down) {\r
     state[note / 8 / 4] |= 1u << (note % 32u);\r
-    //ym2612h_inject(4, 0, 0, 0, -1, 0);\r
-    ym2612h_inject(4, note / 12, note % 12, 1, 3, 13);\r
+    //mkbd_snd_inject(4, 0, 0, 0, -1, 0);\r
+    if (mkbd_kbd_channel >= 0)\r
+      mkbd_snd_inject(mkbd_kbd_channel, note / 12, note % 12, 1,\r
+        mkbd_kbd_echo_channel, mkbd_echo_delay_on);\r
   }\r
   else {\r
     state[note / 8 / 4] &= ~(1u << (note % 32u));\r
     for (i = 0; i < ARRAY_SIZE(state); i++)\r
       v |= state[i];\r
     release_all = !v;\r
-    if (release_all)\r
-      ym2612h_inject(4, 0, 0, 0, 3, 21);\r
+    if (release_all && mkbd_kbd_channel >= 0)\r
+      mkbd_snd_inject(mkbd_kbd_channel, 0, 0, 0,\r
+          mkbd_kbd_echo_channel, mkbd_echo_delay_off);\r
   }\r
 }\r
 \r
@@ -573,8 +635,8 @@ static void mkbd_update(void)
   } note;\r
   int ret;\r
 \r
-  ym2612h_adj_step();\r
-  ym2612h_echo_step();\r
+  do_tempo_adj();\r
+  mkbd_snd_do_frame();\r
 \r
   for (;;)\r
   {\r
@@ -611,7 +673,7 @@ static void mkbd_update(void)
         if (read(mkbd_fd, &data, sizeof(data)) != sizeof(data))\r
           cfail("read", NULL);\r
         //printf("p %02x %02x\n", data[0], data[1]);\r
-        ym2612h_adj_start(4, 4);\r
+        mkbd_snd_adj_start(4, 4);\r
         break;\r
       case 0xf0:\r
         switch (status) {\r
@@ -666,6 +728,9 @@ static int PsndRender(int offset, int length)
   // Fill up DAC output in case of missing samples (Q rounding errors)\r
   if (length-daclen > 0 && PicoIn.sndOut) {\r
     Pico.snd.dac_pos += (length-daclen) << 20;\r
+    if (mkbd_stolen_channels & (1u << 5))\r
+      ;\r
+    else\r
     if (PicoIn.opt & POPT_EN_STEREO) {\r
       s16 *d = PicoIn.sndOut + daclen*2;\r
       int pan = ym2612.REGS[YM2612_CH6PAN];\r
index a7812cb..05c08ae 100644 (file)
@@ -515,6 +515,20 @@ static UINT32 fn_table[4096];      /* fnumber->increment counter */
 \r
 static int g_lfo_ampm;\r
 \r
+\r
+#undef NDEBUG\r
+#include <assert.h>\r
+#include "mkbd.h"\r
+\r
+int mkbd_stolen_channels;\r
+int mkbd_kbd_channel = -1;\r
+int mkbd_kbd_echo_channel = -1;\r
+int mkbd_echo_delay_on;\r
+int mkbd_echo_delay_off;\r
+int mkbd_transpose;\r
+int mkbd_ar_min;\r
+int mkbd_stop_z80;\r
+\r
 /* register number to channel number , slot offset */\r
 #define OPN_CHAN(N) (N&3)\r
 #define OPN_SLOT(N) ((N>>2)&3)\r
@@ -620,7 +634,15 @@ static INLINE void set_ar_ksr(FM_CH *CH, FM_SLOT *SLOT, int v)
        UINT8 old_KSR = SLOT->KSR;\r
        int eg_sh_ar, eg_sel_ar;\r
 \r
-       SLOT->ar = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;\r
+       int c = CH - ym2612.CH;\r
+       int ar = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;\r
+       if (c == mkbd_kbd_channel || c == mkbd_kbd_echo_channel)\r
+               if (ar < mkbd_ar_min)\r
+                       ar = mkbd_ar_min;\r
+       //if (c == 0 && SLOT->ar != ar)\r
+       //      printf("%d,%ld %d->%d\n", c, SLOT - CH->SLOT, SLOT->ar, ar);\r
+\r
+       SLOT->ar = ar;\r
        SLOT->ar_ksr = SLOT->ar + SLOT->ksr;\r
 \r
        SLOT->KSR = 3-(v>>6);\r
@@ -1618,20 +1640,18 @@ static void OPNSetPres(int pres)
        }\r
 }\r
 \r
-#undef NDEBUG\r
-#include <assert.h>\r
-#include "mkbd.h"\r
-\r
 static\r
 const char *keys[] = { "c",  "c#", "d",  "d#", "e",  "f",  "f#", "g",  "g#",  "a",   "a#",  "b" };\r
 //                      643.8 682.1 722.6 765.6 811.1 859.3 910.4 964.6 1021.9 1082.7 1147.1 1215.3\r
 static int fns[] =    { 644,  682,  723,  766,  811,  860,  910,  965,  1022,  1083,  1147,  1215 };\r
 \r
-int mkbd_stolen_channels = (1<<3) | (1<<4);\r
 static int mkbd_blk_fn_overide[6+4];\r
 \r
 static int mkbd_fn_adj_step[6+4];\r
 static int mkbd_fn_adj[6+4];\r
+static int mkbd_ym_kon_mask;       // on now\r
+static int mkbd_ym_kon_next_mask;  // on on next frame\r
+static int mkbd_ym_cooldown_mask;\r
 \r
 // (144 * fnote * 2^20 / φM) / 2^(B-1)\r
 // x *144*2097152/7670443 / 16\r
@@ -1691,6 +1711,14 @@ static void do_log_note(int c)
 \r
 static void do_key_onoff(int c, int v)\r
 {\r
+       assert((u32)c < 6);\r
+       if (v & 0xf0)\r
+               mkbd_ym_kon_mask |= 1 << c;\r
+       else\r
+               mkbd_ym_kon_mask &= ~(1 << c);\r
+       //if (c==4) return;\r
+       //printf("%d c%d k%s %02x\n", Pico.m.frame_count,\r
+       //      c, (v & 0xf0) ? "on " : "off", v);\r
        if(v&0x10) FM_KEYON(c,SLOT1); else FM_KEYOFF(c,SLOT1);\r
        if(v&0x20) FM_KEYON(c,SLOT2); else FM_KEYOFF(c,SLOT2);\r
        if(v&0x40) FM_KEYON(c,SLOT3); else FM_KEYOFF(c,SLOT3);\r
@@ -1711,7 +1739,7 @@ static void set_blk_fn(int c, int blk_fn)
 \r
 static void echo_add(int c, int blk_fn, int frame_delay);\r
 \r
-void ym2612h_inject(int c, unsigned int octave, unsigned int key, int is_on,\r
+static void ym2612h_inject(int c, unsigned int octave, unsigned int key, int is_on,\r
        int echo_c, int echo_frames)\r
 {\r
        UINT32 val = 0;\r
@@ -1719,23 +1747,36 @@ void ym2612h_inject(int c, unsigned int octave, unsigned int key, int is_on,
        //printf("%s %d %d,%d %d\n", __func__, c, octave, key, is_on);\r
        assert(octave < 8);\r
        assert(key < ARRAY_SIZE(fns));\r
+\r
+       mkbd_ym_kon_next_mask &= ~(1 << c);\r
+       if (mkbd_ym_kon_mask & (1 << c))\r
+               mkbd_ym_cooldown_mask |= 1 << c;\r
+       mkbd_blk_fn_overide[c] = 0;\r
+       do_key_onoff(c, 0);\r
        if (is_on) {\r
                val = fns[key]; // + mkbd_fn_adj[c];\r
                assert(val < (1u << 11));\r
                val |= octave << 11;\r
                mkbd_blk_fn_overide[c] = val;\r
-               do_key_onoff(c, 0);\r
                set_blk_fn(c, val);\r
+               if (!(mkbd_ym_cooldown_mask & (1 << c)))\r
+                       do_key_onoff(c, 0xf0);\r
+               else\r
+                       // give a frame for adsr to update\r
+                       mkbd_ym_kon_next_mask |= 1 << c;\r
        }\r
-       else\r
-               mkbd_blk_fn_overide[c] = 0;\r
 \r
        mkbd_fn_adj[c] = mkbd_fn_adj_step[c] = 0;\r
 \r
-       do_key_onoff(c, is_on ? 0xf0 : 0);\r
-\r
-       if (echo_c >= 0)\r
+       if (echo_c >= 0) {\r
+               if (is_on) {\r
+                       // must do it always as there might be an older\r
+                       // koff that we need to override\r
+                       echo_add(echo_c, 0, echo_frames);\r
+                       echo_frames++;\r
+               }\r
                echo_add(echo_c, val, echo_frames);\r
+       }\r
 }\r
 \r
 static struct\r
@@ -1743,20 +1784,28 @@ static struct
        int c;\r
        int blk_fn;\r
        u32 frame;\r
-} echo_ev[8];\r
+} echo_ev[12];\r
 \r
 #define ECHO_MAX_FRAMES 60u\r
 \r
 static void echo_add(int c, int blk_fn, int frame_delay)\r
 {\r
        u32 now = Pico.m.frame_count;\r
-       int i;\r
+       int i, di;\r
 \r
        assert((u32)frame_delay <= ECHO_MAX_FRAMES);\r
        if (now + (u32)frame_delay == 0)\r
                frame_delay++;\r
-       if (blk_fn)\r
-               memset(echo_ev, 0, sizeof(echo_ev));\r
+\r
+       // as kon and koff delays may differ, and kon generates a koff event,\r
+       // kill any older event\r
+       for (i = 0; i < ARRAY_SIZE(echo_ev); i++) {\r
+               if (echo_ev[i].frame == 0 || echo_ev[i].c != c)\r
+                       continue;\r
+               di = echo_ev[i].frame - now;\r
+               if (di >= frame_delay && !echo_ev[i].blk_fn == !blk_fn)\r
+                       echo_ev[i].frame = 0;\r
+       }\r
 \r
        for (i = 0; i < ARRAY_SIZE(echo_ev); i++) {\r
                if (echo_ev[i].frame != 0 && echo_ev[i].frame - now <= ECHO_MAX_FRAMES)\r
@@ -1771,7 +1820,7 @@ static void echo_add(int c, int blk_fn, int frame_delay)
                printf("echo overflow\n");\r
 }\r
 \r
-void ym2612h_echo_step(void)\r
+static void ym2612h_echo_do_step(void)\r
 {\r
        u32 now = Pico.m.frame_count;\r
        int i, c, val;\r
@@ -1785,7 +1834,6 @@ void ym2612h_echo_step(void)
                if (val) {\r
                        mkbd_blk_fn_overide[c] = val;\r
                        set_blk_fn(c, val);\r
-                       do_key_onoff(c, 0);\r
                }\r
                do_key_onoff(c, val ? 0xf0 : 0);\r
                echo_ev[i].frame = 0;\r
@@ -1798,10 +1846,18 @@ void ym2612h_adj_start(int c, int step)
                mkbd_fn_adj_step[c] = step;\r
 }\r
 \r
-void ym2612h_adj_step(void)\r
+static void ym2612h_do_frame(void)\r
 {\r
        int c;\r
 \r
+       mkbd_ym_cooldown_mask = 0;\r
+       for (c = 0; c < 6; c++) {\r
+               if (!(mkbd_ym_kon_next_mask & (1 << c)))\r
+                       continue;\r
+               mkbd_ym_kon_next_mask &= ~(1 << c);\r
+               do_key_onoff(c, 0xf0);\r
+       }\r
+\r
        for (c = 0; c < 6; c++) {\r
                if (mkbd_fn_adj_step[c] == 0)\r
                        continue;\r
@@ -1815,6 +1871,61 @@ void ym2612h_adj_step(void)
        }\r
 }\r
 \r
+void mkbd_steal_toggle(int c, int shift)\r
+{\r
+       if (shift) {\r
+               mkbd_stolen_channels |= 1u << c;\r
+               if (c == mkbd_kbd_channel) {\r
+                       mkbd_kbd_channel = -1;\r
+                       mkbd_kbd_echo_channel = c;\r
+               }\r
+               else if (c == mkbd_kbd_echo_channel)\r
+                       mkbd_kbd_echo_channel = -1;\r
+               else\r
+                       mkbd_kbd_channel = c;\r
+       }\r
+       else {\r
+               mkbd_stolen_channels ^= 1u << c;\r
+               if (!(mkbd_stolen_channels & (1u << c))) {\r
+                       if (c == mkbd_kbd_channel)\r
+                               mkbd_kbd_channel = -1;\r
+                       if (c == mkbd_kbd_echo_channel)\r
+                               mkbd_kbd_echo_channel = -1;\r
+               }\r
+       }\r
+       if (c >= 6) {\r
+               sn76496h_steal(c - 6, !!(mkbd_stolen_channels & (1u << c)));\r
+               return;\r
+       }\r
+       if (mkbd_stolen_channels & (1u << c))\r
+               do_key_onoff(c, 0);\r
+}\r
+\r
+void mkbd_snd_inject(int c, unsigned int octave, unsigned int key, int is_on,\r
+       int echo_c, int echo_frames)\r
+{\r
+       if (c < 6)\r
+               ym2612h_inject(c, octave, key, is_on, echo_c, echo_frames);\r
+       else\r
+               ;\r
+}\r
+\r
+void mkbd_snd_adj_start(int c, int step)\r
+{\r
+       if (c < 6)\r
+               ym2612h_adj_start(c, step);\r
+       else\r
+               ;\r
+}\r
+\r
+void mkbd_snd_do_frame(void)\r
+{\r
+       ym2612h_do_frame();\r
+       ym2612h_echo_do_step();\r
+}\r
+\r
+// -----------------\r
+\r
 /* write a OPN register (0x30-0xff) */\r
 static int OPNWriteReg(int r, int v, int injecting)\r
 {\r
@@ -2169,8 +2280,8 @@ int YM2612Write_(unsigned int a, unsigned int v)
                                        if( c == 3 ) { ret=0; break; }\r
                                        if( v&0x04 ) c+=3;\r
                                        if (is_stolen(c)) { ret = 0; break; }\r
-                                       //if (c == 3 || c == 4)\r
-                                       //      printf("%d %d konoff %02x\n", Pico.m.frame_count, c, v);\r
+                                       //if (c == 0 || c == 4)\r
+                                       //      printf("%d %d k%s %02x\n", Pico.m.frame_count, c, (v & 0xf0) ? "on " : "off", v);\r
                                        if(v&0x10) FM_KEYON(c,SLOT1); else FM_KEYOFF(c,SLOT1);\r
                                        if(v&0x20) FM_KEYON(c,SLOT2); else FM_KEYOFF(c,SLOT2);\r
                                        if(v&0x40) FM_KEYON(c,SLOT3); else FM_KEYOFF(c,SLOT3);\r
index 799aa31..a6f5fed 100644 (file)
@@ -1589,6 +1589,8 @@ static void emu_loop_prep(void)
 #define get_ticks()    plat_get_ticks_us()\r
 #define vsync_delay    ms_to_ticks(1)\r
 \r
+#include "../../pico/sound/mkbd.h"\r
+\r
 void emu_loop(void)\r
 {\r
        int frames_done, frames_shown;  /* actual frames for fps counter */\r
@@ -1683,6 +1685,22 @@ void emu_loop(void)
 #ifdef PFRAMES\r
                sprintf(fpsbuff, "%i", Pico.m.frame_count);\r
 #endif\r
+               int i;\r
+               char buf_c[32];\r
+               notice_msg = buf_c;\r
+               for (i = 0; i < 10; i++) {\r
+                       char c = '0' + i;\r
+                       if (i == mkbd_kbd_channel)\r
+                               c = '*';\r
+                       else if (i == mkbd_kbd_echo_channel)\r
+                               c = '_';\r
+                       else if (mkbd_stolen_channels & (1u << i))\r
+                               c = '.';\r
+                       notice_msg[i] = c;\r
+               }\r
+               i += snprintf(buf_c + i, sizeof(buf_c) - i, " %02x",\r
+                       PicoMem.zram[0x1c24]); // tempo\r
+               notice_msg[i] = 0;\r
 \r
                diff = timestamp_aim - timestamp;\r
 \r
index 8e6987e..6228690 100644 (file)
@@ -20,6 +20,7 @@
 #include "emu.h"\r
 #include "version.h"\r
 #include <cpu/debug.h>\r
+#include "pico/sound/mkbd.h"\r
 \r
 static int load_state_slot = -1;\r
 char **g_argv;\r
@@ -46,6 +47,22 @@ void parse_cmd_line(int argc, char *argv[])
                        else if (strcasecmp(argv[x], "-pdb_connect") == 0) {\r
                                if (x+2 < argc) { pdb_net_connect(argv[x+1], argv[x+2]); x += 2; }\r
                        }\r
+                       else if (strcmp(argv[x], "-mk_c") == 0) {\r
+                               mkbd_kbd_channel = atoi(argv[++x]);\r
+                               mkbd_stolen_channels |= 1u << mkbd_kbd_channel;\r
+                       }\r
+                       else if (strcmp(argv[x], "-mk_ce") == 0) {\r
+                               mkbd_kbd_echo_channel = atoi(argv[++x]);\r
+                               mkbd_stolen_channels |= 1u << mkbd_kbd_echo_channel;\r
+                       }\r
+                       else if (strcmp(argv[x], "-mk_echo_on") == 0)\r
+                               mkbd_echo_delay_on = atoi(argv[++x]);\r
+                       else if (strcmp(argv[x], "-mk_echo_off") == 0)\r
+                               mkbd_echo_delay_off = atoi(argv[++x]);\r
+                       else if (strcmp(argv[x], "-mk_transpose") == 0)\r
+                               mkbd_transpose = atoi(argv[++x]);\r
+                       else if (strcmp(argv[x], "-mk_ar_min") == 0)\r
+                               mkbd_ar_min = atoi(argv[++x]);\r
                        else {\r
                                unrecognized = plat_parse_arg(argc, argv, &x);\r
                        }\r
index 023d7e8..1dd7707 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 023d7e890f1c4386ff3bc095efd96eb65fafe389
+Subproject commit 1dd770727c32898135d5dca81d54f0ca1dfd28ed