Diff for /np2/io/pit.c between versions 1.1.1.1 and 1.14

version 1.1.1.1, 2003/10/16 17:57:57 version 1.14, 2004/01/13 05:30:58
Line 3 Line 3
 //   // 
   
 #include        "compiler.h"  #include        "compiler.h"
 #include        "i286.h"  #include        "cpucore.h"
 #include        "pccore.h"  #include        "pccore.h"
 #include        "iocore.h"  #include        "iocore.h"
 #include        "sound.h"  #include        "sound.h"
 #include        "beep.h"  #include        "beep.h"
   
   
 // #define      uPD71054                                                                // NP2はuPD8253Cベース  // #define      uPD71054                                        // NP2はuPD8253Cベース
   #define BEEPCOUNTEREX                                   // BEEPアイドル時のカウンタをα倍に
   
   
 // --- Interval timer  // --- Interval timer
Line 18 Line 19
 // ver0.31 常に回す…  // ver0.31 常に回す…
 static void setsystimerevent_noint(BOOL absolute) {  static void setsystimerevent_noint(BOOL absolute) {
   
         nevent_set(NEVENT_ITIMER, pc.multiple << 16, systimer_noint, absolute);          nevent_set(NEVENT_ITIMER, pccore.multiple << 16,
                                                                                                   systimer_noint, absolute);
 }  }
   
 void systimer_noint(NEVENTITEM item) {  void systimer_noint(NEVENTITEM item) {
Line 32  static void setsystimerevent(BOOL absolu Line 34  static void setsystimerevent(BOOL absolu
   
         SINT32  cnt;          SINT32  cnt;
   
         cnt = pit.value[0].w;          cnt = pit.value[0];
         if (cnt > 8) {                                                                  // 根拠なし          if (cnt > 8) {                                                                  // 根拠なし
                 cnt *= pc.multiple;                  cnt *= pccore.multiple;
         }          }
         else {          else {
                 cnt = pc.multiple << 16;                  cnt = pccore.multiple << 16;
         }          }
         nevent_set(NEVENT_ITIMER, cnt, systimer, absolute);          nevent_set(NEVENT_ITIMER, cnt, systimer, absolute);
 }  }
Line 45  static void setsystimerevent(BOOL absolu Line 47  static void setsystimerevent(BOOL absolu
 void systimer(NEVENTITEM item) {  void systimer(NEVENTITEM item) {
   
         if (item->flag & NEVENT_SETEVENT) {          if (item->flag & NEVENT_SETEVENT) {
                   if (pit.intr[0]) {
                           pit.intr[0] = 0;
                           pic_setirq(0);
                   }
                 if ((pit.mode[0] & 0x0c) == 0x04) {                  if ((pit.mode[0] & 0x0c) == 0x04) {
                         // レートジェネレータ                          // レートジェネレータ
                           pit.intr[0] = 1;
                         setsystimerevent(NEVENT_RELATIVE);                          setsystimerevent(NEVENT_RELATIVE);
                 }                  }
                 else {                  else {
                         setsystimerevent_noint(NEVENT_RELATIVE);                          nevent_set(NEVENT_ITIMER, pccore.multiple << 16,
                                                                                                   systimer, NEVENT_RELATIVE);
                 }                  }
         }          }
         pic_setirq(0);  
 }  }
   
   
 // --- Beep  // --- Beep
   
   #if defined(BEEPCOUNTEREX)
   static void setbeepeventex(BOOL absolute) {
   
           UINT32  cnt;
   
           cnt = pit.value[1];
           if (cnt > 2) {
                   cnt *= pccore.multiple;
           }
           else {
                   cnt = pccore.multiple << 16;
           }
           while(cnt < 0x100000) {
                   cnt <<= 1;
           }
           nevent_set(NEVENT_BEEP, (SINT32)cnt, beeponeshot, absolute);
   }
   #endif
   
 static void setbeepevent(BOOL absolute) {  static void setbeepevent(BOOL absolute) {
   
         SINT32  cnt;          SINT32  cnt;
   
         cnt = pit.value[1].w;          cnt = pit.value[1];
         if (cnt > 2) {          if (cnt > 2) {
                 cnt *= pc.multiple;                  cnt *= pccore.multiple;
         }          }
         else {          else {
                 cnt = pc.multiple << 16;                  cnt = pccore.multiple << 16;
         }          }
         nevent_set(NEVENT_BEEP, cnt, beeponeshot, absolute);          nevent_set(NEVENT_BEEP, cnt, beeponeshot, absolute);
 }  }
Line 79  void beeponeshot(NEVENTITEM item) { Line 105  void beeponeshot(NEVENTITEM item) {
                 if (!(pit.mode[1] & 0x0c)) {                                                            // ver0.30                  if (!(pit.mode[1] & 0x0c)) {                                                            // ver0.30
                         beep_lheventset(0);                          beep_lheventset(0);
                 }                  }
 #ifdef uPD71054  #if defined(uPD71054)
                 if ((pit.mode[1] & 0x06) == 0x02)                  if ((pit.mode[1] & 0x06) == 0x02)
 #else  #else
                 if (pit.mode[1] & 0x02)                  if (pit.mode[1] & 0x02)
 #endif  #endif
                 {                  {
   #if defined(BEEPCOUNTEREX)
                           setbeepeventex(NEVENT_RELATIVE);
   #else
                         setbeepevent(NEVENT_RELATIVE);                          setbeepevent(NEVENT_RELATIVE);
   #endif
                 }                  }
         }          }
 }  }
