| version 1.1, 2004/08/01 05:31:30 | version 1.9, 2005/02/04 06:42:11 | 
| Line 3 | Line 3 | 
 | #include        "z80core.h" | #include        "z80core.h" | 
 | #include        "pccore.h" | #include        "pccore.h" | 
 | #include        "iocore.h" | #include        "iocore.h" | 
 |  | #include        "nevent.h" | 
 |  | #include        "ievent.h" | 
 | #include        "keystat.h" | #include        "keystat.h" | 
 | #include        "calendar.h" | #include        "calendar.h" | 
 |  |  | 
 |  |  | 
| //                                                          e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef | //                                                           e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef | 
| static const UINT8 CMD_TBL[] = { 0, 1, 0, 0, 1, 0, 1, 0, 0, 3, 0, 3, 0}; | //static const UINT8 cmdtbl[] = { 0, 1, 0, 0, 1, 0, 1, 0, 0, 3, 0, 3, 0}; | 
| static const UINT8 DAT_TBL[] = { 3, 0, 0, 2, 0, 1, 0, 1, 1, 0, 3, 0, 3}; | //static const UINT8 dattbl[] = { 3, 0, 0, 2, 0, 1, 0, 1, 1, 0, 3, 0, 3}; | 
|  |  | 
|  | typedef struct { | 
|  | UINT8   pos; | 
|  | UINT8   flag; | 
|  | } SCPUTBL; | 
|  |  | 
|  | enum { | 
|  | SCPU_CNTMASK    = 0x07, | 
|  | SCPU_INPUT              = 0x08 | 
|  | }; | 
|  |  | 
|  | static const SCPUTBL scputbl[0x20] = { | 
|  | {offsetof(SUBCPU, s.timer[0]),  6},                                     // d0: timer0 set | 
|  | {offsetof(SUBCPU, s.timer[1]),  6},                                     // d1: timer1 set | 
|  | {offsetof(SUBCPU, s.timer[2]),  6},                                     // d2: timer2 set | 
|  | {offsetof(SUBCPU, s.timer[3]),  6},                                     // d3: timer3 set | 
|  | {offsetof(SUBCPU, s.timer[4]),  6},                                     // d4: timer4 set | 
|  | {offsetof(SUBCPU, s.timer[5]),  6},                                     // d5: timer5 set | 
|  | {offsetof(SUBCPU, s.timer[6]),  6},                                     // d6: timer6 set | 
|  | {offsetof(SUBCPU, s.timer[7]),  6},                                     // d7: timer7 set | 
|  | {offsetof(SUBCPU, s.timer[0]),  6 + SCPU_INPUT},        // d8: timer0 get | 
|  | {offsetof(SUBCPU, s.timer[1]),  6 + SCPU_INPUT},        // d9: timer1 get | 
|  | {offsetof(SUBCPU, s.timer[2]),  6 + SCPU_INPUT},        // da: timer2 get | 
|  | {offsetof(SUBCPU, s.timer[3]),  6 + SCPU_INPUT},        // db: timer3 get | 
|  | {offsetof(SUBCPU, s.timer[4]),  6 + SCPU_INPUT},        // dc: timer4 get | 
|  | {offsetof(SUBCPU, s.timer[5]),  6 + SCPU_INPUT},        // dd: timer5 get | 
|  | {offsetof(SUBCPU, s.timer[6]),  6 + SCPU_INPUT},        // de: timer6 get | 
|  | {offsetof(SUBCPU, s.timer[7]),  6 + SCPU_INPUT},        // df: timer7 get | 
|  | {offsetof(SUBCPU, s.zero),              0},                                     // e0: | 
|  | {offsetof(SUBCPU, s.zero),              0},                                     // e1: | 
|  | {offsetof(SUBCPU, s.zero),              0},                                     // e2: | 
|  | {offsetof(SUBCPU, s.work),              3 + SCPU_INPUT},        // e3: game keys | 
|  | {offsetof(SUBCPU, s.vect),              1},                                     // e4: intr vector | 
|  | {offsetof(SUBCPU, s.zero),              0},                                     // e5: | 
|  | {offsetof(SUBCPU, s.work),              2 + SCPU_INPUT},        // e6: game keys | 
|  | {offsetof(SUBCPU, s.tvctrl),    1},                                     // e7: set TV ctrl | 
|  | {offsetof(SUBCPU, s.tvctrl),    1 + SCPU_INPUT},        // e8: get TV ctrl | 
|  | {offsetof(SUBCPU, s.work),              1},                                     // e9: cmt ctrl | 
|  | {offsetof(SUBCPU, s.work),              1 + SCPU_INPUT},        // ea: cmtctrlstat | 
|  | {offsetof(SUBCPU, s.work),              1 + SCPU_INPUT},        // eb: cmttypestat | 
|  | {offsetof(SUBCPU, s.work),              3},                                     // ec: date set | 
|  | {offsetof(SUBCPU, s.work),              3 + SCPU_INPUT},        // ed: date set | 
|  | {offsetof(SUBCPU, s.work),              3},                                     // ee: time set | 
|  | {offsetof(SUBCPU, s.work),              3 + SCPU_INPUT}};       // ef: time set | 
 |  |  | 
 |  |  | 
