📄 m68k-stub.c
字号:
movel a0,a1 /* copy save pointer */ subql #1,d0 /* predecrement loop counter */## copy the framesaveFrameLoop: movew sp@+,a1@+ dbf d0,saveFrameLoop## now that the stack has been clenaed,# save the a7 in use at time of exception movel sp,_superStack /* save supervisor sp */ andiw #0x2000,d1 /* were we in supervisor mode ? */ beq userMode movel a7,a5@(60) /* save a7 */ bra a7saveDoneuserMode: movel usp,a1 movel a1,a5@(60) /* save user stack pointer */a7saveDone:## save size of frame movew d3,a0@-## compute exception number andl #0xfff,d2 /* mask off vector offset */ lsrw #2,d2 /* divide by 4 to get vect num */ movel d2,a0@- /* save it */## save pc causing exception movel a4,a0@-## save old frame link and set the new value movel _lastFrame,a1 /* last frame pointer */ movel a1,a0@- /* save pointer to prev frame */ movel a0,_lastFrame movel d2,sp@- /* push exception num */ movel _exceptionHook,a0 /* get address of handler */ jbsr a0@ /* and call it */ clrl sp@ /* replace exception num parm with frame ptr */ jbsr __returnFromException /* jbsr, but never returns */");#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(".text.globl __catchException__catchException:");DISABLE_INTERRUPTS();asm(" moveml d0-d7/a0-a6,_registers /* save registers */ movel _lastFrame,a0 /* last frame pointer */");SAVE_FP_REGS(); asm(" lea _registers,a5 /* get address of registers */ movel sp@+,d2 /* pop return address */ addl #1530,d2 /* convert return addr to */ divs #6,d2 /* exception number */ extl d2 moveql #3,d3 /* assume a three word frame */ cmpiw #3,d2 /* bus error or address error ? */ bgt normal /* if >3 then normal error */ movel sp@+,a0@- /* copy error info to frame buff*/ movel sp@+,a0@- /* these are never used */ moveql #7,d3 /* this is a 7 word frame */ normal: movew sp@+,d1 /* pop status register */ movel sp@+,a4 /* pop program counter */ movew d1,a5@(66) /* save sr */ movel a4,a5@(68) /* save pc in _regisers[] */ movel a4,a0@- /* copy pc to frame buffer */ movew d1,a0@- /* copy sr to frame buffer */ movel sp,_superStack /* save supervisor sp */ andiw #0x2000,d1 /* were we in supervisor mode ? */ beq userMode movel a7,a5@(60) /* save a7 */ bra saveDone userMode: movel usp,a1 /* save user stack pointer */ movel a1,a5@(60) /* save user stack pointer */saveDone: movew d3,a0@- /* push frame size in words */ movel d2,a0@- /* push vector number */ movel a4,a0@- /* push exception pc */## save old frame link and set the new value movel _lastFrame,a1 /* last frame pointer */ movel a1,a0@- /* save pointer to prev frame */ movel a0,_lastFrame movel d2,sp@- /* push exception num */ movel _exceptionHook,a0 /* get address of handler */ jbsr a0@ /* and call it */ clrl sp@ /* replace exception num parm with frame ptr */ jbsr __returnFromException /* jbsr, but never returns */");#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*/ }#ifndef 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(ch)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(buffer)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()) != '$'); checksum = 0; xmitcsum = -1; count = 0; /* now, read until a # or end of buffer is found */ while (count < BUFMAX) { ch = getDebugChar(); if (ch == '#') break; checksum = checksum + ch; buffer[count] = ch; count = count + 1; } buffer[count] = 0; if (ch == '#') { xmitcsum = hex(getDebugChar()) << 4; xmitcsum += hex(getDebugChar()); if ((remote_debug ) && (checksum != xmitcsum)) { fprintf(stderr,"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. */void putpacket(buffer)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;void debug_error(format, parm)char * format;char * parm;{ if (remote_debug) fprintf(stderr,format,parm);}/* 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(mem, buf, count)char* mem;char* buf;int count;{ int i; unsigned char ch; 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(buf, mem, count)char* buf;char* mem;int count;{ int i; unsigned char ch; 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( exceptionVector )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 + -