Line 97  static void setrs232cevent(BOOL absolute Line 127  static void setrs232cevent(BOOL absolute
   
         SINT32  cnt;          SINT32  cnt;
   
         if (pit.value[2].w > 1) {          if (pit.value[2] > 1) {
                 cnt = pc.multiple * pit.value[2].w * rs232c.mul;                        // ver0.29                  cnt = pccore.multiple * pit.value[2] * rs232c.mul;
         }          }
         else {          else {
                 cnt = (pc.multiple << 16) * rs232c.mul;                                         // ver0.29                  cnt = (pccore.multiple << 16) * rs232c.mul;
         }          }
         nevent_set(NEVENT_RS232C, cnt, rs232ctimer, absolute);          nevent_set(NEVENT_RS232C, cnt, rs232ctimer, absolute);
 }  }
Line 117  void rs232ctimer(NEVENTITEM item) { Line 147  void rs232ctimer(NEVENTITEM item) {
         rs232c_callback();          rs232c_callback();
 }  }
   
   
 // ---------------------------------------------------------------------------  // ---------------------------------------------------------------------------
   
 static UINT16 itimer_latch(int ch) {  static UINT pit_latch(int ch) {
   
         SINT32  clock;          SINT32  clock;
   
         if (ch == 1) {          if (ch == 1) {
                 switch(pit.mode[1] & 0x06) {                  switch(pit.mode[1] & 0x06) {
   #ifdef uPD71054                         // ?
                         case 0x00:                          case 0x00:
   #endif
                         case 0x04:                          case 0x04:
                                 return(pit.value[1].w);                                  return(pit.value[1]);
 #ifdef uPD71054  #ifdef uPD71054
                         case 0x06:                          case 0x06:
                                 return(pit.value[1].w & 0xfffe);                                  return(pit.value[1] & (~1));
 #endif  #endif
                 }                  }
   #if defined(BEEPCOUNTEREX)
                   clock = nevent_getremain(NEVENT_ITIMER + ch);
                   if (clock < 0) {
                           return(0);
                   }
                   clock /= pccore.multiple;
                   if (pit.value[1] > 2) {
                           clock %= pit.value[1];
                   }
                   else {
                           clock = LOW16(clock);
                   }
                   return(clock);
   #endif
         }          }
         clock = nevent_getremain(NEVENT_ITIMER + ch);          clock = nevent_getremain(NEVENT_ITIMER + ch);
         if (clock >= 0) {          if (clock >= 0) {
                 return((UINT16)(clock / pc.multiple));                  return(clock / pccore.multiple);
         }          }
         return(0);          return(0);
 }  }
   
   void pit_setflag(int ch, REG8 value) {
 void itimer_setflag(int ch, BYTE value) {  
   
         pit.flag[ch] = 0;          pit.flag[ch] = 0;
         if (value & 0x30) {          if (value & 0x30) {
                 pit.mode[ch] = value;                  pit.mode[ch] = (UINT8)value;
         }          }
         else {                                                                                                          // latch          else {                                                                                                          // latch
                 pit.latch[ch].w = itimer_latch(ch);                  pit.mode[ch] &= ~0x30;
                   pit.latch[ch] = (UINT16)pit_latch(ch);
         }          }
 }  }
   
 BOOL itimer_setcount(int ch, BYTE value) {  BOOL pit_setcount(int ch, REG8 value) {
   
         switch(pit.mode[ch] & 0x30) {          switch(pit.mode[ch] & 0x30) {
                 case 0x10:              // access low                  case 0x10:              // access low
                         pit.value[ch].w = value;                          pit.value[ch] = value;
                         break;                          break;
   
                 case 0x20:              // access high                  case 0x20:              // access high
                         pit.value[ch].w = value << 8;                          pit.value[ch] = value << 8;
                         break;                          break;
   
                 case 0x30:              // access word                  case 0x30:              // access word
                         if (!(pit.flag[ch] & 2)) {                          if (!(pit.flag[ch] & 2)) {
                                 pit.value[ch].w &= 0xff00;                                  pit.value[ch] &= 0xff00;
                                 pit.value[ch].w += value;                                  pit.value[ch] += value;
                                 pit.flag[ch] ^= 2;                                  pit.flag[ch] ^= 2;
                                 return(TRUE);                                  return(TRUE);
                         }                          }
                         pit.value[ch].w &= 0x00ff;                          pit.value[ch] &= 0x00ff;
                         pit.value[ch].w += value << 8;                          pit.value[ch] += value << 8;
                         pit.flag[ch] ^= 2;                          pit.flag[ch] ^= 2;
                         break;                          break;
         }          }
         return(FALSE);          return(FALSE);
 }  }
   
 BYTE itimer_getcount(int ch) {  REG8 pit_getcount(int ch) {
   
         BYTE    ret;          REG8    ret;
         union {          REG16   w;
                 BYTE    b[2];  
                 UINT16  w;  
         } tim;  
   
         if (!(pit.mode[ch] & 0x30)) {          if (!(pit.mode[ch] & 0x30)) {
                 tim.w = pit.latch[ch].w;                  w = pit.latch[ch];
         }          }
         else {          else {
                 tim.w = itimer_latch(ch);                                                                       // ver0.30                  w = pit_latch(ch);
         }          }
         switch(pit.mode[ch] & 0x30) {          switch(pit.mode[ch] & 0x30) {
                 case 0x10:                                              // access low                  case 0x10:                                              // access low
                         return((BYTE)tim.w);                          return((UINT8)w);
   
                 case 0x20:                                              // access high                  case 0x20:                                              // access high
                         return((BYTE)(tim.w >> 8));                          return((UINT8)(w >> 8));
         }          }
                                                                                 // access word          if (!(pit.flag[ch] & 1)) {                      // access word
         if (!(pit.flag[ch] & 1)) {                  ret = (UINT8)w;
                 ret = (BYTE)tim.w;  
         }          }
         else {          else {
                 ret = (BYTE)(tim.w >> 8);                  ret = (UINT8)(w >> 8);
         }          }
         pit.flag[ch] ^= 1;          pit.flag[ch] ^= 1;
         return(ret);          return(ret);
Line 215  BYTE itimer_getcount(int ch) { Line 258  BYTE itimer_getcount(int ch) {
 // ---- I/O  // ---- I/O
   
 // system timer  // system timer
 static void IOOUTCALL pit_o71(UINT port, BYTE dat) {  static void IOOUTCALL pit_o71(UINT port, REG8 dat) {
   
         if (itimer_setcount(0, dat)) {  //      TRACEOUT(("pic o71: %x", dat));
           if (pit_setcount(0, dat)) {
                 return;                  return;
         }          }
         pic.pi[0].irr &= (~1);          pic.pi[0].irr &= (~1);
           pit.intr[0] = 1;
         setsystimerevent(NEVENT_ABSOLUTE);          setsystimerevent(NEVENT_ABSOLUTE);
         (void)port;          (void)port;
 }  }
   
 // beep  // beep
 static void IOOUTCALL pit_o73(UINT port, BYTE dat) {  static void IOOUTCALL pit_o73(UINT port, REG8 dat) {
   
         if (itimer_setcount(1, dat)) {          if (pit_setcount(1, dat)) {
                 return;                  return;
         }          }
         setbeepevent(NEVENT_ABSOLUTE);          setbeepevent(NEVENT_ABSOLUTE);
Line 236  static void IOOUTCALL pit_o73(UINT port, Line 281  static void IOOUTCALL pit_o73(UINT port,
                 beep_lheventset(1);                  beep_lheventset(1);
         }          }
         else {          else {
                 beep_hzset(pit.value[1].w);                  beep_hzset(pit.value[1]);
         }          }
         (void)port;          (void)port;
 }  }
   
 // rs-232c  // rs-232c
 static void IOOUTCALL pit_o75(UINT port, BYTE dat) {  static void IOOUTCALL pit_o75(UINT port, REG8 dat) {
   
         if (itimer_setcount(2, dat)) {          if (pit_setcount(2, dat)) {
                 return;                  return;
         }          }
         rs232c_open();          rs232c_open();
Line 253  static void IOOUTCALL pit_o75(UINT port, Line 298  static void IOOUTCALL pit_o75(UINT port,
 }  }
   
 // ctrl  // ctrl
 static void IOOUTCALL pit_o77(UINT port, BYTE dat) {  static void IOOUTCALL pit_o77(UINT port, REG8 dat) {
   
         int             ch;          int             ch;
   
   //      TRACEOUT(("pic o77: %x", dat));
         ch = (dat >> 6) & 3;          ch = (dat >> 6) & 3;
         if (ch != 3) {          if (ch != 3) {
                 itimer_setflag(ch, dat);                  pit_setflag(ch, dat);
                 if (ch == 0) {                  // 書込みで itimerのirrがリセットされる…                  if (ch == 0) {                  // 書込みで itimerのirrがリセットされる…
                         pic.pi[0].irr &= (~1);                          pic.pi[0].irr &= (~1);
                           if (dat & 0x30) {       // 一応ラッチ時は割り込みをセットしない
                                   pit.intr[0] = 1;
   //                              setsystimerevent(NEVENT_ABSOLUTE);
                           }
                 }                  }
                 if (ch == 1) {                  if (ch == 1) {
                         beep_modeset();                          beep_modeset();
Line 270  static void IOOUTCALL pit_o77(UINT port, Line 320  static void IOOUTCALL pit_o77(UINT port,
         (void)port;          (void)port;
 }  }
   
 static BYTE IOINPCALL pit_i71(UINT port) {  static REG8 IOINPCALL pit_i71(UINT port) {
   
         return(itimer_getcount((port >> 1) & 3));          return(pit_getcount((port >> 1) & 3));
 }  }
   
   
Line 287  static const IOINP piti71[4] = { Line 337  static const IOINP piti71[4] = {
 void itimer_reset(void) {  void itimer_reset(void) {
   
         ZeroMemory(&pit, sizeof(pit));          ZeroMemory(&pit, sizeof(pit));
         if (pc.cpumode & CPUMODE_8MHz) {          if (pccore.cpumode & CPUMODE_8MHz) {
                 pit.value[1].w = 998;                   // 4MHz                  pit.value[1] = 998;                             // 4MHz
         }          }
         else {          else {
                 pit.value[1].w = 1229;                  // 5MHz                  pit.value[1] = 1229;                    // 5MHz
         }          }
           pit.intr[0] = 1;
         pit.mode[0] = 0x30;          pit.mode[0] = 0x30;
         pit.mode[1] = 0x56;          pit.mode[1] = 0x56;
         pit.mode[2] = 0xb6;          pit.mode[2] = 0xb6;
         pit.mode[3] = 0x36;          pit.mode[3] = 0x36;
         setsystimerevent(NEVENT_ABSOLUTE);          setsystimerevent(NEVENT_ABSOLUTE);
         beep_hzset(pit.value[1].w);          beep_hzset(pit.value[1]);
 }  }
   
 void itimer_bind(void) {  void itimer_bind(void) {

Removed from v.1.1.1.1  
changed lines
  Added in v.1.14


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