|
|
1.1 ! root 1: /* Generator is (c) James Ponder, 1997-2001 http://www.squish.net/generator/ */ ! 2: ! 3: #include "generator.h" ! 4: #include "vdp.h" ! 5: #include "cpu68k.h" ! 6: #include "cpuz80.h" ! 7: #include "reg68k.h" ! 8: #include "ui.h" ! 9: #include "gensound.h" ! 10: ! 11: inline void event_nextevent(void) ! 12: { ! 13: switch(vdp_event++) { ! 14: case 0: ! 15: LOG_DEBUG1(("%08X due %08X, %d A: %d (cd=%d)", ! 16: cpu68k_clocks, vdp_event_start, ! 17: vdp_line - vdp_visstartline, vdp_reg[10], ! 18: vdp_hskip_countdown)); ! 19: if (vdp_line == (vdp_visstartline-1)) { ! 20: vdp_vblank = 0; ! 21: } ! 22: if ((vdp_nextevent = vdp_event_vint - cpu68k_clocks) > 0) ! 23: break; ! 24: vdp_event++; ! 25: case 1: ! 26: LOG_DEBUG1(("%08X due %08X, %d B: %d (cd=%d)", ! 27: cpu68k_clocks, vdp_event_vint, ! 28: vdp_line - vdp_visstartline, vdp_reg[10], ! 29: vdp_hskip_countdown)); ! 30: if (vdp_line == vdp_visendline) { ! 31: vdp_vblank = 1; ! 32: vdp_vsync = 1; ! 33: if (vdp_reg[1] & 1<<5) ! 34: reg68k_external_autovector(6); /* vertical interrupt */ ! 35: } ! 36: if ((vdp_nextevent = vdp_event_hint - cpu68k_clocks) > 0) ! 37: break; ! 38: vdp_event++; ! 39: case 2: ! 40: LOG_DEBUG1(("%08X due %08X, %d C: %d (cd=%d)", ! 41: cpu68k_clocks, vdp_event_hint, ! 42: vdp_line - vdp_visstartline, vdp_reg[10], ! 43: vdp_hskip_countdown)); ! 44: if (vdp_line >= vdp_visstartline && vdp_line < vdp_visendline) ! 45: vdp_hblank = 1; ! 46: if (vdp_line == (vdp_visstartline-1) || (vdp_line > vdp_visendline)) { ! 47: vdp_hskip_countdown = vdp_reg[10]; ! 48: LOG_DEBUG1(("H counter reset to %d", vdp_hskip_countdown)); ! 49: } ! 50: if (vdp_reg[0] & 1<<4) { ! 51: LOG_DEBUG1(("pre = %d", vdp_hskip_countdown)); ! 52: if (vdp_hskip_countdown-- == 0) { ! 53: LOG_DEBUG1(("in = %d", vdp_hskip_countdown)); ! 54: /* re-initialise counter */ ! 55: vdp_hskip_countdown = vdp_reg[10]; ! 56: LOG_DEBUG1(("H counter looped to %d", vdp_hskip_countdown)); ! 57: if (vdp_line >= vdp_visstartline-1 && vdp_line < vdp_visendline-1) ! 58: reg68k_external_autovector(4); /* horizontal interrupt */ ! 59: /* since this game is obviously timing sensitive, we sacrifice ! 60: executing the right number of 68k clocks this frame in order ! 61: to accurately do the moments following H-Int */ ! 62: cpu68k_clocks = vdp_event_hint; ! 63: } ! 64: LOG_DEBUG1(("post = %d", vdp_hskip_countdown)); ! 65: } ! 66: /* the 68k should be frozen for 68k ram to vram copies, so we need ! 67: to eat CPU cyles immediately - implement this at the same time ! 68: as re-working this event loop */ ! 69: if (vdp_dmabytes) { ! 70: vdp_dmabytes-= (vdp_vblank || !(vdp_reg[1] & 1<<6)) /* blank mode ? */ ! 71: ? ((vdp_reg[12] & 1) ? 205 : 167) : ((vdp_reg[12] & 1) ? 18 : 16); ! 72: if (vdp_dmabytes <= 0) { ! 73: vdp_dmabytes = 0; ! 74: vdp_dmabusy = 0; ! 75: } ! 76: } ! 77: if ((vdp_nextevent = vdp_event_hdisplay - cpu68k_clocks) > 0) ! 78: break; ! 79: vdp_event++; ! 80: case 3: ! 81: LOG_DEBUG1(("%08X due %08X, %d D: %d (cd=%d)", ! 82: cpu68k_clocks, vdp_event_hdisplay, ! 83: vdp_line - vdp_visstartline, vdp_reg[10], ! 84: vdp_hskip_countdown)); ! 85: if (vdp_line >= vdp_visstartline-1 && vdp_line < vdp_visendline-1) ! 86: ui_line(vdp_line - vdp_visstartline + 1); ! 87: if ((vdp_nextevent = vdp_event_end - cpu68k_clocks) > 0) ! 88: break; ! 89: vdp_event++; ! 90: case 4: ! 91: /* end of line, do sound, platform stuff */ ! 92: LOG_DEBUG1(("%08X due %08X, %d E: %d (cd=%d)", ! 93: cpu68k_clocks, vdp_event_end, ! 94: vdp_line-vdp_visstartline, vdp_reg[10], ! 95: vdp_hskip_countdown)); ! 96: if (vdp_line >= vdp_visstartline && vdp_line < vdp_visendline) ! 97: vdp_hblank = 0; ! 98: cpuz80_sync(); ! 99: sound_process(); ! 100: vdp_line++; ! 101: if (vdp_line == vdp_totlines) { ! 102: ui_endfield(); ! 103: sound_endfield(); ! 104: cpuz80_interrupt(); ! 105: vdp_endfield(); ! 106: cpuz80_endfield(); ! 107: cpu68k_endfield(); ! 108: cpu68k_frames++; ! 109: } ! 110: vdp_event_start+= vdp_clksperline_68k; ! 111: vdp_event_vint+= vdp_clksperline_68k; ! 112: vdp_event_hint+= vdp_clksperline_68k; ! 113: vdp_event_hdisplay+= vdp_clksperline_68k; ! 114: vdp_event_end+= vdp_clksperline_68k; ! 115: vdp_event = 0; ! 116: vdp_nextevent = 0; ! 117: break; ! 118: } /* switch */ ! 119: } ! 120: ! 121: /*** event_doframe - execute until the end of the current frame ***/ ! 122: ! 123: void event_doframe(void) ! 124: { ! 125: unsigned int startframe; ! 126: ! 127: for (startframe = cpu68k_frames; ! 128: startframe == cpu68k_frames; ! 129: event_nextevent()) { ! 130: while (vdp_nextevent > 0) { ! 131: vdp_nextevent = -reg68k_external_execute(vdp_nextevent); ! 132: } ! 133: } ! 134: } ! 135: ! 136: /*** event_step - execute one instruction with no caching ***/ ! 137: ! 138: void event_dostep(void) ! 139: { ! 140: while (vdp_nextevent <= 0) ! 141: event_nextevent(); ! 142: vdp_nextevent-= reg68k_external_step(); ! 143: } ! 144: ! 145: /*** event_freeze_clocks - freeze 68k for given clock cycles ***/ ! 146: ! 147: void event_freeze_clocks(unsigned int clocks) ! 148: { ! 149: cpu68k_clocks+= clocks; ! 150: ! 151: /* now find out the new time to next event - just to make sure there is ! 152: an event to be generated by inreasing the clock */ ! 153: ! 154: switch(vdp_event) { ! 155: case 0: ! 156: vdp_nextevent = vdp_event_start - cpu68k_clocks; ! 157: case 1: ! 158: vdp_nextevent = vdp_event_vint - cpu68k_clocks; ! 159: break; ! 160: case 2: ! 161: vdp_nextevent = vdp_event_hint - cpu68k_clocks; ! 162: break; ! 163: case 3: ! 164: vdp_nextevent = vdp_event_hdisplay - cpu68k_clocks; ! 165: break; ! 166: case 4: ! 167: vdp_nextevent = vdp_event_end - cpu68k_clocks; ! 168: break; ! 169: } /* switch */ ! 170: ! 171: /* now play catch-up in events */ ! 172: ! 173: while (vdp_nextevent <= 0) ! 174: event_nextevent(); ! 175: } ! 176: ! 177: /*** event_freeze - freeze 68k for given VDP byte transfer ***/ ! 178: ! 179: void event_freeze(unsigned int bytes) ! 180: { ! 181: int wide = vdp_reg[12] & 1; ! 182: unsigned int clocks, possible; ! 183: double percent_possible; ! 184: ! 185: do { ! 186: clocks = vdp_event_end - cpu68k_clocks; ! 187: percent_possible = clocks/vdp_clksperline_68k; ! 188: if (vdp_reg[1] & 1<<6 && !vdp_vblank) { ! 189: /* vdp active */ ! 190: possible = (unsigned int)(percent_possible*(wide ? 18 : 16)); ! 191: } else { ! 192: /* vdp inactive */ ! 193: possible = (unsigned int)(percent_possible*(wide ? 205 : 167)); ! 194: } ! 195: if (bytes >= possible) { ! 196: event_freeze_clocks(clocks); ! 197: bytes-= possible; ! 198: } else { ! 199: event_freeze_clocks(((double)bytes/possible)*clocks); ! 200: bytes = 0; ! 201: } ! 202: } while (bytes > 0); ! 203: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.