|
|
| version 1.3, 2004/08/05 11:30:12 | 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 123 static REG8 ctcch_i(CTCCH *ch, UINT port | Line 331 static REG8 ctcch_i(CTCCH *ch, UINT port |
| 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; | |
| } | } |
| } | } |
| } | } |