Diff for /np2/cbus/mpu98ii.c between versions 1.1 and 1.10

version 1.1, 2003/10/16 17:58:00 version 1.10, 2006/12/10 11:31:20
Line 1 Line 1
   
   // emulation MPU-401 CPU Version 1.3 ('84/07/07)
   
 #include        "compiler.h"  #include        "compiler.h"
 #include        "commng.h"  #include        "commng.h"
 #include        "i286.h"  
 #include        "pccore.h"  #include        "pccore.h"
 #include        "iocore.h"  #include        "iocore.h"
 #include        "cbuscore.h"  #include        "cbuscore.h"
Line 13  enum { Line 15  enum {
         MIDIIN_AVAIL            = 0x80,          MIDIIN_AVAIL            = 0x80,
         MIDIOUT_BUSY            = 0x40,          MIDIOUT_BUSY            = 0x40,
   
         MPU_INT                         = 0xfd,          MPUMSG_TRACKDATAREQ     = 0xf0,
         MPU_ACK                 = 0xfe,          MPUMSG_OVERFLOW         = 0xf8,
           MPUMSG_REQCOND          = 0xf9,
           MPUMSG_DATAEND          = 0xfc,
           MPUMSG_HCLK                     = 0xfd,
           MPUMSG_ACK              = 0xfe,
           MPUMSG_SYS                      = 0xff,
   
         MIDITIMEOUTCLOCK        = 3000,          MIDITIMEOUTCLOCK        = 3000,
         MIDITIMEOUTCLOCK2       = 300          MIDITIMEOUTCLOCK2       = 300
 };  };
   
 enum {  enum {
         MIDIE_STEP              = 0x01,          MIDIE_STEP                      = 0x01,
         MIDIE_2NDPARA   = 0x02,          MIDIE_EVENT                     = 0x02,
         MIDIE_EVENT             = 0x04,          MIDIE_DATA                      = 0x04
         MIDIE_DATA              = 0x08,  };
         MIDIE_F9DATA    = 0x10,  
         MIDIE_F9CMD             = 0x20,  enum {
         MIDIE_F9PARA    = 0x40          MPUCMDP_IDLE            = 0x00,
           MPUCMDP_STEP            = 0x01,
           MPUCMDP_CMD                     = 0x02,
           MPUCMDP_REQ                     = 0x04,
           MPUCMDP_FOLLOWBYTE      = 0x08,
           MPUCMDP_SHORT           = 0x10,
           MPUCMDP_LONG            = 0x20,
           MPUCMDP_INIT            = 0x80
 };  };
   
 enum {  enum {
         MPU1FLAG_A              = 0x01,          MPUSYNCMODE_INT                 = 0x00,
         MPU1FLAG_B              = 0x02,          MPUSYNCMODE_FSK                 = 0x01,
         MPU1FLAG_F9             = 0x04          MPUSYNCMODE_MIDI                = 0x02,
   
           MPUMETROMODE_ACC                = 0x00,
           MPUMETROMODE_OFF                = 0x01,
           MPUMETROMODE_ON                 = 0x02,
   
           MPUFLAG1_PLAY                   = 0x01,
           MPUFLAG1_BENDERTOHOST   = 0x08,
           MPUFLAG1_THRU                   = 0x10,
           MPUFLAG1_DATAINSTOP             = 0x20,
           MPUFLAG1_SENDME                 = 0x40,
           MPUFLAG1_CONDUCTOR              = 0x80,
   
           MPUFLAG2_RTAFF                  = 0x01,
           MPUFLAG2_FSKRESO                = 0x02,
           MPUFLAG2_CLKTOHOST              = 0x04,
           MPUFLAG2_EXECLUTOHOST   = 0x08,
           MPUFLAG2_REFA                   = 0x10,
           MPUFLAG2_REFB                   = 0x20,
           MPUFLAG2_REFC                   = 0x40,
           MPUFLAG2_REFD                   = 0x80
 };  };
   
   
