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

version 1.5, 2004/08/11 12:08:16 version 1.15, 2004/08/15 17:51:53
Line 6 Line 6
 #include        "ievent.h"  #include        "ievent.h"
   
   
   static SINT32 minclock(const CTCCH *ch) {
   
           UINT32  event;
           UINT    i;
           UINT32  clock;
   
           event = 0x01000000;
           for (i=0; i<3; i++) {
                   if ((ch->cmd[i] & 0x82) == 0x80) {
                           clock = 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];
                   }
                   event = min(event, clock);
           }
           if (event == 0) {
                   event = 1;
           }
           return(event);
   }
   
 static REG8 ctcwork(CTCCH *ch) {  static REG8 ctcwork(CTCCH *ch) {
   
         UINT32  baseclock;          UINT32  baseclock;
Line 25  static REG8 ctcwork(CTCCH *ch) { Line 52  static REG8 ctcwork(CTCCH *ch) {
   
         // 0          // 0
         if (!(ch->cmd[0] & 0x02)) {          if (!(ch->cmd[0] & 0x02)) {
                 pulse = stepclock;                                      // 2MHz                  pulse = stepclock;
                 if (!(ch->cmd[0] & 0x40)) {  
                         pulse = pulse * 2;                              // 4MHz  
                 }  
                 count = ch->count[0];                  count = ch->count[0];
                 count -= pulse;                  count -= pulse;
                 if (count <= 0) {                  if (count <= 0) {
Line 43  static REG8 ctcwork(CTCCH *ch) { Line 67  static REG8 ctcwork(CTCCH *ch) {
         // 3          // 3
         if (!(ch->cmd[3] & 0x02)) {          if (!(ch->cmd[3] & 0x02)) {
                 if (!(ch->cmd[3] & 0x40)) {                  if (!(ch->cmd[3] & 0x40)) {
                         pulse3 = stepclock * 2;                         // 4MHz                          pulse3 = stepclock;
                 }                  }
                 count = ch->count[3];                  count = ch->count[3];
                 count -= pulse3;                  count -= pulse3;
Line 56  static REG8 ctcwork(CTCCH *ch) { Line 80  static REG8 ctcwork(CTCCH *ch) {
   
         // 1          // 1
         if (!(ch->cmd[1] & 0x02)) {          if (!(ch->cmd[1] & 0x02)) {
                 pulse = stepclock;                                      // 2MHz                  pulse = stepclock;
                 if (!(ch->cmd[1] & 0x40)) {  
                         pulse = pulse * 2;                              // 4MHz  
                 }  
                 count = ch->count[1];                  count = ch->count[1];
                 count -= pulse;                  count -= pulse;
                 if (count <= 0) {                  if (count <= 0) {
Line 71  static REG8 ctcwork(CTCCH *ch) { Line 92  static REG8 ctcwork(CTCCH *ch) {
   
         // 2          // 2
         if (!(ch->cmd[2] & 0x02)) {          if (!(ch->cmd[2] & 0x02)) {
                 pulse = stepclock;                                      // 2MHz                  pulse = stepclock;
                 if (!(ch->cmd[2] & 0x40)) {  
                         pulse = pulse * 2;                              // 4MHz  
                 }  
                 count = ch->count[2];                  count = ch->count[2];
                 count -= pulse;                  count -= pulse;
                 if (count <= 0) {                  if (count <= 0) {
Line 93  static void ctcstep(CTCCH *ch) { Line 111  static void ctcstep(CTCCH *ch) {
         intr = ctcwork(ch);          intr = ctcwork(ch);
         if (intr) {          if (intr) {
                 ch->intr |= intr;                  ch->intr |= intr;
                 TRACEOUT(("-> ievent_set"));  
                 ievent_set(IEVENT_CTC0 + ch->num);                  ievent_set(IEVENT_CTC0 + ch->num);
         }          }
 }  }
Line 101  static void ctcstep(CTCCH *ch) { Line 118  static void ctcstep(CTCCH *ch) {
 static void ctcnextevent(CTCCH *ch) {  static void ctcnextevent(CTCCH *ch) {
   
         UINT32  event;          UINT32  event;
         UINT    i;  
         UINT32  clock;  
   
         if (ch->intr) {          if (ch->intr) {
                 return;                  return;
         }          }
         event = 0x04000000;          event = minclock(ch) * pccore.multiple;
         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);          nevent_set(NEVENT_CTC0 + ch->num, event, neitem_ctc, NEVENT_ABSOLUTE);
         TRACEOUT(("ctc -> %d (%x)", event, event));  
 }  }
   
 void neitem_ctc(UINT id) {  void neitem_ctc(UINT id) {
Line 145  void neitem_ctc(UINT id) { Line 135  void neitem_ctc(UINT id) {
         intr = ctcwork(ch);          intr = ctcwork(ch);
         if (intr) {          if (intr) {
                 ch->intr |= intr;                  ch->intr |= intr;
                 TRACEOUT(("-> ievent_set"));  
                 ievent_set(IEVENT_CTC0 + ch->num);                  ievent_set(IEVENT_CTC0 + ch->num);
         }          }
         else {          else {
Line 164  BRESULT ieitem_ctc(UINT id) { Line 153  BRESULT ieitem_ctc(UINT id) {
         ch = ctc.ch + (id - IEVENT_CTC0);          ch = ctc.ch + (id - IEVENT_CTC0);
         intr = ctcwork(ch);          intr = ctcwork(ch);
         intr |= ch->intr;          intr |= ch->intr;
         TRACEOUT(("ieitem_ctc %d - %.2x", id - IEVENT_CTC0, intr));  
         r = FALSE;          r = FALSE;
         if (intr) {          if (intr) {
                 for (i=0, bit=1; i<4; i++, bit<<=1) {                  for (i=0, bit=1; i<4; i++, bit<<=1)
   //              for (i=4, bit=8; i--; bit>>=1)
                   {
                         if (intr & bit) {                          if (intr & bit) {
                                   if (!(ch->cmd[i] & 0x80)) {
                                           intr ^= bit;
                                   }
 #if 1                   // アークスのタイミング→あとで修正  #if 1                   // アークスのタイミング→あとで修正
                                 if (0)                                  else if (0)
   #elif 1
                                   else if ((ch->countmax[i] - ch->count[i]) >= ch->range[i])
 #elif 0  #elif 0
                                 if (((ch->count[i] * 17) >> 4) < ch->countmax[i])                                  else if (((ch->cmd[i] & 0x10) == 0) &&
                                                   ((ch->countmax[i] - ch->count[i]) >= (256 >> 1)))
 #else  #else
                                 if (ch->count[i] != ch->countmax[i])                                  else if (ch->count[i] != ch->countmax[i])
 #endif  #endif
                                 {                                  {
                                         intr ^= bit;                                          intr ^= bit;
                                 }                                  }
                                 else if (!(ch->cmd[i] & 0x80)) {  
                                         intr ^= bit;  
                                 }  
                                 else if (!r) {                                  else if (!r) {
                                         r = TRUE;                                          r = TRUE;
                                         intr ^= bit;                                          intr ^= bit;
                                         TRACEOUT(("z80int %d", i));                                          ch->irq = (UINT8)i;
                                         Z80_INT((REG8)(ch->vector + (i << 1)));  //                                      TRACEOUT(("ctc int %d %d [%.2x]", ch->num, i, ch->cmd[i]));
                                           Z80_INTERRUPT((REG8)(ch->vector + (i << 1)));
                                 }                                  }
                         }                          }
                 }                  }
         }          }
         TRACEOUT(("--> %.2x", intr));  
         ch->intr = intr;          ch->intr = intr;
         if (intr) {          if (intr) {
                 TRACEOUT(("-> ievent_set"));  
                 ievent_set(IEVENT_CTC0 + ch->num);                  ievent_set(IEVENT_CTC0 + ch->num);
         }          }
         else {          else {
Line 203  BRESULT ieitem_ctc(UINT id) { Line 195  BRESULT ieitem_ctc(UINT id) {
         return(r);          return(r);
 }  }
   
   void ieeoi_ctc(UINT id) {
   
   
 #if 0  
 void x1_ctc_int(void) {  
   
         CTCCH   *ch;          CTCCH   *ch;
         UINT    r;          REG8    intr;
         SINT32  clk0;          UINT    curirq;
         SINT32  clk4;  
         SINT32  clk2;  
         SINT32  subcnt;  
         UINT    i;  
         REG8    bit;  
         REG8    ctcint_flg;  
   
         ctcint_flg = Z80_ABLEINTERRUPT();  
   
         clk4 = pccore.HSYNC_CLK;  
         clk2 = clk4 >> 1;  
   
         if (pccore.ROM_TYPE >= 2) {          ch = ctc.ch + (id - IEVENT_CTC0);
                 ch = ctc.ch + 0;          intr = ctcwork(ch) | ch->intr;
                 r = 3;          curirq = ch->irq;
           if (intr & (1 << curirq)) {                     // 割り込み中に割り込んだ…
                   // カウンタが0でなければ割り込みを消す
                   if ((ch->countmax[curirq] - ch->count[curirq]) >= ch->range[curirq]) {
                           intr ^= (1 << curirq);
                   }
           }
           ch->intr = intr;
           if (intr) {
                   ievent_set(id);
         }          }
         else {          else {
                 ch = ctc.ch + 2;                  ctcnextevent(ch);
                 r = 1;  
         }          }
   
         do {  
                 clk0 = 0;  
                 bit = 1;  
                 for (i=0; i<4; i++) {  
                         if (!(ch->cmd[i] & 0x02)) {  
                                 if (ch->count[i] <= 0) {  
                                         ch->count[i] += ch->countmax[i];  
                                 }  
                                 if (!(ch->cmd[i] & 0x40)) {  
                                         subcnt = clk4;  
                                 }  
                                 else if (i == 3) {  
                                         subcnt = clk0;  
                                 }  
                                 else {  
                                         subcnt = clk2;  
                                 }  
                                 ch->count[i] -= subcnt;  
                                 if (ch->count[i] <= 0) {  
                                         ch->int_flag |= bit;  
                                         if (!i) {  
                                                 clk0 = 1;  
                                         }  
                                 }  
                         }  
                         bit <<= 1;  
                 }  
   
                 bit = 1;  
                 for (i=0; i<4; i++) {  
                         if (ch->int_flag & bit) {  
                                 if (!(ch->cmd[i] & 0x80)) {  
                                         ch->int_flag ^= bit;  
                                 }  
                                 else if (ctcint_flg) {  
                                         ctcint_flg = 0;  
                                         ch->int_flag ^= bit;  
 //                                      TRACEOUT(("ctc%u int -- %d", 3 - r, i));  
                                         Z80_INT((REG8)(ch->vector + (i << 1)));  
                                 }  
                         }  
                         bit <<= 1;  
                 }  
                 ch++;  
         } while(--r);  
 }  }
 #endif  
   
   
 // ----  // ----
Line 293  static void ctcch_o(CTCCH *ch, UINT port Line 231  static void ctcch_o(CTCCH *ch, UINT port
         if (ch->cmd[port] & 0x04) {          if (ch->cmd[port] & 0x04) {
                 ctcstep(ch);                  ctcstep(ch);
                 ch->basecnt[port] = value;                  ch->basecnt[port] = value;
                 count = 256;                  count = ((value - 1) & 0xff) + 1;
                 if (value) {  
                         count = (SINT32)value;  
                 }  
                 scale = 0;                  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 - 1;
                         }                          }
                         else {                          else {
                                 scale = 4;                                  scale = 4 - 1;
                         }                          }
                 }                  }
                 count <<= scale;                  ch->scale[port] = scale;
                 ch->countmax[port] = count;                  ch->countmax[port] = count << scale;
                 ch->count[port] = count;                  ch->count[port] = count << scale;
                   ch->range[port] = 1 << scale;
                 ch->cmd[port] &= ~6;                  ch->cmd[port] &= ~6;
                 ctcnextevent(ch);                  ctcnextevent(ch);
         }          }
Line 324  static void ctcch_o(CTCCH *ch, UINT port Line 260  static void ctcch_o(CTCCH *ch, UINT port
   
 static REG8 ctcch_i(CTCCH *ch, UINT port) {  static REG8 ctcch_i(CTCCH *ch, UINT port) {
   
         REG8    scale;  
   
         port &= 3;          port &= 3;
         if (port != 3) {          if (port != 3) {
                 return(ch->basecnt[port]);                  return(ch->basecnt[port]);
         }          }
         else {          else {
                 ctcstep(ch);                  ctcstep(ch);
                 scale = 0;                  return((REG8)(ch->count[3] >> ch->scale[3]));
                 if (!(ch->cmd[3] & 0x40)) {  
                         if (ch->cmd[3] & 0x20) {  
                                 scale = 8;  
                         }  
                         else {  
                                 scale = 4;  
                         }  
                 }  
                 return((REG8)(ch->count[3] >> scale));  
         }          }
 }  }
   
Line 399  void ctc_reset(void) { Line 324  void ctc_reset(void) {
         for (i=0; i<3; i++) {          for (i=0; i<3; i++) {
                 ctc.ch[i].num = (UINT8)i;                  ctc.ch[i].num = (UINT8)i;
                 for (j=0; j<4; j++) {                  for (j=0; j<4; j++) {
                         ctc.ch[i].cmd[j] = 0x03;                          ctc.ch[i].cmd[j] = 0x23;
                         ctc.ch[i].count[j] = 256 << 8;                          ctc.ch[i].scale[j] = 7;
                         ctc.ch[i].countmax[j] = 256 << 8;                          ctc.ch[i].count[j] = 256 << 7;
                           ctc.ch[i].countmax[j] = 256 << 7;
                 }                  }
         }          }
 }  }

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


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