Diff for /xmil/io/ctc.c between versions 1.2 and 1.5

version 1.2, 2004/08/04 10:49:21 version 1.5, 2004/08/11 12:08:16
Line 2 Line 2
 #include        "z80core.h"  #include        "z80core.h"
 #include        "pccore.h"  #include        "pccore.h"
 #include        "iocore.h"  #include        "iocore.h"
   #include        "nevent.h"
   #include        "ievent.h"
   
   
   static REG8 ctcwork(CTCCH *ch) {
   
           UINT32  baseclock;
           SINT32  stepclock;
           REG8    intr;
           SINT32  pulse3;
           SINT32  pulse;
           SINT32  count;
   
           baseclock = CPU_CLOCK + CPU_BASECLOCK - CPU_REMCLOCK;
           stepclock = baseclock - ch->baseclock;
           stepclock /= pccore.multiple;
           ch->baseclock += stepclock * pccore.multiple;
   
           intr = 0;
           pulse3 = 0;
   
           // 0
           if (!(ch->cmd[0] & 0x02)) {
                   pulse = stepclock;                                      // 2MHz
                   if (!(ch->cmd[0] & 0x40)) {
                           pulse = pulse * 2;                              // 4MHz
                   }
                   count = ch->count[0];
                   count -= pulse;
                   if (count <= 0) {
                           pulse3 = (0 - count) / ch->countmax[0];
                           pulse3 += 1;
                           count += pulse3 * ch->countmax[0];
                           intr |= (ch->cmd[0] & 0x80) >> (7 - 0);
                   }
                   ch->count[0] = count;
           }
   
           // 3
           if (!(ch->cmd[3] & 0x02)) {
                   if (!(ch->cmd[3] & 0x40)) {
                           pulse3 = stepclock * 2;                         // 4MHz
                   }
                   count = ch->count[3];
                   count -= pulse3;
                   if (count <= 0) {
                           count = ch->countmax[3] - ((0 - count) % ch->countmax[3]);
                           intr |= (ch->cmd[3] & 0x80) >> (7 - 3);
                   }
                   ch->count[3] = count;
           }
   
           // 1
           if (!(ch->cmd[1] & 0x02)) {
                   pulse = stepclock;                                      // 2MHz
                   if (!(ch->cmd[1] & 0x40)) {
                           pulse = pulse * 2;                              // 4MHz
                   }
                   count = ch->count[1];
                   count -= pulse;
                   if (count <= 0) {
                           count = ch->countmax[1] - ((0 - count) % ch->countmax[1]);
                           intr |= (ch->cmd[1] & 0x80) >> (7 - 1);
                   }
                   ch->count[1] = count;
           }
   
           // 2
           if (!(ch->cmd[2] & 0x02)) {
                   pulse = stepclock;                                      // 2MHz
                   if (!(ch->cmd[2] & 0x40)) {
                           pulse = pulse * 2;                              // 4MHz
                   }
                   count = ch->count[2];
                   count -= pulse;
                   if (count <= 0) {
                           count = ch->countmax[2] - ((0 - count) % ch->countmax[2]);
                           intr |= (ch->cmd[2] & 0x80) >> (7 - 2);
                   }
                   ch->count[2] = count;
           }
           return(intr);
   }
   
   static void ctcstep(CTCCH *ch) {
   
           REG8    intr;
   
           intr = ctcwork(ch);
           if (intr) {
                   ch->intr |= intr;
                   TRACEOUT(("-> ievent_set"));
                   ievent_set(IEVENT_CTC0 + ch->num);
           }
   }
   
   static void ctcnextevent(CTCCH *ch) {
   
           UINT32  event;
           UINT    i;
           UINT32  clock;
   
           if (ch->intr) {
                   return;
           }
           event = 0x04000000;
           for (i=0; i<3; i++) {
                   if ((ch->cmd[i] & 0x82) == 0x80) {
                           clock = ch->count[i];
                           if (ch->cmd[i] & 0x40) {
                                   clock = clock * 2;
                           }
                           TRACEOUT(("ch %d -> %d :%.2x:%.8x", i, clock, ch->cmd[i], ch->count[i]));
                           event = min(event, clock);
                   }
           }
           if ((ch->cmd[3] & 0x82) == 0x80) {
                   clock = ch->count[3];
                   if (ch->cmd[3] & 0x40) {
                           clock = (clock - 1) * ch->countmax[0];
                           clock += ch->count[0];
                           if (ch->cmd[0] & 0x40) {
                                   clock = clock * 2;
                           }
                   }
                   TRACEOUT(("ch %d -> %d", 3, clock));
                   event = min(event, clock);
           }
           event /= 2;
           event *= pccore.multiple;
           nevent_set(NEVENT_CTC0 + ch->num, event, neitem_ctc, NEVENT_ABSOLUTE);
           TRACEOUT(("ctc -> %d (%x)", event, event));
   }
   
   void neitem_ctc(UINT id) {
   
           CTCCH   *ch;
           REG8    intr;
   
           ch = ctc.ch + (id - NEVENT_CTC0);
           intr = ctcwork(ch);
           if (intr) {
                   ch->intr |= intr;
                   TRACEOUT(("-> ievent_set"));
                   ievent_set(IEVENT_CTC0 + ch->num);
           }
           else {
                   ctcnextevent(ch);
           }
   }
   
   BRESULT ieitem_ctc(UINT id) {
   
           CTCCH   *ch;
           REG8    intr;
           BRESULT r;
           UINT    i;
           REG8    bit;
   
           ch = ctc.ch + (id - IEVENT_CTC0);
           intr = ctcwork(ch);
           intr |= ch->intr;
           TRACEOUT(("ieitem_ctc %d - %.2x", id - IEVENT_CTC0, intr));
           r = FALSE;
           if (intr) {
                   for (i=0, bit=1; i<4; i++, bit<<=1) {
                           if (intr & bit) {
   #if 1                   // アークスのタイミング→あとで修正
                                   if (0)
   #elif 0
                                   if (((ch->count[i] * 17) >> 4) < ch->countmax[i])
   #else
                                   if (ch->count[i] != ch->countmax[i])
   #endif
                                   {
                                           intr ^= bit;
                                   }
                                   else if (!(ch->cmd[i] & 0x80)) {
                                           intr ^= bit;
                                   }
                                   else if (!r) {
                                           r = TRUE;
                                           intr ^= bit;
                                           TRACEOUT(("z80int %d", i));
                                           Z80_INT((REG8)(ch->vector + (i << 1)));
                                   }
                           }
                   }
           }
           TRACEOUT(("--> %.2x", intr));
           ch->intr = intr;
           if (intr) {
                   TRACEOUT(("-> ievent_set"));
                   ievent_set(IEVENT_CTC0 + ch->num);
           }
           else {
                   ctcnextevent(ch);
           }
           return(r);
   }
   
   
   
   
   #if 0
 void x1_ctc_int(void) {  void x1_ctc_int(void) {
   
         CTCCH   *ch;          CTCCH   *ch;
Line 67  void x1_ctc_int(void) { Line 270  void x1_ctc_int(void) {
                                 else if (ctcint_flg) {                                  else if (ctcint_flg) {
                                         ctcint_flg = 0;                                          ctcint_flg = 0;
                                         ch->int_flag ^= bit;                                          ch->int_flag ^= bit;
                                         TRACEOUT(("ctc%u int -- %d", 3 - r, i));  //                                      TRACEOUT(("ctc%u int -- %d", 3 - r, i));
                                         Z80_INT((REG8)(ch->vector + (i << 1)));                                          Z80_INT((REG8)(ch->vector + (i << 1)));
                                 }                                  }
                         }                          }
Line 76  void x1_ctc_int(void) { Line 279  void x1_ctc_int(void) {
                 ch++;                  ch++;
         } while(--r);          } while(--r);
 }  }
   #endif
   
   
 // ----  // ----
   
 static void ctcch_o(CTCCH *ch, UINT port, REG8 value) {  static void ctcch_o(CTCCH *ch, UINT port, REG8 value) {
   
         REG8    scale;  
         SINT32  count;          SINT32  count;
           REG8    scale;
   
         port &= 3;          port &= 3;
         if (ch->cmd[port] & 0x04) {          if (ch->cmd[port] & 0x04) {
                 scale = 0;                  ctcstep(ch);
                 count = 256;  
                 ch->basecnt[port] = value;                  ch->basecnt[port] = value;
                   count = 256;
                 if (value) {                  if (value) {
                         count = (SINT32)value;                          count = (SINT32)value;
                 }                  }
                   scale = 0;
                 if (!(ch->cmd[port] & 0x40)) {                  if (!(ch->cmd[port] & 0x40)) {
                         if (ch->cmd[port] & 0x20) {                          if (ch->cmd[port] & 0x20) {
                                 scale = 8;                                  scale = 8;
Line 105  static void ctcch_o(CTCCH *ch, UINT port Line 310  static void ctcch_o(CTCCH *ch, UINT port
                 ch->countmax[port] = count;                  ch->countmax[port] = count;
                 ch->count[port] = count;                  ch->count[port] = count;
                 ch->cmd[port] &= ~6;                  ch->cmd[port] &= ~6;
                   ctcnextevent(ch);
         }          }
         else if (value & 1) {          else if (value & 1) {
                   ctcstep(ch);
                 ch->cmd[port] = value;                  ch->cmd[port] = value;
                   ctcnextevent(ch);
         }          }
         else if (!port) {                                                                                               // ver0.25          else if (!port) {                                                                                               // ver0.25
                 ch->vector = (UINT8)(value & 0xf8);                  ch->vector = (UINT8)(value & 0xf8);
Line 116  static void ctcch_o(CTCCH *ch, UINT port Line 324  static void ctcch_o(CTCCH *ch, UINT port
   
 static REG8 ctcch_i(CTCCH *ch, UINT port) {  static REG8 ctcch_i(CTCCH *ch, UINT port) {
   
         UINT    scale;          REG8    scale;
   
         port &= 3;          port &= 3;
         if (port != 3) {          if (port != 3) {
                 return(ch->basecnt[port]);                  return(ch->basecnt[port]);
         }          }
         else {          else {
                   ctcstep(ch);
                 scale = 0;                  scale = 0;
                 if (!(ch->cmd[3] & 0x40)) {                  if (!(ch->cmd[3] & 0x40)) {
                         if (ch->cmd[3] & 0x20) {                          if (ch->cmd[3] & 0x20) {
Line 148  static CTCCH *getctcch(UINT port) { Line 357  static CTCCH *getctcch(UINT port) {
         if (port == 0x1fa8) {          if (port == 0x1fa8) {
                 return(ctc.ch + 1);                  return(ctc.ch + 1);
         }          }
         if ((pccore.SOUND_SW) && (port == 0x0704)) {          if (port == 0x0704) {
                 return(ctc.ch + 2);                  return(ctc.ch + 2);
         }          }
         return(NULL);          return(NULL);
Line 174  REG8 IOINPCALL ctc_i(UINT port) { Line 383  REG8 IOINPCALL ctc_i(UINT port) {
                 return(ctcch_i(ch, port));                  return(ctcch_i(ch, port));
         }          }
         else {          else {
                 return((REG8)0xff);                  return(0xff);
         }          }
 }  }
   
Line 183  REG8 IOINPCALL ctc_i(UINT port) { Line 392  REG8 IOINPCALL ctc_i(UINT port) {
   
 void ctc_reset(void) {  void ctc_reset(void) {
   
         UINT    i, j;          UINT    i;
           UINT    j;
   
         ZeroMemory(&ctc, sizeof(ctc));          ZeroMemory(&ctc, sizeof(ctc));
         for (i=0; i<3; i++) {          for (i=0; i<3; i++) {
                   ctc.ch[i].num = (UINT8)i;
                 for (j=0; j<4; j++) {                  for (j=0; j<4; j++) {
                         ctc.ch[i].cmd[j] = 0x83;                          ctc.ch[i].cmd[j] = 0x03;
                           ctc.ch[i].count[j] = 256 << 8;
                           ctc.ch[i].countmax[j] = 256 << 8;
                 }                  }
         }          }
 }  }

Removed from v.1.2  
changed lines
  Added in v.1.5


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