📄 m68k-stub.c
字号:
.align 4\n\_catchException:\n\");DISABLE_INTERRUPTS();asm("\n\ moveml %d0-%d7/%a0-%a6,registers /* save registers */\n\ movel lastFrame,%a0 /* last frame pointer */\n\");SAVE_FP_REGS(); asm("\n\ lea registers,%a5 /* get address of registers */\n\ movew %sp@,%d1 /* get status register */\n\ movew %d1,%a5@(66) /* save sr */ \n\ movel %sp@(2),%a4 /* save pc in %a4 for later use */\n\ movel %a4,%a5@(68) /* save pc in _regisers[] */\n\\n\#\n\# figure out how many bytes in the stack frame\n\#\n\ movew %sp@(6),%d0 /* get '020 exception format */\n\ movew %d0,%d2 /* make a copy of format word */\n\ andiw #0xf000,%d0 /* mask off format type */\n\ rolw #5,%d0 /* rotate into the low byte *2 */\n\ lea exceptionSize,%a1 \n\ addw %d0,%a1 /* index into the table */\n\ movew %a1@,%d0 /* get number of words in frame */\n\ movew %d0,%d3 /* save it */\n\ subw %d0,%a0 /* adjust save pointer */\n\ subw %d0,%a0 /* adjust save pointer(bytes) */\n\ movel %a0,%a1 /* copy save pointer */\n\ subql #1,%d0 /* predecrement loop counter */\n\#\n\# copy the frame\n\#\n\saveFrameLoop:\n\ movew %sp@+,%a1@+\n\ dbf %d0,saveFrameLoop\n\#\n\# now that the stack has been clenaed,\n\# save the %a7 in use at time of exception\n\\n\ movel %sp,superStack /* save supervisor %sp */\n\ andiw #0x2000,%d1 /* were we in supervisor mode ? */\n\ beq userMode \n\ movel %a7,%a5@(60) /* save %a7 */\n\ bra a7saveDone\n\userMode: \n\ movel %usp,%a1 \n\ movel %a1,%a5@(60) /* save user stack pointer */\n\a7saveDone:\n\\n\#\n\# save size of frame\n\ movew %d3,%a0@-\n\\n\#\n\# compute exception number\n\ andl #0xfff,%d2 /* mask off vector offset */\n\ lsrw #2,%d2 /* divide by 4 to get vect num */\n\ movel %d2,%a0@- /* save it */\n\#\n\# save pc causing exception\n\ movel %a4,%a0@-\n\#\n\# save old frame link and set the new value\n\ movel lastFrame,%a1 /* last frame pointer */\n\ movel %a1,%a0@- /* save pointer to prev frame */\n\ movel %a0,lastFrame\n\\n\ movel %d2,%sp@- /* push exception num */\n\ movel exceptionHook,%a0 /* get address of handler */\n\ jbsr %a0@ /* and call it */\n\ clrl %sp@ /* replace exception num parm with frame ptr */\n\ jbsr _returnFromException /* jbsr, but never returns */\n\\n\");#else /* mc68000 *//* This function is called when an exception occurs. It translates the * return address found on the stack into an exception vector # which * is then handled by either handle_exception or a system handler. * _catchException provides a front end for both. * * stack on entry: stack on exit: * Program counter MSWord exception # MSWord * Program counter LSWord exception # MSWord * Status Register * Return Address MSWord * Return Address LSWord */asm("\n\ .text\n\ .globl _catchException\n\ .align 4\n\_catchException:\n\");DISABLE_INTERRUPTS();asm("\n\ moveml %d0-%d7/%a0-%a6,registers /* save registers */\n\ movel lastFrame,%a0 /* last frame pointer */\n\");SAVE_FP_REGS(); asm("\n\ moveq.l #0,%d2\n\ movew %sp@+,%d2\n\ lea registers,%a5 /* get address of registers */\n\\n\ moveql #3,%d3 /* assume a three word frame */\n\\n\ cmpiw #3,%d2 /* bus error or address error ? */\n\ bgt normal /* if >3 then normal error */\n\ movel %sp@+,%a0@- /* copy error info to frame buff*/\n\ movel %sp@+,%a0@- /* these are never used */\n\ moveql #7,%d3 /* this is a 7 word frame */\n\ \n\normal: \n\ movew %sp@+,%d1 /* pop status register */\n\ movel %sp@+,%a4 /* pop program counter */\n\\n\ cmpiw #33,%d2 /* trap #1, breakpoint ? */\n\ bne not_breakpoint\n\\n\ subql #2,%a4 /* trap leaves the pc after the trap */\n\\n\not_breakpoint:\n\ movew %d1,%a5@(66) /* save sr */ \n\ movel %a4,%a5@(68) /* save pc in _regisers[] */\n\ movel %a4,%a0@- /* copy pc to frame buffer */\n\ movew %d1,%a0@- /* copy sr to frame buffer */\n\\n\ movel %sp,superStack /* save supervisor %sp */\n\\n\ andiw #0x2000,%d1 /* were we in supervisor mode ? */\n\ beq userMode \n\ movel %a7,%a5@(60) /* save %a7 */\n\ bra saveDone \n\userMode:\n\ movel %usp,%a1 /* save user stack pointer */\n\ movel %a1,%a5@(60) /* save user stack pointer */\n\saveDone:\n\\n\ movew %d3,%a0@- /* push frame size in words */\n\ movel %d2,%a0@- /* push vector number */\n\ movel %a4,%a0@- /* push exception pc */\n\\n\#\n\# save old frame link and set the new value\n\#\n\ movel lastFrame,%a1 /* last frame pointer */\n\ movel %a1,%a0@- /* save pointer to prev frame */\n\ movel %a0,lastFrame\n\\n\ movel %d2,%sp@- /* push exception num */\n\ movel exceptionHook,%a0 /* get address of handler */\n\\n\ jbsr %a0@ /* and call it */\n\ clrl %sp@ /* replace exception num parm with frame ptr */\n\ jbsr _returnFromException /* jbsr, but never returns */\n\");#endif/* * remcomHandler is a front end for handle_exception. It moves the * stack pointer into an area reserved for debugger use in case the * breakpoint happened in supervisor mode. */asm("remcomHandler:");asm(" addl #4,%sp"); /* pop off return address */asm(" movel %sp@+,%d0"); /* get the exception number */asm(" movel stackPtr,%sp"); /* move to remcom stack area */asm(" movel %d0,%sp@-"); /* push exception onto stack */asm(" jbsr handle_exception"); /* this never returns */asm(" rts"); /* return */void _returnFromException(Frame *frame){ /* if no passed in frame, use the last one */ if (! frame) { frame = lastFrame; frame->frameSize = 4; frame->format = 0; frame->fsaveHeader = -1; /* restore regs, but we dont have fsave info*/ }#if defined(__mc68000__) && !defined(__mc68020__) /* a 68000 cannot use the internal info pushed onto a bus error * or address error frame when doing an RTE so don't put this info * onto the stack or the stack will creep every time this happens. */ frame->frameSize=3;#endif /* throw away any frames in the list after this frame */ lastFrame = frame; frame->sr = registers[(int) PS]; frame->pc = registers[(int) PC]; if (registers[(int) PS] & 0x2000) { /* return to supervisor mode... */ return_to_super(); } else { /* return to user mode */ return_to_user(); }}int hex(char ch){ if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10); if ((ch >= '0') && (ch <= '9')) return (ch-'0'); if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10); return (-1);}/* scan for the sequence $<data>#<checksum> */void getpacket(char *buffer){ unsigned char checksum; unsigned char xmitcsum; int i; int count; char ch; do { /* wait around for the start character, ignore all other characters */ while ((ch = (getDebugChar() & 0x7f)) != '$'); checksum = 0; xmitcsum = -1; count = 0; /* now, read until a # or end of buffer is found */ while (count < BUFMAX) { ch = getDebugChar() & 0x7f; if (ch == '#') break; checksum = checksum + ch; buffer[count] = ch; count = count + 1; } buffer[count] = 0; if (ch == '#') { xmitcsum = hex(getDebugChar() & 0x7f) << 4; xmitcsum += hex(getDebugChar() & 0x7f); if ((remote_debug ) && (checksum != xmitcsum)) { debug_port_printf ("bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n", checksum,xmitcsum,buffer); } if (checksum != xmitcsum) putDebugChar('-'); /* failed checksum */ else { putDebugChar('+'); /* successful transfer */ /* if a sequence char is present, reply the sequence ID */ if (buffer[2] == ':') { putDebugChar( buffer[0] ); putDebugChar( buffer[1] ); /* remove sequence chars from buffer */ count = strlen(buffer); for (i=3; i <= count; i++) buffer[i-3] = buffer[i]; } } } } while (checksum != xmitcsum); }/* send the packet in buffer. The host get's one chance to read it. This routine does not wait for a positive acknowledge. */voidputpacket(char *buffer){ unsigned char checksum; int count; char ch; /* $<packet info>#<checksum>. */ do { putDebugChar('$'); checksum = 0; count = 0; while ((ch=buffer[count])) { if (! putDebugChar(ch)) return; checksum += ch; count += 1; } putDebugChar('#'); putDebugChar(hexchars[checksum >> 4]); putDebugChar(hexchars[checksum % 16]); } while (1 == 0); /* (getDebugChar() != '+'); */ }char remcomInBuffer[BUFMAX];char remcomOutBuffer[BUFMAX];static short error;/* convert the memory pointed to by mem into hex, placing result in buf *//* return a pointer to the last char put in buf (null) */char *mem2hex(char *mem, char *buf, int count){ int i; unsigned char ch; if (remote_debug) debug_port_printf("mem=0x%x, count=0x%x\n", mem, count); for (i=0;i<count;i++) { ch = *mem++; *buf++ = hexchars[ch >> 4]; *buf++ = hexchars[ch % 16]; } *buf = 0; return(buf);}/* convert the hex array pointed to by buf into binary to be placed in mem *//* return a pointer to the character AFTER the last byte written */char *hex2mem(char *buf, char *mem, int count){ int i; unsigned char ch; if (remote_debug) debug_port_printf("mem=0x%x, count=0x%x\n", mem, count); for (i=0;i<count;i++) { ch = hex(*buf++) << 4; ch = ch + hex(*buf++); *mem++ = ch; } return(mem);}/* a bus error has occurred, perform a longjmp to return execution and allow handling of the error */void handle_buserror(){ longjmp(remcomEnv,1);}/* this function takes the 68000 exception number and attempts to translate this number into a unix compatible signal value */int computeSignal(int exceptionVector){ int sigval; switch (exceptionVector) { case 2 : sigval = 10; break; /* bus error */ case 3 : sigval = 10; break; /* address error */ case 4 : sigval = 4; break; /* illegal instruction */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -