Annotation of generator/main/reg68k.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 "registers.h"
                      5: 
                      6: #include <stdio.h>
                      7: #include <string.h>
                      8: #include <stdlib.h>
                      9: #include <setjmp.h>
                     10: 
                     11: #include "reg68k.h"
                     12: #include "mem68k.h"
                     13: #include "cpu68k.h"
                     14: #include "cpuz80.h"
                     15: #include "vdp.h"
                     16: #include "ui.h"
                     17: #include "compile.h"
                     18: #include "gensound.h"
                     19: 
                     20: /*** externed variables ***/
                     21: 
                     22: #if (!(defined(PROCESSOR_ARM) || defined(PROCESSOR_SPARC) \
                     23:        || defined(PROCESSOR_INTEL)))
                     24:   uint32 reg68k_pc;
                     25:   uint32 *reg68k_regs;
                     26:   t_sr reg68k_sr;
                     27: #endif
                     28: 
                     29: /*** forward references ***/
                     30: 
                     31: 
                     32: /*** reg68k_external_step - execute one instruction ***/
                     33: 
                     34: unsigned int reg68k_external_step(void)
                     35: {
                     36:   static t_ipc ipc;
                     37:   static t_iib *piib;
                     38:   jmp_buf jb;
                     39:   static unsigned int clks;
                     40: 
                     41:   /* !!! entering global register usage area !!! */
                     42: 
                     43:   if (!setjmp(jb)) {
                     44:     /* move PC and register block into global processor register variables */
                     45:     reg68k_pc = regs.pc;
                     46:     reg68k_regs = regs.regs;
                     47:     reg68k_sr = regs.sr;
                     48: 
                     49:     if (regs.pending && ((reg68k_sr.sr_int >> 8) & 7) < regs.pending)
                     50:       reg68k_internal_autovector(regs.pending);
                     51: 
                     52:     if (!(piib = cpu68k_iibtable[fetchword(reg68k_pc)]))
                     53:       ui_err("Invalid instruction @ %08X\n", reg68k_pc);
                     54: 
                     55:     cpu68k_ipc(reg68k_pc,
                     56:               mem68k_memptr[(reg68k_pc>>12) & 0xfff](reg68k_pc & 0xFFFFFF),
                     57:               piib, &ipc);
                     58:     cpu68k_functable[fetchword(reg68k_pc)*2+1](&ipc);
                     59:     clks = piib->clocks; 
                     60:     /* restore global registers back to permanent storage */
                     61:     regs.pc = reg68k_pc;
                     62:     regs.sr = reg68k_sr;
                     63:     longjmp(jb, 1);
                     64:   }
                     65:   cpu68k_clocks+= clks;
                     66:   return clks; /* number of clocks done */
                     67: }
                     68: 
                     69: /*** reg68k_external_execute - execute at least given number of clocks,
                     70:      and return number of clocks executed too much ***/
                     71: 
                     72: unsigned int reg68k_external_execute(unsigned int clocks)
                     73: {
                     74:   unsigned int index, i;
                     75:   t_ipclist *list;
                     76:   t_ipc *ipc;
                     77:   uint32 pc24;
                     78:   jmp_buf jb;
                     79:   static t_ipc step_ipc;
                     80:   static t_iib *step_piib;
                     81:   static int clks;
                     82: 
                     83:   clks = clocks;
                     84: 
                     85:   if (!setjmp(jb)) {
                     86:     /* move PC and register block into global variables */
                     87:     reg68k_pc = regs.pc;
                     88:     reg68k_regs = regs.regs;
                     89:     reg68k_sr = regs.sr;
                     90: 
                     91:     if (regs.pending && ((reg68k_sr.sr_int >> 8) & 7) < regs.pending)
                     92:       reg68k_internal_autovector(regs.pending);
                     93: 
                     94:     do {
                     95:       pc24 = reg68k_pc & 0xffffff;
                     96:       if ((pc24 & 0xff0000) == 0xff0000) {
                     97:        /* executing code from RAM, do not use compiled information */
                     98:        do {
                     99:          step_piib = cpu68k_iibtable[fetchword(reg68k_pc)];
                    100:           if (!step_piib)
                    101:             ui_err("Invalid instruction (iib assert) @ %08X\n", reg68k_pc);
                    102:          cpu68k_ipc(reg68k_pc,
                    103:                     mem68k_memptr[(reg68k_pc>>12) &
                    104:                                  0xfff](reg68k_pc & 0xFFFFFF),
                    105:                     step_piib, &step_ipc);
                    106:          cpu68k_functable[fetchword(reg68k_pc)*2+1](&step_ipc);
                    107:          clks-= step_piib->clocks;
                    108:          cpu68k_clocks+= step_piib->clocks;
                    109:        } while (!step_piib->flags.endblk);
                    110:        list = NULL; /* stop compiler warning ;(  */
                    111:       } else {
                    112:        index = (pc24>>1) & (LEN_IPCLISTTABLE-1);
                    113:        list = ipclist[index];
                    114:        while(list && (list->pc != pc24)) {
                    115:          list = list->next;
                    116:        }
                    117: #ifdef PROCESSOR_ARM
                    118:        if (!list) {
                    119:          list = cpu68k_makeipclist(pc24);
                    120:          list->next = ipclist[index];
                    121:          ipclist[index] = list;
                    122:          list->compiled = compile_make(list);
                    123:        }
                    124:        list->compiled((t_ipc *)(list+1));
                    125: #else
                    126:        if (!list) {
                    127:          /* LOG_USER(("Making IPC list @ %08x", pc24)); */
                    128:          list = cpu68k_makeipclist(pc24);
                    129:          list->next = ipclist[index];
                    130:          ipclist[index] = list;
                    131:        }
                    132:        ipc = (t_ipc *)(list+1);
                    133:        do {
                    134:          ipc->function(ipc);
                    135:          ipc++;
                    136:        } while (*(int *)ipc);
                    137: #endif
                    138:        clks-= list->clocks;
                    139:        cpu68k_clocks+= list->clocks;
                    140:       }
                    141:     } while (clks > 0);
                    142:     /* restore global registers back to permanent storage */
                    143:     regs.pc = reg68k_pc;
                    144:     regs.sr = reg68k_sr;
                    145:     longjmp(jb, 1);
                    146:   }
                    147:   return -clks; /* i.e. number of clocks done too much */
                    148: }
                    149: 
                    150: /*** reg68k_external_autovector - for external use ***/
                    151: 
                    152: void reg68k_external_autovector(int avno)
                    153: {
                    154:   jmp_buf jb;
                    155: 
                    156:   if (!setjmp(jb)) {
                    157:     /* move PC and register block into global processor register variables */
                    158:     reg68k_pc = regs.pc;
                    159:     reg68k_regs = regs.regs;
                    160:     reg68k_sr = regs.sr;
                    161: 
                    162:     reg68k_internal_autovector(avno);
                    163: 
                    164:     /* restore global registers back to permanent storage */
                    165:     regs.pc = reg68k_pc;
                    166:     regs.sr = reg68k_sr;
                    167:     longjmp(jb, 1);
                    168:   }
                    169: }
                    170: 
                    171: /*** reg68k_internal_autovector - go to autovector - this call assumes global
                    172:      registers are already setup ***/
                    173: 
                    174: /* interrupts must not occur during cpu68k_frozen, as this flag indicates
                    175:    that we are catching up events due to a dma transfer.  Since the dma
                    176:    transfer is triggered by a memory write at which stage the current value
                    177:    of the PC is not written anywhere (due to being in the middle of a 68k
                    178:    block and it's in a local register), we MUST NOT use regs.pc - this
                    179:    routine uses reg68k_pc but this is loaded by reg68k_external_autovector,
                    180:    which is called by event_nextevent() and therefore will be a *WRONG*
                    181:    reg68k_pc! */
                    182: 
                    183: void reg68k_internal_autovector(int avno)
                    184: {
                    185:   int curlevel = (reg68k_sr.sr_int>>8) & 7;
                    186:   uint32 tmpaddr;
                    187: 
                    188:   if ((curlevel < avno || avno == 7) && !cpu68k_frozen) {
                    189:     if (regs.stop) {
                    190:       LOG_DEBUG1(("stop finished"));
                    191:       /* autovector whilst in a STOP instruction */
                    192:       reg68k_pc+= 4;
                    193:       regs.stop = 0;
                    194:     }
                    195:     if (!reg68k_sr.sr_struct.s) {
                    196:       regs.regs[15]^= regs.sp;   /* swap A7 and SP */
                    197:       regs.sp^= regs.regs[15];
                    198:       regs.regs[15]^= regs.sp;
                    199:       reg68k_sr.sr_struct.s = 1;
                    200:     }
                    201:     regs.regs[15]-=4;
                    202:     storelong(regs.regs[15], reg68k_pc);
                    203:     regs.regs[15]-=2;
                    204:     storeword(regs.regs[15], reg68k_sr.sr_int);
                    205:     reg68k_sr.sr_struct.t = 0;
                    206:     reg68k_sr.sr_int&= ~0x0700;
                    207:     reg68k_sr.sr_int|= avno << 8;
                    208:     tmpaddr = reg68k_pc;
                    209:     reg68k_pc = fetchlong((V_AUTO+avno-1)*4);
                    210:     /* LOG_USER(("AUTOVECTOR %d: %X -> %X", avno, tmpaddr, reg68k_pc)); */
                    211:     regs.pending = 0;
                    212:   } else {
                    213:     /* LOG_USER(("%08X autovector %d pending", reg68k_pc, avno)); */
                    214:     regs.pending = avno;
                    215:   }
                    216: }
                    217: 
                    218: /*** reg68k_internal_vector - go to vector - this call assumes global
                    219:      registers are already setup ***/
                    220: 
                    221: void reg68k_internal_vector(int vno, uint32 oldpc)
                    222: {
                    223:   if (!reg68k_sr.sr_struct.s) {
                    224:     reg68k_regs[15]^= regs.sp;   /* swap A7 and SP */
                    225:     regs.sp^= reg68k_regs[15];
                    226:     reg68k_regs[15]^= regs.sp;
                    227:     reg68k_sr.sr_struct.s = 1;
                    228:   }
                    229:   reg68k_regs[15]-=4;
                    230:   storelong(reg68k_regs[15], oldpc);
                    231:   reg68k_regs[15]-=2;
                    232:   storeword(reg68k_regs[15], reg68k_sr.sr_int);
                    233:   reg68k_pc = fetchlong(vno*4);
                    234:   /* LOG_USER(("VECTOR %d: %X -> %X\n", vno, oldpc, reg68k_pc)); */
                    235: }   

unix.superglobalmegacorp.com

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