Annotation of generator/main/reg68k.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 "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.