Annotation of generator/src/event.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.