| //********************************************************************** | // ---- | 
 |  |  | 
| // キーボード割り込み | void neitem_scpu(UINT id) { | 
| short x1_sub_int(void) {                                                                // 990922 |  | 
 |  |  | 
| UINT    key; | BRESULT intr; | 
 |  |  | 
| if ((!keystat.req_int) || (subcpu.cmdcnt) || (subcpu.datacnt) || | intr = FALSE; | 
| (!Z80_ABLEINTERRUPT())) {                                               // 割り込めなかったら | // こうすると同時押しが判定できないのでキーバッファを持つべし | 
| return(1);                                                                              // また来週〜 | if (keystat.req_int) { | 
| } | keystat.req_int = 0; | 
| keystat.req_int = 0; | intr = TRUE; | 
| if (!subcpu.Ex[4][0]) {                         // 割り込み不要だったら捨てる | } | 
| return(1); | else if (subcpu.s.keydata) { | 
| } | subcpu.s.keycount++; | 
| if (keystat.shift & 0x40) {                                     // キーが押された場合 | if (subcpu.s.keycount >= subcpu.s.keycountrep) { | 
| key = keystat_getflag(); | subcpu.s.keycount = 0; | 
| subcpu.Ex[0x06][0] = (UINT8)(key >> 0); | intr = TRUE; | 
| subcpu.Ex[0x06][1] = (UINT8)(key >> 8); |  | 
| if (!subcpu.Ex[0x06][1]) {              // 無効なキーだったら捨てる |  | 
| return(1); |  | 
 | } | } | 
| subcpu.INT_SW = 1; | nevent_set(NEVENT_SUBCPU, subcpu.e.intrclock, | 
|  | neitem_scpu, NEVENT_RELATIVE); | 
|  | } | 
|  | if (intr) { | 
|  | ievent_set(IEVENT_SUBCPU); | 
|  | } | 
|  | } | 
|  |  | 
|  | BRESULT ieitem_scpu(UINT id) { | 
|  |  | 
|  | UINT    key; | 
|  | UINT8   keydata; | 
|  |  | 
|  | if ((subcpu.s.cmdcnt) || (subcpu.s.datcnt)) { | 
|  | keystat.req_int = 1;                    // 再送しる | 
|  | subcpu_sendkey(); | 
|  | return(FALSE); | 
|  | } | 
|  | if (subcpu.s.vect == 0) {                       // 割り込み不要だったら捨てる | 
|  | return(FALSE); | 
|  | } | 
|  | key = keystat_getflag(); | 
|  | keydata = (UINT8)(key >> 8); | 
|  | if (subcpu.s.keydata != keydata) { | 
|  | subcpu.s.keydata = keydata; | 
|  | subcpu.s.keycount = 0; | 
|  | subcpu.s.keycountrep = 480; | 
 | } | } | 
 | else { | else { | 
| if (!subcpu.INT_SW) {                   // 何も押されてなかったら割り込まない | if (keydata == 0) { | 
| return(1); | return(FALSE); | 
 | } | } | 
| subcpu.INT_SW = 0; | key = key & (~0x20);                    // rep | 
| key = keystat_getflag(); | subcpu.s.keycountrep = 48;              // 0.1sec | 
| subcpu.Ex[0x06][0] = (UINT8)(key >> 0); | } | 
| subcpu.Ex[0x06][1] = (UINT8)(key >> 8); | subcpu.s.work[1] = (UINT8)key; | 
| } | subcpu.s.work[0] = keydata; | 
| subcpu.mode = 0xe6; | subcpu.s.cmdptr = offsetof(SUBCPU, s.zero); | 
| subcpu.cmdcnt = 0; | subcpu.s.datptr = offsetof(SUBCPU, s.work); | 
| subcpu.datacnt = 2; | subcpu.s.mode = 0xe6; | 
| subcpu.dataptr = offsetof(SUBCPU, Ex[0xe6 - 0xe0][0]); | subcpu.s.cmdcnt = 0; | 
| subcpu.OBF = 0; | subcpu.s.datcnt = 2; | 
| subcpu.IBF = 1; |  | 
|  | //      subcpu.s.OBF = 0; | 
| Z80_INT2(subcpu.Ex[4][0]); | //      subcpu.s.IBF = 1; | 
| return(0); | iocore.s.ppib = (UINT8)((iocore.s.ppib & (~0x20)) | 0x40); | 
|  |  | 
|  | Z80_INTERRUPT(subcpu.s.vect); | 
|  | (void)id; | 
|  | return(TRUE); | 
 | } | } | 
 |  |  | 
 | //********************************************************************** |  | 
 |  |  | 
