--- xmil/io/ctc.c 2004/08/11 16:09:04 1.7 +++ xmil/io/ctc.c 2004/08/13 06:49:31 1.11 @@ -6,6 +6,33 @@ #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) { UINT32 baseclock; @@ -25,10 +52,7 @@ static REG8 ctcwork(CTCCH *ch) { // 0 if (!(ch->cmd[0] & 0x02)) { - pulse = stepclock; // 2MHz - if (!(ch->cmd[0] & 0x40)) { - pulse = pulse * 2; // 4MHz - } + pulse = stepclock; count = ch->count[0]; count -= pulse; if (count <= 0) { @@ -43,7 +67,7 @@ static REG8 ctcwork(CTCCH *ch) { // 3 if (!(ch->cmd[3] & 0x02)) { if (!(ch->cmd[3] & 0x40)) { - pulse3 = stepclock * 2; // 4MHz + pulse3 = stepclock; } count = ch->count[3]; count -= pulse3; @@ -56,10 +80,7 @@ static REG8 ctcwork(CTCCH *ch) { // 1 if (!(ch->cmd[1] & 0x02)) { - pulse = stepclock; // 2MHz - if (!(ch->cmd[1] & 0x40)) { - pulse = pulse * 2; // 4MHz - } + pulse = stepclock; count = ch->count[1]; count -= pulse; if (count <= 0) { @@ -71,10 +92,7 @@ static REG8 ctcwork(CTCCH *ch) { // 2 if (!(ch->cmd[2] & 0x02)) { - pulse = stepclock; // 2MHz - if (!(ch->cmd[2] & 0x40)) { - pulse = pulse * 2; // 4MHz - } + pulse = stepclock; count = ch->count[2]; count -= pulse; if (count <= 0) { @@ -100,38 +118,11 @@ static void ctcstep(CTCCH *ch) { static void ctcnextevent(CTCCH *ch) { UINT32 event; - UINT i; - UINT32 clock; if (ch->intr) { return; } - event = 0x01000000; - 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; - } + event = minclock(ch) * pccore.multiple; nevent_set(NEVENT_CTC0 + ch->num, event, neitem_ctc, NEVENT_ABSOLUTE); } @@ -166,22 +157,24 @@ BRESULT ieitem_ctc(UINT id) { 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]) + if (!(ch->cmd[i] & 0x80)) { + intr ^= bit; + } +#if 0 // アークスのタイミング→あとで修正 + else if (0) +#elif 1 + else if (((ch->cmd[i] & 0x10) == 0) && + ((ch->countmax[i] - ch->count[i]) >= (256 >> 1))) #else - if (ch->count[i] != 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(("ctc int %d %d", ch->num, i)); Z80_INTERRUPT((REG8)(ch->vector + (i << 1))); } } @@ -209,20 +202,18 @@ static void ctcch_o(CTCCH *ch, UINT port if (ch->cmd[port] & 0x04) { ctcstep(ch); ch->basecnt[port] = value; - count = 256; - if (value) { - count = (SINT32)value; - } + count = ((value - 1) & 0xff) + 1; scale = 0; if (!(ch->cmd[port] & 0x40)) { if (ch->cmd[port] & 0x20) { - scale = 8; + scale = 8 - 1; } else { - scale = 4; + scale = 4 - 1; } } count <<= scale; + ch->scale[port] = scale; ch->countmax[port] = count; ch->count[port] = count; ch->cmd[port] &= ~6; @@ -240,24 +231,13 @@ static void ctcch_o(CTCCH *ch, UINT port static REG8 ctcch_i(CTCCH *ch, UINT port) { - REG8 scale; - port &= 3; if (port != 3) { return(ch->basecnt[port]); } else { ctcstep(ch); - scale = 0; - if (!(ch->cmd[3] & 0x40)) { - if (ch->cmd[3] & 0x20) { - scale = 8; - } - else { - scale = 4; - } - } - return((REG8)(ch->count[3] >> scale)); + return((REG8)(ch->count[3] >> ch->scale[3])); } } @@ -283,7 +263,7 @@ void IOOUTCALL ctc_o(UINT port, REG8 val CTCCH *ch; -// TRACEOUT(("ctc - %.4x %.2x [%.4x]", port, value, Z80_PC)); + TRACEOUT(("ctc - %.4x %.2x [%.4x]", port, value, Z80_PC)); ch = getctcch(port); if (ch != NULL) { ctcch_o(ch, port, value); @@ -315,9 +295,10 @@ void ctc_reset(void) { for (i=0; i<3; i++) { ctc.ch[i].num = (UINT8)i; for (j=0; j<4; j++) { - ctc.ch[i].cmd[j] = 0x03; - ctc.ch[i].count[j] = 256 << 8; - ctc.ch[i].countmax[j] = 256 << 8; + ctc.ch[i].cmd[j] = 0x23; + ctc.ch[i].scale[j] = 7; + ctc.ch[i].count[j] = 256 << 7; + ctc.ch[i].countmax[j] = 256 << 7; } } }