typedef void (*ExceptionHook)(int); /* pointer to function with int parm */
typedef void (*Function)(); /* pointer to a function */
-extern putDebugChar(); /* write a single character */
-extern getDebugChar(); /* read and return a single char */
+extern void putDebugChar(); /* write a single character */
+extern int getDebugChar(); /* read and return a single char */
extern Function exceptionHandler(); /* assign an exception handler */
extern ExceptionHook exceptionHook; /* hook variable for errors/exceptions */
static ExceptionHook oldExceptionHook;
+#ifdef mc68020
/* the size of the exception stack on the 68020 varies with the type of
* exception. The following table is the number of WORDS used
* for each exception format.
*/
const short exceptionSize[] = { 4,4,6,4,4,4,4,4,29,10,16,46,12,4,4,4 };
+#endif
+
+#ifdef mc68332
+static const short exceptionSize[] = { 4,4,6,4,4,4,4,4,4,4,4,4,16,4,4,4 };
+#endif
/************* jump buffer used for setjmp/longjmp **************************/
jmp_buf remcomEnv;
.globl __debug_level7
__debug_level7:
movew d0,sp@-");
-#ifdef mc68020
+#if defined (mc68020) || defined (mc68332)
asm(" movew sp@(2),d0");
#else
asm(" movew sp@(6),d0");
bra __catchException
_already7:
movew sp@+,d0");
-#ifndef mc68020
+#if !defined (mc68020) && !defined (mc68332)
asm(" lea sp@(4),sp"); /* pull off 68000 return address */
#endif
asm(" rte");
extern void _catchException ();
-#ifdef mc68020
+#if defined (mc68020) || defined (mc68332)
/* This function is called when a 68020 exception occurs. It saves
* all the cpu and fpcp regs in the _registers array, creates a frame on a
* linked list of frames which has the cpu and fpcp stack frames needed
frame->fsaveHeader = -1; /* restore regs, but we dont have fsave info*/
}
-#ifndef mc68020
+#if !defined (mc68020) && !defined (mc68332)
/* 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.
return (-1);
}
+static char remcomInBuffer[BUFMAX];
+static char remcomOutBuffer[BUFMAX];
/* scan for the sequence $<data>#<checksum> */
-void getpacket(buffer)
-char * buffer;
+
+unsigned char *
+getpacket ()
{
+ unsigned char *buffer = &remcomInBuffer[0];
unsigned char checksum;
unsigned char xmitcsum;
- int i;
- int count;
+ 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);
-
+
+ while (1)
+ {
+ /* wait around for the start character, ignore all other characters */
+ while ((ch = getDebugChar ()) != '$')
+ ;
+
+retry:
+ checksum = 0;
+ xmitcsum = -1;
+ count = 0;
+
+ /* now, read until a # or end of buffer is found */
+ while (count < BUFMAX)
+ {
+ ch = getDebugChar ();
+ if (ch == '$')
+ goto retry;
+ if (ch == '#')
+ break;
+ checksum = checksum + ch;
+ buffer[count] = ch;
+ count = count + 1;
+ }
+ buffer[count] = 0;
+
+ if (ch == '#')
+ {
+ ch = getDebugChar ();
+ xmitcsum = hex (ch) << 4;
+ ch = getDebugChar ();
+ xmitcsum += hex (ch);
+
+ if (checksum != xmitcsum)
+ {
+ if (remote_debug)
+ {
+ fprintf (stderr,
+ "bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n",
+ checksum, xmitcsum, buffer);
+ }
+ 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]);
+
+ return &buffer[3];
+ }
+
+ return &buffer[0];
+ }
+ }
+ }
}
-/* send the packet in buffer. The host get's one chance to read it.
- This routine does not wait for a positive acknowledge. */
+/* send the packet in buffer. */
void putpacket(buffer)
count = 0;
while (ch=buffer[count]) {
- if (! putDebugChar(ch)) return;
+ putDebugChar(ch);
checksum += ch;
count += 1;
}
putDebugChar(hexchars[checksum >> 4]);
putDebugChar(hexchars[checksum % 16]);
- } while (1 == 0); /* (getDebugChar() != '+'); */
+ } while (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);
+ if (remote_debug) fprintf (stderr,format,parm);
}
/* convert the memory pointed to by mem into hex, placing result in buf */
case 3 : sigval = 10; break; /* address error */
case 4 : sigval = 4; break; /* illegal instruction */
case 5 : sigval = 8; break; /* zero divide */
- case 6 : sigval = 16; break; /* chk instruction */
- case 7 : sigval = 16; break; /* trapv instruction */
+ case 6 : sigval = 8; break; /* chk instruction */
+ case 7 : sigval = 8; break; /* trapv instruction */
case 8 : sigval = 11; break; /* privilege violation */
case 9 : sigval = 5; break; /* trace trap */
case 10: sigval = 4; break; /* line 1010 emulator */
case 11: sigval = 4; break; /* line 1111 emulator */
- case 13: sigval = 8; break; /* floating point err */
+
+ /* Coprocessor protocol violation. Using a standard MMU or FPU
+ this cannot be triggered by software. Call it a SIGBUS. */
+ case 13: sigval = 10; break;
+
case 31: sigval = 2; break; /* interrupt */
case 33: sigval = 5; break; /* breakpoint */
*/
void handle_exception(int exceptionVector)
{
- int sigval;
+ int sigval, stepping;
int addr, length;
char * ptr;
int newPC;
putpacket(remcomOutBuffer);
+ stepping = 0;
+
while (1==1) {
- error = 0;
remcomOutBuffer[0] = 0;
- getpacket(remcomInBuffer);
- switch (remcomInBuffer[0]) {
+ ptr = getpacket();
+ switch (*ptr++) {
case '?' : remcomOutBuffer[0] = 'S';
remcomOutBuffer[1] = hexchars[sigval >> 4];
remcomOutBuffer[2] = hexchars[sigval % 16];
mem2hex((char*) registers, remcomOutBuffer, NUMREGBYTES);
break;
case 'G' : /* set the value of the CPU registers - return OK */
- hex2mem(&remcomInBuffer[1], (char*) registers, NUMREGBYTES);
+ hex2mem(ptr, (char*) registers, NUMREGBYTES);
strcpy(remcomOutBuffer,"OK");
break;
exceptionHandler(2,handle_buserror);
/* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
- ptr = &remcomInBuffer[1];
if (hexToInt(&ptr,&addr))
if (*(ptr++) == ',')
if (hexToInt(&ptr,&length))
if (ptr)
{
strcpy(remcomOutBuffer,"E01");
- debug_error("malformed read memory command: %s",remcomInBuffer);
- }
- }
- else {
+ }
+ } else {
exceptionHandler(2,_catchException);
strcpy(remcomOutBuffer,"E03");
debug_error("bus error");
- }
+ }
/* restore handler for bus error */
exceptionHandler(2,_catchException);
exceptionHandler(2,handle_buserror);
/* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */
- ptr = &remcomInBuffer[1];
if (hexToInt(&ptr,&addr))
if (*(ptr++) == ',')
if (hexToInt(&ptr,&length))
if (ptr)
{
strcpy(remcomOutBuffer,"E02");
- debug_error("malformed write memory command: %s",remcomInBuffer);
- }
- }
- else {
+ }
+ } else {
exceptionHandler(2,_catchException);
strcpy(remcomOutBuffer,"E03");
debug_error("bus error");
- }
+ }
/* restore handler for bus error */
exceptionHandler(2,_catchException);
/* cAA..AA Continue at address AA..AA(optional) */
/* sAA..AA Step one instruction from AA..AA(optional) */
- case 'c' :
case 's' :
+ stepping = 1;
+ case 'c' :
/* try to read optional parameter, pc unchanged if no parm */
- ptr = &remcomInBuffer[1];
if (hexToInt(&ptr,&addr))
registers[ PC ] = addr;
registers[ PS ] &= 0x7fff;
/* set the trace bit if we're stepping */
- if (remcomInBuffer[0] == 's') registers[ PS ] |= 0x8000;
+ if (stepping) registers[ PS ] |= 0x8000;
/*
* look for newPC in the linked list of exception frames.