source: trunk/libs/newlib/src/libgloss/m68k/mvme-stub.c @ 584

Last change on this file since 584 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 23.2 KB
RevLine 
[444]1unsigned long sp_ptr;
2unsigned long pc_ptr;
3int cnt;
4#define UNWIND asm ("movel %/sp, %0" : "=g" (sp_ptr));\
5    printf ("\n\t\t== Starting at 0x%x ==\n", sp_ptr);\
6    for (cnt=4; cnt <=32; cnt+=4) {\
7      printf ("+%d(0x%x): 0x%x\t\t-%d(0x%x): 0x%x\n",\
8              cnt, (sp_ptr + cnt), *(unsigned long *)(sp_ptr + cnt),\
9              cnt, (sp_ptr - cnt), *(unsigned long *)(sp_ptr - cnt)\
10              ); }; fflush (stdout);
11
12/****************************************************************************
13
14                THIS SOFTWARE IS NOT COPYRIGHTED 
15   
16   HP offers the following for use in the public domain.  HP makes no
17   warranty with regard to the software or it's performance and the
18   user accepts the software "AS IS" with all faults.
19
20   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
21   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23
24****************************************************************************/
25
26/****************************************************************************
27 *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $                   
28 *
29 *  Module name: remcom.c $ 
30 *  Revision: 1.34 $
31 *  Date: 91/03/09 12:29:49 $
32 *  Contributor:     Lake Stevens Instrument Division$
33 * 
34 *  Description:     low level support for gdb debugger. $
35 *
36 *  Considerations:  only works on target hardware $
37 *
38 *  Written by:      Glenn Engel $
39 *  ModuleState:     Experimental $
40 *
41 *  NOTES:           See Below $
42 *
43 *  To enable debugger support, two things need to happen.  One, a
44 *  call to set_debug_traps() is necessary in order to allow any breakpoints
45 *  or error conditions to be properly intercepted and reported to gdb.
46 *  Two, a breakpoint needs to be generated to begin communication.  This
47 *  is most easily accomplished by a call to breakpoint().  Breakpoint()
48 *  simulates a breakpoint by executing a trap #1.
49 * 
50 *  Some explanation is probably necessary to explain how exceptions are
51 *  handled.  When an exception is encountered the 68000 pushes the current
52 *  program counter and status register onto the supervisor stack and then
53 *  transfers execution to a location specified in it's vector table.
54 *  The handlers for the exception vectors are hardwired to jmp to an address
55 *  given by the relation:  (exception - 256) * 6.  These are decending
56 *  addresses starting from -6, -12, -18, ...  By allowing 6 bytes for
57 *  each entry, a jsr, jmp, bsr, ... can be used to enter the exception
58 *  handler.  Using a jsr to handle an exception has an added benefit of
59 *  allowing a single handler to service several exceptions and use the
60 *  return address as the key differentiation.  The vector number can be
61 *  computed from the return address by [ exception = (addr + 1530) / 6 ].
62 *  The sole purpose of the routine _catchException is to compute the
63 *  exception number and push it on the stack in place of the return address.
64 *  The external function exceptionHandler() is
65 *  used to attach a specific handler to a specific 68k exception.
66 *  For 68020 machines, the ability to have a return address around just
67 *  so the vector can be determined is not necessary because the '020 pushes an
68 *  extra word onto the stack containing the vector offset
69 *
70 *  Because gdb will sometimes write to the stack area to execute function
71 *  calls, this program cannot rely on using the supervisor stack so it
72 *  uses it's own stack area reserved in the int array remcomStack. 
73 *
74 *************
75 *
76 *    The following gdb commands are supported:
77 *
78 * command          function                               Return value
79 *
80 *    g             return the value of the CPU registers  hex data or ENN
81 *    G             set the value of the CPU registers     OK or ENN
82 *
83 *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
84 *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
85 *
86 *    c             Resume at current address              SNN   ( signal NN)
87 *    cAA..AA       Continue at address AA..AA             SNN
88 *
89 *    s             Step one instruction                   SNN
90 *    sAA..AA       Step one instruction from AA..AA       SNN
91 *
92 *    k             kill
93 *
94 *    ?             What was the last sigval ?             SNN   (signal NN)
95 *
96 * All commands and responses are sent with a packet which includes a
97 * checksum.  A packet consists of
98 *
99 * $<packet info>#<checksum>.
100 *
101 * where
102 * <packet info> :: <characters representing the command or response>
103 * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
104 *
105 * When a packet is received, it is first acknowledged with either '+' or '-'.
106 * '+' indicates a successful transfer.  '-' indicates a failed transfer.
107 *
108 * Example:
109 *
110 * Host:                  Reply:
111 * $m0,10#2a               +$00010203040506070809101112131415#42
112 *
113 ****************************************************************************/
114
115#include <stdio.h>
116#include <string.h>
117#include <setjmp.h>
118#include <_ansi.h>
119
120/************************************************************************
121 *
122 * external low-level support routines
123 */
124typedef void (*ExceptionHook)(int);   /* pointer to function with int parm */
125typedef void (*Function)();           /* pointer to a function */
126
127extern int  putDebugChar();   /* write a single character      */
128extern char getDebugChar();   /* read and return a single char */
129
130ExceptionHook exceptionHook;  /* hook variable for errors/exceptions */
131
132/************************/
133/* FORWARD DECLARATIONS */
134/************************/
135/** static void initializeRemcomErrorFrame PARAMS ((void)); **/
136static void initializeRemcomErrorFrame (void);
137
138/************************************************************************/
139/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
140/* at least NUMREGBYTES*2 are needed for register packets */
141#define BUFMAX 400
142
143static char initialized;  /* boolean flag. != 0 means we've been initialized */
144
145int     remote_debug = 0; /*** Robs Thu Sep 24 22:18:51 PDT 1992 ***/
146/*  debug >  0 prints ill-formed commands in valid packets & checksum errors */ 
147
148static const char hexchars[]="0123456789abcdef";
149
150/* there are 180 bytes of registers on a 68020 w/68881      */
151/* many of the fpa registers are 12 byte (96 bit) registers */
152#define NUMREGBYTES 180
153enum regnames {D0,D1,D2,D3,D4,D5,D6,D7, 
154               A0,A1,A2,A3,A4,A5,A6,A7, 
155               PS,PC,
156               FP0,FP1,FP2,FP3,FP4,FP5,FP6,FP7,
157               FPCONTROL,FPSTATUS,FPIADDR
158              };
159
160typedef struct FrameStruct
161{
162    struct FrameStruct  *previous;
163    int       exceptionPC;      /* pc value when this frame created */
164    int       exceptionVector;  /* cpu vector causing exception     */
165    short     frameSize;        /* size of cpu frame in words       */
166    short     sr;               /* for 68000, this not always sr    */
167    int       pc;
168    short     format;
169    int       fsaveHeader;
170    int       morejunk[0];        /* exception frame, fp save... */
171} Frame;
172
173#define FRAMESIZE 500
174int   gdbFrameStack[FRAMESIZE];
175Frame *lastFrame;
176
177/*
178 * these should not be static cuz they can be used outside this module
179 */
180int registers[NUMREGBYTES/4];
181int superStack;
182
183#define STACKSIZE 10000
184int remcomStack[STACKSIZE/sizeof(int)];
185int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
186
187/*
188 * In many cases, the system will want to continue exception processing
189 * when a continue command is given. 
190 * oldExceptionHook is a function to invoke in this case.
191 */
192
193static ExceptionHook oldExceptionHook;
194
195/* the size of the exception stack on the 68020 varies with the type of
196 * exception.  The following table is the number of WORDS used
197 * for each exception format.
198 */
199const short exceptionSize[] = { 4,4,6,4,4,4,4,4,29,10,16,46,12,4,4,4 };
200
201/************* jump buffer used for setjmp/longjmp **************************/
202jmp_buf remcomEnv;
203
204#define BREAKPOINT() asm("   trap #1");
205
206extern void return_to_super (void);
207extern void return_to_user (void);
208extern void _catchException (void);
209
210void _returnFromException( Frame *frame )
211{
212    /* if no passed in frame, use the last one */
213    if (! frame)
214    {
215        frame = lastFrame;
216        frame->frameSize = 4;
217        frame->format = 0;
218        frame->fsaveHeader = -1; /* restore regs, but we dont have fsave info*/
219    }
220
221#ifndef mc68020
222    /* a 68000 cannot use the internal info pushed onto a bus error
223     * or address error frame when doing an RTE so don't put this info
224     * onto the stack or the stack will creep every time this happens.
225     */
226    frame->frameSize=3;
227#endif
228
229    /* throw away any frames in the list after this frame */
230    lastFrame = frame;
231
232    frame->sr = registers[(int) PS];
233    frame->pc = registers[(int) PC];
234
235    if (registers[(int) PS] & 0x2000)
236    { 
237        /* return to supervisor mode... */
238        return_to_super();
239    }
240    else
241    { /* return to user mode */
242        return_to_user();
243    }
244}
245
246int hex(ch)
247char ch;
248{
249  if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10);
250  if ((ch >= '0') && (ch <= '9')) return (ch-'0');
251  if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10);
252  return (-1);
253}
254
255
256/* scan for the sequence $<data>#<checksum>     */
257void getpacket(buffer)
258char * buffer;
259{
260  unsigned char checksum;
261  unsigned char xmitcsum;
262  int  i;
263  int  count;
264  char ch;
265 
266  if (remote_debug) {
267    printf("\nGETPACKET: sr=0x%x, pc=0x%x, sp=0x%x\n",
268           registers[ PS ], 
269           registers[ PC ],
270           registers[ A7 ]
271           ); fflush (stdout);
272    UNWIND
273  }
274
275  do {
276    /* wait around for the start character, ignore all other characters */
277    while ((ch = getDebugChar()) != '$'); 
278     checksum = 0;
279    xmitcsum = -1;
280   
281    count = 0;
282   
283    /* now, read until a # or end of buffer is found */
284    while (count < BUFMAX) {
285      ch = getDebugChar();
286      if (ch == '#') break;
287      checksum = checksum + ch;
288      buffer[count] = ch;
289      count = count + 1;
290      }
291    buffer[count] = 0;
292
293    if (ch == '#') {
294      xmitcsum = hex(getDebugChar()) << 4;
295      xmitcsum += hex(getDebugChar());
296      if ((remote_debug ) && (checksum != xmitcsum)) {
297        fprintf(stderr,"bad checksum.  My count = 0x%x, sent=0x%x. buf=%s\n",
298                                                     checksum,xmitcsum,buffer);
299      }
300     
301      if (checksum != xmitcsum) putDebugChar('-');  /* failed checksum */ 
302      else {
303         putDebugChar('+');  /* successful transfer */
304         /* if a sequence char is present, reply the sequence ID */
305         if (buffer[2] == ':') {
306            putDebugChar( buffer[0] );
307            putDebugChar( buffer[1] );
308            /* remove sequence chars from buffer */
309            count = strlen(buffer);
310            for (i=3; i <= count; i++) buffer[i-3] = buffer[i];
311         } 
312      } 
313    } 
314  } while (checksum != xmitcsum);
315 
316}
317
318/* send the packet in buffer.  The host get's one chance to read it. 
319   This routine does not wait for a positive acknowledge.  */
320
321void putpacket(buffer)
322char * buffer;
323{
324  unsigned char checksum;
325  int  count;
326  char ch;
327 
328  /*  $<packet info>#<checksum>. */
329  /***  do {***/
330  putDebugChar('$');
331  checksum = 0;
332  count    = 0;
333 
334  while (ch=buffer[count]) {
335    if (! putDebugChar(ch)) return;
336    checksum += ch;
337    count += 1;
338  }
339 
340  putDebugChar('#');
341  putDebugChar(hexchars[checksum >> 4]);
342  putDebugChar(hexchars[checksum % 16]);
343
344  if (remote_debug) {
345    printf("\nPUTPACKET: sr=0x%x, pc=0x%x, sp=0x%x\n",
346           registers[ PS ], 
347           registers[ PC ],
348           registers[ A7 ]
349           ); fflush (stdout);
350    UNWIND
351  }
352
353/*** } while (getDebugChar() != '+'); ***/
354/** } while (1 == 0);  (getDebugChar() != '+'); **/
355
356}
357
358char  remcomInBuffer[BUFMAX];
359char  remcomOutBuffer[BUFMAX];
360static short error;
361
362
363void debug_error(format, parm)
364char * format;
365char * parm;
366{
367  if (remote_debug) fprintf(stderr,format,parm);
368}
369
370/* convert the memory pointed to by mem into hex, placing result in buf */
371/* return a pointer to the last char put in buf (null) */
372char* mem2hex(mem, buf, count)
373char* mem;
374char* buf;
375int   count;
376{
377      int i;
378      unsigned char ch;
379      for (i=0;i<count;i++) {
380          ch = *mem++;
381          *buf++ = hexchars[ch >> 4];
382          *buf++ = hexchars[ch % 16];
383      }
384      *buf = 0; 
385      return(buf);
386}
387
388/* convert the hex array pointed to by buf into binary to be placed in mem */
389/* return a pointer to the character AFTER the last byte written */
390char* hex2mem(buf, mem, count)
391char* buf;
392char* mem;
393int   count;
394{
395      int i;
396      unsigned char ch;
397      for (i=0;i<count;i++) {
398          ch = hex(*buf++) << 4;
399          ch = ch + hex(*buf++);
400          *mem++ = ch;
401      }
402      return(mem);
403}
404
405/* a bus error has occurred, perform a longjmp
406   to return execution and allow handling of the error */
407
408void handle_buserror()
409{
410  longjmp(remcomEnv,1);
411}
412
413/* this function takes the 68000 exception number and attempts to
414   translate this number into a unix compatible signal value */
415int computeSignal( exceptionVector )
416int exceptionVector;
417{
418  int sigval;
419  switch (exceptionVector) {
420    case 2 : sigval = 10; break; /* bus error           */
421    case 3 : sigval = 10; break; /* address error       */
422    case 4 : sigval = 4;  break; /* illegal instruction */
423    case 5 : sigval = 8;  break; /* zero divide         */
424    case 6 : sigval = 16; break; /* chk instruction     */
425    case 7 : sigval = 16; break; /* trapv instruction   */
426    case 8 : sigval = 11; break; /* privilege violation */
427    case 9 : sigval = 5;  break; /* trace trap          */
428    case 10: sigval = 4;  break; /* line 1010 emulator  */
429    case 11: sigval = 4;  break; /* line 1111 emulator  */
430    case 13: sigval = 8;  break; /* floating point err  */
431    case 31: sigval = 2;  break; /* interrupt           */
432    case 33: sigval = 5;  break; /* breakpoint          */
433    case 40: sigval = 8;  break; /* floating point err  */
434    case 48: sigval = 8;  break; /* floating point err  */
435    case 49: sigval = 8;  break; /* floating point err  */
436    case 50: sigval = 8;  break; /* zero divide         */
437    case 51: sigval = 8;  break; /* underflow           */
438    case 52: sigval = 8;  break; /* operand error       */
439    case 53: sigval = 8;  break; /* overflow            */
440    case 54: sigval = 8;  break; /* NAN                 */
441    default: 
442      sigval = 7;         /* "software generated"*/
443  }
444  return (sigval);
445}
446
447/**********************************************/
448/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
449/* RETURN NUMBER OF CHARS PROCESSED           */
450/**********************************************/
451int hexToInt(char **ptr, int *intValue)
452{
453    int numChars = 0;
454    int hexValue;
455   
456    *intValue = 0;
457
458    while (**ptr)
459    {
460        hexValue = hex(**ptr);
461        if (hexValue >=0)
462        {
463            *intValue = (*intValue <<4) | hexValue;
464            numChars ++;
465        }
466        else
467            break;
468       
469        (*ptr)++;
470    }
471
472    return (numChars);
473}
474
475/*
476 * This function does all command procesing for interfacing to gdb.
477 */
478void handle_exception(int exceptionVector)
479{
480  int    sigval;
481  int    addr, length;
482  char * ptr;
483  int    newPC;
484  Frame  *frame;
485
486  if (remote_debug)    printf("\nHANDLE_EXCEPTION: vector=%d, sr=0x%x, pc=0x%x, sp=0x%x\n",
487                            exceptionVector,
488                            registers[ PS ], 
489                            registers[ PC ],
490                            registers[ A7 ]
491                              ); fflush (stdout);
492
493  /* reply to host that an exception has occurred */
494  sigval = computeSignal( exceptionVector );
495  remcomOutBuffer[0] = 'S';
496  remcomOutBuffer[1] =  hexchars[sigval >> 4];
497  remcomOutBuffer[2] =  hexchars[sigval % 16];
498  remcomOutBuffer[3] = 0;
499
500  putpacket(remcomOutBuffer); 
501
502  while (1==1) { 
503    error = 0;
504    remcomOutBuffer[0] = 0;
505    getpacket(remcomInBuffer);
506    switch (remcomInBuffer[0]) {
507      case '?' :   remcomOutBuffer[0] = 'S';
508                   remcomOutBuffer[1] =  hexchars[sigval >> 4];
509                   remcomOutBuffer[2] =  hexchars[sigval % 16];
510                   remcomOutBuffer[3] = 0;
511                 break; 
512      case 'd' : remote_debug = !(remote_debug);  /* toggle debug flag */
513                 break; 
514      case 'g' : /* return the value of the CPU registers */
515                mem2hex((char*) registers, remcomOutBuffer, NUMREGBYTES);
516                break;
517      case 'G' : /* set the value of the CPU registers - return OK */
518                hex2mem(&remcomInBuffer[1], (char*) registers, NUMREGBYTES);
519                strcpy(remcomOutBuffer,"OK");
520                break;
521     
522      /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
523      case 'm' : 
524                if (setjmp(remcomEnv) == 0)
525                {
526                    exceptionHandler(2,handle_buserror); 
527
528                    /* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
529                    ptr = &remcomInBuffer[1];
530                    if (hexToInt(&ptr,&addr))
531                        if (*(ptr++) == ',')
532                            if (hexToInt(&ptr,&length)) 
533                            {
534                                ptr = 0;
535                                mem2hex((char*) addr, remcomOutBuffer, length);
536                            }
537
538                    if (ptr)
539                    {
540                      strcpy(remcomOutBuffer,"E01");
541                      debug_error("malformed read memory command: %s",remcomInBuffer);
542                  }     
543                } 
544                else {
545                  exceptionHandler(2,_catchException);   
546                  strcpy(remcomOutBuffer,"E03");
547                  debug_error("bus error");
548                  }     
549               
550                /* restore handler for bus error */
551                exceptionHandler(2,_catchException);   
552                break;
553     
554      /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
555      case 'M' : 
556                if (setjmp(remcomEnv) == 0) {
557                    exceptionHandler(2,handle_buserror); 
558                   
559                    /* TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
560                    ptr = &remcomInBuffer[1];
561                    if (hexToInt(&ptr,&addr))
562                        if (*(ptr++) == ',')
563                            if (hexToInt(&ptr,&length))
564                                if (*(ptr++) == ':')
565                                {
566                                    hex2mem(ptr, (char*) addr, length);
567                                    ptr = 0;
568                                    strcpy(remcomOutBuffer,"OK");
569                                }
570                    if (ptr)
571                    {
572                      strcpy(remcomOutBuffer,"E02");
573                      debug_error("malformed write memory command: %s",remcomInBuffer);
574                      }     
575                } 
576                else {
577                  exceptionHandler(2,_catchException);   
578                  strcpy(remcomOutBuffer,"E03");
579                  debug_error("bus error");
580                  }     
581
582                /* restore handler for bus error */
583                exceptionHandler(2,_catchException);   
584                break;
585     
586     /* cAA..AA    Continue at address AA..AA(optional) */
587     /* sAA..AA   Step one instruction from AA..AA(optional) */
588     case 'c' : 
589     case 's' : 
590          /* try to read optional parameter, pc unchanged if no parm */
591         ptr = &remcomInBuffer[1];
592         if (hexToInt(&ptr,&addr))
593             registers[ PC ] = addr;
594             
595          newPC = registers[ PC];
596         
597          /* clear the trace bit */
598          registers[ PS ] &= 0x7fff;
599         
600          /* set the trace bit if we're stepping */
601          if (remcomInBuffer[0] == 's') registers[ PS ] |= 0x8000;
602         
603          /*
604           * look for newPC in the linked list of exception frames.
605           * if it is found, use the old frame it.  otherwise,
606           * fake up a dummy frame in returnFromException().
607           */
608          if (remote_debug) printf("new pc = 0x%x\n",newPC);
609          frame = lastFrame;
610          while (frame)
611          {
612              if (remote_debug)
613                  printf("frame at 0x%x has pc=0x%x, except#=%d\n",
614                         frame,frame->exceptionPC,
615                         frame->exceptionVector);
616              if (frame->exceptionPC == newPC) break;  /* bingo! a match */
617              /*
618               * for a breakpoint instruction, the saved pc may
619               * be off by two due to re-executing the instruction
620               * replaced by the trap instruction.  Check for this.
621               */
622              if ((frame->exceptionVector == 33) &&
623                  (frame->exceptionPC == (newPC+2))) break;
624              if (frame == frame->previous)
625              {
626                  frame = 0; /* no match found */ 
627                  break; 
628              }
629              frame = frame->previous;
630          }
631         
632          /*
633           * If we found a match for the PC AND we are not returning
634           * as a result of a breakpoint (33),
635           * trace exception (9), nmi (31), jmp to
636           * the old exception handler as if this code never ran.
637           */
638          if (frame) 
639          {
640              if ((frame->exceptionVector != 9)  && 
641                  (frame->exceptionVector != 31) && 
642                  (frame->exceptionVector != 33))
643              { 
644                  /*
645                   * invoke the previous handler.
646                   */
647                  if (oldExceptionHook)
648                      (*oldExceptionHook) (frame->exceptionVector);
649                  newPC = registers[ PC ];    /* pc may have changed  */
650                  if (newPC != frame->exceptionPC)
651                  {
652                      if (remote_debug)
653                          printf("frame at 0x%x has pc=0x%x, except#=%d\n",
654                                 frame,frame->exceptionPC,
655                                 frame->exceptionVector);
656                      /* re-use the last frame, we're skipping it (longjump?)*/
657                      frame = (Frame *) 0;
658                      _returnFromException( frame );  /* this is a jump */
659                  }
660              }
661          }         
662
663          /* if we couldn't find a frame, create one */
664          if (frame == 0)
665          {
666              frame = lastFrame -1 ;
667             
668              /* by using a bunch of print commands with breakpoints,
669                 it's possible for the frame stack to creep down.  If it creeps
670                 too far, give up and reset it to the top.  Normal use should
671                 not see this happen.
672              */
673              if ((unsigned int) (frame-2) < (unsigned int) &gdbFrameStack)
674              {
675                 initializeRemcomErrorFrame();
676                 frame = lastFrame; 
677              }
678              frame->previous = lastFrame;
679              lastFrame = frame;
680              frame = 0;  /* null so _return... will properly initialize it */ 
681          }   
682         
683          _returnFromException( frame ); /* this is a jump */
684
685          break;
686         
687      /* kill the program */
688      case 'k' :  /* do nothing */
689                break;
690      } /* switch */ 
691   
692    /* reply to the request */
693    putpacket(remcomOutBuffer); 
694    }
695}
696
697
698void initializeRemcomErrorFrame()
699{
700    lastFrame = ((Frame *) &gdbFrameStack[FRAMESIZE-1]) - 1;
701    lastFrame->previous = lastFrame;
702}
703
704/* this function is used to set up exception handlers for tracing and
705   breakpoints */
706void set_debug_traps()
707{
708extern void _debug_level7();
709extern void remcomHandler();
710int exception;
711
712  initializeRemcomErrorFrame();
713  stackPtr  = &remcomStack[STACKSIZE/sizeof(int) - 1];
714
715  setup_vectors();
716
717  if (oldExceptionHook != remcomHandler)
718  {
719      oldExceptionHook = exceptionHook;
720      exceptionHook    = remcomHandler;
721  }
722 
723  initialized = 1;
724
725}
726/* This function will generate a breakpoint exception.  It is used at the
727   beginning of a program to sync up with a debugger and can be used
728   otherwise as a quick means to stop program execution and "break" into
729   the debugger. */
730   
731void breakpoint()
732{
733  if (initialized) BREAKPOINT();
734}
Note: See TracBrowser for help on using the repository browser.