Annotation of generator/src/reg68k.c, revision 1.1.1.2

1.1.1.2 ! root        1: /* Generator is (c) James Ponder, 1997-2001 http://www.squish.net/generator/ */
1.1       root        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: 
1.1.1.2 ! root       11: #include "reg68k.h"
1.1       root       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: 
1.1.1.2 ! root       32: /*** reg68k_external_step - execute one instruction ***/
1.1       root       33: 
1.1.1.2 ! root       34: unsigned int reg68k_external_step(void)
1.1       root       35: {
                     36:   static t_ipc ipc;
                     37:   static t_iib *piib;
                     38:   jmp_buf jb;
1.1.1.2 ! root       39:   static unsigned int clks;
        !            40: 
        !            41:   if (!(piib = cpu68k_iibtable[fetchword(regs.pc)]))
        !            42:     ui_err("Invalid instruction @ %08X\n", regs.pc);
1.1       root       43: 
                     44:   /* !!! entering global register usage area !!! */
                     45: 
                     46:   if (!setjmp(jb)) {
1.1.1.2 ! root       47:     /* move PC and register block into global processor register variables */
1.1       root       48:     reg68k_pc = regs.pc;
                     49:     reg68k_regs = regs.regs;
                     50:     reg68k_sr = regs.sr;
                     51: 
1.1.1.2 ! root       52:     if (regs.pending && ((reg68k_sr.sr_int >> 8) & 7) < regs.pending)
        !            53:       reg68k_internal_autovector(regs.pending);
        !            54: 
1.1       root       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:     cpu68k_clocks+= piib->clocks;
1.1.1.2 ! root       60:     clks = cpu68k_clocks;
1.1       root       61:     /* restore global registers back to permanent storage */
                     62:     regs.pc = reg68k_pc;
                     63:     regs.sr = reg68k_sr;
                     64:     longjmp(jb, 1);
                     65:   }
1.1.1.2 ! root       66:   return clks; /* number of clocks done */
1.1       root       67: }
                     68: 
1.1.1.2 ! root       69: /*** reg68k_external_execute - execute at least given number of clocks,
        !            70:      and return number of clocks executed too much (-ve) ***/
1.1       root       71: 
1.1.1.2 ! root       72: unsigned int reg68k_external_execute(unsigned int clocks)
1.1       root       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;
1.1.1.2 ! root       81:   static int clks;
        !            82: 
        !            83:   clks = clocks;
1.1       root       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: 
1.1.1.2 ! root       91:     if (regs.pending && ((reg68k_sr.sr_int >> 8) & 7) < regs.pending)
        !            92:       reg68k_internal_autovector(regs.pending);
        !            93: 
1.1       root       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:          cpu68k_ipc(reg68k_pc,
                    101:                     mem68k_memptr[(reg68k_pc>>12) &
                    102:                                  0xfff](reg68k_pc & 0xFFFFFF),
                    103:                     step_piib, &step_ipc);
                    104:          cpu68k_functable[fetchword(reg68k_pc)*2+1](&step_ipc);
1.1.1.2 ! root      105:          clks-= step_piib->clocks;
1.1       root      106:          cpu68k_clocks+= step_piib->clocks;
                    107:        } while (!step_piib->flags.endblk);
                    108:        list = NULL; /* stop compiler warning ;(  */
                    109:       } else {
                    110:        index = (pc24>>1) & (LEN_IPCLISTTABLE-1);
                    111:        list = ipclist[index];
                    112:        while(list && (list->pc != pc24)) {
                    113:          list = list->next;
                    114:        }
                    115: #ifdef PROCESSOR_ARM
                    116:        if (!list) {
                    117:          list = cpu68k_makeipclist(pc24);
                    118:          list->next = ipclist[index];
                    119:          ipclist[index] = list;
                    120:          list->compiled = compile_make(list);
                    121:        }
                    122:        list->compiled((t_ipc *)(list+1));
                    123: #else
                    124:        if (!list) {
                    125:          /* LOG_USER(("Making IPC list @ %08x", pc24)); */
                    126:          list = cpu68k_makeipclist(pc24);
                    127:          list->next = ipclist[index];
                    128:          ipclist[index] = list;
                    129:        }
                    130:        ipc = (t_ipc *)(list+1);
                    131:        do {
                    132:          ipc->function(ipc);
                    133:          ipc++;
                    134:        } while (*(int *)ipc);
                    135: #endif
1.1.1.2 ! root      136:        clks-= list->clocks;
1.1       root      137:        cpu68k_clocks+= list->clocks;
                    138:       }
