|
|
| version 1.3, 2004/08/11 12:08:16 | version 1.10, 2008/06/02 20:07:31 |
|---|---|
| Line 9 | Line 9 |
| #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}; | * cmd: 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}; | * dat: 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) { | void neitem_scpu(UINT id) { |
| nevent_repeat(id); | BRESULT intr; |
| intr = FALSE; | |
| /* こうすると同時押しが判定できないのでキーバッファを持つべし */ | |
| if (keystat.req_int) { | if (keystat.req_int) { |
| TRACEOUT(("keystat.req_int")); | |
| keystat.req_int = 0; | keystat.req_int = 0; |
| intr = TRUE; | |
| } | |
| else if (subcpu.s.keydata) { | |
| subcpu.s.keycount++; | |
| if (subcpu.s.keycount >= subcpu.s.keycountrep) { | |
| subcpu.s.keycount = 0; | |
| intr = TRUE; | |
| } | |
| nevent_set(NEVENT_SUBCPU, subcpu.e.intrclock, | |
| neitem_scpu, NEVENT_RELATIVE); | |
| } | |
| if (intr) { | |
| ievent_set(IEVENT_SUBCPU); | ievent_set(IEVENT_SUBCPU); |
| } | } |
| } | } |
| Line 29 void neitem_scpu(UINT id) { | Line 88 void neitem_scpu(UINT id) { |
| BRESULT ieitem_scpu(UINT id) { | BRESULT ieitem_scpu(UINT id) { |
| UINT key; | UINT key; |
| UINT8 keydata; | |
| TRACEOUT(("ieitem_scpu")); | if ((subcpu.s.cmdcnt) || (subcpu.s.datcnt)) { |
| if ((subcpu.cmdcnt) || (subcpu.datacnt)) { | keystat.req_int = 1; /* 再送しる */ |
| ievent_set(IEVENT_SUBCPU); | subcpu_sendkey(); |
| return(FALSE); | return(FALSE); |
| } | } |
| if (!subcpu.Ex[4][0]) { // 割り込み不要だったら捨てる | if (subcpu.s.vect == 0) { /* 割り込み不要だったら捨てる */ |
| return(FALSE); | return(FALSE); |
| } | } |
| if (keystat.shift & 0x40) { // キーが押された場合 | key = keystat_getflag(); |
| key = keystat_getflag(); | keydata = (UINT8)(key >> 8); |
| subcpu.Ex[0x06][0] = (UINT8)(key >> 0); | if (subcpu.s.keydata != keydata) { |
| subcpu.Ex[0x06][1] = (UINT8)(key >> 8); | subcpu.s.keydata = keydata; |
| if (!subcpu.Ex[0x06][1]) { // 無効なキーだったら捨てる | subcpu.s.keycount = 0; |
| return(FALSE); | subcpu.s.keycountrep = 480; |
| } | |
| subcpu.INT_SW = 1; | |
| } | } |
| else { | else { |
| if (!subcpu.INT_SW) { // 何も押されてなかったら割り込まない | if (keydata == 0) { |
| return(FALSE); | 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; | |
| Z80_INT(subcpu.Ex[4][0]); | iocore.s.ppib = (UINT8)((iocore.s.ppib & (~0x20)) | 0x40); |
| Z80_INTERRUPT(subcpu.s.vect); | |
| (void)id; | (void)id; |
| return(TRUE); | return(TRUE); |
| } | } |
| #if 0 | /* ---- */ |
| // キーボード割り込み | |
| short x1_sub_int(void) { // 990922 | |
| UINT key; | static void subcpusetbuffer(SUBCPU *s) { |
| if ((!keystat.req_int) || (subcpu.cmdcnt) || (subcpu.datacnt) || | UINT32 key; |
| (!Z80_ABLEINTERRUPT())) { // 割り込めなかったら | |
| return(1); // また来週〜 | |
| } | |
| keystat.req_int = 0; | |
| if (!subcpu.Ex[4][0]) { // 割り込み不要だったら捨てる | |
| return(1); | |
| } | |
| if (keystat.shift & 0x40) { // キーが押された場合 | |
| key = keystat_getflag(); | |
| subcpu.Ex[0x06][0] = (UINT8)(key >> 0); | |
| subcpu.Ex[0x06][1] = (UINT8)(key >> 8); | |
| if (!subcpu.Ex[0x06][1]) { // 無効なキーだったら捨てる | |
| return(1); | |
| } | |
| subcpu.INT_SW = 1; | |
| } | |
| else { | |
| if (!subcpu.INT_SW) { // 何も押されてなかったら割り込まない | |
| return(1); | |
| } | |
| subcpu.INT_SW = 0; | |
| key = keystat_getflag(); | |
| subcpu.Ex[0x06][0] = (UINT8)(key >> 0); | |
| subcpu.Ex[0x06][1] = (UINT8)(key >> 8); | |
| } | |
| subcpu.mode = 0xe6; | |
| subcpu.cmdcnt = 0; | |
| subcpu.datacnt = 2; | |
| subcpu.dataptr = offsetof(SUBCPU, Ex[0xe6 - 0xe0][0]); | |
| subcpu.OBF = 0; | |
| subcpu.IBF = 1; | |
| Z80_INT2(subcpu.Ex[4][0]); | switch(s->s.mode) { |
| return(0); | case 0xe3: |
| } | key = keystat_gete3(); |
| #endif | 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) { | void IOOUTCALL subcpu_o(UINT port, REG8 value) { |
| UINT32 key; | UINT tblpos; |
| const SCPUTBL *p; | |
| if (subcpu.IBF) { | if (iocore.s.ppib & 0x40) { |
| 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; | p = scputbl + tblpos; |
| } | iocore.s.ppib = (UINT8)(iocore.s.ppib & (~0x60)); |
| else if (value >= 0xd8 && value <= 0xdf) { | if (p->flag & SCPU_INPUT) { |
| subcpu.cmdcnt = 0; | subcpu.s.cmdptr = offsetof(SUBCPU, s.zero); |
| subcpu.datacnt = 6; | subcpu.s.datptr = p->pos; |
| } | /* subcpu.s.cmdcnt = 0; */ |
| else if (value >= 0xe3 && value <= 0xef) { | subcpu.s.datcnt = p->flag & SCPU_CNTMASK; |
| subcpu.cmdcnt = CMD_TBL[value - 0xe3]; | iocore.s.ppib |= 0x40; |
| subcpu.datacnt = DAT_TBL[value - 0xe3]; | subcpusetbuffer(&subcpu); |
| } | |
| if (value < 0xe0) { | |
| subcpu.dataptr = offsetof(SUBCPU, Dx[value - 0xd0][0]); | |
| } | } |
| 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(); | iocore.s.ppib |= 0x20; |
| 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 { | 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); | |
| subcpu.IBF = (UINT8)(subcpu.datacnt?1:0); | |
| (void)port; | (void)port; |
| } | } |
| 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 | iocore.s.ppib = (UINT8)(iocore.s.ppib & (~0x60)); |
| if (subcpu.OBF) { | if (subcpu.s.datcnt) { |
| return(0); | 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: | /* reset */ |
| 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: | iocore.s.ppib = (UINT8)(iocore.s.ppib | 0x20); |
| ret = subcpu.Ex[0x0d][3 - subcpu.datacnt]; | |
| 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); | |
| (void)port; | |
| 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; | |
| nevent_set(NEVENT_SUBCPU, pccore.realclock / 400, | |
| neitem_scpu, NEVENT_ABSOLUTE); | |
| } | } |