home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gdb-4.16-base.tgz / gdb-4.16-base.tar / fsf / gdb / utils / amd-udi / montip / udi2mtip.c < prev   
Encoding:
C/C++ Source or Header  |  1993-12-23  |  103.8 KB  |  3,594 lines

  1. static char     _[] = "@(#)udi2mtip.c    5.31 93/11/03 08:34:07, Srini, AMD.";
  2. /******************************************************************************
  3.  * Copyright 1991 Advanced Micro Devices, Inc.
  4.  *
  5.  * This software is the property of Advanced Micro Devices, Inc  (AMD)  which
  6.  * specifically  grants the user the right to modify, use and distribute this
  7.  * software provided this notice is not removed or altered.  All other rights
  8.  * are reserved by AMD.
  9.  *
  10.  * AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS
  11.  * SOFTWARE.  IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL
  12.  * DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR
  13.  * USE OF THIS SOFTWARE.
  14.  *
  15.  * So that all may benefit from your experience, please report  any  problems
  16.  * or  suggestions about this software to the 29K Technical Support Center at
  17.  * 800-29-29-AMD (800-292-9263) in the USA, or 0800-89-1131  in  the  UK,  or
  18.  * 0031-11-1129 in Japan, toll free.  The direct dial number is 512-462-4118.
  19.  *
  20.  * Advanced Micro Devices, Inc.
  21.  * 29K Support Products
  22.  * Mail Stop 573
  23.  * 5900 E. Ben White Blvd.
  24.  * Austin, TX 78741
  25.  * 800-292-9263
  26.  *****************************************************************************
  27.  *      Engineers: Srini Subramanian.
  28.  *****************************************************************************
  29.  * This module implements the UDI procedural interface routines of MONTIP
  30.  * for both the Dos and Unix environments.
  31.  *****************************************************************************
  32.  */
  33. #include <stdio.h>
  34. #include  <signal.h>
  35.  
  36. #ifdef    MSDOS
  37. #include <stdlib.h>
  38. #include <conio.h>
  39. #else
  40. #include <malloc.h>
  41. #endif
  42.  
  43. #include <string.h>
  44. #include "coff.h"
  45. #include "messages.h"
  46. #include "memspcs.h"
  47. #include "macros.h"
  48. #include "udiproc.h"
  49. #include "udiids.h"
  50. #include "udiext.h"
  51. #include "mtip.h"
  52. #include "hif.h"
  53. #include "versions.h"
  54.  
  55. /* 
  56.  * MsgCode halt1, halt2, halt3, halt4 are variables defined as INT32 *
  57.  * inside the macro block *
  58.  */
  59.  
  60.  
  61. #define    CLEAR_PENDING_STOP    StopFlag=0;
  62.  
  63. /* Stop signal handler / macro */
  64. #define    STOP_SIG_HDLR    {\
  65.             INT32   MsgCode;\
  66.             INT32   halt1, halt2, halt3, halt4;\
  67.             StopFlag=0;\
  68.             Mini_build_break_msg();\
  69.             if (Mini_msg_send() != SUCCESS)\
  70.               return((-1) * MONErrCantSendMsg);\
  71.             SIGINT_POLL    \
  72.             MsgCode = Wait_For_Ack();\
  73.             if (MsgCode == ABORT_FAILURE)\
  74.                return ((-1) * MONErrAbortAborted);\
  75.             if (MsgCode == FAILURE)\
  76.                return ((-1) * MONErrNoAck);\
  77.             else if (MsgCode != HALT)\
  78.                return ((-1) * MONErrCantRecvMsg);\
  79.             Mini_unpack_halt_msg(&halt1, &halt2, &halt3, &halt4);\
  80.             };
  81.  
  82. #define    SEND_AND_WAIT_ACK(x)    {\
  83.                 INT32    MsgCode;\
  84.                 if (Mini_msg_send() != SUCCESS)\
  85.                    return((-1)*MONErrCantSendMsg);\
  86.                 SIGINT_POLL    \
  87.                 MsgCode = Wait_For_Ack();\
  88.                 if (MsgCode == ABORT_FAILURE)\
  89.                   return (UDIErrorAborted);\
  90.                 else if (MsgCode == FAILURE)\
  91.                   return ((-1) * MONErrNoAck);\
  92.                 else if (MsgCode == ERROR)\
  93.                   ReturnedError = 1; \
  94.                 else if (MsgCode != (INT32) (x))\
  95.                   return ((-1) * MONErrCantRecvMsg);\
  96.                 };
  97.  
  98. #define    MONUDISession        1
  99.  
  100. static int      AllSections=(STYP_ABS|STYP_TEXT|STYP_LIT|STYP_DATA|STYP_BSS);
  101. static UDIPId   CurrentPID = (UDIPId) UDIProcessProcessor;
  102. static UDIUInt32 PreviousProcessorState;
  103. static UDIUInt32 ProcessorState;
  104. static int      TipAlive = 0;
  105. static    int    NumberOfProcesses=0;
  106. static int      ContinuingSession = 0;
  107. static char    *TargetType;
  108. static char    *SecondTarget;
  109. static char    *CoreFile;
  110. static int      CoreLoaded;
  111. static BreakIdType LastBreakId = 0;
  112. static UDIBool  SupervisorMode;
  113. static UDIBool  RealMode;
  114. static UDIBool  ProtectedMode;
  115. static UDIBool  VirtualMode;
  116. static int      BreaksInPlace;    /* EB29K */
  117. static int      StepCmdGiven = 0;
  118. static int    ReturnedError=0;
  119. static    int    StopFlag=0;
  120. static    int    Interrupted=0;
  121. static    int    RemoteTarget=0;
  122. static    int    NoStepReqd=0;
  123. static    int    NoChan1Ack=0;
  124. static    int    SendACKFirst=0;
  125. static    INT32    MsgAlreadyInBuffer = 0;
  126. static    INT32    MsgAlreadyReceived = 0;
  127. static    int    Channel0Busy=0;
  128. unsigned long    TimeOut;
  129. int        MessageRetries;
  130. int        BlockCount;
  131. int        DelayFactor;
  132. unsigned int    MaxMsgBufSize;
  133. extern int        lpt_initialize;    /* global */
  134. extern int        use_parport;        /* global */
  135. static    UDISizeT    ErrCntRemaining=(UDISizeT) 0;
  136. static    FILE    *coff_in;
  137. static    char    buffer[LOAD_BUFFER_SIZE];
  138.  
  139. /* used in input/output routines */
  140. #define    TIP_IO_BUFSIZE        1024
  141. static     char         channel0_buffer[TIP_IO_BUFSIZE];
  142. static     UDISizeT       Channel0_count=0;
  143. static     char         channel1_buffer[TIP_IO_BUFSIZE];
  144. static     UDISizeT       Channel1_count=0;
  145. static    char        channel2_buffer[TIP_IO_BUFSIZE];
  146. static     UDISizeT       Channel2_count=0;
  147. static     UDIUInt32     Lr4_count;
  148. static     UDIUInt32     TotalDone=(UDIUInt32) 0;
  149. static     CPUOffset     Lr3_addr;
  150.  
  151. #define    TIP_COOKED    0        /* default */
  152. #define    TIP_RAW        1
  153. #define    TIP_CBREAK    2
  154. #define    TIP_ECHO    4
  155. #define    TIP_ASYNC    8
  156. #define    TIP_NBLOCK    0x10
  157. static    UDIUInt32    PgmStdinMode=TIP_COOKED;    /* default */
  158. static    UDIUInt32    StdinCharsNeeded=0;
  159.  
  160. /* Cache register values */
  161. static UDIUInt32 Glob_Regs[128],
  162.                 Loc_Regs[128];
  163. static int      RefreshRegs = 1;
  164. static int      exitstat;
  165. static    char    ConnectString[512];
  166. static    char        TempArgString[1024];
  167.  
  168. static    struct tip_break_table  *bp_table=NULL;
  169.  
  170. /* Global variables */
  171. TIP_TARGET_CONFIG tip_target_config;
  172. TIP_TARGET_STATUS tip_target_status;
  173. TIP_CONFIG      tip_config;
  174. char           *Msg_Logfile;
  175. FILE           *MsgFile;
  176.  
  177. /* ------------- Minimon TIP Specific Error Codes ------------ */
  178. #define    MONNoError        0
  179. #define    MONErrCantSendMsg    1
  180. #define    MONErrCantRecvMsg    2
  181. #define    MONErrCantLoadROMfile    3
  182. #define    MONErrCantInitMsgSystem    4
  183. #define    MONErrCantBreakInROM    5
  184. #define    MONErrCantResetComm    6
  185. #define    MONErrCantAllocBufs    7
  186. #define    MONErrUnknownBreakType    8
  187. #define    MONErrNoAck        9
  188. #define    MONErrNoSynch        10
  189. #define    MONErrCantOpenCoff    11
  190. #define    MONErrCantWriteToMem    12
  191. #define    MONErrAbortAborted    13
  192. #define    MONErrNullConfigString    14
  193. #define    MONErrNoTargetType    15
  194. #define    MONErrOutofMemory    16
  195. #define    MONErrErrorInit        17
  196. #define    MONErrErrorRead        18
  197. #define    MONErrErrorWrite    19
  198. #define    MONErrErrorCopy        20
  199. #define    MONErrErrorSetBreak    21
  200. #define    MONErrErrorStatBreak    22
  201. #define    MONErrErrorRmBreak    23
  202. #define    MONErrConfigInterrupt    24
  203. #define    MONErrNoConfig        25
  204. #define    MONErrMsgInBuf        26
  205. #define    MONErrUnknownTIPCmd    27
  206. #define    MAX_MONERR        28
  207.  
  208. static char    *monerr_tip[] = {
  209.    /* 0 */ "No Error.",
  210.    /* 1 */ "Could not send message to target.",
  211.    /* 2 */ "Did not receive the correct ACK from target.",
  212.    /* 3 */ "Cant load ROM file.",
  213.    /* 4 */ "Cant initialize the message system.",
  214.    /* 5 */ "Cant set breakpoint in ROM.",
  215.    /* 6 */ "Cant reset communication channel.",
  216.    /* 7 */ "Cant reallocate message buffers.",
  217.    /* 8 */ "Breakpoint type requested is not recognized.",
  218.    /* 9 */ "No ACK from target - timed out.",
  219.    /* 10 */ "Timed out synching. No response from target.",
  220.    /* 11 */ "Cannot open ROM file.",
  221.    /* 12 */ "Cannot write to memory while downloading ROM file.",
  222.    /* 13 */ "Ctrl-C aborted previous Ctrl-C processing.",
  223.    /* 14 */ "Null configuration string specified for connection.",
  224.    /* 15 */ "No Target type specified for connection.",
  225.    /* 16 */ "Out of memory.",
  226.    /* 17 */ "Error on target - trying to initialize process.",
  227.    /* 18 */ "Error on target - trying to read.",
  228.    /* 19 */ "Error on target - trying to write.",
  229.    /* 20 */ "Error on target - trying to do copy.",
  230.    /* 21 */ "Error on target - trying to set breakpoint.",
  231.    /* 22 */ "Error on target - trying to query breakpoint.",
  232.    /* 23 */ "Error on target - trying to remove breakpoint.",
  233.    /* 24 */ "User interrupt signal received - Aborting synch.",
  234.    /* 25 */ "Couldn't get target config after reset. Try again.",
  235.    /* 26 */ "Message received from target waiting in buffer.",
  236.    /* 27 */ "Unknown Montip command, Exiting TIP mode."
  237. };
  238.  
  239. #define    MAX_MONERR_SIZE        80
  240.  
  241. /* ---------------- Error Codes -------------------------------- */
  242.  
  243. /* Function declarations */
  244.  
  245. extern    void    IntHandler PARAMS((int num));
  246. extern    void    print_recv_bytes PARAMS((void));
  247. extern    void    set_lpt PARAMS((void));
  248. extern    void    unset_lpt PARAMS((void));
  249. static    FILE    *FindFile PARAMS((char *));
  250. static    char    *GetTargetType PARAMS((char *, char *));
  251. static    INT32    SendConfigWait PARAMS((void));
  252. extern    void    SendACK PARAMS((void));
  253. static     int     parse_string PARAMS((char *string));
  254. static     int     write_args PARAMS((char *argstr, ADDR32 argstart,
  255.                              ADDR32 * datahigh));
  256. static     int     write_argv PARAMS((int arg_count, char *arg_ptr[], 
  257.                    ADDR32 argstart, ADDR32 * hi_data));
  258. static    INT32     SpaceMap_udi2mm PARAMS((CPUSpace space));
  259. static    CPUSpace    SpaceMap_mm2udi PARAMS((INT32 space));
  260. static    int     Reset_Processor PARAMS((void));
  261. static    INT32     Wait_For_Ack PARAMS((void));
  262. static    void     process_target_msg PARAMS((INT32 msgcode));
  263. static    void     process_HALT_msg PARAMS((void));
  264. static    INT32     process_chan0_ack PARAMS((void));
  265. static    void     process_CHAN1_msg PARAMS((void));
  266. static    void     process_CHAN2_msg PARAMS((void));
  267. static    void     process_stdin_needed_req PARAMS((void));
  268. static    void     set_stdin_mode PARAMS((void));
  269. static    void     process_ERR_msg PARAMS((void));
  270. static    void     process_HIF_msg PARAMS((void));
  271. static     int     PutAllBreakpoints PARAMS((void));
  272. static     int     ResetAllBreakpoints PARAMS((void));
  273. static     int     Write_Glob_Reg PARAMS((INT32 RegVal, int RegNum));
  274.  
  275. /*
  276.  * these three functions are called from HIF/IO handlers to do terminal
  277.  * input/output.
  278.  */
  279. extern    void     set_stdin_needed PARAMS((ADDR32 offset, UDICount count));
  280. extern    void     set_stderr_ready PARAMS((ADDR32 offset, UDICount count));
  281. extern    void     set_stdout_ready PARAMS((ADDR32 offset, UDICount count));
  282.  
  283.  
  284. static    INT32      Mini_load_coff PARAMS((char *fname,
  285.                    INT32 space, 
  286.                    INT32 sym,
  287.                    INT32 sects,
  288.                    int   msg));
  289. static    int     update_breakpt_at PARAMS((INT32 space, ADDR32 addr, ADDR32 Inst));
  290. static    int     is_breakpt_at PARAMS((INT32 space, ADDR32 addr));
  291. static    void     add_to_bp_table PARAMS((BreakIdType * id, INT32 space,
  292.         ADDR32 offset, INT32 count, INT32 type, ADDR32 inst));
  293. static    int     get_from_bp_table PARAMS((BreakIdType id, INT32 * space,
  294.                 ADDR32 * offset, INT32 * count,
  295.                 INT32 * type, ADDR32 * inst));
  296. static    int     remove_from_bp_table PARAMS((BreakIdType id));
  297.  
  298. extern    INT32     CheckForMsg PARAMS((INT32 time));
  299.  
  300. extern    int     service_HIF PARAMS((UINT32 svcnm, UINT32 lr2, UINT32 lr3, 
  301.            UINT32 lr4, UINT32 * gr96, UINT32 * gr97, UINT32 * gr121));
  302.  
  303. /* ================================================================= */
  304. /* UDI Procedure definitions  */
  305.  
  306. UDIError 
  307. UDIConnect(string, Session)
  308.   char           *string;
  309.   UDISessionId   *Session;
  310. {
  311.   INT32           MsgCode;
  312.   int         retval;
  313.  
  314.   if (TipAlive) {    /* already connected */
  315.     /* If same TargetType requested, return ConnectionUnavailable */
  316.     SecondTarget = NULL;
  317.     if ((SecondTarget = GetTargetType (SecondTarget, string)) == NULL)
  318.        return (UDIErrorInvalidTIPOption);
  319.     if (strcmp (SecondTarget, TargetType) == 0)
  320.        return (UDIErrorConnectionUnavailable);
  321.     else
  322.        return (UDIErrorTryAnotherTIP);
  323.   } else {
  324.     if (ContinuingSession) {
  325.       ContinuingSession=0; /* reset */
  326.       *Session = (UDISessionId) MONUDISession;
  327.       if ((int) (ProcessorState & 0xFF) != UDINotExecuting) {/* none active */
  328.         CurrentPID = (UDIPId) (UDIProcessProcessor+1);
  329.         NumberOfProcesses=1;
  330.       };
  331.       TipAlive = 1;
  332.       return (UDINoError);
  333.     }
  334.     /* Initialize variables */
  335.     /* Take control of Ctrl-C until connect time */
  336.     signal (SIGINT, IntHandler);
  337.     CoreFile = NULL;
  338.     TargetType = NULL;
  339.     Msg_Logfile = NULL;
  340.     CoreLoaded = 0;
  341.     CurrentPID = (UDIPId) UDIProcessProcessor;
  342.     SupervisorMode = 0;
  343.     RealMode = 0;
  344.     ProtectedMode = 1;    /* default */
  345.     VirtualMode = 0;
  346.     BreaksInPlace = 0;    /* EB29K */
  347.     TimeOut = (unsigned long) 10000;
  348.     MessageRetries = (int) 1000;
  349. #ifdef    MSDOS
  350.     BlockCount = (int) 1000;
  351. #else
  352.     BlockCount = (int) 40000;
  353. #endif
  354.     DelayFactor = (int) 0;
  355.     MaxMsgBufSize = (unsigned int) 0;
  356.     Channel0_count = 0;
  357.     Channel1_count = 0;
  358.     Channel2_count = 0;
  359.     Channel0Busy=0;
  360.     *Session = (UDISessionId) MONUDISession;
  361.     TipAlive = 1; /* no more positive error codes */
  362.  
  363.     /* TIP_CONFIG initialization */
  364.     tip_config.PC_port_base = (INT32) - 1;    /* default */
  365.     tip_config.PC_mem_seg = (INT32) - 1;    /* default */
  366.     (void) strcpy(tip_config.baud_rate, DEFAULT_BAUD_RATE);
  367.     (void) strcpy(tip_config.comm_port, DEFAULT_COMM_PORT);
  368.     (void) strcpy(tip_config.par_port, DEFAULT_PAR_PORT);
  369.     /* Get the CFG register value to find out 29kEndian */
  370.     tip_target_config.P29KEndian = BIG;    /* default */
  371.  
  372.     if ((retval = parse_string(string)) != (int) 0)
  373.       return ((UDIError) retval);    
  374.     if (TargetType == NULL)
  375.        return ((-1) * MONErrNoTargetType);
  376.  
  377.     /* Open Msg_Logfile if any */
  378.     if (Msg_Logfile) {
  379.       if ((MsgFile = fopen(Msg_Logfile, "w")) == NULL)
  380.     Msg_Logfile = NULL;
  381.     }
  382.     /* Initialize message system */
  383.     if (Mini_msg_init(TargetType) != SUCCESS) {
  384.      *Session = (UDISessionId) MONUDISession;
  385.       TipAlive = 1;
  386.       return ((-1) * MONErrCantInitMsgSystem);
  387.     }
  388.     /* Reset communication channel */
  389.     Mini_reset_comm();
  390.  
  391.     /*
  392.      * Should we have different TIPS: one for shared memory & another for
  393.      * serial connections?
  394.      */
  395.     if (CoreFile) {
  396.       if ((MsgCode = Mini_load_coff(CoreFile, (INT32) D_MEM, (INT32) 1, (INT32) AllSections, 0)) != SUCCESS) {
  397.        *Session = (UDISessionId) MONUDISession;
  398.     TipAlive = 1;
  399.     return ((UDIError) MsgCode);
  400.       }
  401.       CoreLoaded = 1;    /* True */
  402.       /* Reset communication channel */
  403.       Mini_reset_comm();
  404.       Mini_go_target();    /* RESET Target Processor */
  405.     }
  406.  
  407.     /* Define TIPs endianess */
  408.  
  409. #ifdef    MSDOS
  410.     tip_target_config.TipEndian = LITTLE;
  411. #else
  412.     tip_target_config.TipEndian = BIG;
  413. #endif
  414.  
  415.    if (strcmp(TargetType, "serial") &&
  416.        strcmp(TargetType, "paral_1") &&
  417.        strcmp(TargetType, "pcserver")) { /* non-serial targets */
  418.      RemoteTarget = 0;    /* not a remote target */
  419.    } else {
  420.      RemoteTarget = 1;    /* remote target */
  421.      SendACKFirst = 1; /* safe to send always */
  422.    }
  423.  
  424.    if (RemoteTarget == 0) {    /* shared memory */
  425.       MsgCode = Wait_For_Ack();
  426.       if (MsgCode == ABORT_FAILURE) 
  427.      return (UDIErrorAborted);
  428.       else if (MsgCode == FAILURE) 
  429.     return((-1) * MONErrNoSynch);
  430.     }
  431.  
  432.     if (SendACKFirst)
  433.      SendACK();
  434.     /* send a config msg to sync with target */
  435.     do {
  436.        MsgCode = SendConfigWait();
  437.     } while (MsgCode == HALT);
  438.     if (MsgCode == ABORT_FAILURE)
  439.        return (UDIErrorAborted);
  440.     else if (MsgCode == FAILURE)
  441.     return ((-1) * MONErrNoSynch);
  442.     else if (MsgCode != CONFIG)
  443.     return ((-1) * MONErrCantRecvMsg);
  444.     Mini_unpack_config_msg(&tip_target_config);
  445.  
  446.     /* Reallocate message buffers to the smallest, if necessary */
  447.     if ((MaxMsgBufSize != (unsigned int) 0) && 
  448.         (MaxMsgBufSize < (unsigned int) tip_target_config.max_msg_size))
  449.        tip_target_config.max_msg_size = (INT32) MaxMsgBufSize;
  450.  
  451.     if (Mini_alloc_msgbuf((int) tip_target_config.max_msg_size) != SUCCESS)
  452.       return ((-1) * MONErrCantAllocBufs);
  453.  
  454.      ProcessorState = (UDIUInt32) UDINotExecuting;
  455.      PreviousProcessorState = (UDIUInt32) UDINotExecuting;
  456.  
  457.     return (UDINoError);
  458.   }
  459. }
  460.  
  461. UDIError 
  462. UDIDisconnect(Session, Terminate)
  463.   UDISessionId    Session;
  464.   UDIBool    Terminate;
  465. {
  466.   if (Session != (UDISessionId) MONUDISession)
  467.     return (UDIErrorNoSuchConnection);
  468.  
  469.   if (Terminate == (UDIBool) UDITerminateSession) {
  470.     if (CoreFile)
  471.       (void) free((char *) CoreFile);
  472.     if (TargetType)
  473.       (void) free((char *) TargetType);
  474.     Mini_msg_exit();    /* clean up message buffers */
  475.     if (Msg_Logfile)
  476.       (void) fclose(MsgFile);
  477.     ProcessorState = (UDIUInt32) UDINotExecuting;
  478.     PreviousProcessorState = (UDIUInt32) UDINotExecuting;
  479.   } else {
  480.     ContinuingSession=1;
  481.   };
  482.   if ((int) (ProcessorState & 0xFF) == UDINotExecuting) {/* none active */
  483.      CurrentPID = (UDIPId) UDIProcessProcessor;
  484.      NumberOfProcesses=0;
  485.   }
  486.   TipAlive = 0;
  487.   return (UDINoError);
  488. }
  489.  
  490. UDIError 
  491. UDISetCurrentConnection(Session)
  492.   UDISessionId    Session;
  493. {
  494.   if (Session != (UDISessionId) MONUDISession)
  495.     return (UDIErrorNoSuchConnection);
  496.  
  497.   return (UDINoError);
  498. }
  499.  
  500. UDIError 
  501. UDICapabilities ( TIPId, TargetId, DFEId, DFE, TIP, DFEIPCId, TIPIPCId, TIPString) 
  502.   UDIUInt32    *TIPId;            /* Out */
  503.   UDIUInt32    *TargetId;        /* Out */
  504.   UDIUInt32    DFEId;            /* In */
  505.   UDIUInt32    DFE;            /* In */
  506.   UDIUInt32    *TIP;            /* Out */
  507.   UDIUInt32    *DFEIPCId;        /* Out */
  508.   UDIUInt32    *TIPIPCId;        /* Out */
  509.   char        *TIPString;        /* Out */
  510. {
  511.   *TIPId = (UDIUInt32) UDIID (UDIProductCode_Montip, MONTIPRev, MONTIPSubRev, MONTIPSubSubRev);
  512.   *TargetId = (UDIUInt32) UDIID (UDIProductCode_Montip, MONTIPRev, MONTIPSubRev, MONTIPSubSubRev);
  513.   if ((int) (DFE & 0x00000FFF) > (int) (MONTIPUDIVers)) {
  514.      *TIP = (UDIUInt32) 0;
  515.   } else if ((int) (DFE & 0x00000FFF) == (int) MONTIPUDIVers) {
  516.      *TIP = (UDIUInt32) DFE;
  517.   } else {
  518.      *TIP = (UDIUInt32) MONTIPUDIVers;
  519.   }
  520.   *DFEIPCId = (UDIUInt32) 0;
  521.   *TIPIPCId = (UDIUInt32) 0;
  522.   (void) strcpy (TIPString, "UDI 1.2 Conformant Montip for 29K targets\0");
  523.   return (UDINoError);
  524. }
  525.  
  526. UDIError 
  527. UDIGetErrorMsg (ErrorCode, MsgSize, Msg, CountDone)
  528.   UDIError    ErrorCode;        /* In */
  529.   UDISizeT    MsgSize;        /* In */
  530.   char        *Msg;            /* Out */
  531.   UDISizeT    *CountDone;        /* Out */
  532. {
  533.   int        index;
  534.  
  535.   /* Continue Previous Error Message */
  536.   if (ErrCntRemaining != (UDISizeT) 0) {
  537.     index = (int) (strlen(monerr_tip[-ErrorCode]) + 1 - ErrCntRemaining);
  538.     if (MsgSize < (UDISizeT) ErrCntRemaining) {
  539.       (void) strncpy((char *) Msg, (char *) (monerr_tip[-ErrorCode]+index), MsgSize);
  540.       *CountDone = MsgSize;
  541.       ErrCntRemaining = ErrCntRemaining - MsgSize;
  542.     } else {
  543.       (void) strcpy((char *) Msg, (char *) (monerr_tip[-ErrorCode]+index));
  544.       *CountDone = (UDISizeT) strlen(Msg) + 1;
  545.       ErrCntRemaining = (UDISizeT) 0;
  546.     }
  547.     return (UDINoError);
  548.   };
  549.   /* A New ErrorCode */
  550.   if ((ErrorCode <= 0) && (ErrorCode > (-1) * MAX_MONERR)) {
  551.     if (MsgSize < (UDISizeT) MAX_MONERR_SIZE) {
  552.       (void) strncpy((char *) Msg, monerr_tip[-ErrorCode], MsgSize);
  553.       *CountDone = MsgSize;
  554.       ErrCntRemaining = (UDISizeT) (strlen(monerr_tip[-ErrorCode])+1) - MsgSize;
  555.     } else {
  556.       (void) strcpy((char *) Msg, monerr_tip[-ErrorCode]);
  557.       *CountDone = (UDISizeT) strlen(Msg) + 1;
  558.       ErrCntRemaining = (UDISizeT) 0;
  559.     }
  560.     return (UDINoError);
  561.   } else {
  562.     return (UDIErrorUnknownError);
  563.   };
  564. }
  565.  
  566. UDIError 
  567. UDIGetTargetConfig(KnownMemory, NumberOfRanges, ChipVersions, NumberOfChips) 
  568.   UDIMemoryRange KnownMemory[];        /* Out */
  569.   UDIInt    *NumberOfRanges;    /* In/Out */
  570.   UDIUInt32    ChipVersions[];        /* Out */
  571.   UDIInt    *NumberOfChips;        /* In/Out */
  572. {
  573.   UDIInt    InRanges, InChips;
  574.   int        Incomplete;
  575.  
  576.   Incomplete = 0;
  577.  
  578.   InRanges = *NumberOfRanges;
  579.   InChips = *NumberOfChips;
  580.  
  581.   if ((InRanges < (UDIInt) MONMaxMemRanges) || (InChips < (UDIInt) MONMaxChips))
  582.      Incomplete = 1;
  583.    
  584.   *NumberOfRanges = (UDIInt) 0;
  585.   switch ((int) InRanges) {
  586.     default:
  587.     case    3 /* MONMaxMemRanges */:
  588.      if (*NumberOfRanges == (UDIInt) 0)
  589.      *NumberOfRanges = (UDIInt) 3;
  590.      KnownMemory[2].Space = (CPUSpace) UDI29KIRAMSpace;
  591.      KnownMemory[2].Offset = (CPUOffset) tip_target_config.I_mem_start;
  592.      KnownMemory[2].Size = (CPUSizeT) tip_target_config.I_mem_size;
  593.     case    2:
  594.      if (*NumberOfRanges == (UDIInt) 0)
  595.      *NumberOfRanges = (UDIInt) 2;
  596.      KnownMemory[1].Space = (CPUSpace) UDI29KDRAMSpace;
  597.      KnownMemory[1].Offset = (CPUOffset) tip_target_config.D_mem_start;
  598.      KnownMemory[1].Size = (CPUSizeT) tip_target_config.D_mem_size;
  599.     case    1:
  600.      if (*NumberOfRanges == (UDIInt) 0)
  601.      *NumberOfRanges = (UDIInt) 1;
  602.      KnownMemory[0].Space = (CPUSpace) UDI29KIROMSpace;
  603.      KnownMemory[0].Offset = (CPUOffset) tip_target_config.ROM_start;
  604.      KnownMemory[0].Size = (CPUSizeT) tip_target_config.ROM_size;
  605.     break;
  606.     case    0:
  607.         *NumberOfRanges = (UDIInt) 0;
  608.     break;
  609.   }
  610.  
  611.   *NumberOfChips = (UDIInt) 0;
  612.   switch ((int) InChips) {
  613.      default:
  614.      case    2: /* MONMaxChips */
  615.        if (*NumberOfChips == (UDIInt) 0) 
  616.        *NumberOfChips = (UDIInt) 2;
  617.        if (tip_target_config.coprocessor == (UINT32) -1)
  618.           ChipVersions[1] = (UDIUInt32) UDI29KChipNotPresent;
  619.        else
  620.           ChipVersions[1] = (UDIUInt32) tip_target_config.coprocessor;
  621.      case    1:
  622.        if (*NumberOfChips == (UDIInt) 0) 
  623.        *NumberOfChips = (UDIInt) 1;
  624.         ChipVersions[0] = (UDIUInt32) tip_target_config.processor_id;
  625.     break;
  626.      case    0:
  627.     *NumberOfChips = (UDIInt) 0;
  628.     break;
  629.   }
  630.   if (Incomplete)
  631.      return (UDIErrorIncomplete);
  632.   else
  633.      return (UDINoError);
  634. }
  635.  
  636. UDIError 
  637. UDICreateProcess(pid)
  638.   UDIPId         *pid;
  639. {
  640.   if (CurrentPID == (UDIPId) (UDIProcessProcessor + 1))
  641.     return (UDIErrorCantCreateProcess);
  642.   CurrentPID = (UDIPId) (UDIProcessProcessor + 1);
  643.   NumberOfProcesses=1;
  644.   *pid = (UDIPId) CurrentPID;
  645.   return (UDINoError);
  646. }
  647.  
  648. UDIError 
  649. UDISetCurrentProcess(pid)
  650.   UDIPId          pid;
  651. {
  652.   if ((pid > (UDIPId) (UDIProcessProcessor + 1)) ||
  653.      (pid < (UDIPId) (UDIProcessProcessor)))
  654.     return (UDIErrorNoSuchProcess);
  655.   if ((NumberOfProcesses == (int) 0) && (pid != (UDIPId) UDIProcessProcessor))
  656.     return (UDIErrorNoSuchProcess);
  657.   CurrentPID = pid;
  658.   return (UDINoError);
  659. }
  660.  
  661. UDIError 
  662. UDIDestroyProcess(pid)
  663.   UDIPId          pid;
  664. {
  665.   if ((pid > (UDIPId) (UDIProcessProcessor + 1)) ||
  666.      (pid < (UDIPId) (UDIProcessProcessor)))
  667.     return (UDIErrorNoSuchProcess);
  668.   CurrentPID = (UDIPId) UDIProcessProcessor;
  669.   ProcessorState = (UDIUInt32) UDINotExecuting;
  670.   PreviousProcessorState = (UDIUInt32) UDINotExecuting;
  671.   NumberOfProcesses=0;
  672.   return (UDINoError);
  673. }
  674.  
  675. UDIError 
  676. UDIInitializeProcess (ProcessMemory, NumberOfRanges, EntryPoint, StackSizes, NumberOfStacks, ArgString)
  677.   UDIMemoryRange ProcessMemory[];    /* In */
  678.   UDIInt    NumberOfRanges;        /* In */
  679.   UDIResource    EntryPoint;        /* In */
  680.   CPUSizeT    StackSizes[];        /* In */
  681.   UDIInt    NumberOfStacks;        /* In */
  682.   char        *ArgString;        /* In */
  683. {
  684.   UDIError        ErrCode;
  685.   UDIRange      text_addr, data_addr;
  686.   CPUSizeT      mem_stack_size, reg_stack_size;
  687.  
  688.   ADDR32          arg_start;
  689.   ADDR32          data_high;
  690.   ADDR32          highmem;
  691.   INT32           os_control;
  692.   INT32        MsgCode;
  693.   UDIInt    i;
  694.  
  695.  
  696.   exitstat = 0;    /* reset */
  697.  
  698.   PgmStdinMode=TIP_COOKED;    /* revert to default mode */
  699.  
  700.   CLEAR_PENDING_STOP
  701.  
  702.   if (CurrentPID == (UDIPId) UDIProcessProcessor) {
  703.     if ((MsgCode = Reset_Processor()) != SUCCESS)
  704.        return ((UDIError) MsgCode);
  705.     do {
  706.        MsgCode = SendConfigWait();
  707.     } while (MsgCode == HALT);
  708.     if (MsgCode == ABORT_FAILURE)
  709.        return (UDIErrorAborted);
  710.     else if (MsgCode == FAILURE)
  711.     return ((-1) * MONErrNoSynch);
  712.     else if (MsgCode != CONFIG)
  713.     return ((-1) * MONErrCantRecvMsg);
  714.     Mini_unpack_config_msg(&tip_target_config);
  715.     /* Reallocate message buffers */
  716.     if (Mini_alloc_msgbuf((int) tip_target_config.max_msg_size) != SUCCESS)
  717.       return ((-1) * MONErrCantAllocBufs);
  718.     ProcessorState = (UDIUInt32) UDINotExecuting;
  719.     Channel0_count = 0;
  720.     Channel1_count = 0;
  721.     Channel2_count = 0;
  722.     Channel0Busy = 0;
  723.     PreviousProcessorState = (UDIUInt32) UDINotExecuting;
  724.     return (UDINoError);
  725.   };
  726.  
  727.  
  728.   /* For other processes */
  729.   /* Set Default Values */
  730.   mem_stack_size = (CPUSizeT) MONDefaultMemStackSize;
  731.   reg_stack_size = (CPUSizeT) MONDefaultRegStackSize;
  732.   text_addr.Low = (CPUOffset) tip_target_config.I_mem_start;
  733.   text_addr.High = (CPUOffset) tip_target_config.I_mem_start +
  734.            (CPUOffset) tip_target_config.I_mem_size - 1;
  735.   data_addr.Low = (CPUOffset) tip_target_config.D_mem_start;
  736.   data_addr.High = (CPUOffset) tip_target_config.D_mem_start +
  737.            (CPUOffset) tip_target_config.D_mem_size -
  738.            (CPUOffset) (mem_stack_size + reg_stack_size + 16) - 1;
  739.  
  740.   /* Get Memory Ranges */
  741.   if (NumberOfRanges != (UDIInt) 0) {
  742.      for (;NumberOfRanges--;) {
  743.        switch ((int) ProcessMemory[NumberOfRanges].Space) {
  744.       case    UDI29KIRAMSpace:
  745.         text_addr.Low = ProcessMemory[NumberOfRanges].Offset;
  746.         text_addr.High = ProcessMemory[NumberOfRanges].Offset +
  747.             (CPUOffset) ProcessMemory[NumberOfRanges].Size;
  748.         break;
  749.       case    UDI29KDRAMSpace:
  750.         data_addr.Low = ProcessMemory[NumberOfRanges].Offset;
  751.         data_addr.High = ProcessMemory[NumberOfRanges].Offset +
  752.             (CPUOffset) ProcessMemory[NumberOfRanges].Size;
  753.         break;
  754.       default: /* don't care */
  755.         break;
  756.        } /* switch */
  757.      } /* for */
  758.   }
  759.   /* Get Stack Sizes */
  760.   for (i = (UDIInt) 0; i < NumberOfStacks; i=i+(UDIInt)1) {
  761.      switch ((int) i) {
  762.     case    0:  /* register stack size */
  763.         if (StackSizes[0] != (CPUSizeT) 0)
  764.           reg_stack_size = StackSizes[0];
  765.         break;
  766.     case    1: /* memory stack size */
  767.         if (StackSizes[1] != (CPUSizeT) 0)
  768.           mem_stack_size = StackSizes[1];
  769.         break;
  770.     default: /* don't care */
  771.         break;
  772.      }
  773.   }
  774.  
  775.   if ((CPUOffset) text_addr.High > (CPUOffset) data_addr.High)
  776.      data_addr.High = text_addr.High;  /* when no data sections */
  777.   arg_start = (data_addr.High + 7) & ~0x7;    /* word boundary */
  778.  
  779.   if ((ErrCode = write_args(ArgString, 
  780.                 arg_start, &data_high)) != UDINoError)
  781.     return (ErrCode);
  782.  
  783.   data_addr.High = (data_high + 7) & ~0x7;    /* double word bdry */
  784.  
  785.   highmem = (ADDR32) 0;
  786.  
  787.   /* User programs run mode */
  788.   if (SupervisorMode)
  789.     os_control = (INT32) 0x10000000;    /* set bit 28 only */
  790.   else if (VirtualMode || ProtectedMode)
  791.     os_control = (INT32) 0;
  792.   else
  793.     os_control = (INT32) 0x80000000;
  794.  
  795.   Mini_build_init_msg((ADDR32) text_addr.Low, (ADDR32) text_addr.High,
  796.               (ADDR32) data_addr.Low, (ADDR32) data_addr.High,
  797.               (ADDR32) EntryPoint.Offset,
  798.               (INT32) mem_stack_size, (INT32) reg_stack_size,
  799.               (ADDR32) highmem,
  800.               (ADDR32) arg_start,
  801.               (INT32) os_control);
  802.   SEND_AND_WAIT_ACK(INIT_ACK);
  803.   if (ReturnedError == (int) 1) {
  804.     ReturnedError = 0;
  805.     return ((-1) * MONErrErrorInit);
  806.   }
  807.   Mini_unpack_init_ack_msg();
  808.  
  809.   ProcessorState = (UDIUInt32) UDINotExecuting;
  810.   PreviousProcessorState = (UDIUInt32) UDINotExecuting;
  811.  
  812.   return (UDINoError);
  813. }
  814.  
  815. UDIError 
  816. UDIRead(from, to, count, size, count_done, host_endian)
  817.   UDIResource     from;
  818.   UDIHostMemPtr   to;
  819.   UDICount        count;
  820.   UDISizeT          size;
  821.   UDICount       *count_done;
  822.   UDIBool         host_endian;
  823. {
  824.   INT32           space = SpaceMap_udi2mm(from.Space);
  825.   INT32           done;
  826.   INT32           ttl_count;
  827.   INT32           msg_count;
  828.   INT32           overhead;
  829.  
  830.   ADDR32          ack_addr;
  831.   INT32          ack_space;
  832.   BYTE           *output;
  833.   UDIError        UDIretval;
  834.  
  835.   UDICount        i;
  836.   INT32          *Version;
  837.  
  838.   int             Gr1_val;
  839.   int             Lrnum;
  840.   int             j;
  841.   UDIResource     temp_from;
  842.   UDICount        temp_done;
  843.   UDIUInt32       start_offset,
  844.                   end_offset;
  845.   BYTE           *reg_data;
  846.  
  847.  
  848.   CLEAR_PENDING_STOP
  849.  
  850.   if (count <= (UDICount) 0) {
  851.     *count_done = (UDICount) 0;
  852.     return (UDINoError);
  853.   }
  854.  
  855.   if (space == (INT32) VERSION_SPACE) {    /* minimon ver cmd */
  856.     Version = (INT32 *) to;
  857.     *Version = (INT32) tip_target_config.version;
  858.      *(Version+1) = (INT32) tip_target_config.os_version; 
  859.     /*  TIPVERSION must be 11 chars or less  */
  860.     strcpy((char *) (Version+2),TIPVERSION); 
  861.     /*  TIPDATE must be 11 chars or less  */
  862.     strcpy((char *) (Version+5),TIPDATE); 
  863.     /* max msg size */
  864.     *(Version + 8) = tip_target_config.max_msg_size;
  865.     /* max bkpts */
  866.     *(Version + 9) = tip_target_config.max_bkpts;
  867.     if ((host_endian) && (tip_target_config.TipEndian != tip_target_config.P29KEndian)) {
  868.       output = (BYTE *) to;
  869.       for (i = 0; i < count; i++) {
  870.         if (size == 4)
  871.       tip_convert32(output);
  872.         else if (size == 2)
  873.       tip_convert16(output);
  874.         output = output + size;
  875.       }
  876.     }    /* hostendian */
  877.     *count_done = (UDICount) count;
  878.     return (UDINoError);
  879.   };
  880.  
  881.   if (space < (INT32) 0) {
  882.     *count_done = (UDICount) 0;
  883.     return (UDIErrorUnknownResourceSpace);
  884.   }
  885.  
  886.   output = (BYTE *) to;
  887.  
  888.   switch (from.Space) {
  889.    case UDI29KPC:
  890.     from.Offset = 1;    /* PC1 */
  891.     break;
  892.    case UDI29KGlobalRegs:
  893.     break;
  894.    case UDI29KRealRegs:
  895.     /* REAL REGS BEGIN */
  896.     /* get global and local reg values from target if target exec'ed */
  897.     if (RefreshRegs) {
  898.       RefreshRegs = 0;    /* reset */
  899.       temp_from.Offset = (CPUOffset) 0;
  900.       temp_from.Space = UDI29KGlobalRegs;
  901.       if ((UDIretval = UDIRead(temp_from,
  902.                    (UDIHostMemPtr) &Glob_Regs[0],
  903.                    (UDICount) 2,
  904.                    (UDISizeT) 4,
  905.                    (UDICount *) &temp_done,
  906.                    (UDIBool) TRUE)) != UDINoError)    /* gr0, gr1 */
  907.     return (UDIretval);
  908.       /* UDIRead ();  gr64 to gr 127 */
  909.       temp_from.Offset = (CPUOffset) 64;
  910.       temp_from.Space = UDI29KGlobalRegs;
  911.       if ((UDIretval = UDIRead(temp_from,
  912.                    (UDIHostMemPtr) &Glob_Regs[64],
  913.                    (UDICount) 64,
  914.                    (UDISizeT) 4,
  915.                    (UDICount *) &temp_done,
  916.                    (UDIBool) TRUE)) != UDINoError)    /* gr0, gr1 */
  917.     return (UDIretval);
  918.       /* UDIRead ();   lr0 to lr127 */
  919.       temp_from.Offset = (CPUOffset) 0;
  920.       temp_from.Space = UDI29KLocalRegs;
  921.       if ((UDIretval = UDIRead(temp_from,
  922.                    (UDIHostMemPtr) &Loc_Regs[0],
  923.                    (UDICount) 128,
  924.                    (UDISizeT) 4,
  925.                    (UDICount *) &temp_done,
  926.                    (UDIBool) TRUE)) != UDINoError)    /* gr0, gr1 */
  927.     return (UDIretval);
  928.     };
  929.  
  930.     start_offset = from.Offset;
  931.     end_offset = start_offset + count;
  932.     output = (BYTE *) to;
  933.     while (start_offset < end_offset) {    /* do only if count is non zero */
  934.       if (start_offset <= (UDIUInt32) 127) {
  935.     reg_data = (BYTE *) &Glob_Regs[(int) start_offset];
  936.     for (j = 0; j < 4 /* sizeof (UDIUInt32) */ ; j++)
  937.       *output++ = *reg_data++;
  938.       } else if ((start_offset >= (UDIUInt32) 128) && (start_offset <= (UDIUInt32) 255)) {
  939.     Gr1_val = (int) (Glob_Regs[1] & 0x000001FC) >> 2;    /* bits 2 to 8 */
  940.     Lrnum = (int) ((int) start_offset - Gr1_val) % 128;
  941.     reg_data = (BYTE *) & Loc_Regs[(int) Lrnum];
  942.     for (j = 0; j < 4 /* sizeof (UDIUInt32) */ ; j++)
  943.       *output++ = *reg_data++;
  944.       } else
  945.     return (UDIErrorUnknownResourceSpace);
  946.       start_offset = start_offset + (UDIUInt32) 1;
  947.     }    /* end while */
  948.     *count_done = (UDICount) count;
  949.     return (UDINoError);
  950.     /* REAL REGS END */
  951.    default:
  952.     break;
  953.   }
  954.  
  955.   output = (BYTE *) to;
  956.   if ( (RemoteTarget == 0) &&
  957.     ((from.Space == UDI29KDRAMSpace) ||
  958.      (from.Space == UDI29KIRAMSpace) ||
  959.      (from.Space == UDI29KIROMSpace))) { /* shared memory board */
  960.       Mini_read_memory(space, from.Offset, count * size, (BYTE *) output);
  961.   } else {
  962.      /* overhead = checksum + header + size rounding + bfr rounding + ? */
  963.      overhead = 32;
  964.      ttl_count = count;
  965.      output = (BYTE *) to;
  966.      while (ttl_count > 0) {    
  967.        /* Check for user interrupt */
  968.        if (StopFlag) {
  969.           STOP_SIG_HDLR
  970.           ProcessorState = (UDIUInt32) UDIStopped;
  971.           PreviousProcessorState = (UDIUInt32) UDIStopped;
  972.           return (UDIErrorAborted);
  973.        }; 
  974.        /* Check possible buffer overflow */
  975.        if ((ttl_count * size) + overhead > 
  976. #ifdef MSDOS
  977.            tip_target_config.max_msg_size) {
  978.          msg_count = (tip_target_config.max_msg_size-overhead) >> (size >> 1);  
  979. #else
  980.            (INT32) 256) { /* SunOS has problems with higher numbers */
  981.          msg_count = (256 - overhead) >> (size >> 1);  
  982. #endif
  983.          ttl_count = ttl_count - msg_count;
  984.        } else {
  985.          msg_count = ttl_count;
  986.          ttl_count = ttl_count - msg_count;
  987.        }
  988.        Mini_build_read_req_msg(space, (ADDR32) from.Offset, msg_count, size);
  989.        SEND_AND_WAIT_ACK(READ_ACK);
  990.        if (ReturnedError == (int) 1) {
  991.      ReturnedError = 0;
  992.      return ((-1) * MONErrErrorRead);
  993.        }
  994.        Mini_unpack_read_ack_msg((INT32 *) &ack_space, (ADDR32 *) &ack_addr,
  995.                  (INT32 *) &done, (BYTE *) output);
  996.        output = output + (msg_count * size);
  997.        if (ISMEM(space))
  998.           from.Offset = from.Offset + (CPUOffset) (msg_count * size);
  999.        else
  1000.           from.Offset = from.Offset + (CPUOffset) msg_count;
  1001.      }
  1002.   } /* end while */
  1003.  
  1004.   if ((host_endian) && 
  1005.     (tip_target_config.TipEndian != tip_target_config.P29KEndian)) {
  1006.     output = (BYTE *) to;
  1007.     for (i = 0; i < count; i++) {
  1008.       if (size == 4)
  1009.     tip_convert32(output);
  1010.       else if (size == 2)
  1011.     tip_convert16(output);
  1012.       output = output + size;
  1013.     }
  1014.   }    /* hostendian */
  1015.  
  1016.   *count_done = (UDICount) count;
  1017.   return (UDINoError);
  1018. }
  1019.  
  1020. UDIError 
  1021. UDIWrite(from, to, count, size, count_done, HostEndian)
  1022.   UDIHostMemPtr   from;
  1023.   UDIResource     to;
  1024.   UDICount        count;
  1025.   UDISizeT          size;
  1026.   UDICount       *count_done;
  1027.   UDIBool         HostEndian;
  1028. {
  1029.   INT32           space = SpaceMap_udi2mm(to.Space);
  1030.   INT32           done;
  1031.   INT32           ttl_count;
  1032.   INT32           msg_count;
  1033.   INT32           overhead;
  1034.   ADDR32          ack_addr;
  1035.   INT32          ack_space;
  1036.   BYTE           *input;
  1037.   UDIError        UDIretval;
  1038.   UDIUInt32       tmpbuf[2];
  1039.   UDICount        i;
  1040.  
  1041.   /* REAL REGS BEGIN */
  1042.   UDIResource     temp_to;
  1043.   UDICount        temp_done;
  1044.   CPUOffset       start_offset,
  1045.                   end_offset;
  1046.   UDIUInt32       Gr1_val;
  1047.  
  1048.   /* REAL REGS END */
  1049.  
  1050.   CLEAR_PENDING_STOP
  1051.  
  1052.   if (space < (INT32) 0) {
  1053.     *count_done = (UDICount) 0;
  1054.     return (UDIErrorUnknownResourceSpace);
  1055.   }
  1056.  
  1057.   if (count <= (UDICount) 0) {
  1058.     *count_done = (UDICount) 0;
  1059.     return (UDINoError);
  1060.   }
  1061.  
  1062.   if (to.Space == UDI29KPC) {
  1063.     /* when writing UDI29KPC, set both PC1 and PC0 */
  1064.     /* NOTE: this assumes we are not in freeze mode */
  1065.     /* this must all be done before doing the endian conversion below */
  1066.     to.Offset = 0;    /* start at PC0 */
  1067.     count = (UDIInt32) 2;    /* writing 2 4-byte quantities */
  1068.     tmpbuf[1] = *((UDIUInt32 *) from);    /* PC1 = PC */
  1069.     if (!HostEndian && (tip_target_config.TipEndian != tip_target_config.P29KEndian)) {
  1070.     tmpbuf[0] = tmpbuf[1];
  1071.     tip_convert32((BYTE *) &tmpbuf[0]);
  1072.         tmpbuf[0] = tmpbuf[0] + 4;    /* PC0 = PC + 4 */
  1073.     tip_convert32((BYTE *) &tmpbuf[0]);
  1074.     } else {
  1075.         tmpbuf[0] = tmpbuf[1] + 4;    /* PC0 = PC + 4 */
  1076.     }
  1077.     from = (UDIHostMemPtr) tmpbuf;    /* set pointer to temporary (8-byte)
  1078.                      * buffer */
  1079.   }
  1080.  
  1081.   switch (to.Space) {
  1082.    case UDI29KLocalRegs:
  1083.     RefreshRegs = 1;
  1084.     break;
  1085.    case UDI29KPC:    /* PC causes special regs(PC0,PC1) space */
  1086.     break;
  1087.    case UDI29KGlobalRegs:
  1088.     RefreshRegs = 1;
  1089.     break;
  1090.    case UDI29KRealRegs:
  1091.     RefreshRegs = 1;
  1092.     /* REAL REGS BEGIN */
  1093.     start_offset = to.Offset;
  1094.     end_offset = start_offset + count - 1;
  1095.     if ((end_offset <= 127)) {    /* all globals asked */
  1096.       temp_to.Offset = to.Offset;
  1097.       temp_to.Space = UDI29KGlobalRegs;
  1098.       if ((UDIretval = UDIWrite(from,
  1099.                 temp_to,
  1100.                 count,
  1101.                 size,
  1102.                 &temp_done,
  1103.                 HostEndian)) != UDINoError)
  1104.     return (UDIretval);
  1105.     } else if (start_offset > 127) {    /* all local regs */
  1106.       /* read gr1 */
  1107.       temp_to.Offset = (CPUOffset) 1;
  1108.       temp_to.Space = UDI29KGlobalRegs;
  1109.       if ((UDIretval = UDIRead(temp_to,
  1110.                    (UDIHostMemPtr) &Gr1_val,
  1111.                    (UDICount) 1,
  1112.                    (UDISizeT) 4,
  1113.                    (UDICount *) &temp_done,
  1114.                    (UDIBool) TRUE)) != UDINoError)    /* gr1 */
  1115.     return (UDIretval);
  1116.       /* recompute start_offset and end_offset */
  1117.       Gr1_val = (Gr1_val & 0x01FC) >> 2;
  1118.       start_offset = (start_offset - Gr1_val) % 128;
  1119.       end_offset = (end_offset - Gr1_val) % 128;
  1120.       input = (BYTE *) from;
  1121.       if (start_offset > end_offset) {    /* wrap around */
  1122.     temp_to.Offset = start_offset;
  1123.     temp_to.Space = UDI29KLocalRegs;
  1124.     if ((UDIretval = UDIWrite(input,
  1125.                   temp_to,
  1126.                   (UDICount) (128 - start_offset),
  1127.                   size,
  1128.                   &temp_done,
  1129.                   HostEndian)) != UDINoError)
  1130.       return (UDIretval);
  1131.     input = input + (int) ((128 - start_offset) * size);
  1132.     temp_to.Offset = (CPUOffset) 0;    /* from LR0 */
  1133.     temp_to.Space = UDI29KLocalRegs;
  1134.     if ((UDIretval = UDIWrite(input,
  1135.                   temp_to,
  1136.                   (UDICount) (end_offset + 1 ),
  1137.                   size,
  1138.                   &temp_done,
  1139.                   HostEndian)) != UDINoError)
  1140.       return (UDIretval);
  1141.       } else {    /* no wrapping */
  1142.     temp_to.Offset = start_offset;
  1143.     temp_to.Space = UDI29KLocalRegs;
  1144.     if ((UDIretval = UDIWrite(input,
  1145.                   temp_to,
  1146.                   count,
  1147.                   size,
  1148.                   &temp_done,
  1149.                   HostEndian)) != UDINoError)
  1150.       return (UDIretval);
  1151.       }
  1152.     } else {    /* overlap */
  1153.       input = (BYTE *) from;
  1154.       /* write globals */
  1155.       temp_to.Offset = start_offset;
  1156.       temp_to.Space = UDI29KGlobalRegs;
  1157.       if ((UDIretval = UDIWrite(input,
  1158.                 temp_to,
  1159.                 ((UDICount) 128 - (UDICount) start_offset),
  1160.                 size,
  1161.                 &temp_done,
  1162.                 HostEndian)) != UDINoError)
  1163.     return (UDIretval);
  1164.       input = input + (int) (size) * ((UDICount) 128 - (UDICount) start_offset);
  1165.       /* write locals */
  1166.       temp_to.Offset = (CPUOffset) 128;
  1167.       temp_to.Space = UDI29KRealRegs;
  1168.       if ((UDIretval = UDIWrite(input,
  1169.                 temp_to,
  1170.                 (UDICount) (count - 128 + start_offset),
  1171.                 size,
  1172.                 &temp_done,
  1173.                 HostEndian)) != UDINoError)
  1174.     return (UDIretval);
  1175.     }
  1176.     *count_done = (UDICount) count;
  1177.     return (UDINoError);
  1178.     /* REAL REGS END */
  1179.    default:
  1180.     break;
  1181.   }
  1182.  
  1183.   if (HostEndian && 
  1184.           (tip_target_config.TipEndian != tip_target_config.P29KEndian)) {
  1185.     input = (BYTE *) from;
  1186.     for (i = 0; i < count; i++) {
  1187.       if (size == 4)
  1188.     tip_convert32(input);
  1189.       else if (size == 2)
  1190.     tip_convert16(input);
  1191.       input = input + size;
  1192.     }
  1193.   }; /* endian conversion done */
  1194.  
  1195.   input = (BYTE *) from;
  1196.   if ((RemoteTarget == 0) &&
  1197.     ((to.Space == UDI29KDRAMSpace) ||
  1198.      (to.Space == UDI29KIRAMSpace) ||
  1199.      (to.Space == UDI29KIROMSpace))) {
  1200.       Mini_write_memory(space, to.Offset, count * size, (BYTE *) input);
  1201.       *count_done = (UDICount) count;
  1202.       return (UDINoError);
  1203.   } else {  /* remote */
  1204.      /* overhead = checksum + header + size rounding + bfr rounding + ? */
  1205.      overhead = 32;
  1206.      ttl_count = count;
  1207.      input = (BYTE *) from;
  1208.      while (ttl_count > 0) {    
  1209.        /* Check for user interrupt */
  1210.        if (StopFlag) {
  1211.           STOP_SIG_HDLR
  1212.           ProcessorState = (UDIUInt32) UDIStopped;
  1213.           PreviousProcessorState = (UDIUInt32) UDIStopped;
  1214.           return (UDIErrorAborted);
  1215.        }; 
  1216.        /* Check possible buffer overflow */
  1217.        if ((ttl_count * size) + overhead > 
  1218.            tip_target_config.max_msg_size) {
  1219.          msg_count = (tip_target_config.max_msg_size-overhead) >> (size >> 1);  
  1220.          ttl_count = ttl_count - msg_count;
  1221.        } else {
  1222.          msg_count = ttl_count;
  1223.          ttl_count = ttl_count - msg_count;
  1224.        }
  1225.        Mini_build_write_req_msg(space, (ADDR32) to.Offset,
  1226.                   msg_count, size, (BYTE *) input);
  1227.        SEND_AND_WAIT_ACK(WRITE_ACK);
  1228.        if (ReturnedError == (int) 1) {
  1229.      ReturnedError = 0;
  1230.      return ((-1) * MONErrErrorWrite);
  1231.        }
  1232.        Mini_unpack_write_ack_msg((INT32 *) &ack_space,
  1233.                   (ADDR32 *) &ack_addr,
  1234.                   (INT32 *) &done);
  1235.        input = input + (msg_count * size);
  1236.        if (ISMEM(space))
  1237.           to.Offset = to.Offset + (CPUOffset) (msg_count * size);
  1238.        else
  1239.           to.Offset = to.Offset + (CPUOffset) msg_count;
  1240.      }    /* while */
  1241.   } /* end remote */
  1242.   *count_done = (to.Space == UDI29KPC) ? (UDICount) 1 : (UDICount) count;
  1243.   return (UDINoError);
  1244. }
  1245.  
  1246. UDIError 
  1247. UDICopy(from, to, count, size, count_done, direction)
  1248.   UDIResource     from;
  1249.   UDIResource     to;
  1250.   UDICount        count;
  1251.   UDISizeT          size;
  1252.   UDICount       *count_done;
  1253.   UDIBool         direction;
  1254. {
  1255.   INT32           f_space = SpaceMap_udi2mm(from.Space);
  1256.   INT32           t_space = SpaceMap_udi2mm(to.Space);
  1257.  
  1258.   UDICount      counter, maxcount,curcount;
  1259.   INT32          fill_count, fill_size;
  1260.   
  1261.   INT32           done;
  1262.   ADDR32          ack_saddr,
  1263.                   ack_daddr;
  1264.  
  1265.   CLEAR_PENDING_STOP
  1266.  
  1267.   if ((t_space < 0) || (f_space < 0)) {
  1268.     *count_done = (UDICount) 0;
  1269.     return (UDIErrorUnknownResourceSpace);
  1270.   }
  1271.  
  1272.   if (count <= (UDICount) 0) {
  1273.     *count_done = (UDICount) 0;
  1274.     return (UDINoError);
  1275.   }
  1276.  
  1277.   RefreshRegs = 1;
  1278.  
  1279.   /* Split the copy to smaller copies based on the message size */
  1280.   maxcount = (UDICount) (tip_target_config.max_msg_size / size);
  1281.   counter = (UDICount) count;
  1282.  
  1283.   while (counter > (UDICount) 0) {
  1284.     /* Check for user interrupt */
  1285.     if (StopFlag) {
  1286.        STOP_SIG_HDLR
  1287.        ProcessorState = (UDIUInt32) UDIStopped;
  1288.        PreviousProcessorState = (UDIUInt32) UDIStopped;
  1289.        return (UDIErrorAborted);
  1290.     }; 
  1291.     curcount = (maxcount < counter) ? maxcount : counter;
  1292.     counter = counter - curcount;
  1293.     if ((size > (UDISizeT) 4) && (t_space == (INT32) I_MEM)) { 
  1294.        /* reduce it to  4, must be a multiple also for I_MEM */
  1295.        fill_count = (INT32) (curcount * (size/4));
  1296.        fill_size = (INT32) size;
  1297.     } else if ((size > (UDISizeT) 4) && (t_space != (INT32) I_MEM)) { 
  1298.        /* copy as bytes */
  1299.        fill_count = (INT32) (curcount * size);
  1300.        fill_size = (INT32) 1; /* bytes */
  1301.     } else {
  1302.        fill_count = (INT32) curcount;
  1303.        fill_size = (INT32) size;
  1304.     };
  1305.     Mini_build_copy_msg(f_space, (ADDR32) from.Offset,
  1306.               t_space, (ADDR32) to.Offset,
  1307.               fill_count, fill_size);
  1308.     SEND_AND_WAIT_ACK(COPY_ACK);
  1309.     if (ReturnedError == (int) 1) {
  1310.       ReturnedError = 0;
  1311.       return ((-1) * MONErrErrorCopy);
  1312.     }
  1313.     Mini_unpack_copy_ack_msg(&f_space, &ack_saddr,
  1314.                &t_space, &ack_daddr, &done);
  1315.     from.Offset = from.Offset + (CPUOffset) (curcount * size);
  1316.     to.Offset = to.Offset + (CPUOffset) (curcount * size);
  1317.   }; /* end while */
  1318.  
  1319.   *count_done = (UDICount) count;
  1320.   return (UDINoError);
  1321. }
  1322.  
  1323. UDIError 
  1324. UDIExecute()
  1325. {
  1326.   INT32           MsgCode;
  1327.  
  1328.     CLEAR_PENDING_STOP
  1329.  
  1330.   if (!NoStepReqd) {
  1331.     if (!StepCmdGiven) {
  1332.       /* Execute one instruction */
  1333.       Mini_build_step_msg((INT32) 1);
  1334.  
  1335.       if (Mini_msg_send() != SUCCESS)
  1336.     return ((-1) * MONErrCantSendMsg);
  1337.       /* process message received from target */
  1338.       MsgCode = Wait_For_Ack();
  1339.       if (MsgCode == ABORT_FAILURE)
  1340.     return (UDIErrorAborted);
  1341.       else if (MsgCode == FAILURE)
  1342.     return ((-1) * MONErrNoAck);
  1343.  
  1344.       process_target_msg(MsgCode);
  1345.  
  1346.       /* if processor state is stepped, set breakpoints, issue a GO */
  1347.       if (ProcessorState != (UDIUInt32) UDIStepped) {
  1348.     RefreshRegs = 1;
  1349.     return (UDINoError);
  1350.       }
  1351.       PutAllBreakpoints();
  1352.       BreaksInPlace = 1;
  1353.     }
  1354.   }
  1355.  
  1356.   Mini_build_go_msg();
  1357.  
  1358.   if (Mini_msg_send() != SUCCESS)
  1359.     return ((-1) * MONErrCantSendMsg);
  1360.  
  1361.   RefreshRegs = 1;
  1362.   ProcessorState = (UDIUInt32) UDIRunning;
  1363.   PreviousProcessorState = (UDIUInt32) UDIRunning;
  1364.  
  1365.   return (UDINoError);
  1366. }
  1367.  
  1368. /*
  1369.  * Stepping will NOT cause any breakpoints to be installed. It will step the
  1370.  * number requested.
  1371.  */
  1372.  
  1373. UDIError 
  1374. UDIStep(steps, steptype, range)
  1375.   UDIUInt32       steps;
  1376.   UDIStepType     steptype;
  1377.   UDIRange        range;
  1378. {
  1379.   CLEAR_PENDING_STOP
  1380.  
  1381.   if (steps == (UDIUInt32) 0)
  1382.     return (UDINoError);
  1383.  
  1384.   if ((steptype & UDIStepOverCalls) || (steptype & UDIStepOverTraps) ||
  1385.        (steptype & UDIStepInRange))
  1386.        return (UDIErrorUnsupportedStepType);
  1387.  
  1388.   StepCmdGiven = 1;
  1389.   Mini_build_step_msg(steps);
  1390.   if (Mini_msg_send() != SUCCESS)
  1391.     return ((-1) * MONErrCantSendMsg);
  1392.   RefreshRegs = 1;
  1393.   ProcessorState = (UDIUInt32) UDIRunning;
  1394.   PreviousProcessorState = (UDIUInt32) UDIRunning;
  1395.  
  1396.   return (UDINoError);
  1397. }
  1398.  
  1399. UDIVoid 
  1400. UDIStop()
  1401. {
  1402.   int    GrossState;
  1403.  
  1404.   GrossState = (int) (ProcessorState & 0xFF);
  1405.   if ((GrossState == UDINotExecuting) || (GrossState == UDIRunning) ||
  1406.       (GrossState == UDIStdoutReady) || (GrossState == UDIStderrReady) ||
  1407.       (GrossState == UDIStdinNeeded) ) {
  1408.       StopFlag = 1; /* This will be reset after its handled */
  1409.   }
  1410.   /* Else ignored */
  1411.   return; 
  1412. }
  1413.  
  1414. UDIError 
  1415. UDIWait(maxtime, pid, stop_reason)
  1416.   UDIInt32        maxtime;
  1417.   UDIPId         *pid;
  1418.   UDIUInt32      *stop_reason;
  1419. {
  1420.   INT32           MsgCode;
  1421.  
  1422.   *pid = (UDIPId) CurrentPID;
  1423.  
  1424.   if (ProcessorState == (UDIUInt32) UDIRunning) {
  1425.     while (1) { /* handle messages as long as they are coming */
  1426.       if (MsgAlreadyInBuffer==1) {
  1427.     MsgCode = MsgAlreadyReceived;
  1428.     MsgAlreadyInBuffer=0;
  1429.       } else {
  1430.         MsgCode = CheckForMsg(maxtime);
  1431.       }
  1432. #if 0
  1433.       MsgCode = CheckForMsg(maxtime);
  1434. #endif
  1435.       if ((MsgCode == FAILURE) || (MsgCode == ABORT_FAILURE)) { /* no news */
  1436.         *stop_reason = ProcessorState;    
  1437.         return (UDINoError);
  1438.       } else {    /* a message from target has arrived */
  1439.         *stop_reason = ProcessorState;
  1440.     if (MsgCode == CHANNEL0_ACK) {
  1441.        process_chan0_ack();
  1442.        return (UDINoError);
  1443.     }
  1444.         (void) process_target_msg(MsgCode);
  1445.         if (ProcessorState != (UDIUInt32) UDIRunning) 
  1446.           return (UDINoError);
  1447.       };
  1448.     }
  1449.   } else {
  1450.     *stop_reason = ProcessorState;
  1451.     return (UDINoError);
  1452.   }
  1453. }
  1454.  
  1455. UDIError 
  1456. UDISetBreakpoint(addr, pass_count, bk_type, break_id)
  1457.   UDIResource     addr;
  1458.   UDIInt32        pass_count;
  1459.   UDIBreakType    bk_type;
  1460.   BreakIdType    *break_id;
  1461. {
  1462.   INT32           space = SpaceMap_udi2mm(addr.Space);
  1463.   ADDR32          ack_addr;
  1464.   INT32           set_count,
  1465.                   set_type;
  1466.   BreakIdType     newid;
  1467.   UDIUInt32       BreakInst;    /* EB29K */
  1468.   UDIError        UDIretval;    /* EB29K */
  1469.  
  1470.   CLEAR_PENDING_STOP
  1471.  
  1472.   if (space < 0)
  1473.     return (UDIErrorUnknownResourceSpace);
  1474.  
  1475.   /*
  1476.    * Minimon currently supports only two types of breakpoints * BKPT_29000
  1477.    * and BKPT_29050 *
  1478.    */
  1479.   if (bk_type & MONBreakFlagHardware) {
  1480.     if (bk_type & MONBreakTranslationEnabled)
  1481.       bk_type = BKPT_29050_BTE_1;
  1482.     else
  1483.       bk_type = BKPT_29050_BTE_0;    /* default */
  1484.   } else if ((bk_type & UDIBreakFlagRead) || (bk_type & UDIBreakFlagWrite))
  1485.     return ((-1) * MONErrUnknownBreakType);
  1486.   else if (bk_type & UDIBreakFlagExecute)
  1487.     bk_type = BKPT_29000;    /* Minimon uses this */
  1488.  
  1489.   if (pass_count == (UDIInt32) 0)
  1490.      pass_count = (UDIInt32) -1; /* make it temporary */
  1491.   Mini_build_bkpt_set_msg(space,
  1492.               (ADDR32) addr.Offset,
  1493.               (INT32) pass_count,
  1494.               (INT32) bk_type);
  1495.   SEND_AND_WAIT_ACK (BKPT_SET_ACK);
  1496.   if (ReturnedError == (int) 1) {
  1497.     ReturnedError = 0;
  1498.     return ((-1) * MONErrErrorSetBreak);
  1499.   }
  1500.   Mini_unpack_bkpt_set_ack_msg((INT32 *) &space,
  1501.                    (ADDR32 *) &ack_addr,
  1502.                    (INT32 *) &set_count,
  1503.                    (INT32 *) &set_type);
  1504.  
  1505.   BreakInst = (ADDR32) - 1;
  1506.  
  1507.   if (!strcmp(TargetType, "eb29k")) {    /* For EB29K */
  1508.     /* UDIRead(); read instruction */
  1509.     if ((UDIretval = UDIRead(addr,
  1510.                  (UDIHostMemPtr) &BreakInst,
  1511.                  (UDICount) 4,
  1512.                  (UDISizeT) 1,
  1513.                  (UDICount *) &ack_addr,
  1514.                  (UDIBool) FALSE)) != UDINoError)    /* 29K endian */
  1515.       return (UDIretval);
  1516.   };
  1517.  
  1518.   add_to_bp_table(&newid, space, addr.Offset, set_count, set_type, BreakInst);
  1519.   *break_id = (BreakIdType) newid;
  1520.   LastBreakId = newid + 1;    /* ??? */
  1521.   return (UDINoError);
  1522. }
  1523.  
  1524. UDIError 
  1525. UDIQueryBreakpoint(break_id, addr, pass_count,
  1526.            bk_type, current_count)
  1527.   BreakIdType     break_id;
  1528.   UDIResource    *addr;
  1529.   UDIInt32       *pass_count;
  1530.   UDIBreakType   *bk_type;
  1531.   UDIInt32       *current_count;
  1532. {
  1533.   INT32           space;
  1534.   ADDR32          offset;
  1535.   INT32           pcount;
  1536.   INT32           type;
  1537.   INT32           ccount;
  1538.   ADDR32          Inst;
  1539.  
  1540.   CLEAR_PENDING_STOP
  1541.  
  1542.   if (break_id >= LastBreakId)
  1543.     return (UDIErrorNoMoreBreakIds);
  1544.  
  1545.   if (get_from_bp_table(break_id, &space, &offset, &pcount, &type, &Inst) != 0)
  1546.     return (UDIErrorInvalidBreakId);
  1547.  
  1548.   Mini_build_bkpt_stat_msg(space, offset);
  1549.   SEND_AND_WAIT_ACK (BKPT_STAT_ACK);
  1550.   if (ReturnedError == (int) 1) {
  1551.     ReturnedError = 0;
  1552.     return ((-1) * MONErrErrorStatBreak);
  1553.   }
  1554.   Mini_unpack_bkpt_stat_ack_msg((INT32 *) &space,
  1555.                 (ADDR32 *) &offset,
  1556.                 (INT32 *) &ccount,
  1557.                 (INT32 *) &type);
  1558.  
  1559.   addr->Space = SpaceMap_mm2udi(space);
  1560.   addr->Offset = (CPUOffset) offset;
  1561.   *pass_count = (UDIInt32) pcount;
  1562.  
  1563.   if (type == (INT32) BKPT_29000)
  1564.     type = UDIBreakFlagExecute;
  1565.   else if (type == BKPT_29050_BTE_0)
  1566.     type = (MONBreakFlagHardware | UDIBreakFlagExecute);
  1567.   else if (type == BKPT_29050_BTE_1)
  1568.     type = (MONBreakTranslationEnabled | MONBreakFlagHardware | UDIBreakFlagExecute);
  1569.   *bk_type = (UDIBreakType) type;
  1570.  
  1571.   *current_count = (UDIInt32) ccount;
  1572.  
  1573.   return (UDINoError);
  1574. }
  1575.  
  1576. UDIError 
  1577. UDIClearBreakpoint(break_id)
  1578.   BreakIdType     break_id;
  1579. {
  1580.   INT32           space;
  1581.   ADDR32          offset;
  1582.   INT32           count;
  1583.   INT32           type;
  1584.   ADDR32          Inst;
  1585.   UDIResource     addr;    /* EB29K */
  1586.   UDIError        UDIretval;    /* EB29K */
  1587.  
  1588.   CLEAR_PENDING_STOP
  1589.  
  1590.   /* should bkpt be removed from linked list ?? */
  1591.   if (get_from_bp_table(break_id, &space, &offset, &count, &type, &Inst) != 0)
  1592.     return (UDIErrorInvalidBreakId);
  1593.  
  1594.   Mini_build_bkpt_rm_msg(space, offset);
  1595.   SEND_AND_WAIT_ACK (BKPT_RM_ACK);
  1596.   if (ReturnedError == (int) 1) {
  1597.     ReturnedError = 0;
  1598.     return ((-1) * MONErrErrorRmBreak);
  1599.   }
  1600.   Mini_unpack_bkpt_rm_ack_msg(&space, &offset);
  1601.  
  1602.   if (!strcmp(TargetType, "eb29k")) {    /* For EB29K */
  1603.     /* Write back the original instruction * UDIWrite(Inst); */
  1604.     addr.Offset = offset;
  1605.     addr.Space = SpaceMap_mm2udi(space);
  1606.     if ((UDIretval = UDIWrite((UDIHostMemPtr) &Inst,
  1607.                   addr,
  1608.                   (UDICount) 4,
  1609.                   (UDISizeT) 1,
  1610.                   &offset,
  1611.                   FALSE)) != UDINoError)
  1612.       return (UDIretval);
  1613.   };
  1614.  
  1615.   remove_from_bp_table(break_id);
  1616.  
  1617.   return (UDINoError);
  1618. }
  1619.  
  1620. UDIError 
  1621. UDIGetStdout(buf, bufsize, count_done)
  1622.   UDIHostMemPtr   buf;
  1623.   UDISizeT          bufsize;
  1624.   UDISizeT         *count_done;
  1625. {
  1626.   static int      chan1_indx = 0;
  1627.   UDISizeT          mincount;
  1628.   UDISizeT          i;
  1629.   char           *temp;
  1630.   UDIUInt32      reg_val;
  1631.   UDIError      UDIretval;
  1632.  
  1633.  
  1634.   if ((int) (ProcessorState & 0xFF) != (int) UDIStdoutReady) {
  1635.      *count_done = (UDISizeT) 0;
  1636.       return (UDINoError);
  1637.   };
  1638.  
  1639.   temp = (char *) buf;    /* used for copying */
  1640.   i = (UDISizeT) chan1_indx;
  1641.   if (Channel1_count) {
  1642.     mincount = (Channel1_count < (UDISizeT) bufsize) ? Channel1_count :
  1643.     (UDISizeT) bufsize;
  1644.     for (i = 0; i < mincount; i++) {
  1645.       (char) *temp++ = (char) channel1_buffer[chan1_indx];
  1646.       chan1_indx = (chan1_indx + 1) % TIP_IO_BUFSIZE;    /* circular buffer */
  1647.     }
  1648.     *count_done = (UDISizeT) mincount;
  1649.     Channel1_count = Channel1_count - mincount;
  1650.     TotalDone = TotalDone + (UDIUInt32) mincount;
  1651.     if (Channel1_count <= (UDISizeT) 0) {
  1652.     /*
  1653.      * The HIF kernel from MiniMON29K release 2.1 expects MONTIP
  1654.      * to send a HIF_CALL_RTN response for a HIF_CALL message, and
  1655.      * a CHANNEL1_ACK response for a CHANNEL1 message, and 
  1656.      * a CHANNEL2_ACK response for a CHANNEL2 message, and
  1657.      * a CHANNEL0 message for a asynchronous input.
  1658.      * The HIF kernel version numbers 0x05 and above support these
  1659.      * features.
  1660.      */
  1661.      if ((tip_target_config.os_version & 0xf) > 4) { /* new HIF kernel */
  1662.        if (!NoChan1Ack) {
  1663.           Mini_build_channel1_ack_msg(TotalDone); /* send gr96 value */
  1664.           if (Mini_msg_send() != SUCCESS)
  1665.             return ((-1) * MONErrCantSendMsg);
  1666.        }
  1667.      } else { /* old HIF kernel */
  1668.        if ((UDIretval = Write_Glob_Reg(TotalDone, (int) 96)) != UDINoError)
  1669.          return (UDIretval);
  1670.        reg_val = (UDIUInt32) 0x80000000;
  1671.        if ((UDIretval = Write_Glob_Reg(reg_val, (int) 121)) != UDINoError)
  1672.          return (UDIretval);
  1673.      }
  1674.       TotalDone = (UDIUInt32) 0;
  1675.       Channel1_count = (UDISizeT) 0;
  1676.       chan1_indx = 0;
  1677.     } else {
  1678.       return (UDINoError);
  1679.     }
  1680.   } else {
  1681.     *count_done = (UDISizeT) 0;
  1682.     TotalDone = (UDIUInt32) 0;
  1683.     Channel1_count = (UDISizeT) 0;
  1684.     chan1_indx = 0;
  1685.     /*
  1686.      * The HIF kernel from MiniMON29K release 2.1 expects MONTIP
  1687.      * to send a HIF_CALL_RTN response for a HIF_CALL message, and
  1688.      * a CHANNEL1_ACK response for a CHANNEL1 message, and 
  1689.      * a CHANNEL2_ACK response for a CHANNEL2 message, and
  1690.      * a CHANNEL0 message for a asynchronous input.
  1691.      * The HIF kernel version numbers 0x05 and above support these
  1692.      * features.
  1693.      */
  1694.      if ((tip_target_config.os_version & 0xf) > 4) { /* new HIF kernel */
  1695.        Mini_build_channel1_ack_msg(TotalDone); /* send gr96 value */
  1696.        if (Mini_msg_send() != SUCCESS)
  1697.          return ((-1) * MONErrCantSendMsg);
  1698.      } else { /* old HIF kernel */
  1699.        if ((UDIretval = Write_Glob_Reg(TotalDone, (int) 96)) != UDINoError)
  1700.          return (UDIretval);
  1701.        reg_val = (UDIUInt32) 0x80000000;
  1702.        if ((UDIretval = Write_Glob_Reg(reg_val, (int) 121)) != UDINoError)
  1703.          return (UDIretval);
  1704.      }
  1705.   }
  1706.   if (StepCmdGiven) {
  1707.     ProcessorState = UDIStepped;
  1708.     PreviousProcessorState = UDIStepped;
  1709.     StepCmdGiven = 0;
  1710.   } else {
  1711.       if (!BreaksInPlace) {
  1712.     PutAllBreakpoints();
  1713.     BreaksInPlace = 1;
  1714.       }
  1715.     /*
  1716.      * The HIF kernel from MiniMON29K release 2.1 expects MONTIP
  1717.      * to send a HIF_CALL_RTN response for a HIF_CALL message, and
  1718.      * a CHANNEL1_ACK response for a CHANNEL1 message, and 
  1719.      * a CHANNEL2_ACK response for a CHANNEL2 message, and
  1720.      * a CHANNEL0 message for a asynchronous input.
  1721.      * The HIF kernel version numbers 0x05 and above support these
  1722.      * features.
  1723.      */
  1724.      if ((tip_target_config.os_version & 0xf) > 4) { /* new HIF kernel */
  1725.        ProcessorState = (UDIUInt32) UDIRunning;
  1726.        PreviousProcessorState = (UDIUInt32) UDIRunning;
  1727.      } else { /* old HIF kernel */
  1728.        UDIExecute();    /* sends a GO to the Debugger to start application */
  1729.      }
  1730.   }
  1731.   return (UDINoError);
  1732. }
  1733.  
  1734. #ifdef    MSDOS
  1735. UDIError OldHIFGetStderr( UDIHostMemPtr buf,UDISizeT bufsize,UDISizeT *count_done);
  1736. #else
  1737. UDIError OldHIFGetStderr();
  1738. #endif
  1739.  
  1740. UDIError 
  1741. UDIGetStderr(buf, bufsize, count_done)
  1742.   UDIHostMemPtr   buf;
  1743.   UDISizeT          bufsize;
  1744.   UDISizeT         *count_done;
  1745. {
  1746.   static int      chan2_indx = 0;
  1747.   UDISizeT          mincount;
  1748.   UDISizeT          i;
  1749.   char           *temp;
  1750.  
  1751.   if ((int) (ProcessorState & 0xFF) != (int) UDIStderrReady) {
  1752.     *count_done = (UDISizeT) 0;
  1753.     return (UDINoError);
  1754.   };
  1755.     /*
  1756.      * The HIF kernel from MiniMON29K release 2.1 expects MONTIP
  1757.      * to send a HIF_CALL_RTN response for a HIF_CALL message, and
  1758.      * a CHANNEL1_ACK response for a CHANNEL1 message, and 
  1759.      * a CHANNEL2_ACK response for a CHANNEL2 message, and
  1760.      * a CHANNEL0 message for a asynchronous input.
  1761.      * The HIF kernel version numbers 0x05 and above support these
  1762.      * features.
  1763.      */
  1764.      if ((tip_target_config.os_version & 0xf) > 4) { /* new HIF kernel */
  1765.     /*
  1766.      * From MiniMON29K release 2.1 all interactions with 
  1767.      * stdin, stdout, stderr by the application is handled without
  1768.      * invoking the Debugger on the target. Thus, a write to stderr
  1769.      * is implemented by a CHANNEL2 message similar to the CHANNEL1
  1770.      * message for stdout.
  1771.      */
  1772.        temp = (char *) buf;    /* used for copying */
  1773.        i = (UDISizeT) chan2_indx;
  1774.        if (Channel2_count) {
  1775.          mincount = (Channel2_count < (UDISizeT) bufsize) ? Channel2_count :
  1776.          (UDISizeT) bufsize;
  1777.          for (i = 0; i < mincount; i++) {
  1778.            (char) *temp++ = (char) channel2_buffer[chan2_indx];
  1779.            chan2_indx = (chan2_indx + 1) % TIP_IO_BUFSIZE;/* circular buffer */
  1780.          }
  1781.          *count_done = (UDISizeT) mincount;
  1782.          Channel2_count = Channel2_count - mincount;
  1783.          TotalDone = TotalDone + (UDIUInt32) mincount;
  1784.          if (Channel2_count <= (UDISizeT) 0) {
  1785.             Mini_build_channel2_ack_msg(TotalDone); /* send gr96 value */
  1786.             if (Mini_msg_send() != SUCCESS)
  1787.               return ((-1) * MONErrCantSendMsg);
  1788.             TotalDone = (UDIUInt32) 0;
  1789.             Channel2_count = (UDISizeT) 0;
  1790.             chan2_indx = 0;
  1791.           } else {
  1792.             return (UDINoError);
  1793.           }
  1794.        } else {
  1795.           *count_done = (UDISizeT) 0;
  1796.           TotalDone = (UDIUInt32) 0;
  1797.           Channel2_count = (UDISizeT) 0;
  1798.           chan2_indx = 0;
  1799.           Mini_build_channel2_ack_msg(TotalDone); /* send gr96 value */
  1800.           if (Mini_msg_send() != SUCCESS)
  1801.             return ((-1) * MONErrCantSendMsg);
  1802.       }
  1803.       if (StepCmdGiven) {
  1804.         ProcessorState = UDIStepped;
  1805.         PreviousProcessorState = UDIStepped;
  1806.         StepCmdGiven = 0;
  1807.       } else {
  1808.           if (!BreaksInPlace) {
  1809.              PutAllBreakpoints();
  1810.              BreaksInPlace = 1;
  1811.           }
  1812.         ProcessorState = (UDIUInt32) UDIRunning;
  1813.         PreviousProcessorState = (UDIUInt32) UDIRunning;
  1814.       }
  1815.      } else { /* old HIF kernel code */
  1816.     return (OldHIFGetStderr(buf, bufsize, count_done));
  1817.      }    /* old kernel code */
  1818.  
  1819.   return (UDINoError);
  1820. }
  1821.  
  1822. UDIError
  1823. OldHIFGetStderr(buf, bufsize, count_done)
  1824.   UDIHostMemPtr   buf;
  1825.   UDISizeT          bufsize;
  1826.   UDISizeT         *count_done;
  1827. /*
  1828.  * For HIF kernel version 0x04 and lower.
  1829.  */
  1830. {
  1831.   UDIUInt32       count;
  1832.   UDIUInt32       done;
  1833.   UDIResource     from;
  1834.   UDIBool         host_endian;
  1835.   UDISizeT          size;
  1836.   UDIError        UDIretval;
  1837.   UDIUInt32       reg_val;
  1838.  
  1839.        /* Lr4_count gives the bytes to be written */
  1840.        /* Lr3_addr gives the address in the target */
  1841.        if (Lr4_count > (UDIUInt32) 0) {
  1842.          count = (Lr4_count < (UDIUInt32) bufsize) ? Lr4_count : (UDIUInt32) bufsize;
  1843.          /* read count bytes from Lr3_addr */
  1844.          from.Offset = Lr3_addr;
  1845.          from.Space = UDI29KDRAMSpace;
  1846.          size = 1;
  1847.          host_endian = FALSE;
  1848.          if ((UDIretval = UDIRead(from,
  1849.                       buf,
  1850.                       count,
  1851.                       size,
  1852.                       &done,
  1853.                       host_endian)) != UDINoError) {
  1854.            return (UDIretval);
  1855.          }
  1856.          *count_done = (UDISizeT) count;
  1857.          Lr4_count = Lr4_count - count;
  1858.          Lr3_addr = Lr3_addr + count;
  1859.          TotalDone = TotalDone + (UDIUInt32) count;
  1860.          if (Lr4_count <= (UDISizeT) 0) {
  1861.              if ((UDIretval = Write_Glob_Reg(TotalDone, (int) 96)) != UDINoError)
  1862.                   return (UDIretval);
  1863.              reg_val = (UDIUInt32) 0x80000000;
  1864.              if ((UDIretval = Write_Glob_Reg(reg_val, (int) 121)) != UDINoError)
  1865.                   return (UDIretval);
  1866.              TotalDone = (UDIUInt32) 0;
  1867.          Lr4_count = (UDIUInt32) 0;
  1868.          } else {
  1869.            return (UDINoError);
  1870.          }
  1871.        } else {
  1872.          *count_done = (UDISizeT) 0;
  1873.          TotalDone = (UDIUInt32) 0;
  1874.          if ((UDIretval = Write_Glob_Reg(TotalDone, (int) 96)) != UDINoError)
  1875.               return (UDIretval);
  1876.          reg_val = (UDIUInt32) 0x80000000;
  1877.          if ((UDIretval = Write_Glob_Reg(reg_val, (int) 121)) != UDINoError)
  1878.               return (UDIretval);
  1879.          Lr4_count = (UDIUInt32) 0;
  1880.        };
  1881.      
  1882.        /* Resume execution  UDIExecute()? */
  1883.        if (StepCmdGiven) {
  1884.          ProcessorState = UDIStepped;
  1885.          PreviousProcessorState = UDIStepped;
  1886.          StepCmdGiven = 0;
  1887.        } else {
  1888.            if (!BreaksInPlace) {
  1889.          PutAllBreakpoints();
  1890.          BreaksInPlace = 1;
  1891.            }
  1892.          UDIExecute();
  1893.        }
  1894.   return (UDINoError);
  1895. }
  1896.  
  1897. #ifdef MSDOS
  1898. UDIError OldHIFPutStdin( UDIHostMemPtr buf,UDISizeT count,UDISizeT *count_done);
  1899. #else
  1900. UDIError OldHIFPutStdin();
  1901. #endif
  1902.  
  1903. UDIError 
  1904. UDIPutStdin(buf, count, count_done)
  1905.   UDIHostMemPtr   buf;
  1906.   UDISizeT          count;
  1907.   UDISizeT         *count_done;
  1908. {
  1909.      char    *CharPtr;
  1910.      UINT32    MinCnt;
  1911.      INT32    Code;
  1912.  
  1913.      if ((tip_target_config.os_version & 0xf) > 0x6) { /* MiniMON29K 3.0 */
  1914.        if ((int) (ProcessorState & 0xFF) != (int) UDIStdinNeeded) {
  1915.            /* non-blocking mode asynchronous mode */
  1916.        /* 
  1917.         if asynchronous mode, we sent a channel0 message for
  1918.         every character sent by DFE in this call. 
  1919.         */
  1920.         if (PgmStdinMode & TIP_NBLOCK) { 
  1921.                if ((Code = Mini_msg_recv(NONBLOCK)) != FAILURE) {
  1922.            MsgAlreadyReceived=Code;
  1923.            MsgAlreadyInBuffer = 1;
  1924.            } 
  1925.                CharPtr = buf;
  1926.            if (!Channel0Busy) {
  1927.              /* send one character and return to DFE */
  1928.              Mini_build_channel0_msg(CharPtr, (INT32) 1);
  1929.              /*
  1930.           * Just send the message here, and wait for the ack later
  1931.              SEND_AND_WAIT_ACK(CHANNEL0_ACK);
  1932.              */
  1933.              if (Mini_msg_send() != SUCCESS) 
  1934.             return((-1) * MONErrCantSendMsg);
  1935. #if 0
  1936.              Channel0Busy = 1;    /* never set */
  1937. #endif
  1938.            } else {
  1939.          /* save it in channel0_buffer */
  1940.              channel0_buffer[Channel0_count] = (char) *CharPtr;
  1941.              Channel0_count=Channel0_count+1;
  1942.            }
  1943.            *count_done = (UDISizeT) 1;
  1944.            return (UDINoError);
  1945.         } else  if (PgmStdinMode & TIP_ASYNC) {
  1946.                if ((Code = Mini_msg_recv(NONBLOCK)) != FAILURE) {
  1947.            MsgAlreadyReceived=Code;
  1948.            MsgAlreadyInBuffer = 1; /* check in UDIWait */
  1949.            } 
  1950.                CharPtr = buf;
  1951.            *count_done = (UDISizeT) 0;
  1952.            for ( ; count > 0; count--) {
  1953.                 Mini_build_channel0_msg(CharPtr, (INT32) 1);
  1954.                /*
  1955.             * Just send the message here, and wait for the ack later
  1956.                SEND_AND_WAIT_ACK(CHANNEL0_ACK);
  1957.                */
  1958.             if (Mini_msg_send() != SUCCESS)
  1959.               return((-1)*MONErrCantSendMsg);
  1960.                 *count_done = (UDISizeT) (*count_done + (UDISizeT) 1);
  1961.                 CharPtr++;
  1962.            }
  1963.                return (UDINoError);
  1964.         }
  1965.        } else { /* synchronous mode */
  1966.       /*
  1967.        in synchronous mode, we send all the characters received using
  1968.        stdin_needed_ack_msg, when the processorstate becomes stdinneeded.
  1969.        This is line-buffered mode. So we clear variables
  1970.        after we send.
  1971.        What do we do when DFE sends more characters than we need now?
  1972.        The count_done return value gives number accepted. But who keeps
  1973.        the rest.
  1974.        Otherwise, what do we do???????
  1975.        */
  1976.       if (PgmStdinMode & TIP_NBLOCK) { 
  1977.          /* send one character and return to DFE */
  1978.              CharPtr = buf;
  1979.              if ((Code = Mini_msg_recv(NONBLOCK)) != FAILURE) {
  1980.            MsgAlreadyReceived=Code;
  1981.            MsgAlreadyInBuffer = 1;
  1982.          }
  1983.          *count_done = (UDISizeT) 1;
  1984.          Mini_build_channel0_msg(CharPtr, (INT32) 1);
  1985.          /*
  1986.           * Send the message now and wait for the ack later.
  1987.          SEND_AND_WAIT_ACK(CHANNEL0_ACK);
  1988.           */
  1989.          if (Mini_msg_send() != SUCCESS)
  1990.            return ((-1)*MONErrCantSendMsg);
  1991.          return (UDINoError);
  1992.       }; 
  1993.  
  1994.       MinCnt = ((UINT32) StdinCharsNeeded > (UINT32) count) ?
  1995.               (UINT32) count : (UINT32) StdinCharsNeeded;
  1996.       Mini_build_stdin_needed_ack_msg (MinCnt, buf);
  1997.           if (Mini_msg_send() != SUCCESS)
  1998.             return ((-1) * MONErrCantSendMsg);
  1999.       *count_done = (UDISizeT) MinCnt;
  2000.       StdinCharsNeeded = 0;        /* reset to zero ?? */
  2001.           if (StepCmdGiven) {
  2002.             ProcessorState = UDIStepped;
  2003.             PreviousProcessorState = UDIStepped;
  2004.             StepCmdGiven = 0;
  2005.           } else {
  2006.             if (!BreaksInPlace) {
  2007.           PutAllBreakpoints();
  2008.           BreaksInPlace = 1;
  2009.             }
  2010.         ProcessorState = UDIRunning;
  2011.         PreviousProcessorState = UDIRunning;
  2012.       }
  2013.       return (UDINoError);
  2014.        }
  2015.      } else if ((tip_target_config.os_version & 0xf) > 4) { /* pre-release */
  2016.     /*
  2017.      * The HIF kernel from MiniMON29K release 2.1 expects MONTIP
  2018.      * to send a HIF_CALL_RTN response for a HIF_CALL message, and
  2019.      * a CHANNEL1_ACK response for a CHANNEL1 message, and 
  2020.      * a CHANNEL2_ACK response for a CHANNEL2 message, and
  2021.      * a CHANNEL0 message for a asynchronous input.
  2022.      * The HIF kernel version numbers 0x05 and above support these
  2023.      * features.
  2024.      */
  2025.        /* Send CHANNEL0 message depending on StdinMode. */
  2026.        CharPtr = buf;
  2027.        if (PgmStdinMode == TIP_COOKED) { /* default line buffered */
  2028.      /*
  2029.       * send a line of input using channel0 
  2030.       * Check for '\n' sent from DFE.
  2031.       */
  2032.       if ((int) *CharPtr == (int) 8) {/* backspace */
  2033.         Channel0_count=Channel0_count-1;
  2034.       } else if ((int) *CharPtr == (int) 127) {/* delete */
  2035.         Channel0_count=Channel0_count-1;
  2036. #ifdef MSDOS
  2037.       } else if ((int) *CharPtr == (int) 10) {/* \n */
  2038.         /* simply return, no change. already padded. */
  2039.         *count_done = count;
  2040.         return (UDINoError);
  2041.       } else if ((int) *CharPtr == (int) 13) {/* end of line */
  2042.         channel0_buffer[Channel0_count] = (char) *CharPtr;
  2043.         Channel0_count=Channel0_count+1;
  2044.         channel0_buffer[Channel0_count] = (char) 10; /* add \n */
  2045.         Channel0_count=Channel0_count+1;
  2046.         Mini_build_channel0_msg(channel0_buffer, Channel0_count);
  2047.         SEND_AND_WAIT_ACK(CHANNEL0_ACK);
  2048.         Channel0_count = 0;    /* reset */
  2049.         *count_done = count;
  2050. #else    /* MSDOS */
  2051.       } else if ((int) *CharPtr == (int) 13) {/* end of line */
  2052.         /* simply return, added on \n */
  2053.         *count_done = count;
  2054.         return (UDINoError);
  2055.       } else if ((int) *CharPtr == (int) 10) {/* \n */
  2056.         channel0_buffer[Channel0_count] = (char) 13; /* add \r */
  2057.         Channel0_count=Channel0_count+1;
  2058.         channel0_buffer[Channel0_count] = (char) *CharPtr;
  2059.         Channel0_count=Channel0_count+1;
  2060.         Mini_build_channel0_msg(channel0_buffer, Channel0_count);
  2061.         SEND_AND_WAIT_ACK(CHANNEL0_ACK);
  2062.         Channel0_count = 0;    /* reset */
  2063. #endif /* MSDOS */
  2064.       } else { /* store it in buffer here */
  2065.         channel0_buffer[Channel0_count] = (char) *CharPtr;
  2066.         Channel0_count=Channel0_count+1;
  2067.         *count_done = count;
  2068.       }
  2069.       return (UDINoError);
  2070.        } else if (PgmStdinMode == TIP_RAW) { /* for other modes of input */
  2071.         channel0_buffer[Channel0_count] = (char) *CharPtr;
  2072.         Channel0_count=Channel0_count+1;
  2073.         Mini_build_channel0_msg(channel0_buffer, Channel0_count);
  2074.         SEND_AND_WAIT_ACK(CHANNEL0_ACK);
  2075.         Channel0_count = 0;    /* reset */
  2076.         *count_done = count;
  2077.         return (UDINoError);
  2078.        } else { /* for other modes of input */
  2079.      /* NOT IMPLEMENTED */
  2080.         return (UDINoError);
  2081.        }
  2082.      } else { /* old HIF kernel */
  2083.        return(OldHIFPutStdin(buf, count, count_done));
  2084.      }
  2085. }
  2086.  
  2087. UDIError
  2088. OldHIFPutStdin(buf, count, count_done)
  2089.   UDIHostMemPtr   buf;
  2090.   UDISizeT          count;
  2091.   UDISizeT         *count_done;
  2092. {
  2093.   UDIResource     to;
  2094.   UDIError        retval;
  2095.   UDIBool         hostendian;
  2096.   UDICount        mincount,
  2097.                   bytes_ret;
  2098.   UDIUInt32       reg_val;
  2099.   UDISizeT          size;
  2100.  
  2101.   if ((int) (ProcessorState & 0xFF) != (int) UDIStdinNeeded) {
  2102.     *count_done = (UDISizeT) 0;
  2103.     return (UDINoError);
  2104.   };
  2105.   /* Lr4_count has count requested */
  2106.   /* Lr3_addr has the destination */
  2107.   if (Lr4_count > (UDIUInt32) 0) {
  2108.     mincount = ((UDICount) count < (UDICount) Lr4_count) ?
  2109.     (UDICount) count :
  2110.     (UDICount) Lr4_count;
  2111.     to.Space = (CPUSpace) UDI29KDRAMSpace;
  2112.     to.Offset = (CPUOffset) Lr3_addr;
  2113.     size = (UDISizeT) 1;
  2114.     hostendian = FALSE;
  2115.     if ((retval = UDIWrite(buf,
  2116.                to,
  2117.                mincount,
  2118.                size,
  2119.                &bytes_ret,
  2120.                hostendian)) != UDINoError) {
  2121.       return ((UDIError) retval);
  2122.     };
  2123.     Lr4_count = (UDIUInt32) 0;
  2124.     *count_done = (UDISizeT) bytes_ret;
  2125.   } else {
  2126.     Lr4_count = (UDIUInt32) 0;
  2127.     *count_done = (UDISizeT) 0;
  2128.   };
  2129.  
  2130.   /*
  2131.    * ASSUMPTION: It's always a non-blocking read & this function is called
  2132.    * only when app. needs data. So, write the number of bytes read to gr96 on
  2133.    * the target.
  2134.    */
  2135.   /* Write gr96  set above */
  2136.   /* gr96 */
  2137.   reg_val = (UDIUInt32) * count_done;    /* same as mincount */
  2138.   if ((retval = Write_Glob_Reg(reg_val, (int) 96)) != UDINoError)
  2139.     return (retval);
  2140.  
  2141.   /* Write Gr121 */
  2142.   reg_val = (UDIUInt32) 0x80000000;
  2143.   if ((retval = Write_Glob_Reg(reg_val, (int) 121)) != UDINoError)
  2144.     return (retval);
  2145.  
  2146.   if (StopFlag) {
  2147.      STOP_SIG_HDLR
  2148.      ProcessorState = (UDIUInt32) UDIStopped;
  2149.      PreviousProcessorState = (UDIUInt32) UDIStopped;
  2150.      return (UDINoError);
  2151.   }; 
  2152.   /* Resume execution UDIExecute()? */
  2153.   if (StepCmdGiven) {
  2154.     ProcessorState = UDIStepped;
  2155.     PreviousProcessorState = UDIStepped;
  2156.     StepCmdGiven = 0;
  2157.   } else {
  2158.       if (!BreaksInPlace) {
  2159.     PutAllBreakpoints();
  2160.     BreaksInPlace = 1;
  2161.       }
  2162.     UDIExecute();
  2163.   }
  2164.  
  2165.   return (UDINoError);
  2166. }
  2167.  
  2168. UDIError 
  2169. UDIStdinMode(mode)
  2170.  UDIMode   *mode;
  2171. {
  2172.   *mode = (UDIMode) (PgmStdinMode);
  2173.   /* restore ProcessorState from saved value in PreviousState */
  2174.   ProcessorState = PreviousProcessorState;
  2175.   return (UDINoError);
  2176. }
  2177.  
  2178. UDIError 
  2179. UDIPutTrans(buf, count, count_done)
  2180.   UDIHostMemPtr   buf;
  2181.   UDISizeT          count;
  2182.   UDISizeT         *count_done;
  2183. {
  2184.   char    *tip_token;
  2185.  
  2186.   tip_token = strtok ((char *) buf, " \t,;\n\r");
  2187.   if (tip_token == NULL)
  2188.         return ((-1) * MONErrUnknownTIPCmd);
  2189.  
  2190.   if (strcmp (tip_token, "tip") == 0)  {
  2191.     tip_token = strtok ((char *) 0, " \t,;\n\r");
  2192.     if (tip_token == NULL)
  2193.        return ((-1) * MONErrUnknownTIPCmd);
  2194.     else {
  2195.       if (strcmp(tip_token, "lpt=1") == 0) {
  2196. #ifdef MSDOS
  2197.     set_lpt();
  2198. #endif
  2199.     use_parport = 1;
  2200.       } else if (strcmp(tip_token, "lpt=0") == 0) {
  2201. #ifdef MSDOS
  2202.     unset_lpt();
  2203. #endif
  2204.     use_parport = 0;
  2205.       } else
  2206.        return ((-1) * MONErrUnknownTIPCmd);
  2207.     }
  2208.     return (UDINoError);
  2209.   } else {
  2210.     return ((-1) * MONErrUnknownTIPCmd);
  2211.   }
  2212.  
  2213. }
  2214.  
  2215. UDIError 
  2216. UDIGetTrans(buf, bufsize, count)
  2217.   UDIHostMemPtr   buf;
  2218.   UDISizeT          bufsize;
  2219.   UDISizeT         *count;
  2220. {
  2221.   CLEAR_PENDING_STOP
  2222.   return (UDIErrorUnsupportedService);
  2223. }
  2224.  
  2225. UDIError 
  2226. UDITransMode(mode)
  2227.   UDIMode   *mode;
  2228. {
  2229.   CLEAR_PENDING_STOP
  2230.   return (UDIErrorUnsupportedService);
  2231. }
  2232.  
  2233. /* Map Space conversion functions */
  2234.  
  2235. static INT32 
  2236. SpaceMap_udi2mm(space)
  2237.   CPUSpace        space;
  2238. {
  2239.   switch (space) {
  2240.    case UDI29KDRAMSpace:
  2241.     return ((INT32) D_MEM);
  2242.    case UDI29KIOSpace:
  2243.     return ((INT32) I_O);
  2244.    case UDI29KCPSpace0:
  2245.     return ((INT32) SPECIAL_REG);
  2246.    case UDI29KCPSpace1:
  2247.     return ((INT32) SPECIAL_REG);
  2248.    case UDI29KIROMSpace:
  2249.     return ((INT32) I_ROM);
  2250.    case UDI29KIRAMSpace:
  2251.     return ((INT32) I_MEM);
  2252.    case UDI29KLocalRegs:
  2253.     return ((INT32) LOCAL_REG);
  2254.    case UDI29KGlobalRegs:
  2255.     return ((INT32) GLOBAL_REG);
  2256.    case UDI29KRealRegs:
  2257.     return ((INT32) GLOBAL_REG);
  2258.    case UDI29KSpecialRegs:
  2259.     return ((INT32) SPECIAL_REG);
  2260.    case UDI29KTLBRegs:
  2261.     return ((INT32) TLB_REG);
  2262.    case UDI29KACCRegs:
  2263.     return ((INT32) SPECIAL_REG);
  2264.    case UDI29KICacheSpace:
  2265.     return ((INT32) I_CACHE);
  2266.    case UDI29KAm29027Regs:
  2267.     return ((INT32) COPROC_REG);
  2268.    case UDI29KPC:
  2269.     return ((INT32) PC_SPACE);
  2270.    case UDI29KDCacheSpace:
  2271.     return ((INT32) D_CACHE);
  2272.    case VERSION_SPACE:
  2273.     return ((INT32) VERSION_SPACE);
  2274.    default:
  2275.     return (FAILURE);
  2276.   };
  2277. }
  2278.  
  2279. static CPUSpace 
  2280. SpaceMap_mm2udi(space)
  2281.   INT32           space;
  2282. {
  2283.   switch (space) {
  2284.    case LOCAL_REG:
  2285.     return ((CPUSpace) UDI29KLocalRegs);
  2286.    case ABSOLUTE_REG:
  2287.     return ((CPUSpace) UDI29KGlobalRegs);
  2288.    case GLOBAL_REG:
  2289.     return ((CPUSpace) UDI29KGlobalRegs);
  2290.    case SPECIAL_REG:
  2291.     return ((CPUSpace) UDI29KSpecialRegs);
  2292.    case TLB_REG:
  2293.     return ((CPUSpace) UDI29KTLBRegs);
  2294.    case COPROC_REG:
  2295.     return ((CPUSpace) UDI29KAm29027Regs);
  2296.    case I_MEM:
  2297.     return ((CPUSpace) UDI29KIRAMSpace);
  2298.    case D_MEM:
  2299.     return ((CPUSpace) UDI29KDRAMSpace);
  2300.    case I_ROM:
  2301.     return ((CPUSpace) UDI29KIROMSpace);
  2302.    case D_ROM:
  2303.     return ((CPUSpace) UDI29KIROMSpace);
  2304.    case I_O:
  2305.     return ((CPUSpace) UDI29KIOSpace);
  2306.    case I_CACHE:
  2307.     return ((CPUSpace) UDI29KICacheSpace);
  2308.    case D_CACHE:
  2309.     return ((CPUSpace) UDI29KDCacheSpace);
  2310.    case PC_SPACE:
  2311.     return ((CPUSpace) UDI29KPC);
  2312.    case A_SPCL_REG:
  2313.     return ((CPUSpace) UDI29KSpecialRegs);
  2314.    default:
  2315.     return (FAILURE);
  2316.   }
  2317. }
  2318.  
  2319. /* Miscellaneous UDI support functions */
  2320.  
  2321. static int
  2322. Reset_Processor()
  2323. {
  2324.   INT32           MsgCode;
  2325.   BreakIdType        i;
  2326.  
  2327.   CLEAR_PENDING_STOP
  2328.  
  2329.   Mini_build_reset_msg();
  2330.   if (Mini_msg_send() != SUCCESS)
  2331.     return ((-1) * MONErrCantSendMsg);
  2332.  
  2333.   MsgCode = Wait_For_Ack();
  2334.   if (MsgCode == ABORT_FAILURE)
  2335.      return (UDIErrorAborted);
  2336.   else if (MsgCode == FAILURE)
  2337.     return ((-1) * MONErrNoSynch);
  2338.  
  2339.   RefreshRegs = 1;
  2340.   /* Clear all breakpoints */
  2341.   BreaksInPlace = 0;
  2342.   for (i = 1; i < LastBreakId; i++)
  2343.      remove_from_bp_table(i);
  2344.  
  2345.   return (SUCCESS);
  2346. }
  2347.  
  2348. static int 
  2349. parse_string(string)
  2350.   char           *string;
  2351. {
  2352.   char           *s;
  2353.  
  2354.   if ((string == NULL) || (strcmp(string,"") == 0))
  2355.     return ((-1) * MONErrNullConfigString);
  2356.  
  2357.   (void) strcpy (&ConnectString[0], string); /* to preserve the original */
  2358.  
  2359.   s = strtok(ConnectString, " ");
  2360.  
  2361.   while (s != NULL) {
  2362.     if ((s[0] == '-') && (s[1] != '\0') && (s[2] == '\0')) {    /* single letter options */
  2363.       switch (s[1]) {
  2364.        case 'S':    /* -Supervisor Mode */
  2365.     SupervisorMode = 1;    /* always in real mode */
  2366.     RealMode = 1;
  2367.     ProtectedMode = 0;
  2368.     VirtualMode = 0;
  2369.     s = strtok(NULL, " ");    /* get next string */
  2370.     break;
  2371.        case 'R':    /* -Real Mode */
  2372.     RealMode = 1;
  2373.     ProtectedMode = 0;
  2374.     VirtualMode = 0;
  2375.     s = strtok(NULL, " ");    /* get next string */
  2376.     break;
  2377.        case 'P':    /* _Protected mode */
  2378.     SupervisorMode = 0;    /* SM mode not supported */
  2379.     RealMode = 0;
  2380.     VirtualMode = 0;
  2381.     ProtectedMode = 1;
  2382.     s = strtok(NULL, " ");    /* get next string */
  2383.     break;
  2384.        case 'V':    /* -Virtual mode */
  2385.     SupervisorMode = 0;    /* SM mode not supported */
  2386.     RealMode = 0;
  2387.     ProtectedMode = 0;
  2388.     VirtualMode = 1;
  2389.     s = strtok(NULL, " ");    /* get next string */
  2390.     break;
  2391.        case 'r':    /* core file */
  2392.     s = strtok(NULL, " ");
  2393.     if (s == NULL) {    /* error */
  2394.       return (UDIErrorInvalidTIPOption);    /* UNKNOWN */
  2395.     } else {
  2396.       if ((CoreFile = (char *) malloc(strlen(s) + 1)) == NULL) {
  2397.         return ((-1) * MONErrOutofMemory);    /* EMALLOC ? */
  2398.       };
  2399.       (void) strcpy(CoreFile, s);
  2400.     };
  2401.     s = strtok(NULL, " ");    /* get next string */
  2402.     break;
  2403.        case 't':    /* target type */
  2404.     s = strtok(NULL, " ");
  2405.     if (s == NULL) {    /* error */
  2406.       return (UDIErrorInvalidTIPOption);    /* UNKNOWN */
  2407.     } else {
  2408.       if ((TargetType = (char *) malloc(strlen(s) + 1))
  2409.           == NULL) {
  2410.         return ((-1) * MONErrOutofMemory);    /* EMALLOC ? */
  2411.       };
  2412.       (void) strcpy(TargetType, s);
  2413.     };
  2414.     s = strtok(NULL, " ");    /* get next string */
  2415.     break;
  2416.        case 'm':    /* message log file */
  2417.     s = strtok(NULL, " ");
  2418.     if (s == NULL) {    /* error */
  2419.       return (UDIErrorInvalidTIPOption);    /* UNKNOWN */
  2420.     } else {
  2421.       if ((Msg_Logfile = (char *) malloc(strlen(s) + 1)) == NULL) {
  2422.         return ((-1) * MONErrOutofMemory);    /* EMALLOC ? */
  2423.       };
  2424.       (void) strcpy(Msg_Logfile, s);
  2425.     };
  2426.     s = strtok(NULL, " ");    /* get next string */
  2427.     break;
  2428.        default:    /* unknown */
  2429.     return (UDIErrorInvalidTIPOption);    /* UNKNOWN */
  2430.       };    /* end switch */
  2431.     } else {    /* multiple letter options */
  2432.       if (strcmp(s, "-com") == 0) {
  2433.     s = strtok(NULL, " ");
  2434.     if (s == NULL) {
  2435.       return (UDIErrorInvalidTIPOption);
  2436.     } else {
  2437.       (void) strcpy(tip_config.comm_port, s);
  2438.     };
  2439.     s = strtok(NULL, " ");    /* get next string */
  2440.       } else if (strcmp(s, "-af") == 0) {
  2441.     SendACKFirst = 1;
  2442.     s = strtok(NULL, " ");    /* get next string */
  2443.       } else if (strcmp(s, "-par") == 0) {
  2444.     s = strtok(NULL, " ");
  2445.     if (s == NULL) {
  2446.       return (UDIErrorInvalidTIPOption);
  2447.     } else {
  2448.       (void) strcpy(tip_config.par_port, s);
  2449.       lpt_initialize = 1;
  2450.     };
  2451.     s = strtok(NULL, " ");    /* get next string */
  2452.       } else if (strcmp(s, "-le") == 0) { /* little endian target */
  2453.     tip_target_config.P29KEndian = LITTLE;
  2454.     s = strtok(NULL, " ");    /* get next string */
  2455.       } else if (strcmp(s, "-re") == 0) {
  2456.     s = strtok(NULL, " ");
  2457.     if (s == NULL) {    /* error */
  2458.       return (UDIErrorInvalidTIPOption);    /* UNKNOWN */
  2459.     } else {
  2460.       if (sscanf(s, "%d", &MessageRetries) != 1)
  2461.         return (UDIErrorInvalidTIPOption);
  2462.     };
  2463.     s = strtok(NULL, " ");    /* get next string */
  2464.       } else if (strcmp(s, "-na") == 0) { /* no need to ack channel1 msg */
  2465.     NoChan1Ack = 1;
  2466.     s = strtok(NULL, " ");    /* get next string */
  2467.       } else if (strcmp(s, "-nt") == 0) {
  2468.     NoStepReqd = 1;
  2469.     s = strtok(NULL, " ");    /* get next string */
  2470.       } else if (strcmp(s, "-mbuf") == 0) {
  2471.     s = strtok(NULL, " ");
  2472.     if (s == NULL) {    /* error */
  2473.       return (UDIErrorInvalidTIPOption);    /* UNKNOWN */
  2474.     } else {
  2475.       if (sscanf(s, "%d", &MaxMsgBufSize) != 1)
  2476.         return (UDIErrorInvalidTIPOption);
  2477.     };
  2478.     s = strtok(NULL, " ");    /* get next string */
  2479.       } else if (strcmp(s, "-del") == 0) {
  2480.     s = strtok(NULL, " ");
  2481.     if (s == NULL) {    /* error */
  2482.       return (UDIErrorInvalidTIPOption);    /* UNKNOWN */
  2483.     } else {
  2484.       if (sscanf(s, "%d", &DelayFactor) != 1)
  2485.         return (UDIErrorInvalidTIPOption);
  2486.     };
  2487.     s = strtok(NULL, " ");    /* get next string */
  2488.       } else if (strcmp(s, "-bl") == 0) {
  2489.     s = strtok(NULL, " ");
  2490.     if (s == NULL) {    /* error */
  2491.       return (UDIErrorInvalidTIPOption);    /* UNKNOWN */
  2492.     } else {
  2493.       if (sscanf(s, "%d", &BlockCount) != 1)
  2494.         return (UDIErrorInvalidTIPOption);
  2495.     };
  2496.     s = strtok(NULL, " ");    /* get next string */
  2497.       } else if (strcmp(s, "-to") == 0) {
  2498.     s = strtok(NULL, " ");
  2499.     if (s == NULL) {    /* error */
  2500.       return (UDIErrorInvalidTIPOption);    /* UNKNOWN */
  2501.     } else {
  2502.       if (sscanf(s, "%ld", &TimeOut) != 1)
  2503.         return (UDIErrorInvalidTIPOption);
  2504.     };
  2505.     s = strtok(NULL, " ");    /* get next string */
  2506.       } else if (strcmp(s, "-seg") == 0) {
  2507.     s = strtok(NULL, " ");
  2508.     if (s == NULL) {    /* error */
  2509.       return (UDIErrorInvalidTIPOption);    /* UNKNOWN */
  2510.     } else {
  2511.       if (sscanf(s, "%lx", &tip_config.PC_mem_seg) != 1)
  2512.         return (UDIErrorInvalidTIPOption);
  2513.     };
  2514.     s = strtok(NULL, " ");    /* get next string */
  2515.       } else if (strcmp(s, "-nblock") == 0) { /* specify NBLOCK Stdin Mode */
  2516.     PgmStdinMode = TIP_NBLOCK;
  2517.     s = strtok(NULL, " ");    /* get next string */
  2518.       } else if (strcmp(s, "-port") == 0) {
  2519.     s = strtok(NULL, " ");
  2520.     if (s == NULL) {    /* error */
  2521.       return (UDIErrorInvalidTIPOption);    /* UNKNOWN */
  2522.     } else {
  2523.       if (sscanf(s, "%lx", &tip_config.PC_port_base) != 1)
  2524.         return (UDIErrorInvalidTIPOption);
  2525.     };
  2526.     s = strtok(NULL, " ");    /* get next string */
  2527.       } else if (strcmp(s, "-baud") == 0) {
  2528.     s = strtok(NULL, " ");
  2529.     if (s == NULL) {    /* error */
  2530.       return (UDIErrorInvalidTIPOption);    /* UNKNOWN */
  2531.     } else {
  2532.       (void) strcpy(tip_config.baud_rate, s);
  2533.     };
  2534.     s = strtok(NULL, " ");    /* get next string */
  2535.       } else    /* unknown option */
  2536.     return (UDIErrorInvalidTIPOption);    /* UNKNOWN */
  2537.     }
  2538.   };    /* end while */
  2539.   return ((int) 0); /* SUCCESS */
  2540. }
  2541.  
  2542. static int
  2543. write_args(argstring, argstart, datahigh)
  2544.   char           *argstring;
  2545.   ADDR32          argstart;
  2546.   ADDR32         *datahigh;
  2547. {
  2548.   char           *argvstring[25];
  2549.   int             i;
  2550.   char           *s;
  2551.  
  2552.   i = 0;
  2553.   if (argstring == NULL) {
  2554.     s = strtok(argstring, " \t\n\r");
  2555.     argvstring[i] = s;
  2556.   } else {
  2557.      (void) strcpy (&TempArgString[0], argstring);
  2558.      s = strtok (&TempArgString[0], " \t\n\r");
  2559.      argvstring[i] = s;
  2560.      if (s != NULL) {
  2561.         while ((s = strtok((char *) 0, " \t\n\r"))) {
  2562.           i++;
  2563.           argvstring[i] = s;
  2564.           (void) strcpy(argvstring[i], s);
  2565.         };
  2566.         /* add the final NULL */ /* i is the argc count */
  2567.         argvstring[++i] = NULL;
  2568.      }
  2569.   }
  2570.   return (write_argv(i, argvstring, argstart, datahigh));
  2571. }
  2572.  
  2573. static int
  2574. write_argv(arg_count, arg_ptr, argstart, hi_data)
  2575.   int             arg_count;
  2576.   char           *arg_ptr[];
  2577. ADDR32          argstart;
  2578. ADDR32         *hi_data;
  2579.  
  2580. {
  2581.  
  2582.   int             i;
  2583.  
  2584.   UDIError        retval;
  2585.   UDIResource     to;
  2586.   UDIBool         hostendian;
  2587.   UDICount        count,
  2588.                   bytes_ret;
  2589.   UDISizeT          size;
  2590.   UDIUInt32       dataend;    /* start address for heap */
  2591.   UDIUInt32       tmp_dataend;    /* start address for heap */
  2592.  
  2593.   /*
  2594.    * * Write args to target
  2595.    */
  2596.  
  2597.   /* Set init.data_end to start of arg string space */
  2598.   /* (saving room for the array of pointers) */
  2599.   dataend = argstart + (arg_count + 1) * sizeof(CPUOffset);
  2600.  
  2601.   for (i = 0; i < arg_count; i = i + 1) {
  2602.  
  2603.     /* Write arg_ptr[i] pointer (Am29000 address) to target */
  2604.     tmp_dataend = dataend;
  2605.     /* We might have to change the endian of the address */
  2606.     if (tip_target_config.P29KEndian != tip_target_config.TipEndian) {
  2607.       tip_convert32((BYTE *) &(tmp_dataend));
  2608.     }
  2609.     to.Offset = argstart + (i * sizeof(CPUOffset));
  2610.     to.Space = UDI29KDRAMSpace;
  2611.     count = (UDICount) 1;
  2612.     size = (UDISizeT) sizeof(CPUOffset);
  2613.     hostendian = FALSE;    /* ???? */
  2614.     if ((retval = UDIWrite((UDIHostMemPtr) &tmp_dataend,
  2615.                to,
  2616.                count,
  2617.                size,
  2618.                &bytes_ret,
  2619.                hostendian)) != UDINoError) {
  2620.       return (retval);
  2621.     };
  2622.     /* Continue if SUCCESSful */
  2623.     /* Write arg_ptr[i] to target */
  2624.     to.Offset = dataend;
  2625.     to.Space = UDI29KDRAMSpace;
  2626.     count = (UDICount) strlen(arg_ptr[i]) + 1;
  2627.     size = (UDISizeT) 1;
  2628.     hostendian = FALSE;
  2629.     if ((retval = UDIWrite(arg_ptr[i],
  2630.                to,
  2631.                count,
  2632.                size,
  2633.                &bytes_ret,
  2634.                hostendian)) != UDINoError) {
  2635.       return (retval);
  2636.     };
  2637.  
  2638.     dataend = dataend + strlen(arg_ptr[i]) + 1;
  2639.  
  2640.   }    /* end for loop */
  2641.  
  2642.   /* return dataend */
  2643.   *hi_data = dataend;
  2644.   /* Write NULL pointer at end of argv array */
  2645.   to.Offset = argstart + arg_count * sizeof(CPUOffset);
  2646.   to.Space = UDI29KDRAMSpace;
  2647.   count = (UDICount) sizeof(CPUOffset);
  2648.   size = (UDISizeT) 1;
  2649.   hostendian = FALSE;
  2650.  
  2651.   if ((retval = UDIWrite("\0\0\0",
  2652.              to,
  2653.              count,
  2654.              size,
  2655.              &bytes_ret,
  2656.              hostendian)) != UDINoError) {
  2657.     return (retval);
  2658.   };
  2659.   return (UDINoError);
  2660. }
  2661.  
  2662. void
  2663. set_stdin_needed(hif_lr3, hif_lr4)
  2664.   ADDR32          hif_lr3;
  2665.   UDICount        hif_lr4;
  2666. {
  2667.   Lr3_addr = (CPUOffset) hif_lr3;
  2668.   Lr4_count = (UDIUInt32) hif_lr4;
  2669.   ProcessorState = (UDIUInt32) UDIStdinNeeded;
  2670.   PreviousProcessorState = (UDIUInt32) UDIStdinNeeded;
  2671. }
  2672.  
  2673. void
  2674. set_stdout_ready(hif_lr3, hif_lr4)
  2675.   ADDR32          hif_lr3;
  2676.   UDICount        hif_lr4;
  2677. {
  2678.   Lr3_addr = (CPUOffset) hif_lr3;
  2679.   Lr4_count = (UDIUInt32) hif_lr4;
  2680.   ProcessorState = (UDIUInt32) UDIStdoutReady;
  2681.   PreviousProcessorState = (UDIUInt32) UDIStdoutReady;
  2682. }
  2683.  
  2684. void
  2685. set_stderr_ready(hif_lr3, hif_lr4)
  2686.   ADDR32          hif_lr3;
  2687.   UDICount        hif_lr4;
  2688. {
  2689.   Lr3_addr = (CPUOffset) hif_lr3;
  2690.   Lr4_count = (UDIUInt32) hif_lr4;
  2691.   ProcessorState = (UDIUInt32) UDIStderrReady;
  2692.   PreviousProcessorState = (UDIUInt32) UDIStderrReady;
  2693. }
  2694.  
  2695. static  INT32
  2696. Wait_For_Ack( /* retries */ )
  2697. {
  2698.   INT32           code;
  2699.   UINT32          count;
  2700.  
  2701.   count=(UINT32) 1;
  2702.  
  2703.   code = FAILURE;
  2704.   while ((code == FAILURE) && (count < TimeOut)) {
  2705.     code = Mini_msg_recv(BLOCK);
  2706.     count = count + 10;
  2707.     /* Check for user interrupt */
  2708.     SIGINT_POLL
  2709.     if (StopFlag) {
  2710.        STOP_SIG_HDLR
  2711.        ProcessorState = (UDIUInt32) UDIStopped;
  2712.        PreviousProcessorState = (UDIUInt32) UDIStopped;
  2713.        return (ABORT_FAILURE);
  2714.     }; 
  2715.   };
  2716.   return (code);
  2717. }
  2718.  
  2719. static  INT32
  2720. CheckForMsg(time)
  2721.   INT32           time;
  2722. {
  2723.   INT32             i;
  2724.   INT32           Code;
  2725.   int             ForEver;
  2726.  
  2727.  
  2728.   ForEver = 0;
  2729.   if (time == (UDIInt32) UDIWaitForever) 
  2730.     ForEver = 1;
  2731.   else 
  2732.    if (RemoteTarget == 1)    /* remote targets */
  2733. #ifdef MSDOS
  2734.        time = time*100;
  2735. #else
  2736.        time = time;
  2737. #endif
  2738.  
  2739.   i = 0;
  2740.   while ((i <= time) || ForEver) {
  2741.     /* Check for user interrupt */
  2742.     SIGINT_POLL
  2743.     if (StopFlag) {
  2744.        STOP_SIG_HDLR
  2745.        ProcessorState = (UDIUInt32) UDIStopped;
  2746.        PreviousProcessorState = (UDIUInt32) UDIStopped;
  2747.        return (ABORT_FAILURE);
  2748.     }; 
  2749.     if ((Code = Mini_msg_recv(NONBLOCK)) != FAILURE)
  2750.       return (Code);
  2751.     i = i + 1;
  2752.   }
  2753.   return (FAILURE);
  2754. }
  2755.  
  2756. static  void
  2757. process_target_msg(msgcode)
  2758.   INT32           msgcode;
  2759. {
  2760.   switch (msgcode) {
  2761.    case HALT:
  2762.     if (BreaksInPlace)
  2763.       ResetAllBreakpoints();
  2764.     BreaksInPlace = 0;
  2765.     process_HALT_msg();
  2766.     break;
  2767.    case CHANNEL1:
  2768.     process_CHAN1_msg();
  2769.     break;
  2770.    case CHANNEL2:
  2771.     process_CHAN2_msg();
  2772.     break;
  2773.    case CHANNEL0_ACK:
  2774.     (void) process_chan0_ack();
  2775.     break;
  2776.    case HIF_CALL:
  2777.     (void) process_HIF_msg();
  2778.     break;
  2779.    case STDIN_NEEDED_REQ:
  2780.     (void) process_stdin_needed_req();
  2781.     break;
  2782.    case STDIN_MODE_REQ:
  2783.     (void) set_stdin_mode();
  2784.     break;
  2785.    case ERROR:
  2786.     if (BreaksInPlace)
  2787.       ResetAllBreakpoints();
  2788.     BreaksInPlace = 0;
  2789.     process_ERR_msg();
  2790.     break;
  2791.    default:
  2792.     if (BreaksInPlace)
  2793.       ResetAllBreakpoints();
  2794.     BreaksInPlace = 0;
  2795.     ProcessorState = (UDIUInt32) UDIHalted;
  2796.     PreviousProcessorState = (UDIUInt32) UDIHalted;
  2797.     fprintf(stderr, "FATAL: a unknown msg 0x%lx\n", msgcode);
  2798.     (void)print_recv_bytes();
  2799.     break;
  2800.   };
  2801. }
  2802.  
  2803. static INT32
  2804. process_chan0_ack()
  2805. {
  2806.   char    nextchar;
  2807.  
  2808.   Channel0Busy = 0;
  2809.   if (Channel0_count > 0) {
  2810.     Channel0_count = Channel0_count - 1;
  2811.     nextchar = channel0_buffer[Channel0_count];
  2812.     Mini_build_channel0_msg(&nextchar, (INT32) 1);
  2813.     if (Mini_msg_send() != SUCCESS) {
  2814.         return((-1) * MONErrCantSendMsg);
  2815.     }
  2816. #if 0
  2817.     Channel0Busy=1;    /* never set */
  2818. #endif
  2819.   }
  2820.   return (UDINoError);
  2821. }
  2822.  
  2823. static  void
  2824. process_HALT_msg()
  2825. {
  2826.   INT32           mspace;
  2827.   ADDR32          pc0,
  2828.                   pc1;
  2829.   INT32           trap_number;
  2830.   INT32        type;
  2831.   ADDR32    Inst;
  2832.   BreakIdType    break_id;
  2833.   INT32        count;
  2834.  
  2835.  
  2836.   Mini_unpack_halt_msg(&mspace, &pc0, &pc1, &trap_number);
  2837.   if (trap_number == (INT32) 0) {
  2838.     if ((break_id = (BreakIdType) is_breakpt_at(mspace, pc1)) 
  2839.                         > (BreakIdType) 0) {
  2840.       ProcessorState = (UDIUInt32) UDIBreak;
  2841.       PreviousProcessorState = (UDIUInt32) UDIBreak;
  2842.       if ((get_from_bp_table(break_id, &mspace, &pc1, 
  2843.                      &count, &type, &Inst) == 0) &&
  2844.                      (count < (INT32) 0))
  2845.          remove_from_bp_table(break_id);
  2846.     } else
  2847.       ProcessorState = (UDIUInt32) UDITrapped;
  2848.       PreviousProcessorState = (UDIUInt32) UDITrapped;
  2849.   } else if (trap_number == 15) {    /* Trace */
  2850.     ProcessorState = (UDIUInt32) UDIStepped;
  2851.     PreviousProcessorState = (UDIUInt32) UDIStepped;
  2852.     StepCmdGiven = 0;    /* step complete */
  2853.   } else if (trap_number == 75) {
  2854.     ProcessorState = (UDIUInt32) UDIBreak;
  2855.     PreviousProcessorState = (UDIUInt32) UDIBreak;
  2856.   } else if (trap_number & 0x1000) { /* HIF specific reason */
  2857.     if ((trap_number & 0xffff) == 0x1000) { /* HIF exit */
  2858.        ProcessorState = (UDIUInt32) (UDIExited | 
  2859.                     ((trap_number & 0xffff0000)>>8));
  2860.        PreviousProcessorState = ProcessorState;
  2861.     } else { /* HIF error */
  2862.        ProcessorState = (UDIUInt32) (UDIHalted | (trap_number & 0xffff0000));
  2863.        PreviousProcessorState = ProcessorState;
  2864.     }
  2865.   } else {
  2866.     ProcessorState = (UDIUInt32) (UDITrapped | (trap_number << 8));
  2867.     PreviousProcessorState = ProcessorState;
  2868.   }
  2869. }
  2870.  
  2871. static    void
  2872. set_stdin_mode()
  2873. {
  2874.   INT32    mode;
  2875.  
  2876.   Mini_unpack_stdin_mode_msg(&mode);
  2877.   Mini_build_stdin_mode_ack_msg(PgmStdinMode);
  2878.   PgmStdinMode = mode;
  2879.   PreviousProcessorState = ProcessorState;    /* save current state */
  2880.   ProcessorState = (UDIUInt32) (UDIStdinModeX);
  2881.   if (Mini_msg_send() != SUCCESS) {
  2882.       ProcessorState = (UDIUInt32) UDIHalted;
  2883.   }
  2884.   return;
  2885. }
  2886.  
  2887. static    void
  2888. process_stdin_needed_req()
  2889. {
  2890.   Mini_unpack_stdin_needed_msg(&StdinCharsNeeded);
  2891.   /* upper 24 bits gives number needed */
  2892.   ProcessorState = (UDIUInt32) (UDIStdinNeeded | (StdinCharsNeeded << 8));
  2893.   PreviousProcessorState = ProcessorState;
  2894. }
  2895.  
  2896. static  void
  2897. process_CHAN1_msg()
  2898. {
  2899.   INT32           count;
  2900.  
  2901.   Mini_unpack_channel1_msg((BYTE *) channel1_buffer, &count);
  2902.   Channel1_count = (UDISizeT) count;
  2903.   /* upper 24 bits gives number to output */
  2904.   ProcessorState = (UDIUInt32) (UDIStdoutReady | (Channel1_count << 8));
  2905.   PreviousProcessorState = ProcessorState;
  2906. }
  2907.  
  2908. static  void
  2909. process_CHAN2_msg()
  2910. {
  2911.   INT32           count;
  2912.  
  2913.   Mini_unpack_channel2_msg((BYTE *) channel2_buffer, &count);
  2914.   Channel2_count = (UDISizeT) count;
  2915.   /* upper 24 bits gives number to output */
  2916.   ProcessorState = (UDIUInt32) (UDIStderrReady | (Channel2_count << 8));
  2917.   PreviousProcessorState = ProcessorState;
  2918. }
  2919.  
  2920. static  void
  2921. process_HIF_msg()
  2922. {
  2923.   INT32           svc_nm,
  2924.                   lr2,
  2925.                   lr3,
  2926.                   lr4,
  2927.                   gr96,
  2928.                   gr97,
  2929.                   gr121;
  2930.   int             retval;
  2931.   INT32        MsgCode;
  2932.  
  2933.   Mini_unpack_hif_msg(&svc_nm, &lr2, &lr3, &lr4);
  2934.   if ((svc_nm == (INT32) HIF_read) && (lr2 == (INT32) 0)) {    /* stdin */
  2935.     set_stdin_needed(lr3, lr4);
  2936.     return;
  2937.   } else if ((svc_nm == (INT32) HIF_write) && (lr2 == (INT32) 2)) {    /* stderr */
  2938.     set_stderr_ready(lr3, lr4);
  2939.     return;
  2940.   } else {
  2941.     retval = service_HIF(svc_nm, lr2, lr3, lr4, &gr96, &gr97, &gr121);
  2942.     if (retval == (INT32) -1) { /* service failed */
  2943.       ProcessorState = (UDIUInt32) UDIHalted;
  2944.       PreviousProcessorState = ProcessorState;
  2945.       return;
  2946.     } ;
  2947.     if (svc_nm == HIF_exit) {
  2948.     if (BreaksInPlace) {    /* For EB29K */
  2949.       BreaksInPlace = 0;
  2950.       ResetAllBreakpoints();
  2951.     };
  2952.        if ((tip_target_config.os_version & 0xf) > 4) { /* new HIF kernel */
  2953.       if ((tip_target_config.os_version & 0xf) > 0x6) { /* send hif rtn */
  2954.         Mini_build_hif_rtn_msg(svc_nm, gr121, gr96, gr97);
  2955.             if (Mini_msg_send() != SUCCESS) {
  2956.           ProcessorState = (UDIUInt32) UDIHalted;
  2957.           PreviousProcessorState = ProcessorState;
  2958.           return;
  2959.         }
  2960.               MsgCode = Wait_For_Ack();    /* debug core sends a HALT msg */
  2961.               if (MsgCode == ABORT_FAILURE) {
  2962.           ProcessorState = (UDIUInt32) UDIHalted;
  2963.           PreviousProcessorState = ProcessorState;
  2964.               } else if (MsgCode == FAILURE) {
  2965.           ProcessorState = (UDIUInt32) UDIHalted;
  2966.           PreviousProcessorState = ProcessorState;
  2967.         } else {
  2968.           ProcessorState = (UDIUInt32) (UDIExited | (lr2 << 8));
  2969.           PreviousProcessorState = ProcessorState;
  2970.         }
  2971.         return;
  2972.       } else {
  2973.         ProcessorState = (UDIUInt32) (UDIExited | (lr2 << 8));
  2974.         PreviousProcessorState = ProcessorState;
  2975.             return;
  2976.       }
  2977.        } else { /* old HIF kernel */
  2978.       exitstat = (int) lr2;
  2979.           if (Write_Glob_Reg(gr121, (int) 121) != UDINoError) {
  2980.           ProcessorState = (UDIUInt32) UDIHalted;
  2981.           PreviousProcessorState = ProcessorState;
  2982.           return;
  2983.           }
  2984.       ProcessorState = (UDIUInt32) (UDIExited | (exitstat << 8));
  2985.       PreviousProcessorState = ProcessorState;
  2986.           return;
  2987.        }
  2988.     } else {    /* not a HIF exit */
  2989.        if ((tip_target_config.os_version & 0xf) > 4) { /* new HIF kernel */
  2990.       Mini_build_hif_rtn_msg(svc_nm, gr121, gr96, gr97);
  2991.           if (Mini_msg_send() != SUCCESS) {
  2992.         ProcessorState = (UDIUInt32) UDIHalted;
  2993.         PreviousProcessorState = ProcessorState;
  2994.         return;
  2995.       }
  2996.       ProcessorState = (UDIUInt32) UDIRunning;
  2997.       PreviousProcessorState = ProcessorState;
  2998.       return;
  2999.        } else { /* old HIF kernel */
  3000.           if (Write_Glob_Reg(gr96, (int) 96) != UDINoError) {
  3001.         ProcessorState = (UDIUInt32) UDIHalted;
  3002.         PreviousProcessorState = ProcessorState;
  3003.           }
  3004.           if (svc_nm == (INT32) HIF_gettz) {
  3005.         if (Write_Glob_Reg(gr97, (int) 97) != UDINoError) {
  3006.           ProcessorState = (UDIUInt32) UDIHalted;
  3007.           PreviousProcessorState = ProcessorState;
  3008.         }
  3009.           }
  3010.           if (Write_Glob_Reg(gr121, (int) 121) != UDINoError) {
  3011.         ProcessorState = (UDIUInt32) UDIHalted;
  3012.         PreviousProcessorState = ProcessorState;
  3013.       }
  3014.           /* UDIExecute()? */
  3015.           if (StepCmdGiven) {
  3016.         ProcessorState = UDIStepped;
  3017.         PreviousProcessorState = ProcessorState;
  3018.           } else {
  3019.           if (!BreaksInPlace) {
  3020.             PutAllBreakpoints();
  3021.             BreaksInPlace = 1;
  3022.           }
  3023.           UDIExecute();
  3024.           }
  3025.        };
  3026.       return;
  3027.     }
  3028.   }
  3029. }
  3030.  
  3031. static  void
  3032. process_ERR_msg()
  3033. {
  3034.   ProcessorState = (UDIUInt32) UDIStopped;
  3035.   PreviousProcessorState = ProcessorState;
  3036. }
  3037.  
  3038. static int
  3039. Write_Glob_Reg(RegVal, RegNum)
  3040.   INT32           RegVal;
  3041.   int             RegNum;
  3042. {
  3043.   UDIResource     to;
  3044.   UDISizeT          size;
  3045.   UDICount        mincount;
  3046.   UDIBool         hostendian;
  3047.   UDICount        bytes_ret;
  3048.   UDIError        retval;
  3049.  
  3050.   to.Space = (CPUSpace) UDI29KGlobalRegs;
  3051.   to.Offset = (CPUOffset) RegNum;
  3052.   size = (UDISizeT) 4;
  3053.   mincount = (UDICount) 1;
  3054.   hostendian = FALSE;
  3055.   if (tip_target_config.TipEndian != tip_target_config.P29KEndian) {
  3056.     tip_convert32((BYTE *) &RegVal);
  3057.   }
  3058.   if ((retval = UDIWrite((UDIHostMemPtr) &RegVal,
  3059.              to,
  3060.              mincount,
  3061.              size,
  3062.              &bytes_ret,
  3063.              hostendian)) != UDINoError) {
  3064.     return ((UDIError) retval);
  3065.   };
  3066.   return (UDINoError);
  3067. }
  3068.  
  3069. static int
  3070. PutAllBreakpoints()
  3071. {
  3072.   UDIResource     addr;
  3073.   UDIError        UDIretval;
  3074.   UDICount        count_done;
  3075.   BreakIdType     break_id;
  3076.   ADDR32          offset;
  3077.   INT32           space;
  3078.   INT32           pcount;
  3079.   INT32           type;
  3080.   ADDR32          Inst;
  3081.   UDIUInt32       IllOp;
  3082.  
  3083.   if (strcmp (TargetType, "eb29k") == 0) { /* if EB29K */
  3084.     for (break_id = 1; break_id < LastBreakId; break_id++) {
  3085.       if (get_from_bp_table(break_id, &space, &offset,
  3086.                 &pcount, &type, &Inst) == 0) {
  3087.         addr.Offset = offset;
  3088.         addr.Space = SpaceMap_mm2udi(space);
  3089.     /* Read Instruction into Breaktable */
  3090.         if (!strcmp(TargetType, "eb29k")) {    
  3091.           if ((UDIretval = UDIRead(addr,
  3092.                  (UDIHostMemPtr) &Inst,
  3093.                  (UDICount) 1,
  3094.                  (UDISizeT) 4,
  3095.                  (UDICount *) &count_done,
  3096.                  (UDIBool) FALSE)) != UDINoError)    /* 29K endian */
  3097.             return (UDIretval);
  3098.         };
  3099.     (void) update_breakpt_at(space, offset, Inst);
  3100.         /* UDIWrite(Illop); write illegal opcode instruction */
  3101.         IllOp = (UDIUInt32) 0x00ccbbaa;    /* Illegal opcode */
  3102.         if ((UDIretval = UDIWrite((UDIHostMemPtr) &IllOp,
  3103.                   addr,
  3104.                   (UDICount) 1,
  3105.                   (UDISizeT) 4,
  3106.                   &count_done,
  3107.                   TRUE)) != UDINoError)
  3108.       return (UDIretval);
  3109.       }
  3110.     }
  3111.   }
  3112.   return (0);
  3113. }
  3114.  
  3115. static int
  3116. ResetAllBreakpoints()
  3117. {
  3118.   UDIResource     addr;
  3119.   UDIError        UDIretval;
  3120.   UDICount        count_done;
  3121.   BreakIdType     break_id;
  3122.   ADDR32          offset;
  3123.   INT32           space;
  3124.   INT32           pcount;
  3125.   INT32           type;
  3126.   ADDR32          Inst;
  3127.  
  3128.   if (strcmp (TargetType, "eb29k") == 0) { /* if EB29K */
  3129.     for (break_id = 1; break_id < LastBreakId; break_id++) {
  3130.       if (get_from_bp_table(break_id, &space, &offset,
  3131.                 &pcount, &type, &Inst) == 0) {
  3132.         /* UDIWrite(); write original instruction */
  3133.         addr.Offset = offset;
  3134.         addr.Space = SpaceMap_mm2udi(space);
  3135.         if ((UDIretval = UDIWrite((UDIHostMemPtr) &Inst,
  3136.                   addr,
  3137.                   (UDICount) 1,
  3138.                   (UDISizeT) 4,
  3139.                   &count_done,
  3140.                   FALSE)) != UDINoError)
  3141.       return (UDIretval);
  3142.       }
  3143.     }
  3144.   }
  3145.   return (0);
  3146. }
  3147.  
  3148. void
  3149. TIPPrintUsage(s)
  3150.   char           *s;
  3151. {
  3152.   fprintf(stderr, "Minimon (UDI 1.2) TIP Version: %s Date: %s\n", TIPVERSION, TIPDATE);
  3153.   fprintf(stderr, "List of Valid MONTIP options are:\n");
  3154.   fprintf(stderr, "-t <target_if_type> - the target interface type MUST be specified\n");
  3155.   fprintf(stderr, "[-r <Minimon_OS_linked_object>] - ROM file to be downloaded, if any\n");
  3156.   fprintf(stderr, "[-m <msg_log_filename>] - file to log messages between TIP and target\n");
  3157.   fprintf(stderr, "[-com <serial_comm_port>] -communication port to use, ex: -com com1:\n");
  3158.   fprintf(stderr, "[-par <paralle_port>] -parallel port for download , ex: -par lpt1:\n");
  3159.   fprintf(stderr, "[-re <retries_for_a_msg>] - number of retries\n");
  3160.   fprintf(stderr, "[-le] - specifies target is little endian\n");
  3161.   fprintf(stderr, "[-mbuf <msg_bufsize_to_use>] - maximum message buffer size\n");
  3162.   fprintf(stderr, "[-bl <msg_block_loopcount>] - block count while receiving\n");
  3163.   fprintf(stderr, "[-to <timeout_loopcount>] - timeout while receiving\n");
  3164.   fprintf(stderr, "[-seg <PC_mem_seg_addr_in_hex>] - PC memory segment base address, ex: -seg D800\n");
  3165.   fprintf(stderr, "[-port <PC_port_base_addr_in_hex>] - PC i/o port base address, ex: -port 2A0\n");
  3166.   fprintf(stderr, "[-baud <baudrate>] - baud rate for serial communications, ex: -baud 38400\n");
  3167.   fprintf(stderr, "[-R/P] - physical or protected mode (ONLY with OSBOOT supplied)\n");
  3168.   fprintf(stderr, "[-S] - run in supervisor mode (ONLY with OSBOOT supplied)\n");
  3169.   exit(1);
  3170. }
  3171.  
  3172. static INT32
  3173. SendConfigWait()
  3174. {
  3175.     INT32    MsgCode;
  3176.     int    count;
  3177.     unsigned long    time;
  3178.  
  3179.     count = (UINT32) 0;
  3180.     MsgCode = (INT32) FAILURE;
  3181.     do {
  3182. #ifdef    MSDOS
  3183.         if (RemoteTarget == 1)
  3184.            Mini_reset_comm();  /* reset communications channel */
  3185. #endif
  3186.       Mini_build_config_req_msg();
  3187.       if (Mini_msg_send() != SUCCESS) {
  3188.         return ((-1) * MONErrCantSendMsg);
  3189.       }
  3190.       count = count + 1;
  3191.       time = (unsigned long) 1;
  3192.       do {
  3193.     time = time + 10;
  3194.         MsgCode = Mini_msg_recv(BLOCK);
  3195.         SIGINT_POLL
  3196.         if (Interrupted) {
  3197.        Interrupted = 0;
  3198.        return ((INT32) ABORT_FAILURE);
  3199.         }
  3200. #ifndef    MSDOS
  3201.         if ((MsgCode == FAILURE) && 
  3202.         (RemoteTarget == 1))
  3203.            Mini_reset_comm();  /* reset communications channel */
  3204. #endif
  3205.       } while ((MsgCode == FAILURE) && (time < TimeOut));
  3206.     } while ((MsgCode == FAILURE) && (count < MessageRetries)); 
  3207.     return (MsgCode);
  3208. }
  3209.  
  3210. static char *
  3211. GetTargetType( Target, FromString)
  3212. char    *Target;
  3213. char    *FromString;
  3214. {
  3215.   char        *s;
  3216.  
  3217.   if (FromString == NULL)
  3218.      return (NULL);
  3219.  
  3220.   (void) strcpy (&ConnectString[0], FromString); /* to preserve the original */
  3221.   s = strtok(ConnectString, " ");
  3222.   while (s != NULL) {
  3223.     if ((s[0] == '-') && (s[1] == 't') && (s[2] == '\0')) { /* -t option */
  3224.        s = strtok (NULL, " "); /* continue search */
  3225.        if (s == NULL)
  3226.       return (NULL);
  3227.        else {
  3228.       Target = s;
  3229.       return (s);
  3230.        }
  3231.     };
  3232.     s = strtok (NULL, " "); /* continue search */
  3233.   }; /* while */
  3234.   return (NULL);
  3235. }
  3236.  
  3237.  
  3238. static INT32
  3239. Mini_load_coff(filename, mspace, sym, Section, quietmode)
  3240.    char *filename;
  3241.    int   quietmode;
  3242.    INT32    sym;
  3243.    INT32    Section;
  3244.    INT32    mspace;
  3245.    {
  3246.    unsigned short  COFF_sections;
  3247.    INT32  flags;
  3248.    INT32  memory_space;
  3249.    INT32  address;
  3250.    INT32  byte_count;
  3251.    INT32  write_count;
  3252.    INT32  temp_byte_count;
  3253.  
  3254.    struct  filehdr      COFF_header;
  3255.    struct  aouthdr      COFF_aout_header;
  3256.    struct  scnhdr      COFF_section_header;
  3257.  
  3258.    /* Open the COFF input file (if we can) */
  3259.    if ((coff_in = FindFile(filename)) == NULL)
  3260.       return ((-1) * MONErrCantOpenCoff);
  3261.  
  3262.    /* Read in COFF header information */
  3263.    if (fread((char *)&COFF_header, sizeof(struct filehdr), 1, coff_in) != 1) {
  3264.       fclose(coff_in); return ((-1) * MONErrCantLoadROMfile);
  3265.    };
  3266.  
  3267.  
  3268.    /* Is it an Am29000 COFF File? */
  3269.    if ((COFF_header.f_magic != 0x17a) && (COFF_header.f_magic != 0x7a01) &&
  3270.        (COFF_header.f_magic != 0x17b) && (COFF_header.f_magic != 0x7b01)) {
  3271.       fclose(coff_in); return ((-1) * MONErrCantLoadROMfile);
  3272.    }
  3273.  
  3274.    /* Get number of COFF sections */
  3275.    if ((COFF_header.f_magic != 0x17a) && (COFF_header.f_magic != 0x017b))
  3276.       tip_convert16((BYTE *) &COFF_header.f_nscns);
  3277.    COFF_sections = (unsigned short) COFF_header.f_nscns;
  3278.  
  3279.    /* Read in COFF a.out header information (if we can) */
  3280.    if (COFF_header.f_opthdr > 0) {
  3281.       if (fread((char *)&COFF_aout_header, sizeof(struct aouthdr), 
  3282.                            1, coff_in) != 1) {
  3283.          fclose(coff_in); return ((-1) * MONErrCantLoadROMfile);
  3284.       };
  3285.       if ((COFF_header.f_magic != 0x17a) && (COFF_header.f_magic != 0x017b)) {
  3286.          tip_convert16((BYTE *) &COFF_header.f_opthdr);
  3287.       }
  3288.    }
  3289.  
  3290.  
  3291.    /*
  3292.    ** Process COFF section headers
  3293.    */
  3294.  
  3295.    /* Process all sections */
  3296.    while ((int) COFF_sections--) {
  3297.  
  3298.       fseek (coff_in, (long) (FILHSZ+(int)COFF_header.f_opthdr+
  3299.                   SCNHSZ*(COFF_header.f_nscns-COFF_sections-1)), 
  3300.                   FROM_BEGINNING);
  3301.  
  3302.       if (fread(&COFF_section_header, 1, SCNHSZ, coff_in) != SCNHSZ) {
  3303.           fclose(coff_in); return ((-1) * MONErrCantLoadROMfile);
  3304.       }
  3305.  
  3306.       if ((COFF_header.f_magic != 0x17a) && (COFF_header.f_magic != 0x017b)) {
  3307.          tip_convert32((BYTE *) &(COFF_section_header.s_paddr));
  3308.          tip_convert32((BYTE *) &(COFF_section_header.s_scnptr));
  3309.          tip_convert32((BYTE *) &(COFF_section_header.s_size));
  3310.          tip_convert32((BYTE *) &(COFF_section_header.s_flags));
  3311.        }
  3312.  
  3313.       address = COFF_section_header.s_paddr;
  3314.       byte_count = COFF_section_header.s_size;
  3315.       flags = COFF_section_header.s_flags;
  3316.  
  3317.       /* Print downloading messages (if necessary) */
  3318.       if ((flags == (INT32) STYP_TEXT) || (flags == (INT32) (STYP_TEXT | STYP_ABS))) {
  3319.      memory_space = I_MEM;
  3320.       } else if ((flags == (INT32) STYP_DATA) || (flags == (INT32) (STYP_DATA | STYP_ABS)) ||
  3321.           (flags == (INT32) STYP_LIT) || (flags == (INT32) (STYP_LIT | STYP_ABS)) ||
  3322.           (flags == (INT32) STYP_BSS) || (flags == (INT32) (STYP_BSS | STYP_ABS))) {
  3323.      memory_space = D_MEM;
  3324.       } else {
  3325.      flags = (INT32) 0;
  3326.       }
  3327.  
  3328.       if ((flags == (INT32) STYP_BSS) || (flags == (INT32) (STYP_BSS | STYP_ABS))) {
  3329.       /* Clear BSS section */
  3330.        if (flags & Section) {
  3331.        (void) memset ((char *) buffer, (int) '\0', sizeof(buffer));
  3332.        while (byte_count > 0) {
  3333.          write_count = (byte_count < (INT32) sizeof(buffer)) ?
  3334.                 byte_count : (INT32) sizeof (buffer);
  3335.          if(Mini_write_memory ((INT32) memory_space,
  3336.                   (ADDR32) address,
  3337.                   (INT32) write_count,
  3338.                   (BYTE *) buffer) != SUCCESS) {
  3339.            (void) fclose(coff_in);
  3340.         return((-1) * MONErrCantWriteToMem);
  3341.          }
  3342.          address = address + write_count;
  3343.          byte_count = byte_count - write_count;
  3344.        }
  3345.     }
  3346.       } else if (flags & Section) { /* not a BSS or COmment */
  3347.      if (flags == (INT32) (flags & Section)) {
  3348.        fseek (coff_in, COFF_section_header.s_scnptr, FROM_BEGINNING);
  3349.            while (byte_count > 0) {
  3350.              temp_byte_count = MIN((INT32) byte_count, (INT32) sizeof(buffer));
  3351.              if (fread((char *) buffer, (int) temp_byte_count, 1, coff_in) != 1) {
  3352.                 fclose(coff_in); return ((-1) * MONErrCantLoadROMfile);
  3353.          };
  3354.              /* Write to 29K memory*/
  3355.              if (Mini_write_memory ((INT32)  memory_space,
  3356.                                 (ADDR32) address,
  3357.                                 (INT32)  temp_byte_count,
  3358.                                 (BYTE *) buffer) != SUCCESS) {
  3359.               (void) fclose(coff_in);
  3360.            return((-1) * MONErrCantWriteToMem);
  3361.          };
  3362.              address = address + temp_byte_count;
  3363.              byte_count = byte_count - temp_byte_count;
  3364.            };
  3365.      };
  3366.       }
  3367.    }  /* end while */
  3368.  
  3369.    (void) fclose(coff_in);
  3370.    return (SUCCESS);
  3371.  
  3372.    }   /* end Mini_loadcoff() */
  3373.  
  3374. /* 
  3375. ** Breakpoint code 
  3376. */
  3377.  
  3378. static void
  3379. add_to_bp_table(id, space, offset, count, type, inst)
  3380. BreakIdType    *id;
  3381. INT32    space;
  3382. ADDR32    offset;
  3383. INT32     count;
  3384. INT32    type;
  3385. ADDR32    inst;
  3386. {
  3387.   static BreakIdType    current_break_id=1;
  3388.   struct tip_break_table      *temp, *temp2;
  3389.  
  3390.   if (bp_table == NULL) { /* first element */
  3391.     bp_table = (struct tip_break_table *) malloc (sizeof(struct tip_break_table));
  3392.     bp_table->id = current_break_id;
  3393.     bp_table->offset = offset;
  3394.     bp_table->space = space;
  3395.     bp_table->count = count;
  3396.     bp_table->type = type;
  3397.     bp_table->BreakInst = inst;
  3398.     bp_table->next = NULL;
  3399.   } else {
  3400.     temp2 = bp_table;
  3401.     temp = (struct tip_break_table *) malloc (sizeof(struct tip_break_table));
  3402.     temp->id = current_break_id;
  3403.     temp->offset = offset;
  3404.     temp->space = space;
  3405.     temp->count = count;
  3406.     temp->type = type;
  3407.     temp->BreakInst = inst;
  3408.     temp->next = NULL;
  3409.     while (temp2->next != NULL)
  3410.       temp2 = temp2->next;
  3411.     temp2->next = temp;
  3412.   };
  3413.   *id = current_break_id;
  3414.   current_break_id++;
  3415. }
  3416.  
  3417. static int 
  3418. get_from_bp_table(id, space, offset, count, type, inst)
  3419. BreakIdType    id;
  3420. INT32    *space;
  3421. ADDR32    *offset;
  3422. INT32     *count;
  3423. INT32    *type;
  3424. ADDR32    *inst;
  3425. {
  3426.   struct tip_break_table  *temp;
  3427.  
  3428.   temp = bp_table;
  3429.  
  3430.   while (temp != NULL) {
  3431.     if (temp->id == id) {
  3432.        *offset = temp->offset;
  3433.        *space = temp->space;
  3434.        *count = temp->count;
  3435.        *type = temp->type;
  3436.        *inst = temp->BreakInst;
  3437.        return(0);
  3438.     } else {
  3439.       temp = temp->next;
  3440.     };
  3441.   }
  3442.   return(-1);
  3443. }
  3444.  
  3445. static int
  3446. remove_from_bp_table(id)
  3447. BreakIdType    id;
  3448. {
  3449.   struct  tip_break_table    *temp, *temp2;
  3450.  
  3451.   if (bp_table == NULL)
  3452.      return (-1);
  3453.   else {
  3454.     temp = bp_table;
  3455.     if (temp->id == id) { /* head of list */
  3456.        bp_table = bp_table->next;
  3457.        (void) free (temp);
  3458.        return (0); /* success */
  3459.     } else {
  3460.        while (temp->next != NULL) {
  3461.           if (temp->next->id == id) {
  3462.          temp2 = temp->next;
  3463.          temp->next = temp->next->next;
  3464.          (void) free (temp2);
  3465.          return (0); /* success */
  3466.           } else {
  3467.             temp = temp->next;
  3468.           }
  3469.        };
  3470.     }
  3471.   };
  3472.   return (-1);  /* failed */
  3473. }
  3474.  
  3475. static int 
  3476. update_breakpt_at(space, offset, Inst)
  3477. INT32    space;
  3478. ADDR32    offset;
  3479. ADDR32    Inst;
  3480. {
  3481.   struct tip_break_table  *temp;
  3482.  
  3483.   temp = bp_table;
  3484.  
  3485.   while (temp != NULL) {
  3486.     if ((temp->space == space) && (temp->offset == offset)) {
  3487.        temp->BreakInst = Inst;
  3488.        return(0);
  3489.     } else {
  3490.       temp = temp->next;
  3491.     };
  3492.   }
  3493.   return (-1);
  3494. }
  3495.  
  3496. static int 
  3497. is_breakpt_at(space, offset)
  3498. INT32    space;
  3499. ADDR32    offset;
  3500. {
  3501.   struct tip_break_table  *temp;
  3502.  
  3503.   temp = bp_table;
  3504.  
  3505.   while (temp != NULL) {
  3506.     if ((temp->space == space) && (temp->offset == offset)) {
  3507.        return((int) temp->id); /* TRUE */
  3508.     } else {
  3509.       temp = temp->next;
  3510.     };
  3511.   }
  3512.   return(0); /* FALSE */
  3513. }
  3514.  
  3515. #ifdef    MSDOS
  3516. #define    PATH_DELIM    ";"
  3517. #define    DIR_SEP_CHAR    (char) '\\'
  3518. #define    APPEND_PATH    "\\lib\\"
  3519. #else
  3520. #define    PATH_DELIM    ":"
  3521. #define    DIR_SEP_CHAR        (char) '/'
  3522. #define    APPEND_PATH    "/lib/"
  3523. #endif
  3524. static FILE  *
  3525. FindFile(filename)
  3526. char    *filename;
  3527. {
  3528.   char    *path, *pathptr;
  3529.   char    *trypath, *at;
  3530.   char    *pathbuf;
  3531.   FILE    *filep;
  3532.  
  3533.   /* is the filename given already complete? */
  3534.   if ((filep = fopen(filename, FILE_OPEN_FLAG)) != NULL) {
  3535.       return(filep);
  3536.   };
  3537.  
  3538.   /* get PATH */
  3539.   if ((pathptr = (char *) getenv ("PATH")) == NULL)
  3540.      return ((FILE *) NULL);
  3541.   if ((path = (char *) malloc ((unsigned int)strlen(pathptr)+1))==NULL)
  3542.      return ((FILE *) NULL);
  3543.   (void) strcpy(path,pathptr); /* local copy */
  3544.   /* alloc buffer */
  3545.   if ((pathbuf = (char *) malloc((unsigned int) strlen(path)+
  3546.            strlen("../lib/ ")+strlen(filename)+3)) == NULL)
  3547.      return ((FILE *) NULL);
  3548.  
  3549.   /* get first item */
  3550.   if ((trypath = strtok(path, PATH_DELIM)) == NULL) { /* one item */
  3551.      (void) strcpy(pathbuf,path);
  3552.      if ((at = strrchr (pathbuf, DIR_SEP_CHAR)) != NULL) {
  3553.          (void) strcpy (at, APPEND_PATH);
  3554.      (void) strcat (pathbuf, filename);
  3555.          if ((filep = fopen(pathbuf, FILE_OPEN_FLAG)) != NULL) 
  3556.        return (filep);
  3557.      } else { /* just append filename */
  3558.          (void) strcat (pathbuf, APPEND_PATH);
  3559.      (void) strcat (pathbuf, filename);
  3560.          if ((filep = fopen(pathbuf, FILE_OPEN_FLAG)) != NULL) 
  3561.        return (filep);
  3562.      };
  3563.      return ((FILE *) NULL);
  3564.   };
  3565.  
  3566.   /* try all items */
  3567.   while (trypath != NULL) {
  3568.       (void) strcpy (pathbuf, trypath);
  3569.       if ((at = strrchr (pathbuf, DIR_SEP_CHAR)) != NULL) {
  3570.          (void) strcpy (at, APPEND_PATH);
  3571.      (void) strcat (pathbuf, filename);
  3572.          if ((filep = fopen(pathbuf, FILE_OPEN_FLAG)) != NULL) 
  3573.        return (filep);
  3574.       } else { /* just append filename */
  3575.          (void) strcat (pathbuf, APPEND_PATH);
  3576.      (void) strcat (pathbuf, filename);
  3577.          if ((filep = fopen(pathbuf, FILE_OPEN_FLAG)) != NULL) 
  3578.        return (filep);
  3579.       };
  3580.       trypath = strtok((char *) 0, PATH_DELIM);
  3581.   }
  3582.  
  3583.   /* didn't succeed */
  3584.   return ((FILE *) NULL);
  3585. }
  3586.  
  3587. void
  3588. IntHandler(num)
  3589. int    num;
  3590. {
  3591.   Interrupted = 1;
  3592.   return;
  3593. }
  3594.