| version 1.7, 2004/08/11 16:09:04 | version 1.11, 2004/08/13 06:49:31 | 
| 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 100  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 = 0x01000000; | 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; |  | 
| } |  | 
| 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; |  | 
| } |  | 
| } |  | 
| event = min(event, clock); |  | 
| } |  | 
| event *= pccore.multiple; |  | 
| event /= 2; |  | 
| if (event == 0) { |  | 
| event = 1; |  | 
| } |  | 
 | nevent_set(NEVENT_CTC0 + ch->num, event, neitem_ctc, NEVENT_ABSOLUTE); | nevent_set(NEVENT_CTC0 + ch->num, event, neitem_ctc, NEVENT_ABSOLUTE); | 
 | } | } | 
 |  |  | 
| Line 166  BRESULT ieitem_ctc(UINT id) { | Line 157  BRESULT ieitem_ctc(UINT id) { | 
 | if (intr) { | if (intr) { | 
 | for (i=0, bit=1; i<4; i++, bit<<=1) { | for (i=0, bit=1; i<4; i++, bit<<=1) { | 
 | if (intr & bit) { | if (intr & bit) { | 
| #if 1                   // アークスのタイミング→あとで修正 | if (!(ch->cmd[i] & 0x80)) { | 
| if (0) | intr ^= bit; | 
| #elif 0 | } | 
| if (((ch->count[i] * 17) >> 4) < ch->countmax[i]) | #if 0                   // アークスのタイミング→あとで修正 | 
|  | else if (0) | 
|  | #elif 1 | 
|  | 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(("ctc int %d %d", ch->num, i)); | 
 | Z80_INTERRUPT((REG8)(ch->vector + (i << 1))); | Z80_INTERRUPT((REG8)(ch->vector + (i << 1))); | 
 | } | } | 
 | } | } | 
| Line 209  static void ctcch_o(CTCCH *ch, UINT port | Line 202  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; | count <<= scale; | 
 |  | ch->scale[port] = scale; | 
 | ch->countmax[port] = count; | ch->countmax[port] = count; | 
 | ch->count[port] = count; | ch->count[port] = count; | 
 | ch->cmd[port] &= ~6; | ch->cmd[port] &= ~6; | 
| Line 240  static void ctcch_o(CTCCH *ch, UINT port | Line 231  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 283  void IOOUTCALL ctc_o(UINT port, REG8 val | Line 263  void IOOUTCALL ctc_o(UINT port, REG8 val | 
 |  |  | 
 | CTCCH   *ch; | CTCCH   *ch; | 
 |  |  | 
| //      TRACEOUT(("ctc - %.4x %.2x [%.4x]", port, value, Z80_PC)); | TRACEOUT(("ctc - %.4x %.2x [%.4x]", port, value, Z80_PC)); | 
 | ch = getctcch(port); | ch = getctcch(port); | 
 | if (ch != NULL) { | if (ch != NULL) { | 
 | ctcch_o(ch, port, value); | ctcch_o(ch, port, value); | 
| Line 315  void ctc_reset(void) { | Line 295  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; | 
 | } | } | 
 | } | } | 
 | } | } |