| void IOOUTCALL subcpu_o(UINT port, REG8 value) { | // ---- | 
|  |  | 
|  | static void subcpusetbuffer(SUBCPU *s) { | 
 |  |  | 
 | UINT32  key; | UINT32  key; | 
 |  |  | 
| if (subcpu.IBF) { | switch(s->s.mode) { | 
|  | case 0xe3: | 
|  | key = keystat_gete3(); | 
|  | s->s.work[2] = (UINT8)(key >> 16); | 
|  | s->s.work[1] = (UINT8)(key >> 8); | 
|  | s->s.work[0] = (UINT8)(key >> 0); | 
|  | break; | 
|  |  | 
|  | case 0xe6: | 
|  | key = keystat_getflag(); | 
|  | s->s.work[1] = (UINT8)(key >> 0); | 
|  | s->s.work[0] = (UINT8)(key >> 8); | 
|  | break; | 
|  |  | 
|  | case 0xea: | 
|  | s->s.work[0] = cmt_ctrl_stat(); | 
|  | break; | 
|  |  | 
|  | case 0xeb: | 
|  | s->s.work[0] = cmt_tape_stat(); | 
|  | break; | 
|  |  | 
|  | case 0xed: | 
|  | calendar_getdate(s->s.work); | 
|  | break; | 
|  |  | 
|  | case 0xef: | 
|  | calendar_gettime(s->s.work); | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | void IOOUTCALL subcpu_o(UINT port, REG8 value) { | 
|  |  | 
|  | UINT            tblpos; | 
|  | const SCPUTBL   *p; | 
|  |  | 
|  | if (iocore.s.ppib & 0x40) {             // subcpu.IBF | 
 | return; | return; | 
 | } | } | 
| if (!subcpu.cmdcnt) { | if (!subcpu.s.cmdcnt) { | 
| subcpu.mode = (UINT8)value; | subcpu.s.mode = (UINT8)value; | 
| subcpu.cmdcnt = 0; | tblpos = value - 0xd0; | 
| subcpu.datacnt = 0; | if (tblpos >= 0x20) { | 
| if (value >= 0xd0 && value <= 0xd7) { | tblpos = 0x10; | 
| subcpu.cmdcnt = 6; |  | 
| subcpu.datacnt = 0; |  | 
| } |  | 
| else if (value >= 0xd8 && value <= 0xdf) { |  | 
| subcpu.cmdcnt = 0; |  | 
| subcpu.datacnt = 6; |  | 
| } |  | 
| else if (value >= 0xe3 && value <= 0xef) { |  | 
| subcpu.cmdcnt = CMD_TBL[value - 0xe3]; |  | 
| subcpu.datacnt = DAT_TBL[value - 0xe3]; |  | 
 | } | } | 
| if (value < 0xe0) { | p = scputbl + tblpos; | 
| subcpu.dataptr = offsetof(SUBCPU, Dx[value - 0xd0][0]); | iocore.s.ppib = (UINT8)(iocore.s.ppib & (~0x60)); | 
|  | if (p->flag & SCPU_INPUT) { | 
|  | subcpu.s.cmdptr = offsetof(SUBCPU, s.zero); | 
|  | subcpu.s.datptr = p->pos; | 
|  | //      subcpu.s.cmdcnt = 0; | 
|  | subcpu.s.datcnt = p->flag & SCPU_CNTMASK; | 
|  | //      subcpu.s.OBF = (UINT8)(subcpu.s.datacnt?0:1);   // = 0 | 
|  | //      subcpu.s.IBF = (UINT8)(subcpu.s.datacnt?1:0);   // = 1 | 
|  | iocore.s.ppib |= 0x40; | 
|  | subcpusetbuffer(&subcpu); | 
 | } | } | 
 | else { | else { | 
| subcpu.dataptr = offsetof(SUBCPU, Ex[value - 0xe0][0]); | subcpu.s.cmdptr = p->pos; | 
| } | subcpu.s.datptr = offsetof(SUBCPU, s.zero); | 
| switch(subcpu.mode) { | subcpu.s.cmdcnt = p->flag & SCPU_CNTMASK; | 
| case 0xe3: | subcpu.s.datcnt = 0; | 
| key = keystat_gete3(); | //      subcpu.s.OBF = (UINT8)(subcpu.s.datacnt?0:1);   // = 1 | 
| subcpu.Ex[0x03][0] = (UINT8)(key >> 0); | //      subcpu.s.IBF = (UINT8)(subcpu.s.datacnt?1:0);   // = 0 | 
| subcpu.Ex[0x03][1] = (UINT8)(key >> 8); | iocore.s.ppib |= 0x20; | 
| subcpu.Ex[0x03][2] = (UINT8)(key >> 16); |  | 
| break; |  | 
|  |  | 
| case 0xe6: |  | 
| key = keystat_getflag(); |  | 
| subcpu.Ex[0x06][0] = (UINT8)(key >> 0); |  | 
| subcpu.Ex[0x06][1] = (UINT8)(key >> 8); |  | 
| break; |  | 
|  |  | 
| case 0xed: |  | 
| calendar_getdate(subcpu.Ex[0x0d]); |  | 
| break; |  | 
|  |  | 
| case 0xef: |  | 
| calendar_gettime(subcpu.Ex[0x0f]); |  | 
| break; |  | 
 | } | } | 
 | } | } | 
 | else { | else { | 
| ((UINT8 *)(&subcpu))[subcpu.dataptr] = value; | subcpu.s.cmdcnt--; | 
| subcpu.dataptr++; | ((UINT8 *)(&subcpu))[subcpu.s.cmdptr + subcpu.s.cmdcnt] = value; | 
| if (--subcpu.cmdcnt == 0) { | if (subcpu.s.cmdcnt == 0) { | 
| switch(subcpu.mode) { | switch(subcpu.s.mode) { | 
 | case 0xe9: | case 0xe9: | 
| cmt_ctrl(subcpu.Ex[0x9][0]); | cmt_ctrl(subcpu.s.work[0]); | 
 | break; | break; | 
 |  |  | 
 | case 0xec: | case 0xec: | 
| calendar_setdate(subcpu.Ex[0x0c]); | calendar_setdate(subcpu.s.work); | 
 | break; | break; | 
 |  |  | 
 | case 0xee: | case 0xee: | 
| calendar_settime(subcpu.Ex[0x0e]); | calendar_settime(subcpu.s.work); | 
 | break; | break; | 
 | } | } | 
 | } | } | 
 | } | } | 
| subcpu.OBF = (UINT8)(subcpu.datacnt?0:1); | (void)port; | 
| subcpu.IBF = (UINT8)(subcpu.datacnt?1:0); |  | 
 | } | } | 
 |  |  | 
 | REG8 IOINPCALL subcpu_i(UINT port) { | REG8 IOINPCALL subcpu_i(UINT port) { | 
 |  |  | 
| UINT32  key; | if (subcpu.s.datcnt) { | 
| REG8    ret; | subcpu.s.datcnt--; | 
|  | } | 
| #if 1                                                                           // D-SIDE で通るように… | else {                                                                  // D-SIDE で通るように… | 
| if (!subcpu.datacnt) {                                  // ポインタは変らない? | subcpusetbuffer(&subcpu); | 
| subcpu.datacnt++; |  | 
|  |  | 
| switch(subcpu.mode) {                                   // 990225 puni |  | 
| case 0xe3: |  | 
| key = keystat_gete3(); |  | 
| subcpu.Ex[0x03][0] = (UINT8)(key >> 0); |  | 
| subcpu.Ex[0x03][1] = (UINT8)(key >> 8); |  | 
| subcpu.Ex[0x03][2] = (UINT8)(key >> 16); |  | 
| break; |  | 
|  |  | 
| case 0xe6: |  | 
| key = keystat_getflag(); |  | 
| subcpu.Ex[0x06][0] = (UINT8)(key >> 0); |  | 
| subcpu.Ex[0x06][1] = (UINT8)(key >> 8); |  | 
| break; |  | 
|  |  | 
| case 0xed: |  | 
| calendar_getdate(subcpu.Ex[0x0d]); |  | 
| break; |  | 
|  |  | 
| case 0xef: |  | 
| calendar_gettime(subcpu.Ex[0x0f]); |  | 
| break; |  | 
| } |  | 
 | } | } | 
 |  |  | 
| #else | //      subcpu.s.OBF = (UINT8)(subcpu.s.datacnt?0:1); | 
| if (subcpu.OBF) { | //      subcpu.s.IBF = (UINT8)(subcpu.s.datacnt?1:0); | 
| return(0); | iocore.s.ppib = (UINT8)(iocore.s.ppib & (~0x60)); | 
|  | if (subcpu.s.datcnt) { | 
|  | iocore.s.ppib |= 0x40; | 
|  | } | 
|  | else { | 
|  | iocore.s.ppib |= 0x20; | 
 | } | } | 
 | #endif |  | 
 | ret = 0; |  | 
 | switch(subcpu.mode) { |  | 
 | case 0xd8: |  | 
 | case 0xd9: |  | 
 | case 0xda: |  | 
 | case 0xdb: |  | 
 | case 0xdc: |  | 
 | case 0xdd: |  | 
 | case 0xde: |  | 
 | case 0xdf: |  | 
 | ret = subcpu.Dx[subcpu.mode - 0xd8][6 - subcpu.datacnt]; |  | 
 | break; |  | 
 |  |  | 
| case 0xe3: | (void)port; | 
| ret = subcpu.Ex[0x03][3 - subcpu.datacnt]; | return(((UINT8 *)(&subcpu))[subcpu.s.datptr + subcpu.s.datcnt]); | 
| break; | } | 
 |  |  | 
 | case 0xe6: |  | 
 | ret = subcpu.Ex[0x06][2 - subcpu.datacnt]; |  | 
 | break; |  | 
 |  |  | 
| case 0xe8: | // ---- | 
| ret = subcpu.Ex[0x07][0]; |  | 
| break; |  | 
 |  |  | 
| case 0xea: | void subcpu_reset(void) { | 
| ret = cmt_ctrl_stat(); |  | 
| break; |  | 
 |  |  | 
| case 0xeb: | ZeroMemory(&subcpu, sizeof(subcpu)); | 
| ret = cmt_tape_stat(); |  | 
| break; |  | 
 |  |  | 
| case 0xed: | //      subcpu.s.OBF = 1; | 
| ret = subcpu.Ex[0x0d][3 - subcpu.datacnt]; | iocore.s.ppib = (UINT8)(iocore.s.ppib | 0x20); | 
| break; |  | 
 |  |  | 
| case 0xef: | #if defined(FIX_Z80A) | 
| ret = subcpu.Ex[0x0f][3 - subcpu.datacnt]; | subcpu.e.intrclock = 2000000 * 2 / 480; | 
| break; | #else | 
| } | subcpu.e.intrclock = pccore.realclock / 480; | 
| subcpu.datacnt--; | #endif | 
| subcpu.OBF = (UINT8)(subcpu.datacnt?0:1); |  | 
| subcpu.IBF = (UINT8)(subcpu.datacnt?1:0); |  | 
| return(ret); |  | 
 | } | } | 
 |  |  | 
 |  | void subcpu_sendkey(void) { | 
 |  |  | 
| // ---- | if (!nevent_iswork(NEVENT_SUBCPU)) { | 
|  | nevent_set(NEVENT_SUBCPU, subcpu.e.intrclock, | 
| void subcpu_reset(void) { | neitem_scpu, NEVENT_ABSOLUTE); | 
|  | } | 
| ZeroMemory(&subcpu, sizeof(subcpu)); |  | 
| subcpu.OBF = 1; |  | 
 | } | } | 
 |  |  |