Annotation of generator/src/event.c, revision 1.1.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.