Line 41  enum { Line 75  enum {
         COMMNG          cm_mpu98;          COMMNG          cm_mpu98;
   
   
 static const BYTE mpuirqnum[4] = {3, 5, 6, 12};  static const UINT8 mpuirqnum[4] = {3, 5, 6, 12};
   
   static const UINT8 shortmsgleng[0x10] = {
                   0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 2, 2, 3, 1};
   
 static const BYTE fd_step1[4][4] = {{0, 0, 0, 0}, {1, 0, 0, 0},  static const UINT8 hclk_step1[4][4] = {{0, 0, 0, 0}, {1, 0, 0, 0},
                                                                 {1, 0, 1, 0}, {1, 1, 1, 0}};                                                                          {1, 0, 1, 0}, {1, 1, 1, 0}};
   
   
 static void makeintclock(void) {  static void makeintclock(void) {
   
         UINT32  l;          UINT32  l;
           UINT    curtempo;
   
         l = mpu98.tempo * 2 * mpu98.tempos / 0x40;          l = mpu98.tempo * 2 * mpu98.reltempo / 0x40;
         if (l < 5*2) {          if (l < 5 * 2) {
                 l = 5*2;                  l = 5 * 2;
           }
           curtempo = l >> 1;
           if (curtempo > 250) {
                   curtempo = 250;
           }
           mpu98.curtempo = curtempo;
           if (!(mpu98.flag2 & MPUFLAG2_FSKRESO)) {
                   l *= mpu98.inttimebase;                                                 //      *12
         }          }
         l *= mpu98.timebase;                                            //      *12          mpu98.stepclock = (pccore.realclock * 5 / l);           //      /12
         mpu98.clock = (pc.realclock * 5 / l);           //      /12  
 }  }
   
 static void sendallclocks(BYTE data) {  static void sethclk(REG8 data) {
   
         BYTE    quarter;          REG8    quarter;
         int             i;          int             i;
   
         quarter = data >> 2;          quarter = data >> 2;
Line 69  static void sendallclocks(BYTE data) { Line 114  static void sendallclocks(BYTE data) {
                 quarter = 64;                  quarter = 64;
         }          }
         for (i=0; i<4; i++) {          for (i=0; i<4; i++) {
                 mpu98.fd_step[i] = fd_step1[data & 3][i];                  mpu98.hclk_step[i] = quarter + hclk_step1[data & 3][i];
                 mpu98.fd_step[i] += quarter;          }
           mpu98.hclk_rem = 0;
   }
   
   static void setdefaultcondition(void) {
   
           mpu98.recvevent = 0;
           mpu98.remainstep = 0;
           mpu98.intphase = 0;
           mpu98.intreq = 0;
   
           ZeroMemory(&mpu98.cmd, sizeof(mpu98.cmd));
           ZeroMemory(mpu98.tr, sizeof(mpu98.tr));
           ZeroMemory(&mpu98.cond, sizeof(mpu98.cond));
   
           mpu98.syncmode = MPUSYNCMODE_INT;
           mpu98.metromode = MPUMETROMODE_OFF;
           mpu98.flag1 = MPUFLAG1_THRU | MPUFLAG1_SENDME;
           mpu98.flag2 = MPUFLAG2_RTAFF;
   
           mpu98.inttimebase = 120 / 24;
           mpu98.tempo = 100;
           mpu98.reltempo = 0x40;
           makeintclock();
           mpu98.midipermetero = 12;
           mpu98.meteropermeas = 8;
           sethclk(240);
           mpu98.acttr = 0x00;
           mpu98.sendplaycnt = 0;
           mpu98.accch = 0xffff;
   }
   
   static void setrecvdata(REG8 data) {
   
           MPURECV *r;
   
           r = &mpu98.r;
           if (r->cnt < MPU98_RECVBUFS) {
                   r->buf[(r->pos + r->cnt) & (MPU98_RECVBUFS - 1)] = data;
                   r->cnt++;
           }
   }
   
   static void sendmpushortmsg(const UINT8 *dat, UINT count) {
   
           UINT    i;
           COMMNG  cm;
   
   #if 0
           if (!(mpu98.flag1 & MPUFLAG1_BENDERTOHOST)) {
                   switch(dat[0] >> 4) {
                           case 0x0a:
                           case 0x0d:
                           case 0x0e:
                                   return;
   
                           case 0x0b:
                                   if (dat[1] < 0x40) {
                                           return;
                                   }
                                   break;
                   }
           }
   #endif
           cm = cm_mpu98;
           for (i=0; i<count; i++) {
                   cm->write(cm, dat[i]);
           }
   }
   
   static void sendmpulongmsg(const UINT8 *dat, UINT count) {
   
           UINT    i;
           COMMNG  cm;
   
           cm = cm_mpu98;
           for (i=0; i<count; i++) {
                   cm->write(cm, dat[i]);
         }          }
         mpu98.fd_remain = 0;  
 }  }
   
 static void setrecvdata(BYTE data) {  static void sendmpureset(void) {
   
         if (mpu98.cnt < MPU98_RECVBUFS) {          UINT    i;
                 mpu98.buf[(mpu98.pos + mpu98.cnt) & (MPU98_RECVBUFS - 1)] = data;          UINT8   sMessage[3];
                 mpu98.cnt++;  
           for (i=0; i<0x10; i++) {
                   sMessage[0] = (UINT8)(0xb0 + i);
                   sMessage[1] = 0x7b;
                   sMessage[2] = 0x00;
                   sendmpushortmsg(sMessage, 3);
         }          }
 }  }
   
 static void mpu98ii_int(void) {  static void mpu98ii_int(void) {
   
           TRACEOUT(("int!"));
         pic_setirq(mpu98.irqnum);          pic_setirq(mpu98.irqnum);
 }  }
   
 static void ch_step(void) {  static void tr_step(void) {
   
         int             i;          int             i;
         BYTE    bit;          REG8    bit;
   
         if (mpu98.flag1 & MPU1FLAG_F9) {          if (mpu98.flag1 & MPUFLAG1_CONDUCTOR) {
                 if (mpu98.f9.step) {                  if (mpu98.cond.step) {
                         mpu98.f9.step--;                          mpu98.cond.step--;
                 }                  }
         }          }
         for (i=0, bit=1; bit; bit<<=1, i++) {          for (i=0, bit=1; i<8; bit<<=1, i++) {
                 if (mpu98.intch & bit) {                  if (mpu98.acttr & bit) {
                         if (mpu98.ch[i].step) {                          if (mpu98.tr[i].step) {
                                 mpu98.ch[i].step--;                                  mpu98.tr[i].step--;
                         }                          }
                 }                  }
         }          }
 }  }
   
 static BOOL ch_nextsearch(void) {  static BOOL tr_nextsearch(void) {
   
         int             i;          int             i;
         BYTE    bit;          REG8    bit;
   
 ch_nextsearch_more:  tr_nextsearch_more:
         if (mpu98.intreq == 9) {          if (mpu98.intphase == 1) {
                 if (mpu98.flag1 & MPU1FLAG_F9) {                  if (mpu98.flag1 & MPUFLAG1_CONDUCTOR) {
                         if (!mpu98.f9.step) {                          if (!mpu98.cond.step) {
                                 setrecvdata(0xf9);                                  mpu98.intreq = MPUMSG_REQCOND;
                                   mpu98.cond.phase |= MPUCMDP_STEP | MPUCMDP_CMD;
                                 mpu98ii_int();                                  mpu98ii_int();
                                 mpu98.f9.datas = 0;  
                                 mpu98.f9.remain = MPU98_EXCVBUFS;  
                                 mpu98.recvevent |= MIDIE_F9DATA;  
                                 return(TRUE);                                  return(TRUE);
                         }                          }
                 }                  }
                 mpu98.intreq = 7;                  mpu98.intphase = 2;
         }          }
         bit = 1 << mpu98.intreq;          if (mpu98.intphase) {
         for (; bit; bit>>=1) {                  bit = 1 << (mpu98.intphase - 2);
                 if (mpu98.intch & bit) {                  do {
                         MPUCH *ch;                          if (mpu98.acttr & bit) {
                         ch = mpu98.ch + mpu98.intreq;                                  MPUTR *tr;
                         if (!ch->step) {                                  tr = mpu98.tr + (mpu98.intphase - 2);
                                 if ((ch->datas) && (ch->remain == 0)) {                                  if (!tr->step) {
                                         if (cm_mpu98 == NULL) {                                          if ((tr->datas) && (tr->remain == 0)) {
                                                 cm_mpu98 = commng_create(COMCREATE_MPU98II);                                                  if (cm_mpu98 == NULL) {
                                         }                                                          cm_mpu98 = commng_create(COMCREATE_MPU98II);
                                         if (ch->data[0] == MIDI_STOP) {                                                  }
                                                 ch->datas = 0;                                                  if (tr->data[0] == MIDI_STOP) {
                                                 cm_mpu98->write(cm_mpu98, MIDI_STOP);                                                          tr->datas = 0;
                                                 setrecvdata(MIDI_STOP);                                                          cm_mpu98->write(cm_mpu98, MIDI_STOP);
                                                 mpu98ii_int();                                                          setrecvdata(MIDI_STOP);
                                                 return(TRUE);                                                          mpu98ii_int();
                                                           return(TRUE);
                                                   }
                                                   for (i=0; i<tr->datas; i++) {
                                                           cm_mpu98->write(cm_mpu98, tr->data[i]);
                                                   }
                                                   tr->datas = 0;
                                         }                                          }
                                         for (i=0; i<ch->datas; i++) {                                          mpu98.intreq = 0xf0 + (mpu98.intphase - 2);
                                                 cm_mpu98->write(cm_mpu98, ch->data[i]);                                          mpu98.recvevent |= MIDIE_STEP;
                                         }                                          mpu98ii_int();
                                         ch->datas = 0;                                          return(TRUE);
                                 }                                  }
                                 setrecvdata((BYTE)(0xf0 + mpu98.intreq));  
                                 mpu98ii_int();  
                                 mpu98.recvevent |= MIDIE_STEP;  
                                 return(TRUE);  
                         }                          }
                 }                          bit <<= 1;
                 mpu98.intreq--;                          mpu98.intphase++;
                   } while(mpu98.intphase < 10);
                   mpu98.intphase = 0;
         }          }
         mpu98.remainstep--;          mpu98.remainstep--;
         if (mpu98.remainstep) {          if (mpu98.remainstep) {
                 ch_step();                  tr_step();
                 mpu98.intreq = 9;                  mpu98.intphase = 1;
                 goto ch_nextsearch_more;                  goto tr_nextsearch_more;
         }          }
         return(FALSE);          return(FALSE);
 }  }
   
 void midiint(NEVENTITEM item) {  void midiint(NEVENTITEM item) {
   
         nevent_set(NEVENT_MIDIINT, mpu98.clock, midiint, NEVENT_RELATIVE);          nevent_set(NEVENT_MIDIINT, mpu98.stepclock, midiint, NEVENT_RELATIVE);
   
         if (mpu98.flag1 & MPU1FLAG_A) {          if (mpu98.flag2 & MPUFLAG2_CLKTOHOST) {
                 if (!mpu98.fd_remain) {                  if (!mpu98.hclk_rem) {
                         mpu98.fd_remain = mpu98.fd_step[mpu98.fd_cnt & 3];                          mpu98.hclk_rem = mpu98.hclk_step[mpu98.hclk_cnt & 3];
                         mpu98.fd_cnt++;                          mpu98.hclk_cnt++;
                 }                  }
                 mpu98.fd_remain--;                  mpu98.hclk_rem--;
                 if (!mpu98.fd_remain) {                  if (!mpu98.hclk_rem) {
                         setrecvdata(MPU_INT);                          setrecvdata(MPUMSG_HCLK);
                         mpu98ii_int();                          mpu98ii_int();
                 }                  }
         }          }
         if (mpu98.flag1 & MPU1FLAG_B) {          if (mpu98.flag1 & MPUFLAG1_PLAY) {
                 if (!mpu98.remainstep++) {                  if (!mpu98.remainstep++) {
                         ch_step();                          tr_step();
                         mpu98.intreq = 9;                          mpu98.intphase = 1;
                         ch_nextsearch();                          tr_nextsearch();
                 }                  }
         }          }
         (void)item;          (void)item;
Line 205  static void midiwait(SINT32 waitclock) { Line 334  static void midiwait(SINT32 waitclock) {
         }          }
 }  }
   
 static BOOL sendcmd(BYTE cmd) {  
   
         BYTE    work;  // ----
   
         mpu98.cmd = cmd;  typedef REG8 (*MPUCMDFN)(REG8 cmd);
         switch(cmd & 0xf0) {  
                 case 0xe0:                              // send 2nddata  
                         mpu98.recvevent |= MIDIE_2NDPARA;  
                         return(TRUE);  
   
                 case 0xa0:                              // recv data  static REG8 mpucmd_xx(REG8 cmd) {
                         return(TRUE);  
   
                 case 0xc0:                              // timebase  //      TRACEOUT(("unknown MPU commands: %.2x", cmd));
                         work = cmd & 0x0f;          (void)cmd;
                         if ((!work) || (work > MPU98_MAXTIMEBASE)) {          return(MPUCMDP_IDLE);
                                 return(FALSE);  }
                         }  
                         mpu98.timebase = work;  
                         makeintclock();  
                         return(TRUE);  
         }  
   
         switch(cmd) {  static REG8 mpucmd_md(REG8 cmd) {                       // 00-2F: Mode
                 case 0xd0:                              // send short  
                 case 0xd1:  
                 case 0xd2:  
                 case 0xd3:  
                 case 0xd4:  
                 case 0xd5:  
                 case 0xd6:  
                 case 0xd7:  
                 case 0xdf:                              // send long  
                         break;  
   
                 case 0xff:                              // reset          TRACEOUT(("mpucmd_md %.2x", cmd));
                         cm_mpu98->msg(cm_mpu98, COMMSG_MIDIRESET, 0);  #if 0
                         mpu98.intch = 0;          switch((cmd >> 0) & 3) {
                   case 1:                                                         // MIDI Stop
                   case 2:                                                         // MIDI Start
                   case 3:                                                         // MIDI Cont
                           break;
           }
   #endif
           switch((cmd >> 2) & 3) {
                   case 1:                                                         // Stop Play
                           mpu98.flag1 &= ~MPUFLAG1_PLAY;
                         mpu98.recvevent = 0;                          mpu98.recvevent = 0;
                           mpu98.intphase = 0;
                         mpu98.intreq = 0;                          mpu98.intreq = 0;
                         mpu98.flag1 = 0;                          ZeroMemory(mpu98.tr, sizeof(mpu98.tr));
                         mpu98.remainstep = 0;                          ZeroMemory(&mpu98.cond, sizeof(mpu98.cond));
                         ZeroMemory(mpu98.ch, sizeof(mpu98.ch));                          if (!(mpu98.flag2 & MPUFLAG2_CLKTOHOST)) {
                         ZeroMemory(&mpu98.f9, sizeof(mpu98.f9));                                  nevent_reset(NEVENT_MIDIINT);
                         nevent_reset(NEVENT_MIDIINT);                          }
                           break;
   
                         mpu98.tempo = 120;                  case 2:                                                         // Start Play
                         mpu98.tempos = 0x40;                          mpu98.flag1 |= MPUFLAG1_PLAY;
                         makeintclock();                          mpu98.remainstep = 0;
                           if (!nevent_iswork(NEVENT_MIDIINT)) {
                                   nevent_set(NEVENT_MIDIINT, mpu98.stepclock,
                                                                                           midiint, NEVENT_ABSOLUTE);
                           }
                           break;
           }
   #if 0
           switch((cmd >> 4) & 3) {
                   case 1:                                                         // Stop Rec
                   case 2:                                                         // Rec
                         break;                          break;
           }
   #endif
           return(MPUCMDP_IDLE);
   }
   
   static REG8 mpucmd_3f(REG8 cmd) {                       // 3F: UART
   
           mpu98.mode = 1;
           sendmpureset();
           (void)cmd;
           return(MPUCMDP_IDLE);
   }
   
   static REG8 mpucmd_sr(REG8 cmd) {                       // 40-7F: Set ch of Ref table
   
           (void)cmd;
           return(MPUCMDP_IDLE);
   }
   
   static REG8 mpucmd_sm(REG8 cmd) {                       // 80-82: Clock Sync/Mode
   
           mpu98.syncmode = cmd - 0x80;
           return(MPUCMDP_IDLE);
   }
   
   static REG8 mpucmd_mm(REG8 cmd) {                       // 83-85: Metronome
   
           mpu98.metromode = cmd - 0x83;
           return(MPUCMDP_IDLE);
   }
   
                 case 0x3f:                              // uart mode on  static REG8 mpucmd_8x(REG8 cmd) {                       // 86-8F: Flag1
                         mpu98.mode = 1;  
                         cm_mpu98->msg(cm_mpu98, COMMSG_MIDIRESET, 0);          REG8    bit;
   
           bit = 1 << ((cmd >> 1) & 7);
           if (cmd & 1) {
                   mpu98.flag1 |= bit;
           }
           else {
                   mpu98.flag1 &= ~bit;
           }
   #if 0
           switch(cmd & 0x0f) {
                   case 0x06:                                                      // 86: Bender to Host / off
                   case 0x07:                                                      // 87: Bender to Host / on
                   case 0x08:                                                      // 88: THRU / off
                   case 0x09:                                                      // 89: THRU / on
                   case 0x0a:                                                      // 8A: Data in Stop / off
                   case 0x0b:                                                      // 8B: Data in Stop / on
                   case 0x0c:                                                      // 8C: Send Me / off
                   case 0x0d:                                                      // 8D: Send Me / on
                   case 0x0e:                                                      // 8E: Conductor / off
                   case 0x0f:                                                      // 8F: Conductor / on
                         break;                          break;
           }
   #endif
           return(MPUCMDP_IDLE);
   }
   
                 case 0x94:                              // disable clock to host  static REG8 mpucmd_9x(REG8 cmd) {                       // 90-9F: Flag2
                         mpu98.flag1 &= ~MPU1FLAG_A;  
                         if (!(mpu98.flag1 & MPU1FLAG_B)) {          REG8    bit;
                                 nevent_reset(NEVENT_MIDIINT);  
                         }          bit = 1 << ((cmd >> 1) & 7);
           if (cmd & 1) {
                   mpu98.flag2 |= bit;
           }
           else {
                   mpu98.flag2 &= ~bit;
           }
           switch(cmd & 0x0f) {
   #if 0
                   case 0x00:                                                      // 90: RT Aff / off
                   case 0x01:                                                      // 91: RT Aff / on
                   case 0x02:                                                      // 92: FSK Reso / INT
                   case 0x03:                                                      // 93: FSK Reso / 24
                         break;                          break;
   #endif
   
                 case 0x05:                  case 0x04:                                                      // 94: CLK to Host / off
                         mpu98.flag1 &= ~MPU1FLAG_B;                          if (!(mpu98.flag1 & MPUFLAG1_PLAY)) {
                         mpu98.recvevent = 0;  
                         mpu98.intreq = 0;  
                         ZeroMemory(mpu98.ch, sizeof(mpu98.ch));  
                         ZeroMemory(&mpu98.f9, sizeof(mpu98.f9));  
                         if (!(mpu98.flag1 & MPU1FLAG_A)) {  
                                 nevent_reset(NEVENT_MIDIINT);                                  nevent_reset(NEVENT_MIDIINT);
                         }                          }
                         break;                          break;
   
                 case 0x95:                              // enable clock to host                  case 0x05:                                                      // 95: CLK to Host / on
                         mpu98.flag1 |= MPU1FLAG_A;  
                         if (!nevent_iswork(NEVENT_MIDIINT)) {                          if (!nevent_iswork(NEVENT_MIDIINT)) {
                                 nevent_set(NEVENT_MIDIINT, mpu98.clock,                                  nevent_set(NEVENT_MIDIINT, mpu98.stepclock,
                                                                                         midiint, NEVENT_ABSOLUTE);                                                                                          midiint, NEVENT_ABSOLUTE);
                         }                          }
                         break;                          break;
   
                 case 0x0a:  #if 0
                         mpu98.flag1 |= MPU1FLAG_B;                  case 0x06:                                                      // 96: Exclu to Host / off
                         mpu98.remainstep = 0;                  case 0x07:                                                      // 97: Exclu to Host / on
                         if (!nevent_iswork(NEVENT_MIDIINT)) {                  case 0x08:                                                      // 98: Ref A / off
                                 nevent_set(NEVENT_MIDIINT, mpu98.clock,                  case 0x09:                                                      // 99: Ref A / on
                                                                                         midiint, NEVENT_ABSOLUTE);                  case 0x0a:                                                      // 9A: Ref B / off
                         }                  case 0x0b:                                                      // 9B: Ref B / on
                   case 0x0c:                                                      // 9C: Ref C / off
                   case 0x0d:                                                      // 9D: Ref C / on
                   case 0x0e:                                                      // 9E: Ref D / off
                   case 0x0f:                                                      // 9F: Ref D / on
                         break;                          break;
   #endif
           }
           return(MPUCMDP_IDLE);
   }
   
                 case 0x8e:                              // disable f9  static REG8 mpucmd_rq(REG8 cmd) {                       // A0-AF: Req
                         mpu98.flag1 &= ~MPU1FLAG_F9;  
                         break;  
   
                 case 0x8f:                              // enable f9          (void)cmd;
                         mpu98.flag1 |= MPU1FLAG_F9;          return(MPUCMDP_REQ);
                         break;  }
   
   static REG8 mpucmd_b1(REG8 cmd) {                       // B1: Clear Rel
   
           mpu98.reltempo = 0x40;
           makeintclock();
           (void)cmd;
           return(MPUCMDP_IDLE);
   }
   
   static REG8 mpucmd_b8(REG8 cmd) {                       // B8: Clear PC
   
           int             i;
   
           for (i=0; i<8; i++) {
                   mpu98.tr[i].step = 0;
           }
           (void)cmd;
           return(MPUCMDP_IDLE);
   }
   
   static REG8 mpucmd_tb(REG8 cmd) {                       // C2-C8: .INT Time Base
   
           mpu98.inttimebase = cmd & 0x0f;
           makeintclock();
           (void)cmd;
           return(MPUCMDP_IDLE);
   }
   
   static REG8 mpucmd_ws(REG8 cmd) {                       // D0-D7: Want to Send Data
   
           (void)cmd;
           return(MPUCMDP_SHORT | MPUCMDP_INIT);
   }
   
   static REG8 mpucmd_df(REG8 cmd) {                       // DF: WSD System
   
           (void)cmd;
           return(MPUCMDP_LONG | MPUCMDP_INIT);
   }
   
 #if 0                                                   // ÌÌÅݤʤΤǥ³¥Þ¥ó¥É¥Á¥§¥Ã¥¯¤·¤Ê¤¤¡Ä  static REG8 mpucmd_fo(REG8 cmd) {                       // E0-EF: Following Byte
                 case 0x01:                              // send MIDI stop  
                 case 0x02:                              // send MIDI start  
                 case 0x03:                              // send MIDI continue  
   
                 case 0x15:                              // stop recording, playback and MIDI          (void)cmd;
           return(MPUCMDP_FOLLOWBYTE);
   }
   
   static REG8 mpucmd_ff(REG8 cmd) {                       // FF: Reset
   
           sendmpureset();
           nevent_reset(NEVENT_MIDIINT);
           setdefaultcondition();
           (void)cmd;
           return(MPUCMDP_IDLE);
   }
   
   static const MPUCMDFN mpucmds[0x100] = {
           mpucmd_xx,              mpucmd_md,              mpucmd_md,              mpucmd_md,              // 00
           mpucmd_xx,              mpucmd_md,              mpucmd_md,              mpucmd_md,
           mpucmd_xx,              mpucmd_md,              mpucmd_md,              mpucmd_md,
           mpucmd_xx,              mpucmd_xx,              mpucmd_xx,              mpucmd_xx,
   
           mpucmd_xx,              mpucmd_md,              mpucmd_md,              mpucmd_md,              // 10
           mpucmd_xx,              mpucmd_md,              mpucmd_md,              mpucmd_md,
           mpucmd_xx,              mpucmd_md,              mpucmd_md,              mpucmd_md,
           mpucmd_xx,              mpucmd_xx,              mpucmd_xx,              mpucmd_xx,
   
           mpucmd_xx,              mpucmd_md,              mpucmd_md,              mpucmd_md,              // 20
           mpucmd_xx,              mpucmd_md,              mpucmd_md,              mpucmd_md,
           mpucmd_xx,              mpucmd_md,              mpucmd_md,              mpucmd_md,
           mpucmd_xx,              mpucmd_xx,              mpucmd_xx,              mpucmd_xx,
   
           mpucmd_xx,              mpucmd_xx,              mpucmd_xx,              mpucmd_xx,              // 30
           mpucmd_xx,              mpucmd_xx,              mpucmd_xx,              mpucmd_xx,
           mpucmd_xx,              mpucmd_xx,              mpucmd_xx,              mpucmd_xx,
           mpucmd_xx,              mpucmd_xx,              mpucmd_xx,              mpucmd_3f,
   
           mpucmd_sr,              mpucmd_sr,              mpucmd_sr,              mpucmd_sr,              // 40
           mpucmd_sr,              mpucmd_sr,              mpucmd_sr,              mpucmd_sr,
           mpucmd_sr,              mpucmd_sr,              mpucmd_sr,              mpucmd_sr,
           mpucmd_sr,              mpucmd_sr,              mpucmd_sr,              mpucmd_sr,
   
           mpucmd_sr,              mpucmd_sr,              mpucmd_sr,              mpucmd_sr,              // 50
           mpucmd_sr,              mpucmd_sr,              mpucmd_sr,              mpucmd_sr,
           mpucmd_sr,              mpucmd_sr,              mpucmd_sr,              mpucmd_sr,
           mpucmd_sr,              mpucmd_sr,              mpucmd_sr,              mpucmd_sr,
   
           mpucmd_sr,              mpucmd_sr,              mpucmd_sr,              mpucmd_sr,              // 60
           mpucmd_sr,              mpucmd_sr,              mpucmd_sr,              mpucmd_sr,
           mpucmd_sr,              mpucmd_sr,              mpucmd_sr,              mpucmd_sr,
           mpucmd_sr,              mpucmd_sr,              mpucmd_sr,              mpucmd_sr,
   
           mpucmd_sr,              mpucmd_sr,              mpucmd_sr,              mpucmd_sr,              // 70
           mpucmd_sr,              mpucmd_sr,              mpucmd_sr,              mpucmd_sr,
           mpucmd_sr,              mpucmd_sr,              mpucmd_sr,              mpucmd_sr,
           mpucmd_sr,              mpucmd_sr,              mpucmd_sr,              mpucmd_sr,
   
           mpucmd_sm,              mpucmd_sm,              mpucmd_sm,              mpucmd_mm,              // 80
           mpucmd_mm,              mpucmd_mm,              mpucmd_8x,              mpucmd_8x,
           mpucmd_8x,              mpucmd_8x,              mpucmd_8x,              mpucmd_8x,
           mpucmd_8x,              mpucmd_8x,              mpucmd_8x,              mpucmd_8x,
   
           mpucmd_9x,              mpucmd_9x,              mpucmd_9x,              mpucmd_9x,              // 90
           mpucmd_9x,              mpucmd_9x,              mpucmd_9x,              mpucmd_9x,
           mpucmd_9x,              mpucmd_9x,              mpucmd_9x,              mpucmd_9x,
           mpucmd_9x,              mpucmd_9x,              mpucmd_9x,              mpucmd_9x,
   
           mpucmd_rq,              mpucmd_rq,              mpucmd_rq,              mpucmd_rq,              // a0
           mpucmd_rq,              mpucmd_rq,              mpucmd_rq,              mpucmd_rq,
           mpucmd_xx,              mpucmd_xx,              mpucmd_xx,              mpucmd_rq,
           mpucmd_rq,              mpucmd_rq,              mpucmd_xx,              mpucmd_rq,
   
           mpucmd_xx,              mpucmd_b1,              mpucmd_xx,              mpucmd_xx,              // b0
           mpucmd_xx,              mpucmd_xx,              mpucmd_xx,              mpucmd_xx,
           mpucmd_b8,              mpucmd_xx,              mpucmd_xx,              mpucmd_xx,
           mpucmd_xx,              mpucmd_xx,              mpucmd_xx,              mpucmd_xx,
   
                 case 0x32:                              // ?          mpucmd_xx,              mpucmd_xx,              mpucmd_tb,              mpucmd_tb,              // c0
                 case 0x34:                              // return timing bytes in stop mode          mpucmd_tb,              mpucmd_tb,              mpucmd_tb,              mpucmd_tb,
                 case 0x35:                              // enable mode messages to PC          mpucmd_tb,              mpucmd_xx,              mpucmd_xx,              mpucmd_xx,
                 case 0x38:                              // enable sys common messages to PC          mpucmd_xx,              mpucmd_xx,              mpucmd_xx,              mpucmd_xx,
                 case 0x39:                              // Enable real time messages to PC  
                 case 0x3c:                              // use CLS sync  
                 case 0x3d:                              // use SMPTE sync  
   
                 case 0x80:                              // use MIDI sync          mpucmd_ws,              mpucmd_ws,              mpucmd_ws,              mpucmd_ws,              // d0
                 case 0x81:                              // use FSK sync          mpucmd_ws,              mpucmd_ws,              mpucmd_ws,              mpucmd_ws,
                 case 0x82:                              // use MIDI sync          mpucmd_xx,              mpucmd_xx,              mpucmd_xx,              mpucmd_xx,
                 case 0x83:                              // enable metronome without accents          mpucmd_xx,              mpucmd_xx,              mpucmd_xx,              mpucmd_df,
                 case 0x84:                              // disable metronome  
                 case 0x8a:                              // disable data in stopped mode  
                 case 0x8b:                              // enable data in stop mode  
                 case 0x8c:                              // disable measure end messages to host  
   
                 case 0x91:                              // enable ext MIDI ctrl          mpucmd_fo,              mpucmd_fo,              mpucmd_fo,              mpucmd_xx,              // e0
                 case 0x97:                              // enable system exclusive messages to PC          mpucmd_fo,              mpucmd_xx,              mpucmd_fo,              mpucmd_fo,
           mpucmd_xx,              mpucmd_xx,              mpucmd_xx,              mpucmd_xx,
           mpucmd_fo,              mpucmd_fo,              mpucmd_fo,              mpucmd_fo,
   
           mpucmd_xx,              mpucmd_xx,              mpucmd_xx,              mpucmd_xx,              // f0
           mpucmd_xx,              mpucmd_xx,              mpucmd_xx,              mpucmd_xx,
           mpucmd_xx,              mpucmd_xx,              mpucmd_xx,              mpucmd_xx,
           mpucmd_xx,              mpucmd_xx,              mpucmd_xx,              mpucmd_ff};
   
   
   static void reqmpucmdgroupd(REG8 cmd) {
   
           switch(cmd) {
                   case 0xa0:                                              // A0: Req Play Cnt Tr1
                   case 0xa1:                                              // A1: Req Play Cnt Tr2
                   case 0xa2:                                              // A2: Req Play Cnt Tr3
                   case 0xa3:                                              // A3: Req Play Cnt Tr4
                   case 0xa4:                                              // A4: Req Play Cnt Tr5
                   case 0xa5:                                              // A5: Req Play Cnt Tr6
                   case 0xa6:                                              // A6: Req Play Cnt Tr7
                   case 0xa7:                                              // A7: Req Play Cnt Tr8
                           setrecvdata(mpu98.tr[cmd - 0xa0].step);
                         break;                          break;
   
                 default:                  case 0xab:                                              // AB: Read & Clear RC
                         return(FALSE);                          setrecvdata(0);
 #endif                          break;
   
                   case 0xac:                                              // AC: Req Major Version
                           setrecvdata(1);
                           break;
   
                   case 0xad:                                              // AD: Req Minor Version
                           setrecvdata(0);
                           break;
   
                   case 0xaf:                                              // AF: Req Tempo
                           setrecvdata(mpu98.curtempo);
                           break;
         }          }
         return(TRUE);  
 }  }
   
 static void group_ex(BYTE cmd, BYTE data) {  static void setmpucmdgroupe(REG8 cmd, REG8 data) {
   
         switch(cmd) {          switch(cmd) {
                 case 0xe0:                              // tempo                  case 0xe0:                              // Set Tempo
                         mpu98.tempo = data;                          mpu98.tempo = data;
                         mpu98.tempos = 0x40;                          mpu98.reltempo = 0x40;
                         makeintclock();                          makeintclock();
                         break;                          break;
   
                 case 0xe1:                              // ? ÁêÂХƥó¥Ý¤Ã¤Ý¤¤¤±¤É¡Ä                  case 0xe1:                              // Rel Tempo
                         mpu98.tempos = data;                          mpu98.reltempo = data;
                         makeintclock();                          makeintclock();
                         break;                          break;
   
                 case 0xe2:                              // ?                  case 0xe2:                              // Graduation
                           break;
   
                   case 0xe4:                              // MIDI/Metro
                           mpu98.midipermetero = data;
                         break;                          break;
   
                 case 0xe4:                              // clocks/click                  case 0xe6:                              // Metro/Meas
                           mpu98.meteropermeas = data;
                         break;                          break;
   
                 case 0xe6:                              // beats/measure                  case 0xe7:                              // INTx4/H.CLK
 //                      TRACE_("beat/measure:", data);                          sethclk(data);
                         break;                          break;
   
                 case 0xe7:                              // send all clocks to host                  case 0xec:                              // Act Tr
                         sendallclocks(data);                          mpu98.acttr = data;
                         break;                          break;
   
                 case 0xec:                              // channel mask?                  case 0xed:                              // Send Play CNT
                         mpu98.intch = data;                          mpu98.sendplaycnt = data;
                           break;
   
                   case 0xee:                              // Acc CH 1-8
                           mpu98.accch = (mpu98.accch & 0xff00) | data;
                           break;
   
                   case 0xef:                              // Acc CH 9-16
                           mpu98.accch = (mpu98.accch & 0x00ff) | (data << 8);
                         break;                          break;
         }          }
 }  }
   
 static void senddat(BYTE data) {  static BOOL sendmpumsg(MPUCMDS *cmd, REG8 data) {
   
         MPUCH   *ch;          if (cmd->phase & MPUCMDP_SHORT) {
                   if (cmd->phase & MPUCMDP_INIT) {
                           cmd->phase &= ~MPUCMDP_INIT;
                           if (!(data & 0x80)) {
                                   cmd->data[0] = cmd->rstat;
                                   cmd->datapos = 1;
                                   cmd->datacnt = shortmsgleng[cmd->rstat >> 4];
                           }
                           else {
                                   if ((data & 0xf0) != 0xf0) {
                                           cmd->rstat = data;
                                   }
                                   cmd->datapos = 0;
                                   cmd->datacnt = shortmsgleng[data >> 4];
                           }
                   }
                   cmd->data[cmd->datapos] = data;
                   cmd->datapos++;
                   if (cmd->datapos >= cmd->datacnt) {
                           sendmpushortmsg(cmd->data, cmd->datacnt);
                           cmd->phase &= ~MPUCMDP_SHORT;
                   }
                   return(TRUE);
           }
           else if (cmd->phase & MPUCMDP_LONG) {
                   if (cmd->phase & MPUCMDP_INIT) {
                           cmd->phase &= ~MPUCMDP_INIT;
                           cmd->datapos = 0;
                           cmd->datacnt = sizeof(cmd->data);
                   }
                   if (cmd->datapos < cmd->datacnt) {
                           cmd->data[cmd->datapos] = data;
                           cmd->datapos++;
                   }
                   switch(cmd->data[0]) {
                           case 0xf0:
                                   if (data == 0xf7) {
                                           cmd->phase &= ~MPUCMDP_LONG;
                                           sendmpulongmsg(cmd->data, cmd->datapos);
                                   }
                                   break;
   
         if (mpu98.recvevent & MIDIE_2NDPARA) {                          case 0xf2:
                 mpu98.recvevent ^= MIDIE_2NDPARA;                          case 0xf3:
                 group_ex(mpu98.cmd, data);                                  if (cmd->datapos >= 3) {
                 if (mpu98.recvevent & MIDIE_EVENT) {                                          cmd->phase &= ~MPUCMDP_LONG;
                         mpu98.recvevent ^= MIDIE_EVENT;                                  }
                         ch_nextsearch();                                  break;
   
                           case 0xf6:
                           default:
                                   cmd->phase &= ~MPUCMDP_LONG;
                                   break;
                   }
                   return(TRUE);
           }
           return(FALSE);
   }
   
   static BRESULT sendmpucmd(MPUCMDS *cmd, REG8 data) {
   
           if (cmd->phase & MPUCMDP_FOLLOWBYTE) {
                   cmd->phase &= ~MPUCMDP_FOLLOWBYTE;
                   setmpucmdgroupe(cmd->cmd, data);
                   return(SUCCESS);
           }
           else if (cmd->phase & (MPUCMDP_SHORT | MPUCMDP_LONG)) {
                   sendmpumsg(cmd, data);
                   return(SUCCESS);
           }
           else {
                   cmd->phase = 0;
                   return(FAILURE);
           }
   }
   
   static BRESULT sendmpucond(MPUCMDS *cmd, REG8 data) {
   
           if (cmd->phase & (MPUCMDP_SHORT | MPUCMDP_LONG)) {
   //              if (mpu98.intreq == 0xf9) {
   //                      mpu98.intreq = 0;
   //              }
                   sendmpumsg(cmd, data);
                   return(SUCCESS);
           }
           else if (cmd->phase & MPUCMDP_STEP) {
                   if (data < 0xf0) {
                           cmd->step = data;
                           cmd->phase &= ~MPUCMDP_STEP;
                   }
                   else {
                           cmd->step = 0xf0;
                           cmd->phase &= ~(MPUCMDP_STEP | MPUCMDP_CMD);
                   }
                   return(SUCCESS);
           }
           else if (cmd->phase & MPUCMDP_CMD) {
                   cmd->phase &= ~MPUCMDP_CMD;
                   cmd->cmd = data;
                   if (data < 0xf0) {
                           REG8 phase;
                           phase = (*mpucmds[data])(data);
                           if (phase & MPUCMDP_REQ) {
                                   phase &= ~MPUCMDP_REQ;
                                   reqmpucmdgroupd(data);
                           }
                           cmd->phase = phase;
                           if (phase & MPUCMDP_FOLLOWBYTE) {
                                   return(SUCCESS);
                           }
                   }
                   else {
                           cmd->phase = 0;
                           if (data == MIDI_STOP) {
                                   cm_mpu98->write(cm_mpu98, MIDI_STOP);
                                   setrecvdata(MIDI_STOP);
                                   mpu98ii_int();
                           }
                 }                  }
           }
           else if (cmd->phase & MPUCMDP_FOLLOWBYTE) {
                   cmd->phase &= ~MPUCMDP_FOLLOWBYTE;
                   setmpucmdgroupe(cmd->cmd, data);
           }
           else {
                   cmd->phase = 0;
                   return(FAILURE);
           }
   
           tr_nextsearch();
           return(SUCCESS);
   }
   
   static void sendmpudata(REG8 data) {
   
           if (mpu98.cmd.phase) {
                   sendmpucmd(&mpu98.cmd, data);
                 return;                  return;
         }          }
   
         if (mpu98.recvevent & MIDIE_STEP) {          if (mpu98.recvevent & MIDIE_STEP) {
                   MPUTR *tr;
                 mpu98.recvevent ^= MIDIE_STEP;                  mpu98.recvevent ^= MIDIE_STEP;
                 ch = mpu98.ch + mpu98.intreq;                  tr = mpu98.tr + (mpu98.intphase - 2);
                 ch->datas = 0;                  tr->datas = 0;
                 if (data < 0xf0) {                  if (data < 0xf0) {
                         mpu98.recvevent ^= MIDIE_EVENT;                          mpu98.recvevent ^= MIDIE_EVENT;
                         ch->step = data;                          tr->step = data;
                 }                  }
                 else {                  else {
                         ch->step = 0xf0;                          tr->step = 0xf0;
                         ch->remain = 0;                          tr->remain = 0;
                         ch->datas = 0;                          tr->datas = 0;
                         ch_nextsearch();                          tr_nextsearch();
                 }                  }
                 return;                  return;
         }          }
         if (mpu98.recvevent & MIDIE_EVENT) {          if (mpu98.recvevent & MIDIE_EVENT) {
                 MPUCH *ch;                  MPUTR *tr;
                 mpu98.recvevent ^= MIDIE_EVENT;                  mpu98.recvevent ^= MIDIE_EVENT;
                 mpu98.recvevent |= MIDIE_DATA;                  mpu98.recvevent |= MIDIE_DATA;
                 ch = mpu98.ch + mpu98.intreq;                  tr = mpu98.tr + (mpu98.intphase - 2);
                 switch(data & 0xf0) {                  switch(data & 0xf0) {
                         case 0xc0:                          case 0xc0:
                         case 0xd0:                          case 0xd0:
                                 ch->remain = 2;                                  tr->remain = 2;
                                 ch->rstat = data;                                  tr->rstat = data;
                                 break;                                  break;
   
                         case 0x80:                          case 0x80:
Line 419  static void senddat(BYTE data) { Line 891  static void senddat(BYTE data) {
                         case 0xa0:                          case 0xa0:
                         case 0xb0:                          case 0xb0:
                         case 0xe0:                          case 0xe0:
                                 ch->remain = 3;                                  tr->remain = 3;
                                 ch->rstat = data;                                  tr->rstat = data;
                                 break;                                  break;
   
                         case 0xf0:                          case 0xf0:
                                 ch->remain = 1;                                  tr->remain = 1;
                                 break;                                  break;
   
                         default:                          default:
                                 ch->data[0] = ch->rstat;                                  tr->data[0] = tr->rstat;
                                 ch->datas = 1;                                  tr->datas = 1;
                                 ch->remain = 2;                                  tr->remain = 2;
                                 if ((ch->rstat & 0xe0) == 0xc0) {                                  if ((tr->rstat & 0xe0) == 0xc0) {
                                         ch->remain--;                                          tr->remain--;
                                 }                                  }
                                 break;                                  break;
                 }                  }
         }          }
         if (mpu98.recvevent & MIDIE_DATA) {          if (mpu98.recvevent & MIDIE_DATA) {
                 MPUCH *ch;                  MPUTR *tr;
                 ch = mpu98.ch + mpu98.intreq;                  tr = mpu98.tr + (mpu98.intphase - 2);
                 if (ch->remain) {                  if (tr->remain) {
                         ch->data[ch->datas] = data;                          tr->data[tr->datas] = data;
                         ch->datas++;                          tr->datas++;
                         ch->remain--;                          tr->remain--;
                 }                  }
                 if (!ch->remain) {                  if (!tr->remain) {
                         mpu98.recvevent ^= MIDIE_DATA;                          mpu98.recvevent ^= MIDIE_DATA;
                         ch_nextsearch();                          tr_nextsearch();
                 }                  }
                 return;                  return;
         }          }
   
         if (mpu98.recvevent & MIDIE_F9DATA) {  #if 1
                 switch(mpu98.f9.cmd) {          if (mpu98.cond.phase)
                         case 0xdf:                              // long message  #else
                                 if (mpu98.f9.remain) {          if (mpu98.cond.phase & (MPUCMDP_CMD | MPUCMDP_FOLLOWBYTE))
                                         mpu98.f9.remain--;  #endif
                                         mpu98.f9.data[mpu98.f9.datas++] = data;          {
                                 }                  sendmpucond(&mpu98.cond, data);
                                 if (data == 0xf7) {  
                                         int             i;  
                                         for (i=0; i<mpu98.f9.datas; i++) {  
                                                 cm_mpu98->write(cm_mpu98, mpu98.f9.data[i]);  
                                         }  
                                         mpu98.f9.datas = 0;  
                                         mpu98.f9.remain = 0;  
                                         mpu98.f9.cmd = 0xf8;  
                                         return;  
                                 }  
                                 break;  
   
                         default:  
                                 mpu98.recvevent ^= MIDIE_F9DATA;  
                                 mpu98.recvevent |= MIDIE_F9CMD;  
                                 mpu98.f9.step = data;  
                                 break;  
                 }  
                 return;  
         }  
         if (mpu98.recvevent & MIDIE_F9CMD) {  
                 mpu98.recvevent ^= MIDIE_F9CMD;  
                 if (data == MIDI_STOP) {  
                         cm_mpu98->write(cm_mpu98, MIDI_STOP);  
                         setrecvdata(MIDI_STOP);  
                         mpu98ii_int();  
                 }  
                 else {  
                         mpu98.f9.cmd = data;  
                         if ((data & 0xf0) == 0xe0) {  
                                 mpu98.recvevent |= MIDIE_F9PARA;  
                         }  
                         else {  
                                 ch_nextsearch();  
                         }  
                 }  
                 return;  
         }  
         if (mpu98.recvevent & MIDIE_F9PARA) {  
                 mpu98.recvevent ^= MIDIE_F9PARA;  
                 group_ex(mpu98.f9.cmd, data);  
                 ch_nextsearch();  
                 return;                  return;
         }          }
 }  }
   
   static void IOOUTCALL mpu98ii_o0(UINT port, REG8 dat) {
 static void IOOUTCALL mpu98ii_o0(UINT port, BYTE dat) {  
   
         UINT    sent;          UINT    sent;
   
   TRACEOUT(("mpu98ii out %.4x %.2x", port, dat));
         if (cm_mpu98 == NULL) {          if (cm_mpu98 == NULL) {
                 cm_mpu98 = commng_create(COMCREATE_MPU98II);                  cm_mpu98 = commng_create(COMCREATE_MPU98II);
         }          }
         if (cm_mpu98->connect != COMCONNECT_OFF) {          if (cm_mpu98->connect != COMCONNECT_OFF) {
   
                 if (mpu98.mode) {                  if (mpu98.mode) {
                         sent = cm_mpu98->write(cm_mpu98, dat);                          sent = cm_mpu98->write(cm_mpu98, (UINT8)dat);
                 }                  }
                 else {                  else {
                         if ((mpu98.cmd == 0xd0) || (mpu98.cmd == 0xdf)) {  //                      TRACEOUT(("send data->%.2x", dat));
                                 sent = cm_mpu98->write(cm_mpu98, dat);                          sendmpudata(dat);
                         }                          sent = 1;
                         else {  
                                 senddat(dat);  
                                 sent = 1;  
                         }  
                 }                  }
                 if (sent) {                  if (sent) {
                         midiwait(pc.midiclock * sent);                          midiwait(mpu98.xferclock * sent);
                 }                  }
         }          }
         (void)port;          (void)port;
 }  }
   
 static void IOOUTCALL mpu98ii_o2(UINT port, BYTE dat) {  static void IOOUTCALL mpu98ii_o2(UINT port, REG8 dat) {
   
   TRACEOUT(("mpu98ii out %.4x %.2x", port, dat));
         if (cm_mpu98 == NULL) {          if (cm_mpu98 == NULL) {
                 cm_mpu98 = commng_create(COMCREATE_MPU98II);                  cm_mpu98 = commng_create(COMCREATE_MPU98II);
         }          }
         if (cm_mpu98->connect != COMCONNECT_OFF) {          if (cm_mpu98->connect != COMCONNECT_OFF) {
                 if (!mpu98.mode) {                  if (!mpu98.mode) {
                         if (sendcmd(dat)) {                          REG8 phase;
                                 setrecvdata(MPU_ACK);  //                      TRACEOUT(("send cmd->%.2x", dat));
                                 mpu98ii_int();                          mpu98.cmd.cmd = dat;
                                 switch(dat) {                          phase = (*mpucmds[dat])(dat);
                                         case 0xac:                      // get mpu major version?                          setrecvdata(MPUMSG_ACK);
                                                 setrecvdata(1);                          mpu98ii_int();
                                                 break;                          if (phase & MPUCMDP_REQ) {
                                         case 0xad:                      // get mpu minor version?                                  phase &= ~MPUCMDP_REQ;
                                                 setrecvdata(0);                                  reqmpucmdgroupd(dat);
                                                 break;  
                                 }  
                         }                          }
                           mpu98.cmd.phase = phase;
                 }                  }
                 else {                  else {
                         if (dat == 0xff) {                          if (dat == 0xff) {
                                 mpu98.mode = 0;                                  mpu98.mode = 0;
                                 setrecvdata(MPU_ACK);                                  setrecvdata(MPUMSG_ACK);
                         }                          }
                 }                  }
                 midiwait(pc.realclock / 10000);                  midiwait(pccore.realclock / 10000);
         }          }
         (void)port;          (void)port;
 }  }
   
 static BYTE IOINPCALL mpu98ii_i0(UINT port) {  static REG8 IOINPCALL mpu98ii_i0(UINT port) {
   
         if (cm_mpu98 == NULL) {          if (cm_mpu98 == NULL) {
                 cm_mpu98 = commng_create(COMCREATE_MPU98II);                  cm_mpu98 = commng_create(COMCREATE_MPU98II);
         }          }
         if (cm_mpu98->connect != COMCONNECT_OFF) {          if (cm_mpu98->connect != COMCONNECT_OFF) {
                 if (mpu98.cnt) {                  if (mpu98.r.cnt) {
                         mpu98.cnt--;                          mpu98.r.cnt--;
                         if (mpu98.cnt) {  #if 0
                           if (mpu98.r.cnt) {
                                 mpu98ii_int();                                  mpu98ii_int();
                         }                          }
                         else {                          else {
                                 pic_resetirq(mpu98.irqnum);                                  pic_resetirq(mpu98.irqnum);
                         }                          }
                         mpu98.data = mpu98.buf[mpu98.pos];  #endif
                         mpu98.pos = (mpu98.pos + 1) & (MPU98_RECVBUFS - 1);                          mpu98.data = mpu98.r.buf[mpu98.r.pos];
                           mpu98.r.pos = (mpu98.r.pos + 1) & (MPU98_RECVBUFS - 1);
                   }
                   else if (mpu98.intreq) {
                           mpu98.data = mpu98.intreq;
                           mpu98.intreq = 0;
                 }                  }
                   if ((mpu98.r.cnt) || (mpu98.intreq)) {
                           mpu98ii_int();
                   }
                   else {
                           pic_resetirq(mpu98.irqnum);
                   }
   
   //              TRACEOUT(("recv data->%.2x", mpu98.data));
   TRACEOUT(("mpu98ii inp %.4x %.2x", port, mpu98.data));
                 return(mpu98.data);                  return(mpu98.data);
         }          }
         (void)port;          (void)port;
         return(0xff);          return(0xff);
 }  }
   
 static BYTE IOINPCALL mpu98ii_i2(UINT port) {  static REG8 IOINPCALL mpu98ii_i2(UINT port) {
   
         BYTE    ret;          REG8    ret;
   
         if (cm_mpu98 == NULL) {          if (cm_mpu98 == NULL) {
                 cm_mpu98 = commng_create(COMCREATE_MPU98II);                  cm_mpu98 = commng_create(COMCREATE_MPU98II);
         }          }
         if (cm_mpu98->connect != COMCONNECT_OFF) {          if (cm_mpu98->connect != COMCONNECT_OFF) {
                 ret = mpu98.status;                  ret = mpu98.status;
                 if (!mpu98.cnt) {                  if ((mpu98.r.cnt == 0) && (mpu98.intreq == 0)) {
                         ret |= MIDIIN_AVAIL;                          ret |= MIDIIN_AVAIL;
                 }                  }
   // TRACEOUT(("mpu98ii inp %.4x %.2x", port, ret));
                 return(ret);                  return(ret);
         }          }
         (void)port;          (void)port;
Line 626  void mpu98ii_reset(void) { Line 1067  void mpu98ii_reset(void) {
         cm_mpu98 = NULL;          cm_mpu98 = NULL;
   
         ZeroMemory(&mpu98, sizeof(mpu98));          ZeroMemory(&mpu98, sizeof(mpu98));
         mpu98.data = MPU_ACK;          mpu98.data = MPUMSG_ACK;
         mpu98.tempo = 120;  
         mpu98.tempos = 0x40;  
         mpu98.timebase = 2;  
         mpu98.port = 0xc0d0 | ((np2cfg.mpuopt & 0xf0) << 6);          mpu98.port = 0xc0d0 | ((np2cfg.mpuopt & 0xf0) << 6);
         mpu98.irqnum = mpuirqnum[np2cfg.mpuopt & 3];          mpu98.irqnum = mpuirqnum[np2cfg.mpuopt & 3];
         pic_registext(mpu98.irqnum);          setdefaultcondition();
         makeintclock();  //      pic_registext(mpu98.irqnum);
 }  }
   
 void mpu98ii_bind(void) {  void mpu98ii_bind(void) {
   
         UINT    port;          UINT    port;
   
           mpu98.xferclock = pccore.realclock / 3125;
           makeintclock();
         port = mpu98.port;          port = mpu98.port;
         iocore_attachout(port, mpu98ii_o0);          iocore_attachout(port, mpu98ii_o0);
         iocore_attachinp(port, mpu98ii_i0);          iocore_attachinp(port, mpu98ii_i0);
Line 650  void mpu98ii_bind(void) { Line 1090  void mpu98ii_bind(void) {
   
 void mpu98ii_callback(void) {  void mpu98ii_callback(void) {
   
         BYTE    data;          UINT8   data;
   
         if (cm_mpu98) {          if (cm_mpu98) {
                 while((mpu98.cnt < MPU98_RECVBUFS) &&                  while((mpu98.r.cnt < MPU98_RECVBUFS) &&
                         (cm_mpu98->read(cm_mpu98, &data))) {                          (cm_mpu98->read(cm_mpu98, &data))) {
                         if (!mpu98.cnt) {                          if (!mpu98.r.cnt) {
                                 mpu98ii_int();                                  mpu98ii_int();
                         }                          }
                         setrecvdata(data);                          setrecvdata(data);

Removed from v.1.1  
changed lines
  Added in v.1.10


RetroPC.NET-CVS <cvs@retropc.net>