1.1.1.2 ! root      139:     } while (clks > 0);
1.1       root      140:     /* restore global registers back to permanent storage */
                    141:     regs.pc = reg68k_pc;
                    142:     regs.sr = reg68k_sr;
                    143:     longjmp(jb, 1);
                    144:   }
1.1.1.2 ! root      145:   return -clks; /* i.e. number of clocks done too much */
1.1       root      146: }
                    147: 
1.1.1.2 ! root      148: /*** reg68k_external_autovector - for external use ***/
        !           149: 
        !           150: void reg68k_external_autovector(int avno)
        !           151: {
        !           152:   jmp_buf jb;
        !           153: 
        !           154:   if (!setjmp(jb)) {
        !           155:     /* move PC and register block into global processor register variables */
        !           156:     reg68k_pc = regs.pc;
        !           157:     reg68k_regs = regs.regs;
        !           158:     reg68k_sr = regs.sr;
        !           159: 
        !           160:     reg68k_internal_autovector(avno);
        !           161: 
        !           162:     /* restore global registers back to permanent storage */
        !           163:     regs.pc = reg68k_pc;
        !           164:     regs.sr = reg68k_sr;
        !           165:     longjmp(jb, 1);
        !           166:   }
        !           167: }
        !           168: 
        !           169: /*** reg68k_internal_autovector - go to autovector - this call assumes global
        !           170:      registers are already setup ***/
        !           171: 
        !           172: void reg68k_internal_autovector(int avno)
1.1       root      173: {
                    174:   int curlevel = (reg68k_sr.sr_int>>8) & 7;
                    175:   uint32 tmpaddr;
                    176: 
1.1.1.2 ! root      177:   LOG_DEBUG1(("autovector %d", avno));
1.1       root      178:   if (curlevel < avno || avno == 7) {
1.1.1.2 ! root      179:     if (regs.stop) {
        !           180:       LOG_DEBUG1(("stop finished"));
        !           181:       /* autovector whilst in a STOP instruction */
        !           182:       reg68k_pc+= 4;
        !           183:       regs.stop = 0;
        !           184:     }
1.1       root      185:     if (!reg68k_sr.sr_struct.s) {
                    186:       regs.regs[15]^= regs.sp;   /* swap A7 and SP */
                    187:       regs.sp^= regs.regs[15];
                    188:       regs.regs[15]^= regs.sp;
                    189:       reg68k_sr.sr_struct.s = 1;
                    190:     }
                    191:     regs.regs[15]-=4;
                    192:     storelong(regs.regs[15], reg68k_pc);
                    193:     regs.regs[15]-=2;
                    194:     storeword(regs.regs[15], reg68k_sr.sr_int);
                    195:     reg68k_sr.sr_struct.t = 0;
                    196:     reg68k_sr.sr_int&= ~0x0700;
                    197:     reg68k_sr.sr_int|= avno << 8;
                    198:     tmpaddr = reg68k_pc;
                    199:     reg68k_pc = fetchlong((V_AUTO+avno-1)*4);
                    200:     LOG_DEBUG1(("AUTOVECTOR %d: %X -> %X", avno, tmpaddr, reg68k_pc));
1.1.1.2 ! root      201:     regs.pending = 0;
        !           202:   } else {
        !           203:     LOG_DEBUG1(("%08X autovector %d pending", reg68k_pc, avno));
        !           204:     regs.pending = avno;
1.1       root      205:   }
                    206: }
                    207: 
1.1.1.2 ! root      208: /*** reg68k_internal_vector - go to vector - this call assumes global
        !           209:      registers are already setup ***/
        !           210: 
        !           211: void reg68k_internal_vector(int vno, uint32 oldpc)
1.1       root      212: {
                    213:   LOG_DEBUG1(("Vector %d called from %8x!", vno, regs.pc));
                    214:   if (!reg68k_sr.sr_struct.s) {
                    215:     regs.regs[15]^= regs.sp;   /* swap A7 and SP */
                    216:     regs.sp^= regs.regs[15];
                    217:     regs.regs[15]^= regs.sp;
                    218:     reg68k_sr.sr_struct.s = 1;
                    219:   }
                    220:   regs.regs[15]-=4;
                    221:   storelong(regs.regs[15], oldpc);
                    222:   regs.regs[15]-=2;
                    223:   storeword(regs.regs[15], reg68k_sr.sr_int);
                    224:   reg68k_pc = fetchlong(vno*4);
                    225:   LOG_DEBUG1(("VECTOR %d: %X -> %X\n", vno, oldpc, reg68k_pc));
                    226: }   

unix.superglobalmegacorp.com

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