| version 1.7, 2003/11/24 07:40:02 | version 1.19, 2004/03/12 18:19:57 | 
| 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 BEEPCOUNTEREX                                   // BEEPアイドル時のカウンタをα倍に | 
|  | #if defined(CPUCORE_IA32) | 
|  | // #define      uPD71054                        // だめぽ _| ̄|○ | 
|  | #endif | 
 |  |  | 
 |  |  | 
 | // --- Interval timer | // --- Interval timer | 
 |  |  | 
 | // ver0.31 常に回す… |  | 
 | static void setsystimerevent_noint(BOOL absolute) { |  | 
 |  |  | 
 | nevent_set(NEVENT_ITIMER, pc.multiple << 16, systimer_noint, absolute); |  | 
 | } |  | 
 |  |  | 
 | void systimer_noint(NEVENTITEM item) { |  | 
 |  |  | 
 | if (item->flag & NEVENT_SETEVENT) { |  | 
 | setsystimerevent_noint(NEVENT_RELATIVE); |  | 
 | } |  | 
 | } |  | 
 |  |  | 
 | static void setsystimerevent(BOOL absolute) { | static void setsystimerevent(BOOL absolute) { | 
 |  |  | 
 | SINT32  cnt; | SINT32  cnt; | 
 |  |  | 
 | cnt = pit.value[0]; | 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 48  void systimer(NEVENTITEM item) { | Line 38  void systimer(NEVENTITEM item) { | 
 | if (pit.intr[0]) { | if (pit.intr[0]) { | 
 | pit.intr[0] = 0; | pit.intr[0] = 0; | 
 | pic_setirq(0); | pic_setirq(0); | 
 | //                      TRACEOUT(("int-08 [%.2x]", pit.mode[0])); |  | 
 | } | } | 
 | if ((pit.mode[0] & 0x0c) == 0x04) { | if ((pit.mode[0] & 0x0c) == 0x04) { | 
 | // レートジェネレータ | // レートジェネレータ | 
| Line 56  void systimer(NEVENTITEM item) { | Line 45  void systimer(NEVENTITEM item) { | 
 | setsystimerevent(NEVENT_RELATIVE); | setsystimerevent(NEVENT_RELATIVE); | 
 | } | } | 
 | else { | else { | 
| nevent_set(NEVENT_ITIMER, pc.multiple << 16, | nevent_set(NEVENT_ITIMER, pccore.multiple << 16, | 
 | systimer, NEVENT_RELATIVE); | systimer, NEVENT_RELATIVE); | 
 | } | } | 
 | } | } | 
| Line 65  void systimer(NEVENTITEM item) { | Line 54  void systimer(NEVENTITEM item) { | 
 |  |  | 
 | // --- 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]; | 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 85  void beeponeshot(NEVENTITEM item) { | Line 93  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 104  static void setrs232cevent(BOOL absolute | Line 116  static void setrs232cevent(BOOL absolute | 
 | SINT32  cnt; | SINT32  cnt; | 
 |  |  | 
 | if (pit.value[2] > 1) { | if (pit.value[2] > 1) { | 
| cnt = pc.multiple * pit.value[2] * rs232c.mul; | cnt = pccore.multiple * pit.value[2] * rs232c.mul; | 
 | } | } | 
 | else { | else { | 
| cnt = (pc.multiple << 16) * rs232c.mul; | cnt = (pccore.multiple << 16) * rs232c.mul; | 
 | } | } | 
 | nevent_set(NEVENT_RS232C, cnt, rs232ctimer, absolute); | nevent_set(NEVENT_RS232C, cnt, rs232ctimer, absolute); | 
 | } | } | 
| Line 126  void rs232ctimer(NEVENTITEM item) { | Line 138  void rs232ctimer(NEVENTITEM item) { | 
 |  |  | 
 | // --------------------------------------------------------------------------- | // --------------------------------------------------------------------------- | 
 |  |  | 
| 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]); | return(pit.value[1]); | 
 | #ifdef uPD71054 | #ifdef uPD71054 | 
 | case 0x06: | case 0x06: | 
| return(pit.value[1] & 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 itimer_setflag(int ch, BYTE value) { | void pit_setflag(int ch, REG8 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.mode[ch] &= ~0x30; | pit.mode[ch] &= ~0x30; | 
| pit.latch[ch] = itimer_latch(ch); | 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 | 
| Line 186  BOOL itimer_setcount(int ch, BYTE value) | Line 214  BOOL itimer_setcount(int ch, BYTE value) | 
 | return(FALSE); | return(FALSE); | 
 | } | } | 
 |  |  | 
| BYTE itimer_getcount(int ch) { | REG8 pit_getcount(int ch) { | 
 |  |  | 
| BYTE    ret; | REG8    ret; | 
| UINT16  w; | REG16   w; | 
 |  |  | 
 | if (!(pit.mode[ch] & 0x30)) { | if (!(pit.mode[ch] & 0x30)) { | 
 | w = pit.latch[ch]; | w = pit.latch[ch]; | 
 | } | } | 
 | else { | else { | 
| w = itimer_latch(ch); | w = pit_latch(ch); | 
 | } | } | 
 | switch(pit.mode[ch] & 0x30) { | switch(pit.mode[ch] & 0x30) { | 
 | case 0x10:                                              // access low | case 0x10:                                              // access low | 
| return((BYTE)w); | return((UINT8)w); | 
 |  |  | 
 | case 0x20:                                              // access high | case 0x20:                                              // access high | 
| return((BYTE)(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)w; |  | 
 | } | } | 
 | else { | else { | 
| ret = (BYTE)(w >> 8); | ret = (UINT8)(w >> 8); | 
 | } | } | 
 | pit.flag[ch] ^= 1; | pit.flag[ch] ^= 1; | 
 | return(ret); | return(ret); | 
| Line 219  BYTE itimer_getcount(int ch) { | Line 246  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) { | 
 |  |  | 
| TRACEOUT(("pic o71: %x [%.4x %.4x]", dat, I286_CS, I286_IP)); | //      TRACEOUT(("pic o71: %x", dat)); | 
| if (itimer_setcount(0, dat)) { | if (pit_setcount(0, dat)) { | 
 | return; | return; | 
 | } | } | 
 | pic.pi[0].irr &= (~1); | pic.pi[0].irr &= (~1); | 
| Line 232  static void IOOUTCALL pit_o71(UINT port, | Line 259  static void IOOUTCALL pit_o71(UINT 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 248  static void IOOUTCALL pit_o73(UINT port, | Line 275  static void IOOUTCALL pit_o73(UINT 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 259  static void IOOUTCALL pit_o75(UINT port, | Line 286  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)); | //      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) {       // 一応ラッチ時は割り込みをセットしない | if (dat & 0x30) {       // 一応ラッチ時は割り込みをセットしない | 
| Line 278  static void IOOUTCALL pit_o77(UINT port, | Line 305  static void IOOUTCALL pit_o77(UINT port, | 
 | beep_modeset(); | beep_modeset(); | 
 | } | } | 
 | } | } | 
 |  | #if defined(uPD71054) | 
 |  | else { | 
 |  | // これ現状じゃだめぽ_| ̄|○ ver0.76に回す… | 
 |  | TRACEOUT(("multiple latch commands - %x", dat)); | 
 |  | for (ch=0; ch<3; ch++) { | 
 |  | if (dat & (2 << ch)) { | 
 |  | if (!(dat & 0x10)) { | 
 |  | } | 
 |  | if (!(dat & 0x20)) { | 
 |  | } | 
 |  | } | 
 |  | } | 
 |  | } | 
 |  | #endif | 
 | (void)port; | (void)port; | 
 | } | } | 
 |  |  | 
| static BYTE IOINPCALL pit_i71(UINT port) { | static REG8 IOINPCALL pit_i71(UINT port) { | 
 |  |  | 
| return(itimer_getcount((port >> 1) & 3)); | int             ch; | 
|  |  | 
|  | ch = (port >> 1) & 3; | 
|  | #if defined(uPD71054) | 
|  | if (pit.stat[ch]) { | 
|  | REG8 ret; | 
|  | ret = pit.stat[ch]; | 
|  | pit.stat[ch] = 0; | 
|  | TRACEOUT(("stat out -> %d-%x", ch, ret)); | 
|  | return(ret); | 
|  | } | 
|  | #endif | 
|  | return(pit_getcount(ch)); | 
 | } | } | 
 |  |  | 
 |  |  | 
| Line 298  static const IOINP piti71[4] = { | Line 351  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] = 998;                             // 4MHz | pit.value[1] = 998;                             // 4MHz | 
 | } | } | 
 | else { | else { | 
 | pit.value[1] = 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; | 
| Line 316  void itimer_bind(void) { | Line 370  void itimer_bind(void) { | 
 |  |  | 
 | iocore_attachsysoutex(0x0071, 0x0cf1, pito71, 4); | iocore_attachsysoutex(0x0071, 0x0cf1, pito71, 4); | 
 | iocore_attachsysinpex(0x0071, 0x0cf1, piti71, 4); | iocore_attachsysinpex(0x0071, 0x0cf1, piti71, 4); | 
 |  | iocore_attachout(0x3fd9, pit_o71); | 
 | iocore_attachout(0x3fdb, pit_o73); | iocore_attachout(0x3fdb, pit_o73); | 
 |  | iocore_attachout(0x3fdd, pit_o75); | 
 | iocore_attachout(0x3fdf, pit_o77); | iocore_attachout(0x3fdf, pit_o77); | 
 |  | iocore_attachinp(0x3fd9, pit_i71); | 
 | iocore_attachinp(0x3fdb, pit_i71); | iocore_attachinp(0x3fdb, pit_i71); | 
 |  | iocore_attachinp(0x3fdd, pit_i71); | 
 | } | } | 
 |  |  |