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 / udi / udip2mm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-23  |  24.9 KB  |  738 lines

  1. /******************************************************************************
  2. *       The process  and all routines contained  herein are the
  3. *       property and trade secrets of AMD Inc. 
  4. *       Except as  provided  for by licence agreement, this code 
  5. *       shall  not  be duplicated,  used or  disclosed  for  any 
  6. *       purpose or reason, in whole or part, without the express 
  7. *       written consent of AMD.
  8. *       Copyright  AMD Inc.  1991
  9. *
  10. *********************************************************************** MODULE
  11. *       $NAME     @(#)udip2mm.c    1.2 91/06/12
  12. *       AUTHORS   Daniel Mann
  13. *       This module implements the UDI-P interface.
  14. ********************************************************************** HISTORY
  15. *
  16. *
  17. **************************************************************** INCLUDE FILES
  18. */
  19. #include <stdio.h>
  20. #include "udiproc.h"
  21. #include "dbg_core.h"
  22. #include "error.h"
  23.  
  24. /* local type decs. and macro defs. not in a .h  file ************* MACRO/TYPE
  25. */
  26. #define BUFER_SIZE 2048
  27. typedef struct msgheader_str
  28. {
  29.     INT32    class;
  30.     INT32    length;
  31.     UINT32    param[BUFER_SIZE];
  32. } msgheader_t;
  33. static    msgheader_t    msg_rbuf;
  34. static    msgheader_t    msg_sbuf;
  35.  
  36. int (*msg_send)();
  37. int (*msg_recv)();
  38.  
  39. /* local dec/defs. which are not in a .h   file *************** LOCAL DEC/DEFS
  40. */
  41. static    INT8    SpaceMap_udi2mm[
  42. /* DRAMSpace    IOSpace        CPSpace0    CPSpace1    IROMSpace */
  43.    D_MEM,    I_O,        -1        ,-1        I_ROM,
  44. /* IRAMSpace    LocalRegs    GlobalRegs    RealRegs    SpecialRegs */
  45.    I_MEM,    LOCAL_REG,    GLOBAL_REG,    GLOBAL_REG,    SPECIAL_REG,
  46. /* TLBRegs    ACCRegs        ICacheSpace    Am29027Regs    PC */
  47.    TLB_REG,    SPECIAL_REG,    I_CACHE,    COPROC_REG,    SPECIAL_REG
  48. /* DCacheSpace */
  49.    D_CACHE ];
  50.  
  51. static    INT8    SpaceMap_mm2udi[
  52. /* LOCAL_REG    GLOBAL_REG    SPECIAL_REG    TLB_REG        COPROC_REG */
  53.    LocalRegs,    GlobalRegs,    SpecialRegs,    TLBRegs,    Am29029Regs,
  54. /* I_MEM    D_MEM        I_ROM        D_ROM        I_O */
  55.    IRAMSpace,    DRAMSpace,    IROMSpace,    -1,        IOSpace,    
  56. /* I_CACHE    D_CACHE */
  57.    ICacheSpace,    DCacheSpace ];
  58.  
  59. UDIPID    default_pid;        /* requested PID */
  60.         
  61. typedef    struct     bkpt_entry_str
  62. {
  63.     UDIResource     addr;
  64.     INT32     passcount;
  65.     UDIBreakType type;
  66. } bkpt_entry_t;
  67. #define        MAX_BKPT 20
  68. bkpt_entry_t    bkpt_table[MAX_BKPT];
  69.  
  70.  
  71. /****************************************************************** PROCEDURES
  72. */
  73.  
  74. /*********************************************************** UDI_GET_ERROR_MSG
  75.      Errors above the value ERRUDI_TIP indicate that the
  76.      TIP  was  not able to complete the request for some
  77.      target   specific    reason.     The    DFE    uses
  78.      UDIGetErrorMsg() to get the descriptive text for
  79.      the error message which can then  be  displayed  to
  80.      the user.
  81. */
  82. UDIError UDIGetErrorMsg(error_code, msg)
  83. UINT32         error_code;    /* in */
  84. UDIHostMemPtr  msg;        /* out -- text of msg */
  85. {
  86.     if(error_code <= 0 || error_code > EMBAUD)
  87.     return EMUSAGE;
  88.     bcopy(error_msg[error_code], (char*) msg,
  89.     strlen(error_msg[error_code]);
  90.     return 0;
  91. }
  92.  
  93. /*************************************************************** UDI_TERMINATE
  94.      UDITerminate() is used to tell the  TIP  that  the
  95.      DFE is finished.
  96. */
  97. UDITerminate()
  98. {
  99. }
  100.  
  101. /******************************************************* UDI_GET_TARGET_CONFIG
  102.      UDIGetTargetConfig() gets information about  the
  103.      target.  I_mem_start/size defines the start address
  104.      and   length    of    instruction    RAM    memory.
  105.      D_mem_start/size  defines  the  start  address  and
  106.      length     of     instruction     Data      memory.
  107.      IR_mem_start/size  defines  the  start  address and
  108.      length of instruction ROM memory.  coprocessor  de-
  109.      fines the type of coprocessor present in the target
  110.      if any.  max_breakpoints defines the maximum number
  111.      of   breakpoints   which  the  target  can  handle.
  112.      max_steps defines the maximum number  of  stepcount
  113.      that can be used in the UDIStep command.
  114. */
  115. UDIError UDIGetTargetConfig(I_mem_start, I_mem_size, D_mem_start,
  116.         D_mem_size, R_mem_start, R_mem_size, cpu_prl, copro_prl)
  117. UDIOffset  *I_mem_start;/* out */
  118. UDIOffset  *I_mem_size;    /* out */
  119. UDIOffset  *D_mem_start;/* out */
  120. UDIOffset  *D_mem_size;    /* out */
  121. UDIOffset  *R_mem_start;/* out */
  122. UDIOffset  *R_mem_size;    /* out */
  123. UINT32       *cpu_prl;    /* out */
  124. UINT32       *copro_prl;    /* out */
  125. {
  126.     UDIError    errno_mm = 0;
  127.  
  128.     msg_sbuf.class = CODE_CONFIG_REQ;
  129.     msg_sbuf.length = 0;
  130.  
  131.     (*msg_send)(&msg_sbuf);            /* send MiniMON message */
  132.     while( (*msg_recv)(&msg_rbuf) );        /* wait for reply */
  133.  
  134.     if(msg_rbuf.class == CONFIG)
  135.     {
  136.     *I_mem_start = msg_rbuf.param[2];
  137.     *I_mem_size  = msg_rbuf.param[3];
  138.     *D_mem_start = msg_rbuf.param[4];
  139.     *D_mem_size  = msg_rbuf.param[5];
  140.     *R_mem_start = msg_rbuf.param[6];
  141.     *R_mem_size  = msg_rbuf.param[7];
  142.     *cpu_prl     = msg_rbuf.param[0];
  143.     *copro_prl   = msg_rbuf.param[10];
  144.     }
  145.     else
  146.     {
  147.     errno_mm = EMBADMSG;
  148.         if(msg_rbuf.class == ERROR)
  149.         errno_mm = msg_rbuf.param[0];
  150.     }
  151.     return errno_mm;
  152. }
  153.  
  154. /********************************************************** UDI_CREATE_PRCOESS
  155.      UDICreateProcess() tells the  target  OS  that  a
  156.      process is to be created and gets a PID back unless
  157.      there is some error.
  158. */
  159. UDIError UDICreateProcess(pid)
  160. UDIPID    *pid;    /* out */
  161. {
  162.     UDIError    errno_mm = 0;
  163.  
  164.     *pid = 1;                /* OSboot sets user PID=1 */
  165.     return errno_mm;
  166. }
  167.  
  168. /********************************************************** UDI_SET_DEFALUT_PID
  169.      UDISetDefaultPid  uses   a   pid   supplied   by
  170.      UDICreateProcess  and  sets it as the default for all
  171.      udi calls until a new default is set.  A user of  a
  172.      single-process OS would only have to use this once.
  173. */
  174. UDIError UDISetDefaultPid(pid)
  175. UDIPID    pid;    /* in */
  176. {
  177.     UDIError    errno_mm = 0;
  178.  
  179.     default_pid = pid;
  180.     return errno_mm;
  181. }
  182.  
  183. /********************************************************* UDI_DESTROY_PROCESS
  184.      UDIDestroyProcess() frees a process resource pre-
  185.      viously created by UDICreateProcess().
  186. */
  187. UDIError UDIDestroyProcess(pid)
  188. UDIPID   pid;    /* in */
  189. {
  190.     UDIError    errno_mm = 0;
  191.  
  192.     return errno_mm;
  193. }
  194.  
  195. /****************************************************** UDI_INITIALIZE_PROCESS
  196.      UDIInitializeProcess() is called after  the  code
  197.      for a process has been loaded.  The pid used is the
  198.      one  set  by  UDISetDfaultPid.   The  parameter
  199.      text_addr  defines  the lowest and highest text ad-
  200.      dresses  used  by  the  process.    The   parameter
  201.      data_addr  defines  the lowest and highest data ad-
  202.      dresses  used  by  the   process.    The   paramter
  203.      entry_point defines the entry point of the process.
  204.      The parameters mem_stack_size  and  reg_stack  size
  205.      define  the sizes of the memory and register stacks
  206.      required  by  the  process.   The   special   value
  207.      UDI_DEFAULT  implies  that  the default stack sizes
  208.      for the target OS should be  used.   The  parameter
  209.      argstring  defines a character string that will get
  210.      parsed into the argv array for  the  process.   The
  211.      target  OS will use the supplied information to set
  212.      up the heaps and stacks and the  program  arguments
  213.      if any.  On return; the PC will be set to the entry
  214.      point of the process.
  215. */
  216. UDIError  UDIInitializeProcess( text_addr, data_addr, entry_point,
  217.             mem_stack_size, reg_stack_size, argstring)
  218. UDIRange    text_addr;        /* in--lowest and highest text addrs */
  219. UDIRange    data_addr;        /* in--lowest and highest data addrs */
  220. UDIResource entry_point;    /* in--process entry point */
  221. CPUSizeT    mem_stack_size;    /* in--memory stack size */
  222. CPUSizeT    reg_stack_size;    /* in--register stack size */
  223. char*        argstring;        /* in--argument string used to */
  224. {
  225.     UDIError    errno_mm = 0;
  226.  
  227.     msg_sbuf.class = CODE_INIT;
  228.     msg_sbuf.length = 8*4;
  229.  
  230.     msg_sbuf.param[0] = text_addr.low;
  231.     msg_sbuf.param[1] = text_addr.high;
  232.     msg_sbuf.param[2] = data_start.low;
  233.     msg_sbuf.param[3] = data_end.hich;
  234.     msg_sbuf.param[4] = entry_point.Offset;
  235.     msg_sbuf.param[5] = mem_stack_size;
  236.     msg_sbuf.param[6] = reg_stack_size;
  237.     msg_sbuf.param[7] = argstring;
  238.  
  239.     (*msg_send)(&msg_sbuf);            /* send MiniMON message */
  240.     while( (*msg_recv)(&msg_rbuf) );        /* wait for reply */
  241.  
  242.     if(msg_rbuf.class == ERROR)
  243.     errno_mm = msg_rbuf.param[0];
  244.     else if(msg_rbuf.class != INIT_ACK)
  245.     errno_mm = EMINIT;
  246.     return errno_mm;
  247. }
  248.  
  249. /****************************************************************** UDI_READ
  250.      UDIRead() reads a block of objects from  a  target
  251.      address+space  to host space.  The parameter struc-
  252.      ture "from" specifies the address space and  offset
  253.      of  the  source.   The parameter "to" specifies the
  254.      destination address in the DFE on  the  host.   The
  255.      parameter  count specifies the number of objects to
  256.      be transferred and "size"  specifies  the  size  of
  257.      each  object.
  258.      The size parameter is used by the TIP to
  259.      perform byte-swapping if the target is not the same
  260.      endian as the  host.   On  completion;  the  output
  261.      parameter  count_done  is  set to the number of ob-
  262.      jects successfully transferred.
  263. */
  264.  
  265. UDIError UDIRead (from, to, count, size, count_done, host_endian)
  266. UDIResource    from;        /* in - source address on target */
  267. UDIVoidPtr    to;        /* out - destination address on host */
  268. UDICount    count;        /* in -- count of objects to be transferred */
  269. UDISize        size;        /* in -- size of each object */
  270. UDICount    *count_done;    /* out - count actually transferred */
  271. UDIBool        host_endian;    /* in -- flag for endian information */
  272. {
  273.     UDIError    errno_mm = 0;
  274.  
  275.     msg_sbuf.class = CODE_READ_REQ;
  276.     msg_sbuf.length = 3*4;
  277.  
  278.     msg_sbuf.param[0] = MapSpace_udi2mm[from.Space];    /* space */
  279.     msg_sbuf.param[1] = from.Offset;            /* address */
  280.     msg_sbuf.param[2] = size*count            /* byte_count */
  281.  
  282.     (*msg_send)(&msg_sbuf);            /* send MiniMON message */
  283.     while( (*msg_recv)(&msg_rbuf) );        /* wait for reply */
  284.  
  285.     if(msg_rbuf.class == READ_ACK)
  286.     {   *count_done = msg_rbuf.param[2]/size;
  287.         bcopy((char*)&(msg_sbuf.param[3])), (char*)to, size*count);
  288.     }
  289.     else
  290.     {
  291.     errno_mm = EMREAD;
  292.     *count_done = 0;
  293.         if(msg_rbuf.class == ERROR)
  294.         errno_mm = msg_rbuf.param[0];
  295.     }
  296.     return errno_mm;
  297. }
  298.  
  299. /****************************************************************** UDI_WRITE
  300.      UDIWrite() writes a block  of  objects  from  host
  301.      space  to  a  target  address+space  The  parameter
  302.      "from" specifies the source address in the  DFE  on
  303.      the  host.   The parameter structure "to" specifies
  304.      the address space and offset of the destination  on
  305.      the  target.   The  parameter  count  specifies the
  306.      number of objects  to  be  transferred  and  "size"
  307.      specifies the size of each object. The size parameter
  308.      is used by the TIP to perform byte-swapping if
  309.      the target is not the same endian as the host.   On
  310.      completion;  the output parameter count_done is set
  311.      to the number of objects successfully transferred.
  312. */
  313. UDIError UDIWrite( from, to, count, size, count_done, HostEndian )
  314. UDIVoidPtr    from;        /* in -- destination address on host */
  315. UDIResource    to;        /* in -- source address on target */
  316. UDICount    count;        /* in -- count of objects to be transferred */
  317. UDISize        size;        /* in -- size of each object */
  318. UDICount    *count_done;    /* out - count actually transferred */
  319. UDIBool        HostEndian;    /* in -- flag for endian information */
  320. {
  321.     UDIError    errno_mm = 0;
  322.  
  323.     msg_sbuf.class = CODE_WRITE_REQ;
  324.     msg_sbuf.length = 3*4 + size*count;
  325.  
  326.     msg_sbuf.param[0] = MapSpace_udi2mm[to.Space];    /* space */
  327.     msg_sbuf.param[1] = to.Offset;            /* address */
  328.     msg_sbuf.param[2] = size*count            /* byte_count */
  329.     bcopy((char*)from, (char*)msg_sbuf.param[3]), size*count);
  330.  
  331.     (*msg_send)(&msg_sbuf);            /* send MiniMON message */
  332.     while( (*msg_recv)(&msg_rbuf) );        /* wait for reply */
  333.  
  334.     if(msg_rbuf.class == WRITE_ACK)
  335.     *count_done = msg_rbuf.param[2]/size;
  336.     else
  337.     {
  338.     errno_mm = EMWRITE;
  339.     *count_done = 0;
  340.         if(msg_rbuf.class == ERROR)
  341.         errno_mm = msg_rbuf.param[0];
  342.     }
  343.     return errno_mm;
  344. }
  345.  
  346. /******************************************************************** UDI_COPY
  347.      UDICopy() copies a block of objects from one  tar-
  348.      get  address/space to another target address/space.
  349.      If the source and destination overlap; the copy  is
  350.      implemented as if a temporary buffer was used.  The
  351.      parameter structure "from"  specifies  the  address
  352.      space  and offset of the destination on the target.
  353.      The parameter structure "to" specifies the  address
  354.      space  and offset of the destination on the target.
  355.      The parameter count specifies the number of objects
  356.      to  be transferred and "size" specifies the size of
  357.      each object.  On completion; the  output  parameter
  358.      count_done is set to the number of objects success-
  359.      fully transferred.
  360. */
  361. UDIError UDICopy(from, to, count, size, count_done, direction )
  362. UDIResource    from;        /* in -- destination address on target */
  363. UDIResource    to;        /* in -- source address on target */
  364. UDICount    count;        /* in -- count of objects to be transferred */
  365. UDISize        size;        /* in -- size of each object */
  366. UDICount    *count_done;    /* out - count actually transferred */
  367. UDIBool        direction;    /* in -- high-to-low or reverse */
  368. {
  369.     UDIError    errno_mm = 0;
  370.  
  371.     msg_sbuf.class = CODE_COPY;
  372.     msg_sbuf.length = 5*4
  373.  
  374.     msg_sbuf.param[0] = MapSpace_udi2mm[from.Space];    /* source space */
  375.     msg_sbuf.param[1] = source.Offset;            /* address */
  376.     msg_sbuf.param[2] = MapSpace_udi2mm[to.Space];    /* dest space */
  377.     msg_sbuf.param[3] = to.Offset;            /* address */
  378.     msg_sbuf.param[4] = size*count            /* byte_count */
  379.  
  380.     (*msg_send)(&msg_sbuf);            /* send MiniMON message */
  381.     while( (*msg_recv)(&msg_rbuf) );        /* wait for reply */
  382.  
  383.     if(msg_rbuf.class == COPY_ACK))
  384.     *count_done = msg_rbuf.param[4]/size;
  385.     else
  386.     {
  387.     errno_mm = EMCOPY;
  388.     *count_done = 0;
  389.         if(msg_rbuf.class == ERROR)
  390.         errno_mm = msg_rbuf.param[0];
  391.     }
  392.     return errno_mm;
  393. }
  394.  
  395. /***************************************************************** UDI_EXECUTE
  396.      UDIExecute() continues execution  of  the  default
  397.      process from the current PC.
  398. */
  399. UDIError UDIExecute()
  400. {
  401.     UDIError    errno_mm = 0;
  402.  
  403.     msg_sbuf.class = CODE_GO;
  404.     msg_sbuf.length = 0;
  405.  
  406.     (*msg_send)(&msg_sbuf);            /* send MiniMON message */
  407.     return errno_mm;
  408. }
  409.  
  410. /******************************************************************** UDI_STEP
  411.      UDIStep()  specifies  a  number  of  "instruction"
  412.      steps  to  make.  The step can be further qualified
  413.      to state whether CALLs  should  or  should  not  be
  414.      stepped over; whether TRAPs should or should not be
  415.      stepped over; and whether stepping should halt when
  416.      the PC gets outside a certain range.  The semantics
  417.      of UDIStep imply that progress  is  made;  ie;  at
  418.      least  one  instruction is executed before traps or
  419.      interrupts are handled.
  420. */
  421. UDIError UDIStep(steps, steptype, range)
  422. UINT32          steps;          /* in -- number of steps */
  423. UDIStepType   steptype;       /* in -- type of stepping to be done */
  424. UDIRange      range;          /* in -- range if StepInRange is TRUE */
  425. {
  426.     UDIError    errno_mm = 0;
  427.  
  428.     msg_sbuf.class = CODE_STEP;
  429.     msg_sbuf.length = 1*4;
  430.  
  431.     msg_sbuf.param[0] = steps;            /* number of steps */
  432.  
  433.     (*msg_send)(&msg_sbuf);            /* send MiniMON message */
  434.  
  435.     while( (*msg_recv)(&msg_rbuf) );        /* wait for reply */
  436.  
  437.     return errno_mm;
  438. }
  439.  
  440. /******************************************************************** UDI_STOP
  441.      UDIStop() stops the default process
  442. */
  443. UDIError UDIStop(stop_pc)
  444. UDIResource    *stop_pc;    /* out -- value of PC where we stopped */
  445. {
  446.     UDIError    errno_mm = 0;
  447.  
  448.     msg_sbuf.class = CODE_BREAK;
  449.     msg_sbuf.length = 0;
  450.  
  451.     (*msg_send)(&msg_sbuf);            /* send MiniMON message */
  452.     while( (*msg_recv)(&msg_rbuf) );        /* wait for reply */
  453.  
  454.     if(msg_rbuf.class == HALT)
  455.     stop_pc->Offset = msg_rbuf.param[2];        /* PC1 address */
  456.     stop_pc->Space =
  457.         MapSpace_mm2udi[msg_rbuf.param[0]];    /* address space  */
  458.     else
  459.     {
  460.     errno_mm = EMBADMSG;
  461.         if(msg_rbuf.class == ERROR)
  462.         errno_mm = msg_rbuf.param[0];
  463.     }
  464.     return errno_mm;
  465. }
  466.  
  467.  
  468. /******************************************************************* SIG_TIMER
  469. */
  470. void    sig_timer()
  471. {
  472. }
  473.  
  474. /******************************************************************** UDI_WAIT
  475.      UDIWait() returns the state of the target  proces-
  476.      sor.  The TIP is expected to return when the target
  477.      state is no longer RUNNING  or  when  maxtime  mil-
  478.      liseconds have elapsed; whichever comes first.  The
  479.      special maxtime value UDI_WAIT_FOREVER  essentially
  480.      means  that  the  DFE blocks until the target is no
  481.      longer RUNNING.  On completion; pid is used to  re-
  482.      port  which  process  stopped (necessary for multi-
  483.      process targets).  On completion; stop_pc is usual-
  484.      ly set to the PC where execution stopped.
  485.  
  486.      The return status STDIN_NEEDED allows  the  TIP  to
  487.      tell  the DFE that the target program is requesting
  488.      input  and  the  TIP's  own  internal   buffer   of
  489.      charcters is empty.  The DFE can inform the user of
  490.      this situation if it desires.
  491.  
  492.      Possible states are:
  493.          NOT_EXECUTING
  494.              RUNNING
  495.              STOPPED (due to UDIStop)
  496.              BREAK   (breakpoint hit)
  497.              STEPPED (completed number of steps requested by UDIStep)
  498.              WAITING (wait mode bit set)
  499.              HALTED  (at a halt instruction)
  500.              WARNED  (not executing because WARN line asserted)
  501.              TRAPPED (invalid trap taken; indicates trap number)
  502.              STDOUT_READY (stopped waiting for stdout to be output)
  503.              STDERR_READY (stopped waiting for stderr to be output)
  504.              STDIN_NEEDED (stopped waiting for stdin to be supplied)
  505. */
  506. UDIError UDIWait(maxtime, pid, stop_reason)
  507. INT32      maxtime;        /* in -- maximum time to wait for completion */
  508. UDIPID     *pid;           /* out -- pid of process which stopped if any */
  509. UINT32     *stop_reason;   /* out -- PC where process stopped */
  510. {
  511.     UDIError    errno_mm = 0;
  512.  
  513.     if(signal(SIGALRM, sig_timer)) == -1) errno_mm = 
  514.  
  515.  
  516.     return errno_mm;
  517. }
  518.  
  519. /********************************************************** UDI_SET_BREAKPOINT
  520.      UDISetBreakpoint() sets a breakpoint  at  an  ad-
  521.      dress  and  uses  the  passcount  to state how many
  522.      times that instruction should  be  hit  before  the
  523.      break  occurs.   The  passcount  continues to count
  524.      down; even if a different breakpoint is hit and  is
  525.      reinitialized  only when this breakpoint is hit.  A
  526.      passcount value of 0 indicates  a Temporary  break-
  527.      point  that  will  be  removed  whenever  execution
  528.      stops. A negative passcount indicates a non-sticky
  529.      breakpoint.
  530. */
  531. UDIError UDISetBreakpoint (addr, passcount, type, break_id)
  532. UDIResource    addr;        /* in -- where breakpoint gets set */
  533. INT32        passcount;    /* in -- passcount for breakpoint  */
  534. UDIBreakType    type;        /* in -- breakpoint type */
  535. INT32        *break_id;    /* out-- break number assigned */
  536. {
  537.     UDIError     errno_mm = 0;
  538.     bkpt_entry_t *bkpt_p = &bkpt_table[break_id];
  539.     int         cnt = 0;
  540.  
  541.     if(type != UDIBreakFlagExecute)
  542.     {    errno_mm = EMBKPTSET;
  543.     return errno_mm;
  544.     }
  545.     while( cnt < MAX_BKPT)        /* find BKPT slot in table */
  546.         if( !(bkpt_p->type) ) break;
  547.     else    cnt++;
  548.     if(cnt >= MAX_BKPT)
  549.     {    errno_mm = EMBKPTNONE;
  550.     return errno_mm;
  551.     }
  552.     bkpt_p->address.Offset = addr.Offset;
  553.     bkpt_p->address.Space  = addr.Space;
  554.     bkpt_p->passcount = passcount;
  555.     bkpt_p->type = type;
  556.     *break_id = cnt;
  557.    
  558.     msg_sbuf.class = CODE_SET_BKPT;
  559.     msg_sbuf.length = 4*4;
  560.  
  561.     msg_sbuf.param[0] = MapSpace_udi2mm[addr.Space];
  562.     msg_sbuf.param[1] = addr.Offset;
  563.     msg_sbuf.param[2] = passcount;
  564.     msg_sbuf.param[3] = -1;            /* non 050 breakpoint */
  565.  
  566.     (*msg_send)(&msg_sbuf);            /* send MiniMON message */
  567.     while( (*msg_recv)(&msg_rbuf) );        /* wait for reply */
  568.  
  569.     if(msg_rbuf.class == ERROR)
  570.     errno_mm = msg_rbuf.param[0];
  571.     else if(msg_rbuf.class != CODE_SET_BKPT_ACK)
  572.         errno_mm = EMBKPTSET;
  573.     return error_mm;
  574. }
  575.  
  576. /******************************************************** UDI_QUERY_BREAKPOINT
  577. */
  578. UDIError UDIQueryBreakpoint (break_id, addr, passcount, type, current_count)
  579. INT32        break_id;    /* in -- select brekpoint */
  580. UDIResource    *addr;        /* out - where breakpoint gets set */
  581. INT32        *passcount;    /* out - passcount for breakpoint  */
  582. UDIBreakType    *type;        /* out - breakpoint type */
  583. INT32        *current_count;    /* out - current passcount for breakpoint  */
  584. {
  585.     UDIError    errno_mm = 0;
  586.  
  587.     msg_sbuf.class = CODE_BKPT_STAT;
  588.     msg_sbuf.length = 2*4;
  589.  
  590.     msg_sbuf.param[0] = MapSpace_udi2mm[addr.Space];
  591.     msg_sbuf.param[1] = addr.Offset;
  592.  
  593.     (*msg_send)(&msg_sbuf);            /* send MiniMON message */
  594.     while( (*msg_recv)(&msg_rbuf) );        /* wait for reply */
  595.  
  596.     if(msg_rbuf.class == CODE_BKPT_STAT_ACK)
  597.     {
  598.     addr->Offset = bkpt_table[break_id].addr.Offset;
  599.     addr->Space  = bkpt_table[break_id].addr.Space;
  600.     *passcount = bkpt_table[break_id].passcount;
  601.     *type = bkpt_table[break_id].type;
  602.     *current_count = msg_rbuf.param[2];
  603.     }
  604.     else if(msg_rbuf.class == ERROR)
  605.     errno_mm = msg_rbuf.param[0];
  606.     else errno_mm = EMBKPTSTAT;
  607.     return errno_mm;
  608. }
  609.  
  610. /******************************************************** UDI_CLEAR_BREAKPOINT
  611.      UDIClearBreakpoint() is used to  clear  a  break-
  612.      point.
  613. */
  614. UDIError UDIClearBreakpoint (break_id)
  615. INT32        break_id;    /* in -- select brekpoint */
  616. {
  617.     UDIError     errno_mm = 0;
  618.     bkpt_entry_t *bkpt_p = &bkpt_table[break_id];
  619.  
  620.     msg_sbuf.class = CODE_RM_BKPT;
  621.     msg_sbuf.length = 2*4;
  622.  
  623.     msg_sbuf.param[0] = MapSpace_udi2mm[bkpt_p->Space];
  624.     msg_sbuf.param[1] = bkpt->Offset;
  625.  
  626.     (*msg_send)(&msg_sbuf);            /* send MiniMON message */
  627.     while( (*msg_recv)(&msg_rbuf) );        /* wait for reply */
  628.  
  629.     if(msg_rbuf.class == CODE_RM_BKPT_ACK)
  630.     {
  631.         bkpt->Space = 0;            /* invalidate BKPT entry */
  632.     }
  633.     else if(msg_rbuf.class == ERROR)
  634.     errno_mm = msg_rbuf.param[0];
  635.     else errno_mm = EMBKPTRM;
  636.     return errno_mm;
  637. }
  638.  
  639. /************************************************************** UDI_GET_STDOUT
  640.      UDIGetStdout()  is  called   when   a   call   to
  641.      UDIWait()  returns  with  the status STDOUT_READY.
  642.      The parameter "buf" specifies the DFE's buffer  ad-
  643.      dress  which  is  expected to be filled by the TIP.
  644.      The parameter "bufsize" specifies the size of  this
  645.      buffer.  On return; count_done is set to the number
  646.      of bytes actually written to buf.  The  DFE  should
  647.      keep  calling  UDIGetStdout() until count_done is
  648.      less than bufsize.
  649. */
  650. UDIError UDIGetStdout(buf, bufsize, count_done)
  651. UDIHostMemPtr    buf;        /* out -- buffer to be filled */
  652. CPUSizeT    bufsize;    /* in -- buffer size in bytes */
  653. CPUSizeT    *count_done;    /* out -- number of bytes written to buf */
  654. {
  655.     UDIError    errno_mm = EMBADMSG;
  656.  
  657.     return errno_mm;
  658. }
  659.  
  660. /************************************************************** UDI_GET_STDERR
  661.      UDIGetStderr()  is  called   when   a   call   to
  662.      UDIWait()  returns  with  the status STDERR_READY.
  663.      In   other    respects    it    is    similar    to
  664.      UDIGetStdout().
  665. */
  666. UDIError UDIGetStderr(buf, bufsize, count)
  667. UDIHostMemPtr buf;    /* out -- buffer to be filled */
  668. UINT32    bufsize;    /* in  -- buffer size in bytes */
  669. INT32    *count;        /* out -- number of bytes written to buf */
  670. {
  671.     UDIError    errno_mm = EMBADMSG;
  672.  
  673.     return errno_mm;
  674. }
  675.  
  676. /*************************************************************** UDI_PUT_STDIN
  677.      UDIPutStdin() is called whenever the DFE wants to
  678.      deliver an input character to the TIP.  This may be
  679.      in response to a status STDIN_NEEDED but  need  not
  680.      be.   (Some  target  operating  systems  will never
  681.      block for input).  Any buffering and  line  editing
  682.      of  the  stdin  characters is done under control of
  683.      the TIP.
  684. */
  685. INT32    UDIPutStdin (buf, bufsize, count)
  686. UDIHostMemPtr buf;    /* out - buffer to be filled */
  687. UINT32    bufsize;    /* in -- buffer size in bytes */
  688. INT32    *count;        /* out - number of bytes written to buf */
  689. {
  690.     UDIError    errno_mm = EMBADMSG;
  691.  
  692.     return errno_mm;
  693. }
  694.  
  695. /*************************************************************** UDI_PUT_TRANS
  696.      UDIPutTrans() is used to feed input to  the  pass-
  697.      thru  mode.   The  parameter "buf" is points to the
  698.      input data in DFE memory.   The  parameter  "count"
  699.      specifies the number of bytes.
  700. */
  701. INT32    UDIPutTrans (buf, count)
  702. UDIHostMemPtr    buf;    /* in -- buffer address containing input data */
  703. CPUSizeT    count;    /* in -- number of bytes in buf */
  704. {
  705.     UDIError    errno_mm = EMBADMSG;
  706.  
  707.     return errno_mm;
  708. }
  709.  
  710. /*************************************************************** UDI_GET_TRANS
  711.      UDIGetTrans() is used to get output lines from the
  712.      pass-thru mode The parameter "buf" specifies to the
  713.      buffer to be filled in DFE space.  "bufsize" speci-
  714.      fies the size of the buffer and; on return, "count"
  715.      is set to the number of bytes put  in  the  buffer.
  716.      The DFE should continue to call UDIGetTrans() un-
  717.      til count is less than bufsize.  Other possible re-
  718.      turn values are:
  719.              EOF -- leave transparent mode
  720.              UDI_GET_INPUT -- host should get  some  in-
  721.      put;                                  then     call
  722.      UDIPutTrans().
  723. */
  724. INT32    UDIGetTrans (buf, bufsize, count)
  725. UDIHostMemPtr    buf;        /* out -- buffer to be filled */
  726. CPUSizeT    bufsize;    /* in  -- size of buf */
  727. CPUSizeT    *count;        /* out -- number of bytes in buf */
  728. {
  729.     UDIError    errno_mm = EMBADMSG;
  730.  
  731.     return errno_mm;
  732. }
  733.