--- generator/main/event.c 2020/03/04 04:46:43 1.1.1.1 +++ generator/main/event.c 2020/03/04 04:47:07 1.1.1.3 @@ -10,6 +10,10 @@ #include "snprintf.h" +/* due to DMA transfers, event_nextevent can be called during an instruction + cycle (reg68k_external_execute -> instruction -> vdp write -> dma -> + event_freeze -> event_nextevent). Be careful */ + /* time for next event - update vdp_event - return when to call again */ inline void event_nextevent(void) @@ -17,15 +21,18 @@ inline void event_nextevent(void) /* call this when it *is* time for the next event as dictated by vdp_event, so we switch on it and update vdp_event at the same time */ - switch(vdp_event++) { + switch (vdp_event++) { case 0: -EVENT_NEWLINE: + EVENT_NEWLINE: LOG_DEBUG1(("%08X due %08X, %d A: %d (cd=%d)", cpu68k_clocks, vdp_event_start, vdp_line - vdp_visstartline, vdp_reg[10], vdp_hskip_countdown)); - if (vdp_line == (vdp_visstartline-1)) { + if (vdp_line == 0) + sound_startfield(); + if (vdp_line == (vdp_visstartline - 1)) { vdp_vblank = 0; + vdp_hskip_countdown = vdp_reg[10]; } if ((vdp_nextevent = vdp_event_vint - cpu68k_clocks) > 0) break; @@ -38,8 +45,8 @@ EVENT_NEWLINE: if (vdp_line == vdp_visendline) { vdp_vblank = 1; vdp_vsync = 1; - if (vdp_reg[1] & 1<<5) - reg68k_external_autovector(6); /* vertical interrupt */ + if (vdp_reg[1] & 1 << 5) + reg68k_external_autovector(6); /* vertical interrupt */ } if ((vdp_nextevent = vdp_event_hint - cpu68k_clocks) > 0) break; @@ -51,19 +58,19 @@ EVENT_NEWLINE: vdp_hskip_countdown)); if (vdp_line >= vdp_visstartline && vdp_line < vdp_visendline) vdp_hblank = 1; - if (vdp_line == (vdp_visstartline-1) || (vdp_line > vdp_visendline)) { + if (vdp_line == (vdp_visstartline - 1) || (vdp_line > vdp_visendline)) { vdp_hskip_countdown = vdp_reg[10]; LOG_DEBUG1(("H counter reset to %d", vdp_hskip_countdown)); } - if (vdp_reg[0] & 1<<4) { + if (vdp_reg[0] & 1 << 4) { LOG_DEBUG1(("pre = %d", vdp_hskip_countdown)); if (vdp_hskip_countdown-- == 0) { LOG_DEBUG1(("in = %d", vdp_hskip_countdown)); /* re-initialise counter */ vdp_hskip_countdown = vdp_reg[10]; LOG_DEBUG1(("H counter looped to %d", vdp_hskip_countdown)); - if (vdp_line >= vdp_visstartline-1 && vdp_line < vdp_visendline-1) - reg68k_external_autovector(4); /* horizontal interrupt */ + if (vdp_line >= vdp_visstartline - 1 && vdp_line < vdp_visendline - 1) + reg68k_external_autovector(4); /* horizontal interrupt */ /* since this game is obviously timing sensitive, we sacrifice executing the right number of 68k clocks this frame in order to accurately do the moments following H-Int */ @@ -71,11 +78,9 @@ EVENT_NEWLINE: } LOG_DEBUG1(("post = %d", vdp_hskip_countdown)); } - /* the 68k should be frozen for 68k ram to vram copies, so we need - to eat CPU cyles immediately - implement this at the same time - as re-working this event loop */ - if (vdp_dmabytes) { - vdp_dmabytes-= (vdp_vblank || !(vdp_reg[1] & 1<<6)) /* blank mode ? */ + /* the 68k is frozen for 68k ram to vram copies, see event_freeze */ + if (vdp_dmabytes) { /* blank mode ? */ + vdp_dmabytes -= (vdp_vblank || !(vdp_reg[1] & 1 << 6)) ? ((vdp_reg[12] & 1) ? 205 : 167) : ((vdp_reg[12] & 1) ? 18 : 16); if (vdp_dmabytes <= 0) { vdp_dmabytes = 0; @@ -90,8 +95,7 @@ EVENT_NEWLINE: cpu68k_clocks, vdp_event_hdisplay, vdp_line - vdp_visstartline, vdp_reg[10], vdp_hskip_countdown)); - if (vdp_line >= vdp_visstartline-1 && vdp_line < vdp_visendline-1) - ui_line(vdp_line - vdp_visstartline + 1); + ui_line(vdp_line - vdp_visstartline + 1); if ((vdp_nextevent = vdp_event_end - cpu68k_clocks) > 0) break; /* vdp_event++; - not required, we set vdp_event to 0 below */ @@ -99,31 +103,32 @@ EVENT_NEWLINE: /* end of line, do sound, platform stuff */ LOG_DEBUG1(("%08X due %08X, %d E: %d (cd=%d)", cpu68k_clocks, vdp_event_end, - vdp_line-vdp_visstartline, vdp_reg[10], + vdp_line - vdp_visstartline, vdp_reg[10], vdp_hskip_countdown)); if (vdp_line >= vdp_visstartline && vdp_line < vdp_visendline) vdp_hblank = 0; cpuz80_sync(); - sound_process(); + sound_line(); vdp_line++; if (vdp_line == vdp_visendline) cpuz80_interrupt(); if (vdp_line == vdp_totlines) { + /* the order of these is important */ + sound_endfield(); /* must be before ui_endfield for GYM log */ ui_endfield(); - sound_endfield(); - vdp_endfield(); + vdp_endfield(); /* must be after ui_endfield as it alters state */ cpuz80_endfield(); cpu68k_endfield(); cpu68k_frames++; } - vdp_event_start+= vdp_clksperline_68k; - vdp_event_vint+= vdp_clksperline_68k; - vdp_event_hint+= vdp_clksperline_68k; - vdp_event_hdisplay+= vdp_clksperline_68k; - vdp_event_end+= vdp_clksperline_68k; + vdp_event_start += vdp_clksperline_68k; + vdp_event_vint += vdp_clksperline_68k; + vdp_event_hint += vdp_clksperline_68k; + vdp_event_hdisplay += vdp_clksperline_68k; + vdp_event_end += vdp_clksperline_68k; vdp_event = 1; goto EVENT_NEWLINE; - } /* switch */ + } /* switch */ } /*** event_doframe - execute until the end of the current frame ***/ @@ -136,7 +141,8 @@ void event_doframe(void) while (vdp_nextevent > 0) vdp_nextevent = -reg68k_external_execute(vdp_nextevent); event_nextevent(); - } while (startframe == cpu68k_frames); + } + while (startframe == cpu68k_frames); } @@ -145,7 +151,7 @@ void event_doframe(void) void event_dostep(void) { /* execute one instruction and subtract from vdp_nextevent those cycles */ - vdp_nextevent-= reg68k_external_step(); + vdp_nextevent -= reg68k_external_step(); /* if negative or 0, i.e. we have done all the cycles we need to this event, call event_nextevent! */ while (vdp_nextevent <= 0) @@ -163,7 +169,6 @@ void event_dostep(void) void event_freeze_clocks(unsigned int clocks) { - int old_nextevent = vdp_nextevent; int missed = 0; /* first - fix vdp_nextevent to be correct for right now, due to block @@ -175,23 +180,23 @@ void event_freeze_clocks(unsigned int cl switch (vdp_event) { case 0: missed = vdp_nextevent - (vdp_event_start - cpu68k_clocks); - vdp_nextevent-= missed; + vdp_nextevent -= missed; break; case 1: missed = vdp_nextevent - (vdp_event_vint - cpu68k_clocks); - vdp_nextevent-= missed; + vdp_nextevent -= missed; break; case 2: missed = vdp_nextevent - (vdp_event_hint - cpu68k_clocks); - vdp_nextevent-= missed; + vdp_nextevent -= missed; break; case 3: missed = vdp_nextevent - (vdp_event_hdisplay - cpu68k_clocks); - vdp_nextevent-= missed; + vdp_nextevent -= missed; break; case 4: missed = vdp_nextevent - (vdp_event_end - cpu68k_clocks); - vdp_nextevent-= missed; + vdp_nextevent -= missed; break; default: printf("assertion failed: bad vdp_event in event_freeze_clocks: %d\n", @@ -200,8 +205,8 @@ void event_freeze_clocks(unsigned int cl /* move cpu68k_clocks and vdp_nextevent forward in time */ - cpu68k_clocks+= clocks; - vdp_nextevent-= clocks; + cpu68k_clocks += clocks; + vdp_nextevent -= clocks; /* now catch up events */ @@ -211,7 +216,7 @@ void event_freeze_clocks(unsigned int cl /* and then un-adjust vdp_nextevent, as the block marking code will update this later */ - vdp_nextevent+= missed; + vdp_nextevent += missed; } /*** event_freeze - freeze 68k for given VDP byte transfer ***/ @@ -223,27 +228,27 @@ void event_freeze(unsigned int bytes) double percent_possible; int togo = (int)bytes; - cpu68k_frozen = 1; /* prohibit interrupts since PC is not known in the - middle of a 68k block due to register mappings */ + cpu68k_frozen = 1; /* prohibit interrupts since PC is not known in the + middle of a 68k block due to register mappings */ while (togo > 0) { /* clocks will be negative if we're in the middle of a cpu block */ clocks = vdp_event_end - cpu68k_clocks; if (clocks < 0) clocks = 0; - percent_possible = clocks/vdp_clksperline_68k; - if (vdp_reg[1] & 1<<6 && !vdp_vblank) { + percent_possible = clocks / vdp_clksperline_68k; + if (vdp_reg[1] & 1 << 6 && !vdp_vblank) { /* vdp active */ - possible = (unsigned int)(percent_possible*(wide ? 18 : 16)); + possible = (unsigned int)(percent_possible * (wide ? 18 : 16)); } else { /* vdp inactive */ - possible = (unsigned int)(percent_possible*(wide ? 205 : 167)); + possible = (unsigned int)(percent_possible * (wide ? 205 : 167)); } if (togo >= possible) { event_freeze_clocks(clocks); - togo-= possible; + togo -= possible; } else { - event_freeze_clocks(((double)togo/possible)*clocks); + event_freeze_clocks(((double)togo / possible) * clocks); togo = 0; } }